diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/CREDITS linux.ac/CREDITS --- linux.vanilla/CREDITS Sat Sep 11 00:54:01 1999 +++ linux.ac/CREDITS Sun Sep 19 17:38:38 1999 @@ -482,11 +482,11 @@ S: USA N: Alex deVries -E: puffin@redhat.com -D: Various SGI parts, bits of HAL2 and Newport -S: 18 Bernier Terrace -S: Kanata, Ontario -S: K2L 2V@ +E: adevries@thepuffingroup.com +D: Various SGI parts, bits of HAL2 and Newport, PA-RISC Linux. +S: 41.5 William Street +S: Ottawa, Ontario +S: K1N 6Z9 S: CANADA N: Eddie C. Dost @@ -858,6 +858,14 @@ S: 14059 Berlin S: Germany +N: David Hinds +E: dhinds@zen.stanford.edu +W: http://hyper.stanford.edu/~dhinds +D: PCMCIA and CardBus stuff, PCMCIA-HOWTO, PCMCIA client drivers +S: 2019 W. Middlefield Rd #1 +S: Mountain View, CA 94043 +S: USA + N: Michael Hipp E: hippm@informatik.uni-tuebingen.de D: drivers for the racal ni5210 & ni6510 Ethernet-boards @@ -1399,11 +1407,13 @@ E: acme@conectiva.com.br W: http://www.conectiva.com.br/~acme D: wanrouter hacking +D: USB hacking +D: miscellaneous Makefile & Config.in fixes D: Cyclom 2X synchronous card driver D: i18n for minicom, net-tools, util-linux, fetchmail, etc -S: Conectiva Informatica LTDA +S: Conectiva Informática LTDA S: R. Prof. Rubens Elke Braga, 558 - Parolin -S: 80220-320 Curitiba - Parana +S: 80220-320 Curitiba - Paraná S: Brazil N: Michael Meskes @@ -1628,6 +1638,13 @@ S: Tula 300000 S: Russia +N: Johnnie Peters +E: jpeters@phx.mcd.mot.com +D: Motorola PowerPC changes for PReP +S: 2900 S. Diable Way +S: Tempe, Arizona 85282 +S: USA + N: Kirk Petersen E: kirk@speakeasy.org W: http://www.speakeasy.org/~kirk/ @@ -1954,7 +1971,7 @@ S: Canada M2N 2Z1 N: Adrian Sun -E: asun@u.washington.edu +E: asun@cobaltnet.com D: hfs support D: alpha rtc port, random appletalk fixes S: Department of Zoology, University of Washington @@ -1997,9 +2014,9 @@ D: Miscellaneous kernel hacker D: Cyclom 2X driver hacker D: linuxconf apache & proftpd module maintainer -S: Conectiva Informatica LTDA +S: Conectiva Informática LTDA S: R. Prof. Rubens Elke Braga, 558 - Parolin -S: 80220-320 Curitiba - Parana +S: 80220-320 Curitiba - Paraná S: Brazil N: Stefan Traby @@ -2193,8 +2210,14 @@ N: David Weinehall E: tao@acc.umu.se -D: NE/2-driver maintainer +W: http://www.acc.umu.se/~tao/ +W: http://www.acc.umu.se/~mcalinux/ +D: Fixes for the NE/2-driver D: Miscellaneous MCA-support +D: Cleanup of the Config-files +S: Axtorpsvagen 40:20 +S: S-903 37 UMEA +S: Sweden N: Matt Welsh E: mdw@metalab.unc.edu diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/Documentation/CodingStyle linux.ac/Documentation/CodingStyle --- linux.vanilla/Documentation/CodingStyle Wed Jun 24 22:30:07 1998 +++ linux.ac/Documentation/CodingStyle Tue Sep 14 20:48:06 1999 @@ -210,3 +210,26 @@ "indent" has a lot of options, and especially when it comes to comment re-formatting you may want to take a look at the manual page. But remember: "indent" is not a fix for bad programming. + + + Chapter 7: Configuration-files + +For configuration options (arch/xxx/config.in, and all the Config.in files), +somewhat different indentation is used. + +An indention level of 3 is used in the code, while the text in the config- +options should have an indention-level of 2 to indicate dependencies. The +latter only applies to bool/tristate options. For other options, just use +common sense. An example: + +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate 'Apply nitroglycerine inside the keyboard (DANGEROUS)' CONFIG_BOOM + if [ "$CONFIG_BOOM" != "n" ]; then + bool ' Output nice messages when you explode' CONFIG_CHEER + fi +fi + +Generally, CONFIG_EXPERIMENTAL should surround all options not considered +stable. All options that are known to trash data (experimental write- +support for file-systems, for instance) should be denoted (DANGEROUS), other +Experimental options should be denoted (EXPERIMENTAL). diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/Documentation/Configure.help linux.ac/Documentation/Configure.help --- linux.vanilla/Documentation/Configure.help Sat Sep 11 00:54:01 1999 +++ linux.ac/Documentation/Configure.help Mon Sep 20 14:04:56 1999 @@ -74,9 +74,13 @@ MAINTAINERS, REPORTING_BUGS, Documentation/BUG-HUNTING, and Documentation/oops-tracing.txt in the kernel source). + This option will also make obsoleted drivers available. These are + drivers that have been replaced by something else, and/or are + scheduled to be removed in a future kernel release. + Unless you intend to help test and develop a feature or driver that falls into this category, or you have a situation that requires - using these features you should probably say N here, which will + using these features, you should probably say N here, which will cause this configure script to present you with fewer choices. If you say Y here, you will be offered the choice of using features or drivers that are currently considered to be in the alpha-test phase. @@ -162,7 +166,7 @@ time indication of CPU usage, by lighting whenever the idle task is not currently executing. -Kernel FP software completion +Kernel FP software completion (EXPERIMENTAL) CONFIG_MATHEMU This option is required for IEEE compliant floating point arithmetic on the Alpha. The only time you would ever not say Y is to say M in @@ -1306,7 +1310,7 @@ http://lena.fnet.fr/ (To browse the WWW, you need to have access to a machine on the Internet that has a program like lynx or netscape). -Support for Algorithmics P4032 +Support for Algorithmics P4032 (EXPERIMENTAL) CONFIG_ALGOR_P4032 This is an evaluation board of the British company Algorithmics. The board uses the R4300 and a R5230 CPUs. For more information about @@ -1600,7 +1604,7 @@ If you want to use your SGI's built-in serial ports under Linux, answer Y. -SGI Newport Graphics support +SGI Newport Graphics support (EXPERIMENTAL) CONFIG_SGI_NEWPORT_GFX If you have an SGI machine and you want to compile the graphics drivers, say Y here. This will include the code for the @@ -1828,7 +1832,7 @@ you have use for it; the module is called binfmt_misc.o. If you don't know what to answer at this point, say Y. -Solaris binary emulation +Solaris binary emulation (EXPERIMENTAL) CONFIG_SOLARIS_EMUL This is experimental code which will enable you to run (many) Solaris binaries on your SPARC Linux machine. @@ -1989,7 +1993,7 @@ This enables support for Cirrus Logic GD542x/543x based boards on Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum. If you have a PCI-based system, this enables support for these chips: - GD-543x, GD-544x, GD-5480. + GD-543x, GD-544x, GD-546x (Laguna), or GD-5480. Say N unless you have such a graphics board or plan to get one before you next recompile the kernel. @@ -2020,7 +2024,7 @@ If you have a S3 Trio say Y. Say N for S3 Virge. ATI Mach64 display support -CONFIG_FB_ATY +CONFIG_FB_ATY (EXPERIMENTAL) This driver supports graphics boards with the ATI Mach64 chips. PowerMac "control" frame buffer device support @@ -2077,7 +2081,7 @@ includes a server that supports the frame buffer device directly (XF68_FBDev). -Matrox unified accelerated driver +Matrox unified accelerated driver (EXPERIMENTAL) CONFIG_FB_MATROX Say Y here if you have Matrox Millennium, Matrox Millennium II, Matrox Mystique, Matrox Mystique 220, Matrox Productiva G100, Matrox @@ -2819,7 +2823,7 @@ Say Y unless you know what you are doing. -The IPv6 protocol +The IPv6 protocol (EXPERIMENTAL) CONFIG_IPV6 This is experimental support for the next version of the Internet Protocol: IP version 6 (also called IPng "IP next generation"). @@ -2946,7 +2950,7 @@ The module will be called af_spx.o. If you want to compile it as a module, say M here and read Documentation/modules.txt. -DECnet networking +DECnet networking (EXPERIMENTAL) CONFIG_DECNET The DECnet networking protocol was used in many products made by Digital (now Compaq). It provides reliable stream and sequenced @@ -2971,7 +2975,7 @@ use this system call and the proper way to get the information provided by this call is to use rtnetlink. -DECnet Router Support +DECnet Router Support (EXPERIMENTAL) CONFIG_DECNET_ROUTER Add support for turning your DECnet Endnode into a level 1 or 2 router. This is an unfinished option for developers only. If you @@ -3460,7 +3464,7 @@ can only use one protocol at a time, depending on what the other end can understand). -CCITT X.25 Packet Layer +CCITT X.25 Packet Layer (EXPERIMENTAL) CONFIG_X25 X.25 is a set of standardized network protocols, similar in scope to frame relay; the one physical line from your box to the X.25 network @@ -3512,7 +3516,7 @@ want), say M here and read Documentation/modules.txt. The module will be called lapb.o. If unsure, say N. -802.2 LLC (VERY EXPERIMENTAL) +802.2 LLC (EXPERIMENTAL) CONFIG_LLC This is a Logical Link Layer protocol used for X.25 connections over Ethernet, using ordinary Ethernet cards. @@ -3843,14 +3847,15 @@ about anything having "SCSI" in its name other than hard disks, CDROMs or tapes, say Y here. These won't be supported by the kernel directly, so you need some additional software which knows how to - talk to these devices using the SCSI protocol. For CD-writers, you - would need the program cdwrite, available via FTP (user: anonymous) - from ftp://metalab.unc.edu/pub/Linux/utils/disk-management; for - other devices, it's possible that you'll have to write the driver - software yourself, so have a look at the SCSI-HOWTO and at the - SCSI-Programming-HOWTO, both available via FTP (user: anonymous) in - ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Please read the file - Documentation/scsi-generic.txt for more information. + talk to these devices using the SCSI protocol. For scanners, look at + SANE (www.mostang.com/sane). For CD writer software look at cdrecord + (www.fokus.gmd.de/research/cc/glone/employees/joerg.schilling/private + /cdrecord.html) and for burning a "disk at once": cdrdao + (www.ping.de/sites/daneb/cdrdao.html). Cdparanoia is a high quality + digital reader of audio CDs (www.xiph.org/paranoia). + For other devices, it's possible that you'll have to write the driver + software yourself. Please read the file Documentation/scsi-generic.txt + for more information. If you want to compile this as a module ( = code which can be inserted in and removed from the running kernel whenever you want), @@ -4066,6 +4071,15 @@ does not work correctly without modification please contact the author by email at ipslinux@us.ibm.com. +IBM ServeRAID Support +CONFIG_SCSI_IPS + This is support for the IBM ServeRAID hardware RAID controllers. + Consult the SCSI-HOWTO, available via anonymous FTP from + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO, and the file + README.ips in drivers/scsi for more information. If this driver + does not work correctly without modification please contact the + author by email at ipslinux@us.ibm.com. + BusLogic SCSI support CONFIG_SCSI_BUSLOGIC This is support for BusLogic MultiMaster and FlashPoint SCSI Host @@ -4277,7 +4291,13 @@ MB/s with wide FAST-40 LVD devices and controllers. Recent versions of the 53C8XX chips are better supported by the - option "SYM53C8XX SCSI support", below. + option "SYM53C8XX SCSI support", below. This option will configure + a different driver. + + If you want the kernel to select the recommended driver for each of + of your NCR/SYM53C8XX controllers you may just configure both the + NCR53C8XX and the SYM53C8XX options to Y, or if modules are preferred, + load first the sym53c8xx.o module and then the ncr53c8xx.o module. Note: there is yet another driver for the 53c8xx family of controllers ("NCR53c7,8xx SCSI support" above). If you want to use them both, @@ -4396,7 +4416,7 @@ There is no safe option and the default answer is recommended. -assume boards are SYMBIOS compatible +assume boards are SYMBIOS compatible (EXPERIMENTAL) CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT This option allows you to enable some features depending on GPIO wiring. These General Purpose Input/Output pins can be used for @@ -4933,7 +4953,7 @@ Generally, saying N is fine. -SCSI Debug host simulator. +SCSI Debugging host simulator (EXPERIMENTAL) CONFIG_SCSI_DEBUG This is a host adapter simulator that can be programmed to simulate a large number of conditions that could occur on a real bus. The @@ -4995,7 +5015,7 @@ This enables support for the Cumana SCSI I card. If you have an Acorn system with one of these, say Y. If unsure, say N. -Cumana SCSI II support +Cumana SCSI II support (EXPERIMENTAL) CONFIG_SCSI_CUMANA_2 This enables support for the Cumana SCSI II card. If you have an Acorn system with one of these, say Y. If unsure, say N. @@ -5006,12 +5026,12 @@ in the Econet socket. If you have an Acorn system with one of these, say Y. If unsure, say N. -EESOX SCSI support +EESOX SCSI support (EXPERIMENTAL) CONFIG_SCSI_EESOXSCSI This enables support for the EESOX SCSI card. If you have an Acorn system with one of these, say Y, otherwise say N. -Powertec SCSI support +Powertec SCSI support (EXPERIMENTAL) CONFIG_SCSI_POWERTECSCSI This enables support for the Powertec SCSI card on Acorn systems. If you have one of these, say Y. If unsure, say N. @@ -5305,6 +5325,23 @@ The kernels on both machines need to have this PLIP option enabled for this to work. + The plipconfig utility, can be used to change several parameters + of the plip driver once it has been opened. It is part of the net-tools + package, whose location and current version number is contained in + the file Documentation/Changes. + + This drivers performs better if the parallel port used has an IRQ + associated with it, but can also work in poll mode with no IRQ. + If IRQ-less mode is used, it is required to change the trigger timeout + on the *other* side of the connection to about 10000usec (on a i386), + though values as small as 5000usec are known to work. If both sides are + used in IRQ-less mode, both sides need to use said trigger timeout. + In order to perform this change on a Linux, the command + 'plipconfig plipX trigger 10000' can be used, where plipX is the + appropriate PLIP device. + For a discussion on the trigger timeout, see + Documentation/networking/PLIP.txt. + The PLIP driver has two modes, mode 0 and mode 1. The parallel ports (the connectors at the computers with 25 holes) are connected with "null printer" or "Turbo Laplink" cables which can transmit 4 bits @@ -5353,7 +5390,7 @@ module, say M here and read Documentation/modules.txt. If unsure, say N. -Ethertap network tap +Ethertap network tap (EXPERIMENTAL) CONFIG_ETHERTAP If you say Y here (and have said Y to "Kernel/User network link driver", above) and create a character special file /dev/tap0 with @@ -5521,7 +5558,7 @@ full bandwidth of your network connection, try saying Y here. If unsure, say N. -QoS and/or fair queueing +QoS and/or fair queueing (EXPERIMENTAL) CONFIG_NET_SCHED When the kernel has several packets to send out over the network devices, it has to make a decision which one to send first. This is @@ -5726,6 +5763,18 @@ whenever you want). If you want to compile it as a module, say M here and read Documentation/modules.txt. +SBNI Leased Line Adapters +CONFIG_SBNI + This is a driver for ISA SBNI12-xx cards that is a low cost + alternative to leased line modems. Say Y if you want to insert + driver into kernel or say M to compile driver as a module. + + You can find more information and last versions of drivers and + utilities at http://www.granch.ru. If you have any question you + can mail to sbni@granch.ru. + + Say N if unsure. + WAN Drivers CONFIG_WAN_DRIVERS Say Y to this option if your Linux box contains a WAN card and you @@ -5790,7 +5839,7 @@ you say N, the PPP support will not be included in the driver (saves about 16 KB of kernel memory). -Cyclom 2X(tm) multiprotocol cards +Cyclom 2X(tm) multiprotocol cards (EXPERIMENTAL) CONFIG_CYCLADES_SYNC Cyclom 2X from Cyclades Corporation (http://www.cyclades.com and http://www.cyclades.com.br; to browse the WWW, you need to have @@ -5962,6 +6011,18 @@ module, say M here and read Documentation/modules.txt as well as Documentation/networking/net-modules.txt. +PCI DM9102 support +CONFIG_DM9102 + This driver is for DM9102 compatible PCI cards from Davicom + (http://www.davicom.com.tw) + If you have a PCI DM9102 network (Ethernet) card, say Y. + + This driver is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called dmfe.o. If you want to compile it as a + module, say M here and read Documentation/modules.txt as well as + Documentation/networking/net-modules.txt. + Racal-Interlan (Micom) NI cards CONFIG_NET_VENDOR_RACAL If you have a network (Ethernet) card belonging to this class, such @@ -5974,7 +6035,7 @@ the questions about NI cards. If you say Y, you will be asked for your specific card in the following questions. -NI5010 support +NI5010 support (EXPERIMENTAL) CONFIG_NI5010 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in @@ -6011,7 +6072,7 @@ module, say M here and read Documentation/modules.txt as well as Documentation/networking/net-modules.txt. -RealTek 8129/8139 (not 8019/8029!) support +RealTek 8129/8139 (not 8019/8029!) support (EXPERIMENTAL) CONFIG_RTL8139 This is a driver for the Fast Ethernet PCI network cards based on the RTL8129 and RTL8139 chips. If you have one of those, say Y and @@ -6023,7 +6084,7 @@ say M here and read Documentation/modules.txt. This is recommended. The module will be called rtl8139.o. -Packet Engines Yellowfin Gigabit-NIC support +Packet Engines Yellowfin Gigabit-NIC support (EXPERIMENTAL) CONFIG_YELLOWFIN Say Y here if you have a Packet Engines G-NIC PCI Gigabit Ethernet adapter. This adapter is used by the Beowulf Linux cluster project. @@ -6056,7 +6117,7 @@ If you don't have this card, of course say N. -Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support +Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support (EXPERIMENTAL) CONFIG_ACENIC Say Y here if you have an Alteon AceNIC, 3Com 3C985(B), NetGear GA620, SGI Gigabit or Farallon PN9000-SX PCI Gigabit Ethernet @@ -6144,7 +6205,7 @@ Documentation/networking/net-modules.txt. The module will be called 3c505.o. -3c507 support +3c507 support (EXPERIMENTAL) CONFIG_EL16 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in @@ -6374,7 +6435,7 @@ Documentation/networking/net-modules.txt. The module will be called ewrk3.o. -SEEQ8005 support +SEEQ8005 support (EXPERIMENTAL) CONFIG_SEEQ8005 This is a driver for the SEEQ 8005 network (Ethernet) card. If this is for you, read the Ethernet-HOWTO, available via FTP (user: @@ -6560,7 +6621,7 @@ module, say M here and read Documentation/modules.txt as well as Documentation/networking/net-modules.txt. -Mylex EISA LNE390A/LNE390B support +Mylex EISA LNE390A/LNE390B support (EXPERIMENTAL) CONFIG_LNE390 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in @@ -6572,7 +6633,7 @@ module, say M here and read Documentation/modules.txt as well as Documentation/networking/net-modules.txt. -Novell/Eagle/Microdyne NE3210 EISA support +Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL) CONFIG_NE3210 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in @@ -6658,7 +6719,7 @@ module, say M here and read Documentation/modules.txt as well as Documentation/networking/net-modules.txt. -ICL EtherTeam 16i/32 support +ICL EtherTeam 16i/32 support (EXPERIMENTAL) CONFIG_ETH16I If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in @@ -6700,7 +6761,7 @@ a module, say M here and read Documentation/modules.txt as well as Documentation/networking/net-modules.txt. -Racal-Interlan EISA ES3210 support +Racal-Interlan EISA ES3210 support (EXPERIMENTAL) CONFIG_ES3210 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in @@ -6730,7 +6791,7 @@ Say Y here if you have an Seeq based Ethernet network card. This is used in many Silicon Graphics machines. -Zenith Z-Note support +Zenith Z-Note support (EXPERIMENTAL) CONFIG_ZNET The Zenith Z-Note notebook computer has a built-in network (Ethernet) card, and this is the Linux driver for it. Note that the @@ -7225,13 +7286,6 @@ ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini. Probably the quota support is only useful for multi user systems. If unsure, say N. -Acorn's ADFS filesystem support (read only) (EXPERIMENTAL) -CONFIG_ADFS_FS - The Advanced Disk File System is the filesystem used on floppy and - hard disks by Acorn Systems. Currently in development, as a read- - only driver for hard disks. These should be the first partition - (eg. /dev/[sh]d?1) on each of your drives. If unsure, say N. - Minix fs support CONFIG_MINIX_FS Minix is a simple operating system used in many classes about OS's. @@ -7324,7 +7378,7 @@ like lynx or netscape). Say Y here if you want to be able to read Joliet CDROMs under Linux. -UDF Filesystem support +UDF Filesystem support (read only) CONFIG_UDF_FS This is the new filesystem used by some CDROMS and DVD drivers. Say Y if you intend to mount DVD discs or CDRWs written in packet mode, @@ -7524,7 +7578,7 @@ Most people say N here. -NFS server support +NFS server support (EXPERIMENTAL) CONFIG_NFSD If you want your Linux box to act as a NFS *server*, so that other computers on your local network which support NFS can access certain @@ -7552,7 +7606,7 @@ directories that are mount points on the local filesystem (this is how nfsd behaves on Sun systems), say yes here. If unsure, say N. -OS/2 HPFS filesystem support (read/write) +OS/2 HPFS filesystem support CONFIG_HPFS_FS OS/2 is IBM's operating system for PC's, the same as Warp, and HPFS is the filesystem used for organizing files on OS/2 hard disk @@ -7589,7 +7643,7 @@ The module will be called ntfs.o. If you want to compile it as a module, say M here and read Documentation/modules.txt. -NTFS read-write support (experimental) +NTFS write support (DANGEROUS) CONFIG_NTFS_RW If you say Y here, you will (hopefully) be able to write to NTFS file systems as well as read from them. The read-write support @@ -7656,7 +7710,7 @@ The module is called affs.o. If you want to compile it as a module, say M here and read Documentation/modules.txt. If unsure, say N. -Apple Macintosh filesystem support (experimental) +Apple Macintosh filesystem support (EXPERIMENTAL) CONFIG_HFS_FS If you say Y here, you will be able to mount Macintosh-formatted floppy disks and hard drive partitions with full read-write access. @@ -7683,7 +7737,7 @@ If you don't know whether you need it, then you don't need it: answer N. -QNX filesystem support (EXPERIMENTAL) +QNX filesystem support (read only) (EXPERIMENTAL) CONFIG_QNX4FS_FS This is the filesystem used by the operating system QNX 4. Say Y if you intend to mount QNX hard disks or floppies. Unless you say Y to @@ -7697,7 +7751,7 @@ If unsure, say N. -QNXFS read-write support (FOR TESTING ONLY) +QNXFS write support (DANGEROUS) CONFIG_QNX4FS_RW Say Y if you want to test write support for QNX filesystems. @@ -7720,7 +7774,7 @@ If you are not a part of a fairly large, distributed network, you probably do not need an automounter, and can say N here. -UFS filesystem support +UFS filesystem support (read only) CONFIG_UFS_FS BSD and derivate versions of Unix (such as SunOS, FreeBSD, NetBSD, OpenBSD and NeXTstep) use a filesystem called UFS. Some System V @@ -7750,12 +7804,12 @@ If you haven't heard about all of this before, it's safe to say N. -UFS filesystem write support (experimental) +UFS filesystem write support (DANGEROUS) CONFIG_UFS_FS_WRITE Say Y here if you want to try writing to UFS partitions. This is experimental, so you should back up your UFS partitions beforehand. -EFS filesystem support (experimental) +EFS filesystem support (read only) (EXPERIMENTAL) CONFIG_EFS_FS EFS is the filesystem used for CDROMs and filesystems by SGI's IRIX. This implementation only offers read-only access. If you don't know @@ -7767,18 +7821,6 @@ Say Y to this only if you plan on mounting disks with SGI disklabels. This is not required to mount EFS-format CDROMs. -EFS filesystem support (experimental) -CONFIG_EFS_FS - EFS is the filesystem used for CDROMs and filesystems by SGI's IRIX. - This implementation only offers read-only access. If you don't know - what all this is about, it's safe to say N. For more information - about EFS see it's homepage at http://aeschi.ch.eu.org/efs. - -SGI disklabel support -CONFIG_SGI_DISKLABEL - Say Y to this only if you plan on mounting disks with SGI disklabels. - This is not required to mount EFS-format CDROMs. - BSD disklabel (FreeBSD partition tables) support CONFIG_BSD_DISKLABEL FreeBSD uses its own hard disk partition scheme on your PC. It @@ -8614,7 +8656,7 @@ and read Documentation/modules.txt. The module will be called esp.o. If unsure, say N. -Multi-Tech multiport card support +Multi-Tech multiport card support (EXPERIMENTAL) CONFIG_ISI This is a driver for the Multi-Tech cards which provide several serial ports. The driver is experimental and can currently only be @@ -8926,7 +8968,7 @@ backup programs assume for SCSI tape drives) or `1' (no restriction on block size, but disables builtin compression). -Number of DMA buffers +Number of DMA buffers (EXPERIMENTAL) CONFIG_FT_NR_BUFFERS Please leave this at `3' unless you REALLY know what you are doing. It is not necessary to change this value. Values below 3 make the @@ -9096,7 +9138,7 @@ short description of the parameters that can be set at boot or load time. -FDC FIFO Threshold before requesting DMA service +FDC FIFO Threshold before requesting DMA service (EXPERIMENTAL) CONFIG_FT_FDC_THR Set the FIFO threshold of the FDC. If this is higher the DMA controller may serve the FDC after a higher latency time. If this is @@ -9107,7 +9149,7 @@ If unsure, don't touch the initial value, i.e. leave it at "8". -FDC maximum data rate +FDC maximum data rate (EXPERIMENTAL) CONFIG_FT_FDC_MAX_RATE With some motherboard/FDC combinations ftape will not be able to run your FDC/tape drive combination at the highest available @@ -9140,6 +9182,9 @@ The AMD K6-2 (stepping 8 and above) and K6-3 processors have two MTRRs. These are supported. + + The AMD Athlon (K7) uses exactly the same MTRR architecture as + the Intel P6 family and this processor is supported by this driver. The Centaur C6 (WinChip) has 8 MCRs, allowing write-combining. These are supported. @@ -9365,11 +9410,12 @@ your computer. For details, read Documentation/watchdog.txt in the kernel source. - The watchdog is usually used together with the watchdog daemon - which is available via FTP (user: anonymous) from - ftp://tsx-11.mit.edu/pub/linux/sources/sbin/. This daemon can also - monitor NFS connections and can reboot the machine when the process - table is full. + The watchdog is usually used together with the watchdog daemon which is + available via FTP (user: anonymous) from + ftp://metalab.unc.edu/pub/linux/system/daemons/watchdog. This daemon can + check a larger part of the system. For instance it can monitor NFS + connections and reboot the machine when the process table is full or the + workload exceeds a predefined value. If unsure, say N. @@ -9744,20 +9790,6 @@ You can say M here to compile this driver as a module; the module is called sb.o. -Generic OPL2/OPL3 FM synthesizer support -CONFIG_SOUND_ADLIB - Answer Y if your card has a FM chip made by Yamaha (OPL2/OPL3/OPL4). - Answering Y is usually a safe and recommended choice, however some - cards may have software (TSR) FM emulation. Enabling FM support with - these cards may cause trouble (I don't currently know of any such - cards, however). - - Please read the file Documentation/sound/OPL3 if your card has an - OPL3 chip. - - If unsure, say Y. - - #Loopback MIDI device support #CONFIG_SOUND_VMIDI ### @@ -10027,7 +10059,15 @@ FM synthesizer (YM3812/OPL-3) support CONFIG_SOUND_YM3812 - Answer Y here, unless you know you will not need the option. + Answer Y if your card has a FM chip made by Yamaha (OPL2/OPL3/OPL4). + Answering Y is usually a safe and recommended choice, however some + cards may have software (TSR) FM emulation. Enabling FM support with + these cards may cause trouble (I don't currently know of any such + cards, however). + Please read the file Documentation/sound/OPL3 if your card has an + OPL3 chip. + + If unsure, say Y. Sun Audio support CONFIG_SUN_AUDIO @@ -10224,6 +10264,23 @@ Say Y here to include support for the Rockwell WaveArtist sound system. This driver is mainly for the NetWinder. +VIA 82Cxxx Audio Codec +CONFIG_SOUND_VIA82CXXX + Say Y here to include support for the audio codec found on + VIA 82Cxxx-based chips. Typically these are built into a motherboard. + DO NOT select SoundBlaster or Adlib with this driver, unless you have + a SoundBlaster or Adlib card in addition to your VIA audio chip. + +NeoMagic 256AV/256ZX sound chipsets +CONFIG_SOUND_NM256 + Say M here to include audio support for the NeoMagic 256AV/256ZX + chipsets. These are the audio chipsets found in the Sony Z505S/SX/DX, + some Sony F-series, and the Dell Latitude CPi and CPt laptops. It includes + support for an AC97-compatible mixer and an apparently proprietary sound + engine. + + See Documentation/sound/NM256 for further information. + Are you using a crosscompiler CONFIG_CROSSCOMPILE Say Y here if you are compiling the kernel on a different @@ -10635,7 +10692,7 @@ This is the driver for the Sun ESP SCSI host adapter. The ESP chipset is present in most SPARC-based computers. -SPARC /dev/openprom compatibility driver +SPARC /dev/openprom compatibility driver (EXPERIMENTAL) CONFIG_SUN_OPENPROMIO This driver provides user programs with an interface to the SPARC PROM device tree. The driver implements a SunOS-compatible @@ -10734,7 +10791,7 @@ If you anticipate running this kernel on a computer with a MC68060 processor, say Y. Otherwise, say N. -Math emulation support +Math emulation support (EXPERIMENTAL) CONFIG_M68KFPU_EMU At some point in the future, this will cause floating-point math instructions to be emulated by the kernel on machines that lack a @@ -10793,6 +10850,7 @@ Note that even if you say N here, you can still use your expansion cards. If in doubt, say Y. +Amiga 1200/600 PCMCIA support (EXPERIMENTAL) CONFIG_AMIGA_PCMCIA Include support in the kernel for pcmcia on Amiga 1200 and Amiga 600. If you intend to use pcmcia cards say Y; otherwise say N. @@ -10924,7 +10982,7 @@ 1260 accelerator, and the optional SCSI module, say Y. Otherwise, say N. -Blizzard PowerUP 603e+ SCSI support +Blizzard PowerUP 603e+ SCSI support (EXPERIMENTAL) CONFIG_BLZ603EPLUS_SCSI If you have an Amiga 1200 with a Phase5 Blizzard PowerUP 603e+ accelerator, say Y. Otherwise, say N. @@ -11108,7 +11166,7 @@ want). If you want to compile it as a module, say M here and read Documentation/modules.txt. -Atari DSP56k Digital Signal Processor support +Atari DSP56k Digital Signal Processor support (EXPERIMENTAL) CONFIG_ATARI_DSP56K If you want to be able to use the DSP56001 in Falcons, say Y. This driver is still experimental, and if you don't know what it is, or @@ -11502,6 +11560,25 @@ Enter either 0x20c, 0x30c, 0x24c or 0x34c here. The card default is 0x34c, if you haven't changed the jumper setting on the card. +Trust FM Radio Card +CONFIG_RADIO_TRUST + Choose Y here if you have this FM radio card, and then fill in the + port address below. + + In order to control your radio card, you will need to use programs + that are compatible with the Video for Linux API. Information on + this API and pointers to "v4l" programs may be found at + http://roadrunner.swansea.uk.linux.org/v4l.shtml. + + If you want to compile this driver as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read Documentation/modules.txt. The module will be + called radio-trust.o. + +Trust FM Radio I/O port +CONFIG_RADIO_TRUST_PORT + Enter the I/O port of your card (usually 0x350 or 0x358). + PlanB Video-In for PowerMacs CONFIG_VIDEO_PLANB PlanB is the V4L driver for the PowerMac 7x00/8x00 series video @@ -11688,7 +11765,7 @@ to crash during startup when this option is enabled. Say Y unless you experience problems that you suspect may be caused by this. -Disable pgtable cache +Disable pgtable cache (EXPERIMENTAL) CONFIG_NO_PGT_CACHE Normally the kernel maintains a `quicklist' of preallocated pagetable structures in order to increase performance. On machines with very @@ -11711,7 +11788,7 @@ time by entering them here. As a minimum, you should specify the memory size and the root device (eg, mem=64M root=/dev/nfs) -Hardware alignment trap +Hardware alignment trap (EXPERIMENTAL) CONFIG_ALIGNMENT_TRAP ARM processors can not fetch/store information which is not naturally aligned on the bus, ie, a 4 byte fetch must start at an address divisable @@ -11818,7 +11895,7 @@ If you say Y here, you also need to say Y or M to a compression protocol below. -IrLAP Deflate Compression Protocol +IrLAP Deflate Compression Protocol (EXPERIMENTAL) CONFIG_IRDA_DEFLATE Say Y here if you want to build support for the Deflate compression protocol. The deflate compression (GZIP) is exactly @@ -12041,7 +12118,7 @@ boards from BVM Ltd. Everyone using one of these boards should say Y here. -Universal Serial Bus (USB) Support (Experimental) +Universal Serial Bus (USB) support (EXPERIMENTAL) CONFIG_USB This will enable support for the Universal Serial Bus (USB). USB allows you to connect up to 127 external devices such as keyboards, @@ -12147,7 +12224,7 @@ It is safe to say N to this -- it is not needed for normal printing or parallel port CD-ROM/disk support. -Kernel httpd acceleration (experimental) +Kernel httpd acceleration (EXPERIMENTAL) CONFIG_KHTTPD The kernel httpd acceleration daemon (kHTTPd) is a (limited) webserver build into the kernel. It is limited since it can only @@ -12167,6 +12244,8 @@ # capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet, # Intel, IRQ, Linux, MSDOS, NetWare, NetWinder, NFS, # PCI, SCSI, SPARC +# capitalize +# comments: DANGEROUS, EXPERIMENTAL, OBSOLETE # two words: hard drive, hard disk, sound card, home page # other: it's safe to save; daemon; use --, not - or --- # diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/Documentation/fb/clgenfb.txt linux.ac/Documentation/fb/clgenfb.txt --- linux.vanilla/Documentation/fb/clgenfb.txt Sat Sep 11 00:54:01 1999 +++ linux.ac/Documentation/fb/clgenfb.txt Sat Sep 11 19:31:00 1999 @@ -45,9 +45,7 @@ Version 1.9.4.4 --------------- * Preliminary Laguna support -* Overhaul color register routines. Shifts are now based on offset - values in var.cmap, so as long as those are correctly set for PReP - things should work (knock on wood). +* Overhaul color register routines. * Associated with the above, console colors are now obtained from a LUT called 'palette' instead of from the VGA registers. This code was modeled after that in atyfb and matroxfb. diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/Documentation/filesystems/proc.txt linux.ac/Documentation/filesystems/proc.txt --- linux.vanilla/Documentation/filesystems/proc.txt Thu Jan 1 01:00:00 1970 +++ linux.ac/Documentation/filesystems/proc.txt Wed Sep 15 23:53:21 1999 @@ -0,0 +1,1379 @@ + +----------------------------------------------------------------------- + + T H E /proc F I L E S Y S T E M + +----------------------------------------------------------------------- +/proc/sys Terrehon Bowden January 27 1999 + Bodo Bauer +----------------------------------------------------------------------- +Version 1.1 Kernel version 2.2 +----------------------------------------------------------------------- +Contents + +1 Introduction/Credits + +1.1 Legal Issues + +2 The /proc file system + +2.1 Process specific subdirectories +2.2 Kernel data +2.3 IDE devices in /proc/ide +2.4 Networking info in /proc/net +2.5 SCSI info +2.6 Parallel port info in /proc/parport +2.7 TTY info in /proc/tty + +3 Reading and modifying kernel parameters + +3.1 /proc/sys/debug and /proc/sys/proc +3.2 /proc/fs - File system data +3.3 /proc/fs/binfmt_misc - Miscellaneous binary formats +3.4 /proc/sys/kernel - General kernel parameters +3.5 /proc/sys/vm - The virtual memory subsystem +3.6 /proc/sys/dev - Device specific parameters +3.7 /proc/sys/sunrpc - Remote procedure calls +3.8 /proc/sys/net - Networking stuff +3.9 /proc/sys/net/ipv4 - IPV4 settings=20 +3.10 Appletalk +3.11 IPX + +----------------------------------------------------------------------- + +1 Introduction/Credits + +This documentation is part of a soon to be released book published by +IDG Books on the SuSE Linux distribution. As there is no complete +documentation for the /proc file system and we've used many freely +available sources to write this chapter, it seems only fair to give +the work back to the Linux community. This work is based on the +2.1.132 and 2.2.0-pre-kernel versions. I'm afraid it's still far from +complete, but we hope it will be useful. As far as we know, it is the +first 'all-in-one' document about the /proc file system. It is +focused on the Intel x86 hardware, so if you are looking for PPC, ARM, +SPARC, APX, etc., features, you probably won't find what you are +looking for. It also only covers IPv4 networking, not IPv6 nor other +protocols - sorry. + +We'd like to thank Alan Cox, Rik van Riel, and Alexey Kuznetsov. We'd +also like to extend a special thank you to Andi Kleen for +documentation, which we relied on heavily to create this document, as +well as the additional information he provided. Thanks to everybody +else who contributed source or docs to the Linux kernel and helped +create a great piece of software... :) + +If you have any comments, corrections or additions, please don't +hesitate to contact Bodo Bauer at bb@ricochet.net. We'll be happy to +add them to this document. + +The latest version of this document is available online at +http://www.suse.com/~bb/Docs/proc.html in HTML, ASCII, and as +Postscript file. + +1.1 Legal Stuff + +We don't guarantee the correctness of this document, and if you come +to us complaining about how you screwed up your system because of +incorrect documentation, we won't feel responsible... + +----------------------------------------------------------------------- + +2 The /proc file system + +The proc file system acts as an interface to internal data structures +in the kernel. It can be used to obtain information about the system +and to change certain kernel parameters at runtime. It contains +(among other things) one subdirectory for each process running on the +system which is named after the process id (PID) of the process. The +link self points to the process reading the file system. + +2.1 Process specific subdirectories + +Each process subdirectory has the in table 1.1 listed entries. + + _________________________________________________ + cmdline Command line arguments + environ Values of environment variables + fd Directory, which contains all file descriptors + mem Memory held by this process + stat Process status + status Process status in human readable form + cwd Link to the current working directory + exe Link to the executable of this process + maps Memory maps + root Link to the root directory of this process + statm Process memory status information + _________________________________________________ + Table 1.1: Process specific entries in /proc + +For example, to get the status information of a process, all you have +to do is read the file /proc/PID/status: + +> cat /proc/self/status +Name: cat +State: R (running) +Pid: 5633 +PPid: 5609 +Uid: 501 501 501 501 +Gid: 100 100 100 100 +Groups: 100 16 +VmSize: 804 kB +VmLck: 0 kB +VmRSS: 344 kB +VmData: 68 kB +VmStk: 20 kB +VmExe: 12 kB +VmLib: 660 kB +SigPnd: 0000000000000000 +SigBlk: 0000000000000000 +SigIgn: 0000000000000000 +SigCgt: 0000000000000000 +CapInh: 00000000fffffeff +CapPrm: 0000000000000000 +CapEff: 0000000000000000 + +This shows you almost the same information as you would get if you +viewed it with the ps command. In fact, ps uses the proc file system +to obtain its information. + +The statm file contains more detailed information about the process +memory usage. It contains seven values with the following meanings: + +size total program size +resident size of in memory portions +shared number of the pages that are shared +trs number of pages that are 'code' +drs number of pages of data/stack +lrs number of pages of library +dt number of dirty pages + +The ratio text/data/library is approximate only by heuristics. + +2.2 Kernel data + +Similar to the process entries, these are files which give information +about the running kernel. The files used to obtain this information +are contained in /proc and are listed in table 1.2. Not all of these +will be present in your system. It depends on the kernel configuration +and the loaded modules, which files are there, and which are missing. + + ________________________________________________ + apm Advanced power management info + cmdline Kernel command line + cpuinfo Info about the CPU + devices Available devices (block and character) + dma Used DMS channels + filesystems Supported filesystems + interrupts Interrupt usage + ioports I/O port usage + kcore Kernel core image + kmsg Kernel messages + ksyms Kernel symbol table + loadavg Load average + locks Kernel locks + meminfo Memory info + misc Miscellaneous + modules List of loaded modules + mounts Mounted filesystems + partitions Table of partitions known to the system + rtc Real time clock + slabinfo Slab pool info + stat Overall statistics + swaps Swap space utilization + uptime System uptime + version Kernel version + ________________________________________________ + Table 1.2: Kernel info in /proc + +You can, for example, check which interrupts are currently in use and +what they are used for by looking in the file /proc/interrupts: + +> cat /proc/interrupts + CPU0 + 0: 8728810 XT-PIC timer + 1: 895 XT-PIC keyboard + 2: 0 XT-PIC cascade + 3: 531695 XT-PIC aha152x + 4: 2014133 XT-PIC serial + 5: 44401 XT-PIC pcnet_cs + 8: 2 XT-PIC rtc + 11: 8 XT-PIC i82365 + 12: 182918 XT-PIC PS/2 Mouse + 13: 1 XT-PIC fpu + 14: 1232265 XT-PIC ide0 + 15: 7 XT-PIC ide1 +NMI: 0 + +There three more important subdirectories in /proc: net, scsi and +sys. The general rule is that the contents, or even the existence of +these directories, depends on your kernel configuration. If SCSI is +not enabled, the directory scsi may not exist. The same is true with +the net, which is only there when networking support is present in the +running kernel. + +The slabinfo file gives information about memory usage on the slab +level. Linux uses slab pools for memory management above page level +in version 2.2. Commonly used objects have their own slab pool (like +network buffers, directory cache, etc.). + +2.3 IDE devices in /proc/ide + +This subdirectory contains information about all IDE devices that the +kernel is aware of. There is one subdirectory for each device +(i.e. hard disk) containing the following files: + + cache The cache + capacity Capacity of the medium + driver Driver and version + geometry Physical and logical geometry + identify Device identify block + media Media type + model Device identifier + settings Device setup + smart_thresholds IDE disk management thresholds + smart_values IDE disk management values + +2.4 Networking info in /proc/net + +This directory follows the usual pattern. Table 1.3 lists the files +and their meaning. + + ____________________________________________________ + arp Kernel ARP table + dev network devices with statistics + dev_mcast Lists the Layer2 multicast groups a + device is listening to (interface index, + label, number of references, number of + bound addresses). + dev_stat network device status + ip_fwchains Firewall chain linkage + ip_fwnames Firewall chains + ip_masq Directory containing the masquerading + tables. + ip_masquerade Major masquerading table + netstat Network statistics + raw Raw device statistics + route Kernel routing table + rpc Directory containing rpc info + rt_cache Routing cache + snmp SNMP data + sockstat Socket statistics + tcp TCP sockets + tr_rif Token ring RIF routing table + udp UDP sockets + unix UNIX domain sockets + wireless Wireless interface data (Wavelan etc) + igmp IP multicast addresses, which this host joined + psched Global packet scheduler parameters. + netlink List of PF_NETLINK sockets. + ip_mr_vifs List of multicast virtual interfaces. + ip_mr_cache List of multicast routing cache. + udp6 UDP sockets (IPv6) + tcp6 TCP sockets (IPv6) + raw6 Raw device statistics (IPv6) + igmp6 IP multicast addresses, which this host joineed (IPv6) + if_inet6 List of IPv6 interface addresses. + ipv6_route Kernel routing table for IPv6 + rt6_stats global IPv6 routing tables statistics. + sockstat6 Socket statistics (IPv6) + snmp6 Snmp data (IPv6) + ____________________________________________________ + Table 1.3: Network info in /proc/net + +You can use this information to see which network devices are +available in your system and how much traffic was routed over those +devices: + +> cat /proc/net/dev +Inter-|Receive |[... + face |bytes packets errs drop fifo frame compressed multicast|[... + lo: 908188 5596 0 0 0 0 0 0 [... + ppp0:15475140 20721 410 0 0 410 0 0 [... + eth0: 614530 7085 0 0 0 0 0 1 [... + +...] Transmit +...] bytes packets errs drop fifo colls carrier compressed +...] 908188 5596 0 0 0 0 0 0 +...] 1375103 17405 0 0 0 0 0 0 +...] 1703981 5535 0 0 0 3 0 0 + +2.5 SCSI info + +If you have a SCSI host adapter in your system, you'll find a +subdirectory named after the driver for this adapter in /proc/scsi. +You'll also see a list of all recognized SCSI devices in /proc/scsi: + +>cat /proc/scsi/scsi +Attached devices: +Host: scsi0 Channel: 00 Id: 00 Lun: 00 + Vendor: QUANTUM Model: XP34550W Rev: LXY4 + Type: Direct-Access ANSI SCSI revision: 02 +Host: scsi0 Channel: 00 Id: 01 Lun: 00 + Vendor: SEAGATE Model: ST34501W Rev: 0018 + Type: Direct-Access ANSI SCSI revision: 02 +Host: scsi0 Channel: 00 Id: 02 Lun: 00 + Vendor: SEAGATE Model: ST34501W Rev: 0017 + Type: Direct-Access ANSI SCSI revision: 02 +Host: scsi0 Channel: 00 Id: 04 Lun: 00 + Vendor: ARCHIVE Model: Python 04106-XXX Rev: 703b + Type: Sequential-Access ANSI SCSI revision: 02 + +The directory named after the driver has one file for each adapter +found in the system. These files contain information about +the controller, including the used IRQ and the IO address range: + +>cat /proc/scsi/ncr53c8xx/0 +General information: + Chip NCR53C875, device id 0xf, revision id 0x4 + IO port address 0xec00, IRQ number 11 + Synchronous period factor 12, max commands per lun 4 + +2.6 Parallel port info in /proc/parport + +The directory /proc/parport contains information about the parallel +ports of your system. It has one subdirectory for each port, named +after the port number (0,1,2,...). + +This directory contains four files: + + autoprobe Autoprobe results of this port + devices Connected device modules + hardware Hardware info (port type, io-port, DMA, IRQ, etc.) + irq Used interrupt, if any + +2.7 TTY info in /proc/tty + +Information about the available and the actually used tty's can be +found in /proc/tty. You'll find entries for drivers and line +disciplines in this directory, as shown in the table below: + + drivers List of drivers and their usage + ldiscs Registered line disciplines + driver/serial Usage statistic and status of single tty lines + +To see which tty's are currently in use, you can simply look into the +file /proc/tty/drivers: + +>cat /proc/tty/drivers +pty_slave /dev/pts 136 0-255 pty:slave +pty_master /dev/ptm 128 0-255 pty:master +pty_slave /dev/ttyp 3 0-255 pty:slave +pty_master /dev/pty 2 0-255 pty:master +serial /dev/cua 5 64-67 serial:callout +serial /dev/ttyS 4 64-67 serial +/dev/tty0 /dev/tty0 4 0 system:vtmaster +/dev/ptmx /dev/ptmx 5 2 system +/dev/console /dev/console 5 1 system:console +/dev/tty /dev/tty 5 0 system:/dev/tty +unknown /dev/tty 4 1-63 console + +----------------------------------------------------------------------- + +3 Reading and modifying kernel parameters + +A very interesting part of /proc is the directory /proc/sys. This not +only provides information, it also allows you to change parameters +within the kernel. Be very careful when trying this. You can optimize +your system, but you also can crash it. Never play around with kernel +parameters on a production system. Set up a development machine and +test to make sure that everything works the way you want it to. You +may have no alternative but to reboot the machine once an error has +been made. + +To change a value, simply echo the new value into the file. An example +is given below in the section on the file system data. You need to be +root to do this. You can create your own boot script to get this done +every time your system boots. + +The files in /proc/sys can be used to tune and monitor miscellaneous +and general things in the operation of the Linux kernel. Since some +of the files can inadvertently disrupt your system, it is advisable to +read both documentation and source before actually making +adjustments. In any case, be very careful when writing to any of these +files. The entries in /proc may change slightly between the 2.1.* and +the 2.2 kernel, so review the kernel documentation if there is any +doubt. You'll find the documentation in the directory +/usr/src/linux/Documentation/sys. This chapter is heavily based on the +documentation included in the pre 2.2 kernels. Thanks to Rick van Riel +for providing this information. + +3.1 /proc/sys/debug and /proc/sys/proc + +These two subdirectories are empty. + +3.2 /proc/fs - File system data + +This subdirectory contains specific file system, file handle, inode, +dentry and quota information. + +Currently, these files are in /proc/sys/fs: + +dentry-state + Status of the directory cache. Since directory entries are + dynamically allocated and deallocated, this file gives information + about the current status. It holds six values, in which the last + two are not used and are always zero. The other four mean: + + nr_dentry Seems to be zero all the time + nr_unused Number of unused cache entries + age_limit Age in seconds after the entry may be + reclaimed, when memory is short + want_pages internal + +dquot-nr and dquot-max + The file dquot-max shows the maximum number of cached disk quota + entries. + + The file dquot-nr shows the number of allocated disk quota + entries and the number of free disk quota entries. + + If the number of free cached disk quotas is very low and you have + a large number of simultaneous system users, you might want + to raise the limit. + +file-nr and file-max + The kernel allocates file handles dynamically, but as yet + doesn't free them again. + + The value in file-max denotes the maximum number of file handles + that the Linux kernel will allocate. When you get a lot of error + messages about running out of file handles, you might want to raise + this limit. The default value is 4096. To change it, just write the + new number into the file: + + # cat /proc/sys/fs/file-max + 4096 + # echo 8192 > /proc/sys/fs/file-max + # cat /proc/sys/fs/file-max + 8192 + + This method of revision is useful for all customizable parameters + of the kernel - simply echo the new value to the corresponding + file. + + The three values in file-nr denote the number of allocated file + handles, the number of used file handles, and the maximum number of + file handles. When the allocated file handles come close to the + maximum, but the number of actually used ones is far behind, you've + encountered a peak in your usage of file handles and you don't need + to increase the maximum. + + However, there is still a per process limit of open files, which + unfortunatly can't be changed that easily. It is set to 1024 by + default. To change this you have to edit the files limits.h and + fs.h in the directory /usr/src/linux/include/linux. Change the + definition of NR_OPEN and recompile the kernel. + +inode-state, inode-nr and inode-max + As with file handles, the kernel allocates the inode structures + dynamically, but can't free them yet. + + The value in inode-max denotes the maximum number of inode + handlers. This value should be 3 to 4 times larger than the value + in file-max, since stdin, stdout, and network sockets also need an + inode struct to handle them. If you regularly run out of inodes, + you should increase this value. + + The file inode-nr contains the first two items from inode-state, so + we'll skip to that file... + + inode-state contains three actual numbers and four dummy values. The + actual numbers are (in order of appearance) nr_inodes, nr_free_inodes, + and preshrink. + + nr_inodes + Denotes the number of inodes the system has allocated. This can + be slightly more than inode-max because Linux allocates them one + pageful at a time. + + nr_free_inodes + Represents the number of free inodes and pre shrink is nonzero + when the nr_inodes > inode-max and the system needs to prune the + inode list instead of allocating more. + +super-nr and super-max + Again, super block structures are allocated by the kernel, + but not freed. The file super-max contains the maximum number of + super block handlers, where super-nr shows the number of + currently allocated ones. + + Every mounted file system needs a super block, so if you plan to + mount lots of file systems, you may want to increase these + numbers. + +3.3 /proc/fs/binfmt_misc - Miscellaneous binary formats + +Besides these files, there is the subdirectory +/proc/sys/fs/binfmt_misc. This handles the kernel support for +miscellaneous binary formats. + +Binfmt_misc provides the ability to register additional binary formats +to the Kernel without compiling an additional module/kernel. Therefore +binfmt_misc needs to know magic numbers at the beginning or the +filename extension of the binary. + +It works by maintaining a linked list of structs, that contain a +description of a binary format, including a magic with size (or the +filename extension), offset and mask, and the interpreter name. On +request it invokes the given interpreter with the original program as +argument, as binfmt_java and binfmt_em86 and binfmt_mz do. +Since binfmt_misc does not define any default binary-formats, you have to +register an additional binary-format. + +There are two general files in binfmt_misc and one file per registered +format. The two general files are register and status. + +Registering a new binary format + +echo :name:type:offset:magic:mask:interpreter: > /proc/sys/fs/binfmt_misc/register + +with appropriate name (the name for the /proc-dir entry), offset +(defaults to 0, if omitted), magic and mask (which can be omitted, +defaults to all 0xff) and last but not least, the interpreter that is +to be invoked (for example and testing '/bin/echo'). Type can be M for +usual magic matching or E for filename extension matching (give +extension in place of magic). + +To check or reset the status of the binary format handler: + +If you do a cat on the file /proc/sys/fs/binfmt_misc/status, you will +get the current status (enabled/disabled) of binfmt_misc. Change the +status by echoing 0 (disables) or 1 (enables) or -1 (caution: this +clears all previously registered binary formats) to status. For +example echo 0 > status to disable binfmt_misc (temporarily). + +Status of a single handler + +Each registered handler has an entry in /proc/sys/fs/binfmt_misc. +These files perform the same function as status, but their scope is +limited to the actual binary format. By cating this file, you also +receive all related information about the interpreter/magic of the +binfmt. + +Example usage of binfmt_misc (emulate binfmt_java) + +cd /proc/sys/fs/binfmt_misc +echo ':Java:M::\xca\xfe\xba\xbe::/usr/local/java/bin/javawrapper:' > register +echo ':HTML:E::html::/usr/local/java/bin/appletviewer:' > register +echo ':Applet:M::msg_bad -** -> target answered (ok) NEG WIDE wdtr set - clrack -** -> target answered (!ok) NEG WIDE wdtr defa. REJ--->msg_bad -** -> any other msgin NEG FAIL noop defa. - dispatch -** -** Target tries to negotiate: -** -> incoming message --- SYNC sdtr set SDTR - -** -> incoming message --- WIDE wdtr set WDTR - -** We sent our answer: -** -> target doesn't msgout --- PROTO ? defa. - dispatch -** -**----------------------------------------------------------------------------- +**--------------------------------------------------------------------- */ - case SIR_NEGO_FAILED: - /*------------------------------------------------------- - ** - ** Negotiation failed. - ** Target doesn't send an answer message, - ** or target rejected our message. - ** - ** Remove negotiation request. - ** - **------------------------------------------------------- - */ - OUTB (HS_PRT, HS_BUSY); - - /* fall through */ - - case SIR_NEGO_PROTO: - /*------------------------------------------------------- - ** - ** Negotiation failed. - ** Target doesn't fetch the answer message. - ** - **------------------------------------------------------- - */ - - if (DEBUG_FLAGS & DEBUG_NEGO) { - PRINT_ADDR(cp->cmd); - printk ("negotiation failed sir=%x status=%x.\n", - num, cp->nego_status); - }; - - /* - ** any error in negotiation: - ** fall back to default mode. - */ - switch (cp->nego_status) { - - case NS_SYNC: - ncr_setsync (np, cp, 0, 0xe0); - break; - - case NS_WIDE: - ncr_setwide (np, cp, 0, 0); - break; - - }; - np->msgin [0] = M_NOOP; - np->msgout[0] = M_NOOP; - cp->nego_status = 0; - break; +/*========================================================== +** +** ncr chip handler for SYNCHRONOUS DATA TRANSFER +** REQUEST (SDTR) message. +** +**========================================================== +** +** Read comments above. +** +**---------------------------------------------------------- +*/ +static void ncr_sync_nego(ncb_p np, tcb_p tp, ccb_p cp) +{ + u_char scntl3; + u_char chg, ofs, per, fak; - case SIR_NEGO_SYNC: - /* - ** Synchronous request message received. - */ + /* + ** Synchronous request message received. + */ - if (DEBUG_FLAGS & DEBUG_NEGO) { - PRINT_ADDR(cp->cmd); - printk ("sync msgin: "); - (void) ncr_show_msg (np->msgin); - printk (".\n"); - }; + if (DEBUG_FLAGS & DEBUG_NEGO) { + ncr_print_msg(cp, "sync msg in", np->msgin); + }; - /* - ** get requested values. - */ + /* + ** get requested values. + */ - chg = 0; - per = np->msgin[3]; - ofs = np->msgin[4]; - if (ofs==0) per=255; + chg = 0; + per = np->msgin[3]; + ofs = np->msgin[4]; + if (ofs==0) per=255; - /* - ** if target sends SDTR message, - ** it CAN transfer synch. - */ + /* + ** if target sends SDTR message, + ** it CAN transfer synch. + */ - if (ofs) - tp->inq_byte7 |= INQ7_SYNC; + if (ofs) + tp->inq_byte7 |= INQ7_SYNC; - /* - ** check values against driver limits. - */ + /* + ** check values against driver limits. + */ - if (per < np->minsync) - {chg = 1; per = np->minsync;} - if (per < tp->minsync) - {chg = 1; per = tp->minsync;} - if (ofs > tp->maxoffs) - {chg = 1; ofs = tp->maxoffs;} + if (per < np->minsync) + {chg = 1; per = np->minsync;} + if (per < tp->minsync) + {chg = 1; per = tp->minsync;} + if (ofs > tp->maxoffs) + {chg = 1; ofs = tp->maxoffs;} - /* - ** Check against controller limits. - */ + /* + ** Check against controller limits. + */ + fak = 7; + scntl3 = 0; + if (ofs != 0) { + ncr_getsync(np, per, &fak, &scntl3); + if (fak > 7) { + chg = 1; + ofs = 0; + } + } + if (ofs == 0) { fak = 7; + per = 0; scntl3 = 0; - if (ofs != 0) { - ncr_getsync(np, per, &fak, &scntl3); - if (fak > 7) { - chg = 1; - ofs = 0; - } - } - if (ofs == 0) { - fak = 7; - per = 0; - scntl3 = 0; - tp->minsync = 0; - } - - if (DEBUG_FLAGS & DEBUG_NEGO) { - PRINT_ADDR(cp->cmd); - printk ("sync: per=%d scntl3=0x%x ofs=%d fak=%d chg=%d.\n", - per, scntl3, ofs, fak, chg); - } + tp->minsync = 0; + } - if (INB (HS_PRT) == HS_NEGOTIATE) { - OUTB (HS_PRT, HS_BUSY); - switch (cp->nego_status) { + if (DEBUG_FLAGS & DEBUG_NEGO) { + PRINT_ADDR(cp->cmd); + printk ("sync: per=%d scntl3=0x%x ofs=%d fak=%d chg=%d.\n", + per, scntl3, ofs, fak, chg); + } - case NS_SYNC: + if (INB (HS_PRT) == HS_NEGOTIATE) { + OUTB (HS_PRT, HS_BUSY); + switch (cp->nego_status) { + case NS_SYNC: + /* + ** This was an answer message + */ + if (chg) { /* - ** This was an answer message + ** Answer wasn't acceptable. */ - if (chg) { - /* - ** Answer wasn't acceptable. - */ - ncr_setsync (np, cp, 0, 0xe0); - OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, msg_bad)); - } else { - /* - ** Answer is ok. - */ - ncr_setsync (np, cp, scntl3, (fak<<5)|ofs); - OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, clrack)); - }; - return; - - case NS_WIDE: - ncr_setwide (np, cp, 0, 0); - break; + ncr_setsync (np, cp, 0, 0xe0); + OUTL (nc_dsp, NCB_SCRIPTH_PHYS (np, msg_bad)); + } else { + /* + ** Answer is ok. + */ + ncr_setsync (np, cp, scntl3, (fak<<5)|ofs); + OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, clrack)); }; + return; + + case NS_WIDE: + ncr_setwide (np, cp, 0, 0); + break; }; + }; - /* - ** It was a request. Set value and - ** prepare an answer message - */ + /* + ** It was a request. Set value and + ** prepare an answer message + */ - ncr_setsync (np, cp, scntl3, (fak<<5)|ofs); + ncr_setsync (np, cp, scntl3, (fak<<5)|ofs); - np->msgout[0] = M_EXTENDED; - np->msgout[1] = 3; - np->msgout[2] = M_X_SYNC_REQ; - np->msgout[3] = per; - np->msgout[4] = ofs; + np->msgout[0] = M_EXTENDED; + np->msgout[1] = 3; + np->msgout[2] = M_X_SYNC_REQ; + np->msgout[3] = per; + np->msgout[4] = ofs; - cp->nego_status = NS_SYNC; + cp->nego_status = NS_SYNC; - if (DEBUG_FLAGS & DEBUG_NEGO) { - PRINT_ADDR(cp->cmd); - printk ("sync msgout: "); - (void) ncr_show_msg (np->msgout); - printk (".\n"); - } + if (DEBUG_FLAGS & DEBUG_NEGO) { + ncr_print_msg(cp, "sync msgout", np->msgout); + } - if (!ofs) { - OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, msg_bad)); - return; - } - np->msgin [0] = M_NOOP; + np->msgin [0] = M_NOOP; - break; + if (!ofs) + OUTL (nc_dsp, NCB_SCRIPTH_PHYS (np, msg_bad)); + else + OUTL (nc_dsp, NCB_SCRIPTH_PHYS (np, sdtr_resp)); +} - case SIR_NEGO_WIDE: - /* - ** Wide request message received. - */ - if (DEBUG_FLAGS & DEBUG_NEGO) { - PRINT_ADDR(cp->cmd); - printk ("wide msgin: "); - (void) ncr_show_msg (np->msgin); - printk (".\n"); - }; +/*========================================================== +** +** ncr chip handler for WIDE DATA TRANSFER REQUEST +** (WDTR) message. +** +**========================================================== +** +** Read comments above. +** +**---------------------------------------------------------- +*/ +static void ncr_wide_nego(ncb_p np, tcb_p tp, ccb_p cp) +{ + u_char chg, wide; - /* - ** get requested values. - */ + /* + ** Wide request message received. + */ + if (DEBUG_FLAGS & DEBUG_NEGO) { + ncr_print_msg(cp, "wide msgin", np->msgin); + }; - chg = 0; - wide = np->msgin[3]; + /* + ** get requested values. + */ - /* - ** if target sends WDTR message, - ** it CAN transfer wide. - */ + chg = 0; + wide = np->msgin[3]; - if (wide) - tp->inq_byte7 |= INQ7_WIDE16; + /* + ** if target sends WDTR message, + ** it CAN transfer wide. + */ - /* - ** check values against driver limits. - */ + if (wide) + tp->inq_byte7 |= INQ7_WIDE16; - if (wide > tp->usrwide) - {chg = 1; wide = tp->usrwide;} + /* + ** check values against driver limits. + */ - if (DEBUG_FLAGS & DEBUG_NEGO) { - PRINT_ADDR(cp->cmd); - printk ("wide: wide=%d chg=%d.\n", wide, chg); - } + if (wide > tp->usrwide) + {chg = 1; wide = tp->usrwide;} - if (INB (HS_PRT) == HS_NEGOTIATE) { - OUTB (HS_PRT, HS_BUSY); - switch (cp->nego_status) { + if (DEBUG_FLAGS & DEBUG_NEGO) { + PRINT_ADDR(cp->cmd); + printk ("wide: wide=%d chg=%d.\n", wide, chg); + } - case NS_WIDE: + if (INB (HS_PRT) == HS_NEGOTIATE) { + OUTB (HS_PRT, HS_BUSY); + switch (cp->nego_status) { + case NS_WIDE: + /* + ** This was an answer message + */ + if (chg) { /* - ** This was an answer message + ** Answer wasn't acceptable. */ - if (chg) { - /* - ** Answer wasn't acceptable. - */ - ncr_setwide (np, cp, 0, 1); - OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, msg_bad)); - } else { - /* - ** Answer is ok. - */ - ncr_setwide (np, cp, wide, 1); - OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, clrack)); - }; - return; - - case NS_SYNC: - ncr_setsync (np, cp, 0, 0xe0); - break; + ncr_setwide (np, cp, 0, 1); + OUTL (nc_dsp, NCB_SCRIPTH_PHYS (np, msg_bad)); + } else { + /* + ** Answer is ok. + */ + ncr_setwide (np, cp, wide, 1); + OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, clrack)); }; + return; + + case NS_SYNC: + ncr_setsync (np, cp, 0, 0xe0); + break; }; + }; - /* - ** It was a request, set value and - ** prepare an answer message - */ + /* + ** It was a request, set value and + ** prepare an answer message + */ - ncr_setwide (np, cp, wide, 1); + ncr_setwide (np, cp, wide, 1); - np->msgout[0] = M_EXTENDED; - np->msgout[1] = 2; - np->msgout[2] = M_X_WIDE_REQ; - np->msgout[3] = wide; + np->msgout[0] = M_EXTENDED; + np->msgout[1] = 2; + np->msgout[2] = M_X_WIDE_REQ; + np->msgout[3] = wide; - np->msgin [0] = M_NOOP; + np->msgin [0] = M_NOOP; - cp->nego_status = NS_WIDE; + cp->nego_status = NS_WIDE; - if (DEBUG_FLAGS & DEBUG_NEGO) { - PRINT_ADDR(cp->cmd); - printk ("wide msgout: "); - (void) ncr_show_msg (np->msgin); - printk (".\n"); - } - break; + if (DEBUG_FLAGS & DEBUG_NEGO) { + ncr_print_msg(cp, "wide msgout", np->msgout); + } -/*-------------------------------------------------------------------- -** -** Processing of special messages -** -**-------------------------------------------------------------------- + OUTL (nc_dsp, NCB_SCRIPTH_PHYS (np, wdtr_resp)); +} + +/* +** Reset SYNC or WIDE to default settings. +** Called when a negotiation does not succeed either +** on rejection or on protocol error. */ +static void ncr_nego_default(ncb_p np, tcb_p tp, ccb_p cp) +{ + /* + ** any error in negotiation: + ** fall back to default mode. + */ + switch (cp->nego_status) { - case SIR_REJECT_RECEIVED: - /*----------------------------------------------- - ** - ** We received a M_REJECT message. - ** - **----------------------------------------------- - */ + case NS_SYNC: + ncr_setsync (np, cp, 0, 0xe0); + break; - PRINT_ADDR(cp->cmd); - printk ("M_REJECT received (%x:%x).\n", - (unsigned)scr_to_cpu(np->lastmsg), np->msgout[0]); + case NS_WIDE: + ncr_setwide (np, cp, 0, 0); break; - case SIR_REJECT_TO_SEND: - /*----------------------------------------------- - ** - ** We received an unknown message - ** - **----------------------------------------------- - */ + }; + np->msgin [0] = M_NOOP; + np->msgout[0] = M_NOOP; + cp->nego_status = 0; +} + +/*========================================================== +** +** ncr chip handler for MESSAGE REJECT received for +** a WIDE or SYNCHRONOUS negotiation. +** +**========================================================== +** +** Read comments above. +** +**---------------------------------------------------------- +*/ +static void ncr_nego_rejected(ncb_p np, tcb_p tp, ccb_p cp) +{ + ncr_nego_default(np, tp, cp); + OUTB (HS_PRT, HS_BUSY); +} - PRINT_ADDR(cp->cmd); - printk ("M_REJECT to send for "); - (void) ncr_show_msg (np->msgin); - printk (".\n"); - np->msgout[0] = M_REJECT; - break; -/*-------------------------------------------------------------------- +/*========================================================== +** +** +** ncr chip exception handler for programmed interrupts. ** -** Processing of special messages ** -**-------------------------------------------------------------------- +**========================================================== */ - case SIR_IGN_RESIDUE: - /*----------------------------------------------- - ** - ** We received an IGNORE RESIDUE message, - ** which couldn't be handled by the script. - ** - **----------------------------------------------- - */ +void ncr_int_sir (ncb_p np) +{ + u_char num = INB (nc_dsps); + u_long dsa = INL (nc_dsa); + ccb_p cp = ncr_ccb_from_dsa(np, dsa); + u_char target = INB (nc_sdid) & 0x0f; + tcb_p tp = &np->target[target]; + int tmp; - PRINT_ADDR(cp->cmd); - printk ("M_IGN_RESIDUE received, but not yet implemented.\n"); - break; -#if 0 - case SIR_MISSING_SAVE: - /*----------------------------------------------- - ** - ** We received an DISCONNECT message, - ** but the datapointer wasn't saved before. - ** - **----------------------------------------------- - */ + if (DEBUG_FLAGS & DEBUG_TINY) printk ("I#%d", num); - PRINT_ADDR(cp->cmd); - printk ("M_DISCONNECT received, but datapointer not saved: " - "data=%x save=%x goal=%x.\n", - (unsigned) INL (nc_temp), - (unsigned) scr_to_cpu(np->header.savep), - (unsigned) scr_to_cpu(np->header.goalp)); - break; + switch (num) { + /* + ** See comments in the SCRIPTS code. + */ +#ifdef SCSI_NCR_PCIQ_SYNC_ON_INTR + case SIR_DUMMY_INTERRUPT: + goto out; #endif + /* + ** The C code is currently trying to recover from something. + ** Typically, user want to abort some command. + */ + case SIR_SCRIPT_STOPPED: + case SIR_TARGET_SELECTED: + case SIR_ABORT_SENT: + ncr_sir_task_recovery(np, num); + return; + /* + ** The device didn't go to MSG OUT phase after having + ** been selected with ATN. We donnot want to handle + ** that. + */ + case SIR_SEL_ATN_NO_MSG_OUT: + printk ("%s:%d: No MSG OUT phase after selection with ATN.\n", + ncr_name (np), target); + goto out_stuck; + /* + ** The device didn't switch to MSG IN phase after + ** having reseleted the initiator. + */ + case SIR_RESEL_NO_MSG_IN: + /* + ** After reselection, the device sent a message that wasn't + ** an IDENTIFY. + */ + case SIR_RESEL_NO_IDENTIFY: + /* + ** If devices reselecting without sending an IDENTIFY + ** message still exist, this should help. + ** We just assume lun=0, 1 CCB, no tag. + */ + if (tp->l0p) { + OUTL (nc_dsa, scr_to_cpu(tp->l0p->tasktbl[0])); + OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, resel_go)); + return; + } + /* + ** The device reselected a LUN we donnot know of. + */ + case SIR_RESEL_BAD_LUN: + np->msgout[0] = M_RESET; + goto out; + /* + ** The device reselected for an untagged nexus and we + ** haven't any. + */ + case SIR_RESEL_BAD_I_T_L: + np->msgout[0] = M_ABORT; + goto out; + /* + ** The device reselected for a tagged nexus that we donnot + ** have. + */ + case SIR_RESEL_BAD_I_T_L_Q: + np->msgout[0] = M_ABORT_TAG; + goto out; + /* + ** The SCRIPTS let us know that the device has grabbed + ** our message and will abort the job. + */ + case SIR_RESEL_ABORTED: + np->lastmsg = np->msgout[0]; + np->msgout[0] = M_NOOP; + printk ("%s:%d: message %x sent on bad reselection.\n", + ncr_name (np), target, np->lastmsg); + goto out; + /* + ** The SCRIPTS let us know that a message has been + ** successfully sent to the device. + */ + case SIR_MSG_OUT_DONE: + np->lastmsg = np->msgout[0]; + np->msgout[0] = M_NOOP; + /* Should we really care of that */ + if (np->lastmsg == M_PARITY || np->lastmsg == M_ID_ERROR) { + if (cp) + cp->xerr_status &= ~XE_PARITY_ERR; + } + goto out; + /* + ** The device didn't send a GOOD SCSI status. + ** We may have some work to do prior to allow + ** the SCRIPTS processor to continue. + */ + case SIR_BAD_STATUS: + if (!cp) + goto out; + ncr_sir_to_redo(np, num, cp); + return; + /* + ** We are asked by the SCRIPTS to prepare a + ** REJECT message. + */ + case SIR_REJECT_TO_SEND: + ncr_print_msg(cp, "M_REJECT to send for ", np->msgin); + np->msgout[0] = M_REJECT; + goto out; + /* + ** We have been ODD at the end of a DATA IN + ** transfer and the device didn't send a + ** IGNORE WIDE RESIDUE message. + ** It is a data overrun condition. + */ + case SIR_SWIDE_OVERRUN: + if (cp) + cp->xerr_status |= XE_EXTRA_DATA; + goto out; + /* + ** We have been ODD at the end of a DATA OUT + ** transfer. + ** It is a data underrun condition. + */ + case SIR_SODL_UNDERRUN: + if (cp) + cp->xerr_status |= XE_EXTRA_DATA; + goto out; + /* + ** We received a message. + */ + case SIR_MSG_RECEIVED: + if (!cp) + goto out_stuck; + switch (np->msgin [0]) { + /* + ** We received an extended message. + ** We handle MODIFY DATA POINTER, SDTR, WDTR + ** and reject all other extended messages. + */ + case M_EXTENDED: + switch (np->msgin [2]) { + case M_X_MODIFY_DP: + if (DEBUG_FLAGS & DEBUG_POINTER) + ncr_print_msg(cp,"modify DP",np->msgin); + tmp = (np->msgin[3]<<24) + (np->msgin[4]<<16) + + (np->msgin[5]<<8) + (np->msgin[6]); + ncr_modify_dp(np, tp, cp, tmp); + return; + case M_X_SYNC_REQ: + ncr_sync_nego(np, tp, cp); + return; + case M_X_WIDE_REQ: + ncr_wide_nego(np, tp, cp); + return; + default: + goto out_reject; + } + break; + /* + ** We received a 1/2 byte message not handled from SCRIPTS. + ** We are only expecting MESSAGE REJECT and IGNORE WIDE + ** RESIDUE messages that haven't been anticipated by + ** SCRIPTS on SWIDE full condition. Unanticipated IGNORE + ** WIDE RESIDUE messages are aliased as MODIFY DP (-1). + */ + case M_IGN_RESIDUE: + if (DEBUG_FLAGS & DEBUG_POINTER) + ncr_print_msg(cp,"ign wide residue", np->msgin); + ncr_modify_dp(np, tp, cp, -1); + return; + case M_REJECT: + if (INB (HS_PRT) == HS_NEGOTIATE) + ncr_nego_rejected(np, tp, cp); + else { + PRINT_ADDR(cp->cmd); + printk ("M_REJECT received (%x:%x).\n", + scr_to_cpu(np->lastmsg), np->msgout[0]); + } + goto out_clrack; + break; + default: + goto out_reject; + } + break; + /* + ** We received an unknown message. + ** Ignore all MSG IN phases and reject it. + */ + case SIR_MSG_WEIRD: + ncr_print_msg(cp, "WEIRD message received", np->msgin); + OUTL (nc_dsp, NCB_SCRIPTH_PHYS (np, msg_weird)); + return; + /* + ** Negotiation failed. + ** Target does not send us the reply. + ** Remove the HS_NEGOTIATE status. + */ + case SIR_NEGO_FAILED: + OUTB (HS_PRT, HS_BUSY); + /* + ** Negotiation failed. + ** Target does not want answer message. + */ + case SIR_NEGO_PROTO: + ncr_nego_default(np, tp, cp); + goto out; }; out: OUTONB (nc_dcntl, (STD|NOCOM)); + return; +out_reject: + OUTL (nc_dsp, NCB_SCRIPTH_PHYS (np, msg_bad)); + return; +out_clrack: + OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, clrack)); + return; out_stuck: } + /*========================================================== ** ** @@ -8599,8 +10052,8 @@ static ccb_p ncr_get_ccb (ncb_p np, u_char tn, u_char ln) { tcb_p tp = &np->target[tn]; - lcb_p lp = tp->lp[ln]; - u_char tag = NO_TAG; + lcb_p lp = ncr_lp(np, tp, ln); + u_short tag = NO_TAG; XPT_QUEHEAD *qp; ccb_p cp = (ccb_p) 0; @@ -8644,9 +10097,10 @@ if (lp->busyccbs < lp->maxnxs) { tag = lp->cb_tags[lp->ia_tag]; ++lp->ia_tag; - if (lp->ia_tag == SCSI_NCR_MAX_TAGS) + if (lp->ia_tag == MAX_TAGS) lp->ia_tag = 0; - lp->tags_umap |= (((tagmap_t) 1) << tag); + cp->tags_si = lp->tags_si; + ++lp->tags_sum[cp->tags_si]; } else goto out_free; @@ -8663,6 +10117,7 @@ /* ** Remember all informations needed to free this CCB. */ + cp->to_abort = 0; cp->tag = tag; cp->target = tn; cp->lun = ln; @@ -8691,7 +10146,7 @@ static void ncr_free_ccb (ncb_p np, ccb_p cp) { tcb_p tp = &np->target[cp->target]; - lcb_p lp = tp->lp[cp->lun]; + lcb_p lp = ncr_lp(np, tp, cp->lun); if (DEBUG_FLAGS & DEBUG_TAGS) { PRINT_LUN(np, cp->target, cp->lun); @@ -8706,10 +10161,9 @@ if (lp) { if (cp->tag != NO_TAG) { lp->cb_tags[lp->if_tag++] = cp->tag; - if (lp->if_tag == SCSI_NCR_MAX_TAGS) + if (lp->if_tag == MAX_TAGS) lp->if_tag = 0; - lp->tags_umap &= ~(((tagmap_t) 1) << cp->tag); - lp->tags_smap &= lp->tags_umap; + --lp->tags_sum[cp->tags_si]; lp->tasktbl[cp->tag] = cpu_to_scr(np->p_bad_i_t_l_q); } else { lp->tasktbl[0] = cpu_to_scr(np->p_bad_i_t_l); @@ -8770,6 +10224,11 @@ cp->phys.header.go.restart = cpu_to_scr(NCB_SCRIPTH_PHYS(np,bad_i_t_l)); /* + ** Initilialyze some other fields. + */ + cp->phys.smsg_ext.addr = cpu_to_scr(vtobus(&np->msgin[2])); + + /* ** Chain into wakeup list and free ccb queue. */ cp->link_ccb = np->ccbc; @@ -8820,25 +10279,6 @@ */ static void ncr_init_tcb (ncb_p np, u_char tn) { - tcb_p tp = &np->target[tn]; - - /* - ** Already bone. - */ - if (tp->luntbl) - return; - /* - ** Allocate the lcb bus address array. - */ - tp->luntbl = m_calloc(256, "LUNTBL", MEMO_WARN); - if (!tp->luntbl) - return; - - /* - ** Compute the bus address of this table. - */ - tp->b_luntbl = cpu_to_scr(vtobus(tp->luntbl)); - /* ** Check some alignments required by the chip. */ @@ -8858,7 +10298,7 @@ static lcb_p ncr_alloc_lcb (ncb_p np, u_char tn, u_char ln) { tcb_p tp = &np->target[tn]; - lcb_p lp = tp->lp[ln]; + lcb_p lp = ncr_lp(np, tp, ln); /* ** Already done, return. @@ -8870,21 +10310,46 @@ ** Initialize the target control block if not yet. */ ncr_init_tcb(np, tn); - if (!tp->luntbl) - goto fail; /* - ** Allocate the lcb. + ** Allocate the lcb bus address array. + ** Compute the bus address of this table. */ - lp = m_calloc(sizeof(struct lcb), "LCB", MEMO_WARN); - if (!lp) - goto fail; - tp->lp[ln] = lp; + if (ln && !tp->luntbl) { + int i; + + tp->luntbl = m_calloc(256, "LUNTBL", MEMO_WARN); + if (!tp->luntbl) + goto fail; + for (i = 0 ; i < 64 ; i++) + tp->luntbl[i] = cpu_to_scr(vtobus(&np->resel_badlun)); + tp->b_luntbl = cpu_to_scr(vtobus(tp->luntbl)); + } + + /* + ** Allocate the table of pointers for LUN(s) > 0, if needed. + */ + if (ln && !tp->lmp) { + tp->lmp = m_calloc(MAX_LUN * sizeof(lcb_p), "LMP", MEMO_WARN); + if (!tp->lmp) + goto fail; + } /* + ** Allocate the lcb. ** Make it available to the chip. */ - tp->luntbl[ln] = cpu_to_scr(vtobus(lp)); + lp = m_calloc(sizeof(struct lcb), "LCB", MEMO_WARN); + if (!lp) + goto fail; + if (ln) { + tp->lmp[ln] = lp; + tp->luntbl[ln] = cpu_to_scr(vtobus(lp)); + } + else { + tp->l0p = lp; + tp->b_lun0 = cpu_to_scr(vtobus(lp)); + } /* ** Initialize the CCB queue headers. @@ -8924,7 +10389,7 @@ static lcb_p ncr_setup_lcb (ncb_p np, u_char tn, u_char ln, u_char *inq_data) { tcb_p tp = &np->target[tn]; - lcb_p lp = tp->lp[ln]; + lcb_p lp = ncr_lp(np, tp, ln); u_char inq_byte7; int i; @@ -8934,14 +10399,16 @@ if (!lp && !(lp = ncr_alloc_lcb(np, tn, ln))) goto fail; +#if 0 /* No more used. Left here as provision */ /* - ** Get device quirks from a speciality table. + ** Get device quirks. */ - tp->quirks = ncr_lookup (inq_data); + tp->quirks = 0; if (tp->quirks && bootverbose) { PRINT_LUN(np, tn, ln); printk ("quirks=%x.\n", tp->quirks); } +#endif /* ** Evaluate trustable target/unit capabilities. @@ -8984,18 +10451,23 @@ ** initialyze the task table if not yet. */ if ((inq_byte7 & INQ7_QUEUE) && lp->tasktbl == &lp->tasktbl_0) { - lp->tasktbl = m_calloc(256, "TASKTBL", MEMO_WARN); + lp->tasktbl = m_calloc(MAX_TASKS*4, "TASKTBL", MEMO_WARN); if (!lp->tasktbl) { lp->tasktbl = &lp->tasktbl_0; goto fail; } lp->b_tasktbl = cpu_to_scr(vtobus(lp->tasktbl)); - for (i = 0 ; i < 64 ; i++) + for (i = 0 ; i < MAX_TASKS ; i++) lp->tasktbl[i] = cpu_to_scr(np->p_notask); - for (i = 0 ; i < SCSI_NCR_MAX_TAGS ; i++) + + lp->cb_tags = m_calloc(MAX_TAGS, "CB_TAGS", MEMO_WARN); + if (!lp->cb_tags) + goto fail; + for (i = 0 ; i < MAX_TAGS ; i++) lp->cb_tags[i] = i; - lp->maxnxs = SCSI_NCR_MAX_TAGS; - lp->tags_stime = jiffies; + + lp->maxnxs = MAX_TAGS; + lp->tags_stime = ktime_get(3*HZ); } /* @@ -9043,7 +10515,7 @@ /* ** For 64 bit systems, we use the 8 upper bits of the size field ** to provide bus address bits 32-39 to the SCRIPTS processor. -** This allows the 896 to access up to 1 tera-bytes of memory. +** This allows the 895A and 896 to address up to 1 TB of memory. ** For 32 bit chips on 64 bit systems, we must be provided with ** memory addresses that fit into the first 32 bit bus address ** range and so, this does not matter and we expect an error from @@ -9325,62 +10797,6 @@ /*========================================================== ** -** -** Device lookup. -** -** @GENSCSI@ should be integrated to scsiconf.c -** -** -**========================================================== -*/ - -struct table_entry { - char * manufacturer; - char * model; - char * version; - u_long info; -}; - -static struct table_entry device_tab[] = -{ -#if 0 - {"", "", "", QUIRK_NOMSG}, -#endif - {"SONY", "SDT-5000", "3.17", QUIRK_NOMSG}, - {"WangDAT", "Model 2600", "01.7", QUIRK_NOMSG}, - {"WangDAT", "Model 3200", "02.2", QUIRK_NOMSG}, - {"WangDAT", "Model 1300", "02.4", QUIRK_NOMSG}, - {"", "", "", 0} /* catch all: must be last entry. */ -}; - -static u_long ncr_lookup(char * id) -{ - struct table_entry * p = device_tab; - char *d, *r, c; - - for (;;p++) { - - d = id+8; - r = p->manufacturer; - while ((c=*r++)) if (c!=*d++) break; - if (c) continue; - - d = id+16; - r = p->model; - while ((c=*r++)) if (c!=*d++) break; - if (c) continue; - - d = id+32; - r = p->version; - while ((c=*r++)) if (c!=*d++) break; - if (c) continue; - - return (p->info); - } -} - -/*========================================================== -** ** Determine the ncr's clock frequency. ** This is essential for the negotiation ** of the synchronous transfer rate. @@ -9395,7 +10811,7 @@ ** do not have a clock doubler and so are provided with a ** 80 MHz clock. All other fast20 boards incorporate a doubler ** and so should be delivered with a 40 MHz clock. -** The recent fast40 chips (895/896) use a 40 Mhz base clock +** The recent fast40 chips (895/896/895A) use a 40 Mhz base clock ** and provide a clock quadrupler (160 Mhz). The code below ** tries to deal as cleverly as possible with all this stuff. ** @@ -9436,7 +10852,8 @@ */ static unsigned __init ncrgetfreq (ncb_p np, int gen) { - unsigned ms = 0; + unsigned int ms = 0; + unsigned int f; /* * Measure GEN timer delay in order @@ -9453,7 +10870,6 @@ * performed trust the higher delay * (lower frequency returned). */ - OUTB (nc_stest1, 0); /* make sure clock doubler is OFF */ OUTW (nc_sien , 0); /* mask all scsi interrupts */ (void) INW (nc_sist); /* clear pending scsi interrupt */ OUTB (nc_dien , 0); /* mask all dma interrupts */ @@ -9471,12 +10887,28 @@ */ OUTB (nc_scntl3, 0); - if (bootverbose >= 2) - printk ("%s: Delay (GEN=%d): %u msec\n", ncr_name(np), gen, ms); /* * adjust for prescaler, and convert into KHz */ - return ms ? ((1 << gen) * 4340) / ms : 0; + f = ms ? ((1 << gen) * 4340) / ms : 0; + + if (bootverbose >= 2) + printk ("%s: Delay (GEN=%d): %u msec, %u KHz\n", + ncr_name(np), gen, ms, f); + + return f; +} + +static unsigned __init ncr_getfreq (ncb_p np) +{ + u_int f1, f2; + int gen = 11; + + (void) ncrgetfreq (np, gen); /* throw away first result */ + f1 = ncrgetfreq (np, gen); + f2 = ncrgetfreq (np, gen); + if (f1 > f2) f1 = f2; /* trust lower result */ + return f1; } /* @@ -9492,7 +10924,7 @@ f1 = 40000; /* - ** True with 875/895/896 with clock multiplier selected + ** True with 875/895/896/895A with clock multiplier selected */ if (mult > 1 && (stest1 & (DBLEN+DBLSEL)) == DBLEN+DBLSEL) { if (bootverbose >= 2) @@ -9506,16 +10938,11 @@ ** Otherwise trust scntl3 BIOS setting. */ if (np->multiplier != mult || (scntl3 & 7) < 3 || !(scntl3 & 1)) { - unsigned f2; - - (void) ncrgetfreq (np, 11); /* throw away first result */ - f1 = ncrgetfreq (np, 11); - f2 = ncrgetfreq (np, 11); + OUTB (nc_stest1, 0); /* make sure doubler is OFF */ + f1 = ncr_getfreq (np); if (bootverbose) - printk ("%s: NCR clock is %uKHz, %uKHz\n", ncr_name(np), f1, f2); - - if (f1 > f2) f1 = f2; /* trust lower result */ + printk ("%s: NCR clock is %uKHz\n", ncr_name(np), f1); if (f1 < 45000) f1 = 40000; else if (f1 < 55000) f1 = 50000; @@ -9541,6 +10968,21 @@ np->clock_khz = f1; } +/* + * Get/probe PCI clock frequency + */ +static u_int __init ncr_getpciclock (ncb_p np) +{ + static u_int f = 0; + + if (!f) { + OUTB (nc_stest1, SCLK); /* Use the PCI clock as SCSI clock */ + f = ncr_getfreq (np); + OUTB (nc_stest1, 0); + } + return f; +} + /*===================== LINUX ENTRY POINTS SECTION ==========================*/ #ifndef uchar @@ -9592,6 +11034,11 @@ #define OPT_SAFE_SETUP 22 #define OPT_USE_NVRAM 23 #define OPT_EXCLUDE 24 +#define OPT_HOST_ID 25 + +#ifdef SCSI_NCR_IARB_SUPPORT +#define OPT_IARB 26 +#endif static char setup_token[] __initdata = "tags:" "mpar:" @@ -9606,7 +11053,11 @@ "buschk:" "optim:" "recovery:" "safe:" "nvram:" - "excl:"; + "excl:" "hostid:" +#ifdef SCSI_NCR_IARB_SUPPORT + "iarb:" +#endif + ; /* DONNOT REMOVE THIS ';' */ #ifdef MODULE #define ARG_SEP ' ' @@ -9631,7 +11082,7 @@ } -void __init sym53c8xx_setup(char *str, int *ints) +int __init sym53c8xx_setup(char *str) { #ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT char *cur = str; @@ -9736,6 +11187,14 @@ if (xi < SCSI_NCR_MAX_EXCLUDES) driver_setup.excludes[xi++] = val; break; + case OPT_HOST_ID: + driver_setup.host_id = val; + break; +#ifdef SCSI_NCR_IARB_SUPPORT + case OPT_IARB: + driver_setup.iarb = val; + break; +#endif default: printk("sym53c8xx_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur); break; @@ -9745,8 +11204,15 @@ ++cur; } #endif /* SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT */ + return 0; } +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13) +#ifndef MODULE +__setup("sym53c8xx=", sym53c8xx_setup); +#endif +#endif + static int sym53c8xx_pci_init(Scsi_Host_Template *tpnt, uchar bus, uchar device_fn, ncr_device *device); @@ -9893,7 +11359,7 @@ #if defined(SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT) && defined(MODULE) if (sym53c8xx) - sym53c8xx_setup(sym53c8xx, (int *) 0); + sym53c8xx_setup(sym53c8xx); #endif #ifdef SCSI_NCR_DEBUG_INFO_SUPPORT ncr_debug = driver_setup.debug; @@ -9945,8 +11411,16 @@ continue; } ++index; + /* Some HW as the HP LH4 may report twice PCI devices */ + for (i = 0; i < count ; i++) { + if (devtbl[i].slot.bus == bus && + devtbl[i].slot.device_fn == device_fn) + break; + } + if (i != count) /* Ignore this device if we already have it */ + continue; devp = &devtbl[count]; - devp->host_id = 255; + devp->host_id = driver_setup.host_id; devp->attach_done = 0; if (sym53c8xx_pci_init(tpnt, bus, device_fn, devp)) { continue; @@ -10050,7 +11524,7 @@ **=================================================================== */ #if LINUX_VERSION_CODE <= LinuxVersionCode(2,1,92) -static int __init +static int __init pci_read_base_address(u_char bus, u_char device_fn, int offset, u_long *base) { u_int32 tmp; @@ -10067,18 +11541,27 @@ } return offset; } -#else /* LINUX_VERSION_CODE > LinuxVersionCode(2,1,92) */ -static int __init +#elif LINUX_VERSION_CODE <= LinuxVersionCode(2,3,12) +static int __init pci_get_base_address(struct pci_dev *pdev, int index, u_long *base) { - /* FIXME! This is just unbelieably horrible backwards compatibility code */ - struct resource *res = pdev->resource + index; - - *base = res->start | (res->flags & 0xf); - if ((res->flags & 0x7) == 0x4) { + *base = pdev->base_address[index++]; + if ((*base & 0x7) == 0x4) { +#if BITS_PER_LONG > 32 + *base |= (((u_long)pdev->base_address[index]) << 32); +#endif ++index; } - return index+1; + return index; +} +#else /* LINUX_VERSION_CODE > LinuxVersionCode(2,3,12) */ +static int __init +pci_get_base_address(struct pci_dev *pdev, int index, u_long *base) +{ + *base = pdev->resource[index].start; + if ((pdev->resource[index].flags & 0x7) == 0x4) + ++index; + return ++index; } #endif @@ -10094,6 +11577,7 @@ u_short vendor_id, device_id, command; u_char cache_line_size, latency_timer; u_char suggested_cache_line_size = 0; + u_char pci_fix_up; u_char revision; #if LINUX_VERSION_CODE > LinuxVersionCode(2,1,92) struct pci_dev *pdev; @@ -10173,18 +11657,18 @@ if (revision > ncr_chip_table[i].revision_id) continue; if (!(ncr_chip_table[i].features & FE_LDSTR)) - continue; + break; chip = &device->chip; memcpy(chip, &ncr_chip_table[i], sizeof(*chip)); chip->revision_id = revision; break; } -#if defined(__i386__) /* ** Ignore Symbios chips controlled by SISL RAID controller. ** This controller sets value 0x52414944 at RAM end - 16. */ +#if defined(__i386__) && !defined(SCSI_NCR_PCI_MEM_NOT_SUPPORTED) if (chip && (base_2 & PCI_BASE_ADDRESS_MEM_MASK)) { unsigned int ram_size, ram_val; u_long ram_ptr; @@ -10206,7 +11690,7 @@ } } } -#endif +#endif /* i386 and PCI MEMORY accessible */ if (!chip) { printk(NAME53C8XX ": not initializing, device not supported\n"); @@ -10267,6 +11751,9 @@ ** coherent with hardware and software resource identifications. ** This is fairly simple, but seems still too complex for Sparc. */ + base = __pa(base); + base_2 = __pa(base_2); + if (!cache_line_size) suggested_cache_line_size = 16; @@ -10290,9 +11777,16 @@ /* ** Check availability of IO space, memory space. ** Enable master capability if not yet. + ** + ** We shouldn't have to care about the IO region when + ** we are using MMIO. But calling check_region() from + ** both the ncr53c8xx and the sym53c8xx drivers prevents + ** from attaching devices from the both drivers. + ** If you have a better idea, let me know. */ -#ifdef NCR_IOMAPPED - if (!(command & PCI_COMMAND_IO) || !(io_port & 1)) { +/* #ifdef NCR_IOMAPPED */ +#if 1 + if (!(command & PCI_COMMAND_IO)) { printk(NAME53C8XX ": I/O base address (0x%lx) disabled.\n", (long) io_port); io_port = 0; @@ -10307,7 +11801,8 @@ base &= PCI_BASE_ADDRESS_MEM_MASK; base_2 &= PCI_BASE_ADDRESS_MEM_MASK; -#ifdef NCR_IOMAPPED +/* #ifdef NCR_IOMAPPED */ +#if 1 if (io_port && check_region (io_port, 128)) { printk(NAME53C8XX ": IO region 0x%lx[0..127] is in use\n", (long) io_port); @@ -10315,7 +11810,8 @@ } if (!io_port) return -1; -#else +#endif +#ifndef NCR_IOMAPPED if (!base) { printk(NAME53C8XX ": MMIO base address disabled.\n"); return -1; @@ -10354,11 +11850,24 @@ if (!driver_setup.max_wide) chip->features &= ~FE_WIDE; + /* + ** Some features are required to be enabled in order to + ** work around some chip problems. :) ;) + ** (ITEM 12 of a DEL about the 896 I haven't yet). + ** We must ensure the chip will use WRITE AND INVALIDATE. + ** The revision number limit is for now arbitrary. + */ + pci_fix_up = driver_setup.pci_fix_up; + if (device_id == PCI_DEVICE_ID_NCR_53C896 && revision <= 0x10) { + chip->features |= (FE_WRIE | FE_CLSE); + pci_fix_up |= 3; /* Force appropriate PCI fix-up */ + } + #ifdef SCSI_NCR_PCI_FIX_UP_SUPPORT /* ** Try to fix up PCI config according to wished features. */ - if ((driver_setup.pci_fix_up & 1) && (chip->features & FE_CLSE) && + if ((pci_fix_up & 1) && (chip->features & FE_CLSE) && !cache_line_size && suggested_cache_line_size) { cache_line_size = suggested_cache_line_size; pcibios_write_config_byte(bus, device_fn, @@ -10367,7 +11876,7 @@ cache_line_size); } - if ((driver_setup.pci_fix_up & 2) && cache_line_size && + if ((pci_fix_up & 2) && cache_line_size && (chip->features & FE_WRIE) && !(command & PCI_COMMAND_INVALIDATE)) { printk(NAME53C8XX": setting PCI_COMMAND_INVALIDATE (fix-up)\n"); command |= PCI_COMMAND_INVALIDATE; @@ -10379,7 +11888,7 @@ ** (latency timer >= burst length + 6, we add 10 to be quite sure) */ - if ((driver_setup.pci_fix_up & 4) && chip->burst_max) { + if ((pci_fix_up & 4) && chip->burst_max) { uchar lt = (1 << chip->burst_max) + 6 + 10; if (latency_timer < lt) { latency_timer = lt; @@ -10532,7 +12041,7 @@ np = ((struct host_data *) host->hostdata)->ncb; tp = &np->target[device->id]; - lp = tp->lp[device->lun]; + lp = ncr_lp(np, tp, device->lun); /* ** Select queue depth from driver setup. @@ -10548,8 +12057,8 @@ device->queue_depth = numtags; if (device->queue_depth < 2) device->queue_depth = 2; - if (device->queue_depth > SCSI_NCR_MAX_TAGS) - device->queue_depth = SCSI_NCR_MAX_TAGS; + if (device->queue_depth > MAX_TAGS) + device->queue_depth = MAX_TAGS; /* ** Since the queue depth is not tunable under Linux, @@ -10973,8 +12482,14 @@ uc->cmd = UC_SETDEBUG; else if ((arg_len = is_keyword(ptr, len, "setflag")) != 0) uc->cmd = UC_SETFLAG; + else if ((arg_len = is_keyword(ptr, len, "resetdev")) != 0) + uc->cmd = UC_RESETDEV; + else if ((arg_len = is_keyword(ptr, len, "cleardev")) != 0) + uc->cmd = UC_CLEARDEV; +#ifdef SCSI_NCR_PROFILE_SUPPORT else if ((arg_len = is_keyword(ptr, len, "clearprof")) != 0) uc->cmd = UC_CLEARPROF; +#endif else arg_len = 0; @@ -10991,6 +12506,8 @@ case UC_SETTAGS: case UC_SETWIDE: case UC_SETFLAG: + case UC_RESETDEV: + case UC_CLEARDEV: SKIP_SPACES(1); if ((arg_len = is_keyword(ptr, len, "all")) != 0) { ptr += arg_len; len -= arg_len; @@ -11034,14 +12551,12 @@ uc->data |= DEBUG_ALLOC; else if ((arg_len = is_keyword(ptr, len, "phase"))) uc->data |= DEBUG_PHASE; - else if ((arg_len = is_keyword(ptr, len, "poll"))) - uc->data |= DEBUG_POLL; else if ((arg_len = is_keyword(ptr, len, "queue"))) uc->data |= DEBUG_QUEUE; else if ((arg_len = is_keyword(ptr, len, "result"))) uc->data |= DEBUG_RESULT; - else if ((arg_len = is_keyword(ptr, len, "scatter"))) - uc->data |= DEBUG_SCATTER; + else if ((arg_len = is_keyword(ptr, len, "pointer"))) + uc->data |= DEBUG_POINTER; else if ((arg_len = is_keyword(ptr, len, "script"))) uc->data |= DEBUG_SCRIPT; else if ((arg_len = is_keyword(ptr, len, "tiny"))) @@ -11052,10 +12567,6 @@ uc->data |= DEBUG_NEGO; else if ((arg_len = is_keyword(ptr, len, "tags"))) uc->data |= DEBUG_TAGS; - else if ((arg_len = is_keyword(ptr, len, "freeze"))) - uc->data |= DEBUG_FREEZE; - else if ((arg_len = is_keyword(ptr, len, "restart"))) - uc->data |= DEBUG_RESTART; else return -EINVAL; ptr += arg_len; len -= arg_len; @@ -11167,7 +12678,7 @@ (u_long) np->reg); #endif copy_info(&info, " Synchronous period factor %d, ", (int) np->minsync); - copy_info(&info, "max commands per lun %d\n", SCSI_NCR_MAX_TAGS); + copy_info(&info, "max commands per lun %d\n", MAX_TAGS); if (driver_setup.debug || driver_setup.verbose > 1) { copy_info(&info, " Debug flags 0x%x, ", driver_setup.debug); @@ -11350,8 +12861,8 @@ nvram_stop(np, &gpreg); #ifdef SCSI_NCR_DEBUG_NVRAM -printk("sym53c8xx: NvRAM marker=%x trailer=%x %x %x %x %x %x byte_count=%d/%d checksum=%x/%x\n", - nvram->start_marker, +printk("sym53c8xx: NvRAM type=%x trailer=%x %x %x %x %x %x byte_count=%d/%d checksum=%x/%x\n", + nvram->type, nvram->trailer[0], nvram->trailer[1], nvram->trailer[2], nvram->trailer[3], nvram->trailer[4], nvram->trailer[5], nvram->byte_count, sizeof(*nvram) - 12, @@ -11375,7 +12886,8 @@ /* * Read Symbios NvRAM data and compute checksum. */ -static u_short __init nvram_read_data(ncr_slot *np, u_char *data, int len, u_char *gpreg, u_char *gpcntl) +static u_short __init +nvram_read_data(ncr_slot *np, u_char *data, int len, u_char *gpreg, u_char *gpcntl) { int x; u_short csum; @@ -11404,7 +12916,8 @@ * WRITE a byte to the NVRAM and then get an ACK to see it was accepted OK, * GPIO0 must already be set as an output */ -static void __init nvram_write_byte(ncr_slot *np, u_char *ack_data, u_char write_data, u_char *gpreg, u_char *gpcntl) +static void __init +nvram_write_byte(ncr_slot *np, u_char *ack_data, u_char write_data, u_char *gpreg, u_char *gpcntl) { int x; @@ -11418,7 +12931,8 @@ * READ a byte from the NVRAM and then send an ACK to say we have got it, * GPIO0 must already be set as an input */ -static void __init nvram_read_byte(ncr_slot *np, u_char *read_data, u_char ack_data, u_char *gpreg, u_char *gpcntl) +static void __init +nvram_read_byte(ncr_slot *np, u_char *read_data, u_char ack_data, u_char *gpreg, u_char *gpcntl) { int x; u_char read_bit; @@ -11436,7 +12950,8 @@ * Output an ACK to the NVRAM after reading, * change GPIO0 to output and when done back to an input */ -static void __init nvram_writeAck(ncr_slot *np, u_char write_bit, u_char *gpreg, u_char *gpcntl) +static void __init +nvram_writeAck(ncr_slot *np, u_char write_bit, u_char *gpreg, u_char *gpcntl) { OUTB (nc_gpcntl, *gpcntl & 0xfe); nvram_doBit(np, 0, write_bit, gpreg); @@ -11447,7 +12962,8 @@ * Input an ACK from NVRAM after writing, * change GPIO0 to input and when done back to an output */ -static void __init nvram_readAck(ncr_slot *np, u_char *read_bit, u_char *gpreg, u_char *gpcntl) +static void __init +nvram_readAck(ncr_slot *np, u_char *read_bit, u_char *gpreg, u_char *gpcntl) { OUTB (nc_gpcntl, *gpcntl | 0x01); nvram_doBit(np, read_bit, 1, gpreg); @@ -11458,7 +12974,8 @@ * Read or write a bit to the NVRAM, * read if GPIO0 input else write if GPIO0 output */ -static void __init nvram_doBit(ncr_slot *np, u_char *read_bit, u_char write_bit, u_char *gpreg) +static void __init +nvram_doBit(ncr_slot *np, u_char *read_bit, u_char write_bit, u_char *gpreg) { nvram_setBit(np, write_bit, gpreg, SET_BIT); nvram_setBit(np, 0, gpreg, SET_CLK); @@ -11480,7 +12997,8 @@ /* * Set/clear data/clock bit in GPIO0 */ -static void __init nvram_setBit(ncr_slot *np, u_char write_bit, u_char *gpreg, int bit_mode) +static void __init +nvram_setBit(ncr_slot *np, u_char write_bit, u_char *gpreg, int bit_mode) { UDELAY (5); switch (bit_mode){ @@ -11566,7 +13084,8 @@ /* * Read Tekram NvRAM data and compute checksum. */ -static u_short __init Tnvram_read_data(ncr_slot *np, u_short *data, int len, u_char *gpreg) +static u_short __init +Tnvram_read_data(ncr_slot *np, u_short *data, int len, u_char *gpreg) { u_char read_bit; u_short csum; @@ -11591,7 +13110,8 @@ /* * Send read command and address to NVRAM */ -static void __init Tnvram_Send_Command(ncr_slot *np, u_short write_data, u_char *read_bit, u_char *gpreg) +static void __init +Tnvram_Send_Command(ncr_slot *np, u_short write_data, u_char *read_bit, u_char *gpreg) { int x; @@ -11605,7 +13125,8 @@ /* * READ a byte from the NVRAM */ -static void __init Tnvram_Read_Word(ncr_slot *np, u_short *nvram_data, u_char *gpreg) +static void __init +Tnvram_Read_Word(ncr_slot *np, u_short *nvram_data, u_char *gpreg) { int x; u_char read_bit; @@ -11624,7 +13145,8 @@ /* * Read bit from NVRAM */ -static void __init Tnvram_Read_Bit(ncr_slot *np, u_char *read_bit, u_char *gpreg) +static void __init +Tnvram_Read_Bit(ncr_slot *np, u_char *read_bit, u_char *gpreg) { UDELAY (2); Tnvram_Clk(np, gpreg); @@ -11634,7 +13156,8 @@ /* * Write bit to GPIO0 */ -static void __init Tnvram_Write_Bit(ncr_slot *np, u_char write_bit, u_char *gpreg) +static void __init +Tnvram_Write_Bit(ncr_slot *np, u_char write_bit, u_char *gpreg) { if (write_bit & 0x01) *gpreg |= 0x02; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/sym53c8xx.h linux.ac/drivers/scsi/sym53c8xx.h --- linux.vanilla/drivers/scsi/sym53c8xx.h Tue May 25 22:47:42 1999 +++ linux.ac/drivers/scsi/sym53c8xx.h Mon Sep 20 21:00:34 1999 @@ -1,7 +1,7 @@ /****************************************************************************** ** High Performance device driver for the Symbios 53C896 controller. ** -** Copyright (C) 1998 Gerard Roudier +** Copyright (C) 1998-1999 Gerard Roudier ** ** This driver also supports all the Symbios 53C8XX controller family, ** except 53C810 revisions < 16, 53C825 revisions < 16 and all diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/sym53c8xx_defs.h linux.ac/drivers/scsi/sym53c8xx_defs.h --- linux.vanilla/drivers/scsi/sym53c8xx_defs.h Tue May 25 22:47:23 1999 +++ linux.ac/drivers/scsi/sym53c8xx_defs.h Mon Sep 20 21:00:31 1999 @@ -1,7 +1,7 @@ /****************************************************************************** ** High Performance device driver for the Symbios 53C896 controller. ** -** Copyright (C) 1998 Gerard Roudier +** Copyright (C) 1998-1999 Gerard Roudier ** ** This driver also supports all the Symbios 53C8XX controller family, ** except 53C810 revisions < 16, 53C825 revisions < 16 and all @@ -137,13 +137,13 @@ #define SCSI_NCR_MAX_SYNC (40) /* - * Allow tags from 2 to 64, default 8 + * Allow tags from 2 to 256, default 8 */ #ifdef CONFIG_SCSI_NCR53C8XX_MAX_TAGS #if CONFIG_SCSI_NCR53C8XX_MAX_TAGS < 2 #define SCSI_NCR_MAX_TAGS (2) -#elif CONFIG_SCSI_NCR53C8XX_MAX_TAGS > 64 -#define SCSI_NCR_MAX_TAGS (64) +#elif CONFIG_SCSI_NCR53C8XX_MAX_TAGS > 256 +#define SCSI_NCR_MAX_TAGS (256) #else #define SCSI_NCR_MAX_TAGS CONFIG_SCSI_NCR53C8XX_MAX_TAGS #endif @@ -175,6 +175,13 @@ #endif /* + * Immediate arbitration + */ +#if defined(CONFIG_SCSI_NCR53C8XX_IARB) +#define SCSI_NCR_IARB_SUPPORT +#endif + +/* * Sync transfer frequency at startup. * Allow from 5Mhz to 40Mhz default 20 Mhz. */ @@ -238,7 +245,7 @@ */ #ifdef CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT #define SCSI_NCR_SETUP_LED_PIN (1) -#define SCSI_NCR_SETUP_DIFF_SUPPORT (3) +#define SCSI_NCR_SETUP_DIFF_SUPPORT (4) #else #define SCSI_NCR_SETUP_LED_PIN (0) #define SCSI_NCR_SETUP_DIFF_SUPPORT (0) @@ -250,6 +257,57 @@ #define SCSI_NCR_SETUP_SETTLE_TIME (2) /* +** Bridge quirks work-around option defaulted to 1. +*/ +#ifndef SCSI_NCR_PCIQ_WORK_AROUND_OPT +#define SCSI_NCR_PCIQ_WORK_AROUND_OPT 1 +#endif + +/* +** Work-around common bridge misbehaviour. +** +** - Do not flush posted writes in the opposite +** direction on read. +** - May reorder DMA writes to memory. +** +** This option should not affect performances +** significantly, so it is the default. +*/ +#if SCSI_NCR_PCIQ_WORK_AROUND_OPT == 1 +#define SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM +#define SCSI_NCR_PCIQ_MAY_REORDER_WRITES +#define SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS + +/* +** Same as option 1, but also deal with +** misconfigured interrupts. +** +** - Edge triggerred instead of level sensitive. +** - No interrupt line connected. +** - IRQ number misconfigured. +** +** If no interrupt is delivered, the driver will +** catch the interrupt conditions 10 times per +** second. No need to say that this option is +** not recommended. +*/ +#elif SCSI_NCR_PCIQ_WORK_AROUND_OPT == 2 +#define SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM +#define SCSI_NCR_PCIQ_MAY_REORDER_WRITES +#define SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS +#define SCSI_NCR_PCIQ_BROKEN_INTR + +/* +** Some bridge designers decided to flush +** everything prior to deliver the interrupt. +** This option tries to deal with such a +** behaviour. +*/ +#elif SCSI_NCR_PCIQ_WORK_AROUND_OPT == 3 +#define SCSI_NCR_PCIQ_SYNC_ON_INTR +#endif + +/* ** Other parameters not configurable with "make config" ** Avoid to change these constants, unless you know what you are doing. */ @@ -258,20 +316,20 @@ #define SCSI_NCR_MAX_SCATTER (127) #define SCSI_NCR_MAX_TARGET (16) -/* No need to use a too large adapter queue */ -#if SCSI_NCR_MAX_TAGS <= 32 -#define SCSI_NCR_CAN_QUEUE (7*SCSI_NCR_MAX_TAGS) -#else -#define SCSI_NCR_CAN_QUEUE (250) -#endif - +/* +** Compute some desirable value for CAN_QUEUE +** and CMD_PER_LUN. +** The driver will use lower values if these +** ones appear to be too large. +*/ +#define SCSI_NCR_CAN_QUEUE (8*SCSI_NCR_MAX_TAGS + 2*SCSI_NCR_MAX_TARGET) #define SCSI_NCR_CMD_PER_LUN (SCSI_NCR_MAX_TAGS) -#define SCSI_NCR_SG_TABLESIZE (SCSI_NCR_MAX_SCATTER) +#define SCSI_NCR_SG_TABLESIZE (SCSI_NCR_MAX_SCATTER) #define SCSI_NCR_TIMER_INTERVAL (HZ) #if 1 /* defined CONFIG_SCSI_MULTI_LUN */ -#define SCSI_NCR_MAX_LUN (8) +#define SCSI_NCR_MAX_LUN (16) #else #define SCSI_NCR_MAX_LUN (1) #endif @@ -279,6 +337,18 @@ #ifndef HOSTS_C /* +** These simple macros limit expression involving +** kernel time values (jiffies) to some that have +** chance not to be too much incorrect. :-) +*/ +#define ktime_get(o) (jiffies + (u_long) o) +#define ktime_exp(b) ((long)(jiffies) - (long)(b) >= 0) +#define ktime_dif(a, b) ((long)(a) - (long)(b)) +/* These ones are not used in this driver */ +#define ktime_add(a, o) ((a) + (u_long)(o)) +#define ktime_sub(a, o) ((a) - (u_long)(o)) + +/* ** IO functions definition for big/little endian support. ** For now, the NCR is only supported in little endian addressing mode, ** and big endian byte ordering is only supported for the PPC. @@ -384,6 +454,10 @@ #define PCI_DEVICE_ID_NCR_53C896 0xb #endif +#ifndef PCI_DEVICE_ID_NCR_53C895A +#define PCI_DEVICE_ID_NCR_53C895A 0x12 +#endif + /* ** NCR53C8XX devices features table. */ @@ -391,31 +465,33 @@ unsigned short device_id; unsigned short revision_id; char *name; - unsigned char burst_max; + unsigned char burst_max; /* log-base-2 of max burst */ unsigned char offset_max; unsigned char nr_divisor; unsigned int features; #define FE_LED0 (1<<0) -#define FE_WIDE (1<<1) -#define FE_ULTRA (1<<2) -#define FE_ULTRA2 (1<<3) -#define FE_DBLR (1<<4) -#define FE_QUAD (1<<5) -#define FE_ERL (1<<6) -#define FE_CLSE (1<<7) -#define FE_WRIE (1<<8) -#define FE_ERMP (1<<9) -#define FE_BOF (1<<10) -#define FE_DFS (1<<11) -#define FE_PFEN (1<<12) -#define FE_LDSTR (1<<13) -#define FE_RAM (1<<14) -#define FE_CLK80 (1<<15) -#define FE_RAM8K (1<<16) -#define FE_64BIT (1<<17) -#define FE_IO256 (1<<18) -#define FE_NOPM (1<<19) -#define FE_LEDC (1<<20) +#define FE_WIDE (1<<1) /* Wide data transfers */ +#define FE_ULTRA (1<<2) /* Ultra speed 20Mtrans/sec */ +#define FE_ULTRA2 (1<<3) /* Ultra 2 - 40 Mtrans/sec */ +#define FE_DBLR (1<<4) /* Clock doubler present */ +#define FE_QUAD (1<<5) /* Clock quadrupler present */ +#define FE_ERL (1<<6) /* Enable read line */ +#define FE_CLSE (1<<7) /* Cache line size enable */ +#define FE_WRIE (1<<8) /* Write & Invalidate enable */ +#define FE_ERMP (1<<9) /* Enable read multiple */ +#define FE_BOF (1<<10) /* Burst opcode fetch */ +#define FE_DFS (1<<11) /* DMA fifo size */ +#define FE_PFEN (1<<12) /* Prefetch enable */ +#define FE_LDSTR (1<<13) /* Load/Store supported */ +#define FE_RAM (1<<14) /* On chip RAM present */ +#define FE_CLK80 (1<<15) /* Board clock is 80 MHz */ +#define FE_RAM8K (1<<16) /* On chip RAM sized 8Kb */ +#define FE_64BIT (1<<17) /* Supports 64-bit addressing */ +#define FE_IO256 (1<<18) /* Requires full 256 bytes in PCI space */ +#define FE_NOPM (1<<19) /* Scripts handles phase mismatch */ +#define FE_LEDC (1<<20) /* Hardware control of LED */ +#define FE_DIFF (1<<21) /* Support Differential SCSI */ + #define FE_CACHE_SET (FE_ERL|FE_CLSE|FE_WRIE|FE_ERMP) #define FE_SCSI_SET (FE_WIDE|FE_ULTRA|FE_ULTRA2|FE_DBLR|FE_QUAD|F_CLK80) #define FE_SPECIAL_SET (FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM) @@ -449,35 +525,53 @@ FE_WIDE|FE_ERL} \ , \ {PCI_DEVICE_ID_NCR_53C825, 0x0f, "825", 4, 8, 4, \ - FE_WIDE|FE_ERL|FE_BOF} \ + FE_WIDE|FE_ERL|FE_BOF|FE_DIFF} \ , \ {PCI_DEVICE_ID_NCR_53C825, 0xff, "825a", 6, 8, 4, \ - FE_WIDE|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM} \ + FE_WIDE|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM|FE_DIFF} \ , \ {PCI_DEVICE_ID_NCR_53C860, 0xff, "860", 4, 8, 5, \ FE_ULTRA|FE_CLK80|FE_CACHE_SET|FE_BOF|FE_LDSTR|FE_PFEN} \ , \ {PCI_DEVICE_ID_NCR_53C875, 0x01, "875", 6, 16, 5, \ - FE_WIDE|FE_ULTRA|FE_CLK80|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}\ + FE_WIDE|FE_ULTRA|FE_CLK80|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|\ + FE_RAM|FE_DIFF} \ , \ {PCI_DEVICE_ID_NCR_53C875, 0x0f, "875", 6, 16, 5, \ - FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}\ + FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| \ + FE_RAM|FE_DIFF} \ + , \ + {PCI_DEVICE_ID_NCR_53C875, 0x1f, "876", 6, 16, 5, \ + FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| \ + FE_RAM|FE_DIFF} \ + , \ + {PCI_DEVICE_ID_NCR_53C875, 0x2f, "875E", 6, 16, 5, \ + FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| \ + FE_RAM|FE_DIFF} \ , \ {PCI_DEVICE_ID_NCR_53C875, 0xff, "876", 6, 16, 5, \ - FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}\ + FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| \ + FE_RAM|FE_DIFF} \ , \ {PCI_DEVICE_ID_NCR_53C875J,0xff, "875J", 6, 16, 5, \ - FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}\ + FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| \ + FE_RAM} \ , \ {PCI_DEVICE_ID_NCR_53C885, 0xff, "885", 6, 16, 5, \ - FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}\ + FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| \ + FE_RAM|FE_DIFF} \ , \ {PCI_DEVICE_ID_NCR_53C895, 0xff, "895", 6, 31, 7, \ - FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}\ + FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| \ + FE_RAM} \ , \ - {PCI_DEVICE_ID_NCR_53C896, 0xff, "896", 7, 31, 7, \ - FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM|\ - FE_RAM8K|FE_64BIT|FE_IO256|FE_NOPM|FE_LEDC}\ + {PCI_DEVICE_ID_NCR_53C896, 0xff, "896", 6, 31, 7, \ + FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| \ + FE_RAM|FE_RAM8K|FE_64BIT|FE_IO256|FE_NOPM|FE_LEDC} \ + , \ + {PCI_DEVICE_ID_NCR_53C895A, 0xff, "895a", 6, 31, 7, \ + FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| \ + FE_RAM|FE_RAM8K|FE_64BIT|FE_IO256|FE_NOPM|FE_LEDC} \ } /* @@ -494,10 +588,47 @@ PCI_DEVICE_ID_NCR_53C875J, \ PCI_DEVICE_ID_NCR_53C885, \ PCI_DEVICE_ID_NCR_53C895, \ - PCI_DEVICE_ID_NCR_53C896 \ + PCI_DEVICE_ID_NCR_53C896, \ + PCI_DEVICE_ID_NCR_53C895A \ } /* +** Driver setup structure. +** +** This structure is initialized from linux config options. +** It can be overridden at boot-up by the boot command line. +*/ +#define SCSI_NCR_MAX_EXCLUDES 8 +struct ncr_driver_setup { + u_char master_parity; + u_char scsi_parity; + u_char disconnection; + u_char special_features; + u_char ultra_scsi; + u_char force_sync_nego; + u_char reverse_probe; + u_char pci_fix_up; + u_char use_nvram; + u_char verbose; + u_char default_tags; + u_short default_sync; + u_short debug; + u_char burst_max; + u_char led_pin; + u_char max_wide; + u_char settle_delay; + u_char diff_support; + u_char irqm; + u_char bus_check; + u_char optimize; + u_char recovery; + u_char host_id; + u_short iarb; + u_int excludes[SCSI_NCR_MAX_EXCLUDES]; + char tag_ctrl[100]; +}; + +/* ** Initial setup. ** Can be overriden at startup by a command line. */ @@ -524,7 +655,9 @@ 0, \ 1, \ 0, \ - 0 \ + 0, \ + 255, \ + 0x00 \ } /* @@ -555,9 +688,139 @@ 1, \ 1, \ 0, \ - 0 \ + 0, \ + 255 \ } +#ifdef SCSI_NCR_NVRAM_SUPPORT +/* +** Symbios NvRAM data format +*/ +#define SYMBIOS_NVRAM_SIZE 368 +#define SYMBIOS_NVRAM_ADDRESS 0x100 + +struct Symbios_nvram { +/* Header 6 bytes */ + u_short type; /* 0x0000 */ + u_short byte_count; /* excluding header/trailer */ + u_short checksum; + +/* Controller set up 20 bytes */ + u_char v_major; /* 0x00 */ + u_char v_minor; /* 0x30 */ + u_int32 boot_crc; + u_short flags; +#define SYMBIOS_SCAM_ENABLE (1) +#define SYMBIOS_PARITY_ENABLE (1<<1) +#define SYMBIOS_VERBOSE_MSGS (1<<2) +#define SYMBIOS_CHS_MAPPING (1<<3) +#define SYMBIOS_NO_NVRAM (1<<3) /* ??? */ + u_short flags1; +#define SYMBIOS_SCAN_HI_LO (1) + u_short term_state; +#define SYMBIOS_TERM_CANT_PROGRAM (0) +#define SYMBIOS_TERM_ENABLED (1) +#define SYMBIOS_TERM_DISABLED (2) + u_short rmvbl_flags; +#define SYMBIOS_RMVBL_NO_SUPPORT (0) +#define SYMBIOS_RMVBL_BOOT_DEVICE (1) +#define SYMBIOS_RMVBL_MEDIA_INSTALLED (2) + u_char host_id; + u_char num_hba; /* 0x04 */ + u_char num_devices; /* 0x10 */ + u_char max_scam_devices; /* 0x04 */ + u_char num_valid_scam_devives; /* 0x00 */ + u_char rsvd; + +/* Boot order 14 bytes * 4 */ + struct Symbios_host{ + u_short type; /* 4:8xx / 0:nok */ + u_short device_id; /* PCI device id */ + u_short vendor_id; /* PCI vendor id */ + u_char bus_nr; /* PCI bus number */ + u_char device_fn; /* PCI device/function number << 3*/ + u_short word8; + u_short flags; +#define SYMBIOS_INIT_SCAN_AT_BOOT (1) + u_short io_port; /* PCI io_port address */ + } host[4]; + +/* Targets 8 bytes * 16 */ + struct Symbios_target { + u_char flags; +#define SYMBIOS_DISCONNECT_ENABLE (1) +#define SYMBIOS_SCAN_AT_BOOT_TIME (1<<1) +#define SYMBIOS_SCAN_LUNS (1<<2) +#define SYMBIOS_QUEUE_TAGS_ENABLED (1<<3) + u_char rsvd; + u_char bus_width; /* 0x08/0x10 */ + u_char sync_offset; + u_short sync_period; /* 4*period factor */ + u_short timeout; + } target[16]; +/* Scam table 8 bytes * 4 */ + struct Symbios_scam { + u_short id; + u_short method; +#define SYMBIOS_SCAM_DEFAULT_METHOD (0) +#define SYMBIOS_SCAM_DONT_ASSIGN (1) +#define SYMBIOS_SCAM_SET_SPECIFIC_ID (2) +#define SYMBIOS_SCAM_USE_ORDER_GIVEN (3) + u_short status; +#define SYMBIOS_SCAM_UNKNOWN (0) +#define SYMBIOS_SCAM_DEVICE_NOT_FOUND (1) +#define SYMBIOS_SCAM_ID_NOT_SET (2) +#define SYMBIOS_SCAM_ID_VALID (3) + u_char target_id; + u_char rsvd; + } scam[4]; + + u_char spare_devices[15*8]; + u_char trailer[6]; /* 0xfe 0xfe 0x00 0x00 0x00 0x00 */ +}; +typedef struct Symbios_nvram Symbios_nvram; +typedef struct Symbios_host Symbios_host; +typedef struct Symbios_target Symbios_target; +typedef struct Symbios_scam Symbios_scam; + +/* +** Tekram NvRAM data format. +*/ +#define TEKRAM_NVRAM_SIZE 64 +#define TEKRAM_NVRAM_ADDRESS 0 + +struct Tekram_nvram { + struct Tekram_target { + u_char flags; +#define TEKRAM_PARITY_CHECK (1) +#define TEKRAM_SYNC_NEGO (1<<1) +#define TEKRAM_DISCONNECT_ENABLE (1<<2) +#define TEKRAM_START_CMD (1<<3) +#define TEKRAM_TAGGED_COMMANDS (1<<4) +#define TEKRAM_WIDE_NEGO (1<<5) + u_char sync_index; + u_short word2; + } target[16]; + u_char host_id; + u_char flags; +#define TEKRAM_MORE_THAN_2_DRIVES (1) +#define TEKRAM_DRIVES_SUP_1GB (1<<1) +#define TEKRAM_RESET_ON_POWER_ON (1<<2) +#define TEKRAM_ACTIVE_NEGATION (1<<3) +#define TEKRAM_IMMEDIATE_SEEK (1<<4) +#define TEKRAM_SCAN_LUNS (1<<5) +#define TEKRAM_REMOVABLE_FLAGS (3<<6) /* 0: disable; 1: boot device; 2:all */ + u_char boot_delay_index; + u_char max_tags_index; + u_short flags1; +#define TEKRAM_F2_F6_ENABLED (1) + u_short spare[29]; +}; +typedef struct Tekram_nvram Tekram_nvram; +typedef struct Tekram_target Tekram_target; + +#endif /* SCSI_NCR_NVRAM_SUPPORT */ + /**************** ORIGINAL CONTENT of ncrreg.h from FreeBSD ******************/ /*----------------------------------------------------------------- @@ -573,6 +836,7 @@ /*01*/ u_char nc_scntl1; /* no reset */ #define ISCON 0x10 /* connected to scsi */ #define CRST 0x08 /* force reset */ + #define IARB 0x02 /* immediate arbitration */ /*02*/ u_char nc_scntl2; /* no disconnect expected */ #define SDU 0x80 /* cmd: disconnect will raise error */ @@ -639,7 +903,10 @@ #define DM 0x04 /* sta: DIFFSENS mismatch (895/6 only) */ #define LDSC 0x02 /* sta: disconnect & reconnect */ -/*10*/ u_int32 nc_dsa; /* --> Base page */ +/*10*/ u_char nc_dsa; /* --> Base page */ +/*11*/ u_char nc_dsa1; +/*12*/ u_char nc_dsa2; +/*13*/ u_char nc_dsa3; /*14*/ u_char nc_istat; /* --> Main Command and status */ #define CABRT 0x80 /* cmd: abort current operation */ @@ -696,7 +963,7 @@ #define BOF 0x02 /* mod: burst op code fetch */ /*39*/ u_char nc_dien; -/*3a*/ u_char nc_dwt; +/*3a*/ u_char nc_sbr; /*3b*/ u_char nc_dcntl; /* --> Script execution control */ #define CLSE 0x80 /* mod: cache line size enable */ @@ -736,6 +1003,7 @@ /*4c*/ u_char nc_stest0; /*4d*/ u_char nc_stest1; + #define SCLK 0x80 /* Use the PCI clock as SCSI clock */ #define DBLEN 0x08 /* clock doubler running */ #define DBLSEL 0x04 /* clock doubler selected */ @@ -794,8 +1062,15 @@ /*c0*/ u_int32 nc_pmjad1; /* Phase Mismatch Jump Address 1 */ /*c4*/ u_int32 nc_pmjad2; /* Phase Mismatch Jump Address 2 */ -/*c8*/ u_int32 nc_rbc; /* Remaining Byte Count */ -/*cc*/ u_int32 nc_ua; /* Updated Address */ +/*c8*/ u_char nc_rbc; /* Remaining Byte Count */ +/*c9*/ u_char nc_rbc1; /* */ +/*ca*/ u_char nc_rbc2; /* */ +/*cb*/ u_char nc_rbc3; /* */ + +/*cc*/ u_char nc_ua; /* Updated Address */ +/*cd*/ u_char nc_ua1; /* */ +/*ce*/ u_char nc_ua2; /* */ +/*cf*/ u_char nc_ua3; /* */ /*d0*/ u_int32 nc_esa; /* Entry Storage Address */ /*d4*/ u_char nc_ia; /* Instruction Address */ /*d5*/ u_char nc_ia1; @@ -815,10 +1090,6 @@ #define REGJ(p,r) (offsetof(struct ncr_reg, p ## r)) #define REG(r) REGJ (nc_, r) -#ifndef TARGET_MODE -#define TARGET_MODE 0 -#endif - typedef u_int32 ncrcmd; /*----------------------------------------------------------- @@ -855,9 +1126,15 @@ **----------------------------------------------------------- */ -#define SCR_MOVE_ABS(l) ((0x08000000 ^ (TARGET_MODE << 1ul)) | (l)) -#define SCR_MOVE_IND(l) ((0x28000000 ^ (TARGET_MODE << 1ul)) | (l)) -#define SCR_MOVE_TBL (0x18000000 ^ (TARGET_MODE << 1ul)) +#define OPC_MOVE 0x08000000 + +#define SCR_MOVE_ABS(l) ((0x00000000 | OPC_MOVE) | (l)) +#define SCR_MOVE_IND(l) ((0x20000000 | OPC_MOVE) | (l)) +#define SCR_MOVE_TBL (0x10000000 | OPC_MOVE) + +#define SCR_CHMOV_ABS(l) ((0x00000000) | (l)) +#define SCR_CHMOV_IND(l) ((0x20000000) | (l)) +#define SCR_CHMOV_TBL (0x10000000) struct scr_tblmove { u_int32 size; @@ -870,7 +1147,7 @@ ** **----------------------------------------------------------- ** -** SEL_ABS | SCR_ID (0..7) [ | REL_JMP] +** SEL_ABS | SCR_ID (0..15) [ | REL_JMP] ** <> ** ** SEL_TBL | << dnad_offset>> [ | REL_JMP] @@ -1104,7 +1381,7 @@ ** Conditions: ** WHEN (phase) ** IF (phase) -** CARRY +** CARRYSET ** DATA (data, mask) ** **----------------------------------------------------------- diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/u14-34f.c linux.ac/drivers/scsi/u14-34f.c --- linux.vanilla/drivers/scsi/u14-34f.c Sat Sep 11 00:54:10 1999 +++ linux.ac/drivers/scsi/u14-34f.c Sat Sep 18 09:19:35 1999 @@ -1,6 +1,16 @@ /* * u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters. * + * 16 Sep 1999 Rev. 5.11 for linux 2.2.12 and 2.3.18 + * + Updated to the new __setup interface for boot command line options. + * + When loaded as a module, accepts the new parameter boot_options + * which value is a string with the same format of the kernel boot + * command line options. A valid example is: + * modprobe u14-34f 'boot_options=\"0x230,0x340,lc:y,mq:4\"' + * + * 22 Jul 1999 Rev. 5.00 for linux 2.2.10 and 2.3.11 + * + Removed pre-2.2 source code compatibility. + * * 26 Jul 1998 Rev. 4.33 for linux 2.0.35 and 2.1.111 * Added command line option (et:[y|n]) to use the existing * translation (returned by scsicam_bios_param) as disk geometry. @@ -159,7 +169,7 @@ * * Multiple U14F and/or U34F host adapters are supported. * - * Copyright (C) 1994-1998 Dario Ballabio (dario@milano.europe.dg.com) + * Copyright (C) 1994-1999 Dario Ballabio (dario@milano.europe.dg.com) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that redistributions of source @@ -251,7 +261,7 @@ * After the optional list of detection probes, other possible command line * options are: * - * eh:y use new scsi code (linux 2.2 only); + * eh:y use new scsi code; * eh:n use old scsi code; * et:y use disk geometry returned by scsicam_bios_param; * et:n use disk geometry jumpered on the board; @@ -318,7 +328,7 @@ #if defined(MODULE) #include -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,26) +MODULE_PARM(boot_options, "s"); MODULE_PARM(io_port, "1-" __MODULE_STRING(MAX_INT_PARAM) "i"); MODULE_PARM(linked_comm, "i"); MODULE_PARM(have_old_firmware, "i"); @@ -327,7 +337,6 @@ MODULE_PARM(use_new_eh_code, "i"); MODULE_PARM(ext_tran, "i"); MODULE_AUTHOR("Dario Ballabio"); -#endif #endif @@ -349,42 +358,21 @@ #include "u14-34f.h" #include #include - -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,36) #include +#include + +#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,18) +#include #else -#define __initfunc(A) A -#define __initdata -#define __init +#include #endif -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,101) -#include -#define IRQ_FLAGS -#define IRQ_LOCK -#define IRQ_LOCK_SAVE -#define IRQ_UNLOCK -#define IRQ_UNLOCK_RESTORE #define SPIN_FLAGS unsigned long spin_flags; #define SPIN_LOCK spin_lock_irq(&io_request_lock); #define SPIN_LOCK_SAVE spin_lock_irqsave(&io_request_lock, spin_flags); #define SPIN_UNLOCK spin_unlock_irq(&io_request_lock); #define SPIN_UNLOCK_RESTORE \ spin_unlock_irqrestore(&io_request_lock, spin_flags); -static int use_new_eh_code = TRUE; -#else -#define IRQ_FLAGS unsigned long irq_flags; -#define IRQ_LOCK cli(); -#define IRQ_LOCK_SAVE do {save_flags(irq_flags); cli();} while (0); -#define IRQ_UNLOCK sti(); -#define IRQ_UNLOCK_RESTORE do {restore_flags(irq_flags);} while (0); -#define SPIN_FLAGS -#define SPIN_LOCK -#define SPIN_LOCK_SAVE -#define SPIN_UNLOCK -#define SPIN_UNLOCK_RESTORE -static int use_new_eh_code = FALSE; -#endif struct proc_dir_entry proc_scsi_u14_34f = { PROC_SCSI_U14_34F, 6, "u14_34f", @@ -467,6 +455,10 @@ #define ASOK 0x00 #define ASST 0x91 +#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,18) +#define ARRAY_SIZE(x) (sizeof (x) / sizeof((x)[0])) +#endif + #define YESNO(a) ((a) ? 'y' : 'n') #define TLDEV(type) ((type) == TYPE_DISK || (type) == TYPE_ROM) @@ -531,7 +523,7 @@ /* Initialize num_boards so that ihdlr can work while detect is in progress */ static unsigned int num_boards = MAX_BOARDS; -static unsigned long io_port[] __initdata = { +static unsigned long io_port[] = { /* Space for MAX_INT_PARAM ports usable while loading as a module */ SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, @@ -569,6 +561,8 @@ static int setup_done = FALSE; static int link_statistics = 0; static int ext_tran = FALSE; +static int use_new_eh_code = TRUE; +static char *boot_options = NULL; #if defined(HAVE_OLD_UX4F_FIRMWARE) static int have_old_firmware = TRUE; @@ -591,9 +585,7 @@ static void select_queue_depths(struct Scsi_Host *host, Scsi_Device *devlist) { Scsi_Device *dev; int j, ntag = 0, nuntag = 0, tqd, utqd; - IRQ_FLAGS - IRQ_LOCK_SAVE j = ((struct hostdata *) host->hostdata)->board_number; for(dev = devlist; dev; dev = dev->next) { @@ -641,7 +633,6 @@ dev->queue_depth, link_suffix, tag_suffix); } - IRQ_UNLOCK_RESTORE return; } @@ -685,10 +676,8 @@ outb(CMD_OGM_INTR, sh[j]->io_port + REG_LCL_INTR); SPIN_UNLOCK - IRQ_UNLOCK time = jiffies; while ((jiffies - time) < HZ && limit++ < 20000) udelay(100L); - IRQ_LOCK SPIN_LOCK if (cpp->adapter_status || HD(j)->cp_stat[0] != FREE) { @@ -700,7 +689,7 @@ return FALSE; } -static inline int __init port_detect \ +static inline int port_detect \ (unsigned long port_base, unsigned int j, Scsi_Host_Template *tpnt) { unsigned char irq, dma_channel, subversion, i; unsigned char in_byte; @@ -746,7 +735,9 @@ sprintf(name, "%s%d", driver_name, j); if(check_region(port_base, REGION_SIZE)) { +#if defined(DEBUG_DETECT) printk("%s: address 0x%03lx in use, skipping probe.\n", name, port_base); +#endif return FALSE; } @@ -780,11 +771,7 @@ if (have_old_firmware) tpnt->use_clustering = DISABLE_CLUSTERING; -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,101) tpnt->use_new_eh_code = use_new_eh_code; -#else - use_new_eh_code = FALSE; -#endif sh[j] = scsi_register(tpnt, sizeof(struct hostdata)); @@ -893,7 +880,7 @@ if (max_queue_depth < MAX_CMD_PER_LUN) max_queue_depth = MAX_CMD_PER_LUN; if (j == 0) { - printk("UltraStor 14F/34F: Copyright (C) 1994-1998 Dario Ballabio.\n"); + printk("UltraStor 14F/34F: Copyright (C) 1994-1999 Dario Ballabio.\n"); printk("%s config options -> of:%c, lc:%c, mq:%d, eh:%c, et:%c.\n", driver_name, YESNO(have_old_firmware), YESNO(linked_comm), max_queue_depth, YESNO(use_new_eh_code), YESNO(ext_tran)); @@ -914,8 +901,7 @@ return TRUE; } -void __init u14_34f_setup(char *str, int *ints) -{ +static void internal_setup(char *str, int *ints) { int i, argc = ints[0]; char *cur = str, *pc; @@ -949,14 +935,30 @@ return; } -int __init u14_34f_detect(Scsi_Host_Template *tpnt) +static int option_setup(char *str) { + int ints[MAX_INT_PARAM]; + char *cur = str; + int i = 1; + + while (cur && isdigit(*cur) && i <= MAX_INT_PARAM) { + ints[i++] = simple_strtoul(cur, NULL, 0); + + if ((cur = strchr(cur, ',')) != NULL) cur++; + } + + ints[0] = i - 1; + internal_setup(cur, ints); + return 0; +} + +int u14_34f_detect(Scsi_Host_Template *tpnt) { unsigned int j = 0, k; - IRQ_FLAGS - IRQ_LOCK_SAVE tpnt->proc_dir = &proc_scsi_u14_34f; + if(boot_options) option_setup(boot_options); + #if defined(MODULE) /* io_port could have been modified when loading as a module */ if(io_port[0] != SKIP) { @@ -975,7 +977,6 @@ } num_boards = j; - IRQ_UNLOCK_RESTORE return j; } @@ -1111,11 +1112,8 @@ int u14_34f_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { int rtn; - IRQ_FLAGS - IRQ_LOCK_SAVE rtn = do_qcomm(SCpnt, done); - IRQ_UNLOCK_RESTORE return rtn; } @@ -1187,16 +1185,11 @@ int u14_34f_old_abort(Scsi_Cmnd *SCarg) { int rtn; - IRQ_FLAGS - IRQ_LOCK_SAVE rtn = do_old_abort(SCarg); - IRQ_UNLOCK_RESTORE return rtn; } -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,101) - static inline int do_abort(Scsi_Cmnd *SCarg) { unsigned int i, j; @@ -1274,8 +1267,6 @@ return do_abort(SCarg); } -#endif /* new_eh_code */ - static inline int do_old_reset(Scsi_Cmnd *SCarg) { unsigned int i, j, time, k, c, limit = 0; int arg_done = FALSE; @@ -1363,10 +1354,8 @@ HD(j)->in_reset = TRUE; SPIN_UNLOCK - IRQ_UNLOCK time = jiffies; while ((jiffies - time) < (10 * HZ) && limit++ < 200000) udelay(100L); - IRQ_LOCK SPIN_LOCK printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit); @@ -1402,7 +1391,6 @@ continue; SCpnt->scsi_done(SCpnt); - IRQ_LOCK } HD(j)->in_reset = FALSE; @@ -1420,16 +1408,11 @@ int u14_34f_old_reset(Scsi_Cmnd *SCarg, unsigned int reset_flags) { int rtn; - IRQ_FLAGS - IRQ_LOCK_SAVE rtn = do_old_reset(SCarg); - IRQ_UNLOCK_RESTORE return rtn; } -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,101) - static inline int do_reset(Scsi_Cmnd *SCarg) { unsigned int i, j, time, k, c, limit = 0; int arg_done = FALSE; @@ -1511,10 +1494,8 @@ HD(j)->in_reset = TRUE; SPIN_UNLOCK - IRQ_UNLOCK time = jiffies; while ((jiffies - time) < (10 * HZ) && limit++ < 200000) udelay(100L); - IRQ_LOCK SPIN_LOCK printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit); @@ -1550,7 +1531,6 @@ continue; SCpnt->scsi_done(SCpnt); - IRQ_LOCK } HD(j)->in_reset = FALSE; @@ -1567,8 +1547,6 @@ return do_reset(SCarg); } -#endif /* new_eh_code */ - int u14_34f_biosparam(Disk *disk, kdev_t dev, int *dkinfo) { unsigned int j = 0; int size = disk->capacity; @@ -1957,24 +1935,18 @@ static void do_interrupt_handler(int irq, void *shap, struct pt_regs *regs) { unsigned int j; - IRQ_FLAGS SPIN_FLAGS /* Check if the interrupt must be processed by this handler */ if ((j = (unsigned int)((char *)shap - sha)) >= num_boards) return; SPIN_LOCK_SAVE - IRQ_LOCK_SAVE ihdlr(irq, j); - IRQ_UNLOCK_RESTORE SPIN_UNLOCK_RESTORE } int u14_34f_release(struct Scsi_Host *shpnt) { unsigned int i, j; - IRQ_FLAGS - - IRQ_LOCK_SAVE for (j = 0; sh[j] != NULL && sh[j] != shpnt; j++); @@ -1990,7 +1962,6 @@ release_region(sh[j]->io_port, sh[j]->n_io_port); scsi_unregister(sh[j]); - IRQ_UNLOCK_RESTORE return FALSE; } @@ -1998,4 +1969,15 @@ Scsi_Host_Template driver_template = ULTRASTOR_14_34F; #include "scsi_module.c" + +#else + +#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,18) +void u14_34f_setup(char *str, int *ints) { + internal_setup(str, ints); +} +#else +__setup("u14-34f=", option_setup); #endif + +#endif /* end MODULE */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/u14-34f.h linux.ac/drivers/scsi/u14-34f.h --- linux.vanilla/drivers/scsi/u14-34f.h Tue May 25 22:47:22 1999 +++ linux.ac/drivers/scsi/u14-34f.h Mon Sep 20 21:00:18 1999 @@ -16,12 +16,10 @@ int u14_34f_old_reset(Scsi_Cmnd *, unsigned int); int u14_34f_biosparam(Disk *, kdev_t, int *); -#define U14_34F_VERSION "4.33.00" +#define U14_34F_VERSION "5.11.00" #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s)) -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,101) - #define ULTRASTOR_14_34F { \ name: "UltraStor 14F/34F rev. " U14_34F_VERSION " ", \ detect: u14_34f_detect, \ @@ -39,22 +37,5 @@ use_clustering: ENABLE_CLUSTERING, \ use_new_eh_code: 1 /* Enable new error code */ \ } - -#else /* Use old scsi code */ - -#define ULTRASTOR_14_34F { \ - name: "UltraStor 14F/34F rev. " U14_34F_VERSION " ", \ - detect: u14_34f_detect, \ - release: u14_34f_release, \ - queuecommand: u14_34f_queuecommand, \ - abort: u14_34f_old_abort, \ - reset: u14_34f_old_reset, \ - bios_param: u14_34f_biosparam, \ - this_id: 7, \ - unchecked_isa_dma: 1, \ - use_clustering: ENABLE_CLUSTERING \ - } - -#endif #endif diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/wd33c93.h linux.ac/drivers/scsi/wd33c93.h --- linux.vanilla/drivers/scsi/wd33c93.h Tue Aug 17 17:27:33 1999 +++ linux.ac/drivers/scsi/wd33c93.h Thu Sep 2 16:51:27 1999 @@ -190,6 +190,9 @@ typedef struct { volatile unsigned char SASR; char pad; +#ifdef CONFIG_SGI + char pad2,pad3; +#endif volatile unsigned char SCMD; } wd33c93_regs; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sgi/Config.in linux.ac/drivers/sgi/Config.in --- linux.vanilla/drivers/sgi/Config.in Mon Jul 5 22:33:51 1999 +++ linux.ac/drivers/sgi/Config.in Mon Sep 13 00:22:42 1999 @@ -6,13 +6,13 @@ bool 'SGI Zilog85C30 serial support' CONFIG_SGI_SERIAL if [ "$CONFIG_SGI_SERIAL" != "n" ]; then - define_bool CONFIG_SERIAL y + define_bool CONFIG_SERIAL y fi bool 'SGI DS1286 RTC support' CONFIG_SGI_DS1286 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'SGI Newport Graphics support' CONFIG_SGI_NEWPORT_GFX + tristate 'SGI Newport Graphics support (EXPERIMENTAL)' CONFIG_SGI_NEWPORT_GFX fi endmenu diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sgi/char/shmiq.c linux.ac/drivers/sgi/char/shmiq.c --- linux.vanilla/drivers/sgi/char/shmiq.c Thu Aug 26 14:42:15 1999 +++ linux.ac/drivers/sgi/char/shmiq.c Thu Sep 2 16:51:29 1999 @@ -118,7 +118,7 @@ s->tail = tail_next; shmiqs [device].tail = tail_next; if (shmiqs [device].fasync) - kill_fasync (shmiqs [device].fasync, SIGIO); + kill_fasync (shmiqs [device].fasync, SIGIO, POLL_IN); wake_up_interruptible (&shmiqs [device].proc_list); } diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sound/Config.in linux.ac/drivers/sound/Config.in --- linux.vanilla/drivers/sound/Config.in Tue Sep 7 22:07:06 1999 +++ linux.ac/drivers/sound/Config.in Sun Sep 19 17:37:24 1999 @@ -9,40 +9,40 @@ # Prompt user for primary drivers. -dep_tristate 'C-Media PCI (CMI8338/8378)' CONFIG_SOUND_CMPCI $CONFIG_SOUND +dep_tristate ' C-Media PCI (CMI8338/8378)' CONFIG_SOUND_CMPCI $CONFIG_SOUND if [ "$CONFIG_SOUND_CMPCI" = "y" -o "$CONFIG_SOUND_CMPCI" = "m" ]; then - bool 'Enable legacy FM' CONFIG_SOUND_CMPCI_FM - bool 'Enable legacy MPU-401' CONFIG_SOUND_CMPCI_MIDI + bool ' Enable legacy FM' CONFIG_SOUND_CMPCI_FM + bool ' Enable legacy MPU-401' CONFIG_SOUND_CMPCI_MIDI fi -dep_tristate 'Ensoniq AudioPCI (ES1370)' CONFIG_SOUND_ES1370 $CONFIG_SOUND -dep_tristate 'Creative Ensoniq AudioPCI 97 (ES1371)' CONFIG_SOUND_ES1371 $CONFIG_SOUND -dep_tristate 'ESS Technology Solo1' CONFIG_SOUND_ESSSOLO1 $CONFIG_SOUND +dep_tristate ' Ensoniq AudioPCI (ES1370)' CONFIG_SOUND_ES1370 $CONFIG_SOUND +dep_tristate ' Creative Ensoniq AudioPCI 97 (ES1371)' CONFIG_SOUND_ES1371 $CONFIG_SOUND +dep_tristate ' ESS Technology Solo1' CONFIG_SOUND_ESSSOLO1 $CONFIG_SOUND if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - dep_tristate 'ESS Maestro, Maestro2, Maestro2E driver' CONFIG_SOUND_MAESTRO $CONFIG_SOUND + dep_tristate ' ESS Maestro, Maestro2, Maestro2E driver (EXPERIMENTAL)' CONFIG_SOUND_MAESTRO $CONFIG_SOUND fi -dep_tristate 'S3 SonicVibes' CONFIG_SOUND_SONICVIBES $CONFIG_SOUND +dep_tristate ' S3 SonicVibes' CONFIG_SOUND_SONICVIBES $CONFIG_SOUND if [ "$CONFIG_VISWS" = "y" ]; then - dep_tristate 'SGI Visual Workstation Sound' CONFIG_SOUND_VWSND $CONFIG_SOUND + dep_tristate ' SGI Visual Workstation Sound' CONFIG_SOUND_VWSND $CONFIG_SOUND fi -dep_tristate 'Support for Turtle Beach MultiSound Classic, Tahiti, Monterey' CONFIG_SOUND_MSNDCLAS $CONFIG_SOUND +dep_tristate ' Support for Turtle Beach MultiSound Classic, Tahiti, Monterey' CONFIG_SOUND_MSNDCLAS $CONFIG_SOUND if [ "$CONFIG_SOUND_MSNDCLAS" = "y" -o "$CONFIG_SOUND_MSNDCLAS" = "m" ]; then if [ "$CONFIG_SOUND_MSNDCLAS" = "y" ]; then - comment 'Compiled-in MSND Classic support requires firmware during compilation.' + comment ' Compiled-in MSND Classic support requires firmware during compilation.' define_bool CONFIG_MSNDCLAS_HAVE_BOOT y else define_bool CONFIG_MSNDCLAS_HAVE_BOOT n fi - string ' Full pathname of MSNDINIT.BIN firmware file' CONFIG_MSNDCLAS_INIT_FILE "/etc/sound/msndinit.bin" - string ' Full pathname of MSNDPERM.BIN firmware file' CONFIG_MSNDCLAS_PERM_FILE "/etc/sound/msndperm.bin" + string 'Full pathname of MSNDINIT.BIN firmware file' CONFIG_MSNDCLAS_INIT_FILE "/etc/sound/msndinit.bin" + string 'Full pathname of MSNDPERM.BIN firmware file' CONFIG_MSNDCLAS_PERM_FILE "/etc/sound/msndperm.bin" fi if [ "$CONFIG_SOUND_MSNDCLAS" = "y" ]; then - int 'MSND Classic IRQ 5,7,9,10,11,12' CONFIG_MSNDCLAS_IRQ 5 - hex 'MSND Classic memory B0000,C8000,D0000,D8000,E0000,E8000' CONFIG_MSNDCLAS_MEM D0000 - hex 'MSND Classic I/O 210,220,230,240,250,260,290,3E0' CONFIG_MSNDCLAS_IO 290 + int ' MSND Classic IRQ 5, 7, 9, 10, 11, 12' CONFIG_MSNDCLAS_IRQ 5 + hex ' MSND Classic memory B0000, C8000, D0000, D8000, E0000, E8000' CONFIG_MSNDCLAS_MEM D0000 + hex ' MSND Classic I/O 210, 220, 230, 240, 250, 260, 290, 3E0' CONFIG_MSNDCLAS_IO 290 fi -dep_tristate 'Support for Turtle Beach MultiSound Pinnacle, Fiji' CONFIG_SOUND_MSNDPIN $CONFIG_SOUND +dep_tristate ' Support for Turtle Beach MultiSound Pinnacle, Fiji' CONFIG_SOUND_MSNDPIN $CONFIG_SOUND if [ "$CONFIG_SOUND_MSNDPIN" = "y" -o "$CONFIG_SOUND_MSNDPIN" = "m" ]; then if [ "$CONFIG_SOUND_MSNDPIN" = "y" ]; then comment 'Compiled-in MSND Pinnacle support requires firmware during compilation.' @@ -54,115 +54,94 @@ string ' Full pathname of PNDSPERM.BIN firmware file' CONFIG_MSNDPIN_PERM_FILE "/etc/sound/pndsperm.bin" fi if [ "$CONFIG_SOUND_MSNDPIN" = "y" ]; then - int 'MSND Pinnacle IRQ 5,7,9,10,11,12' CONFIG_MSNDPIN_IRQ 5 - hex 'MSND Pinnacle memory B0000,C8000,D0000,D8000,E0000,E8000' CONFIG_MSNDPIN_MEM D0000 - hex 'MSND Pinnacle I/O 210,220,230,240,250,260,290,3E0' CONFIG_MSNDPIN_IO 290 - bool 'MSND Pinnacle has S/PDIF I/O' CONFIG_MSNDPIN_DIGITAL - bool 'MSND Pinnacle non-PnP Mode' CONFIG_MSNDPIN_NONPNP + int ' MSND Pinnacle IRQ 5, 7, 9, 10, 11, 12' CONFIG_MSNDPIN_IRQ 5 + hex ' MSND Pinnacle memory B0000, C8000, D0000, D8000, E0000, E8000' CONFIG_MSNDPIN_MEM D0000 + hex 'MSND Pinnacle I/O 210, 220, 230, 240, 250, 260, 290, 3E0' CONFIG_MSNDPIN_IO 290 + bool ' MSND Pinnacle has S/PDIF I/O' CONFIG_MSNDPIN_DIGITAL + bool ' MSND Pinnacle non-PnP Mode' CONFIG_MSNDPIN_NONPNP if [ "$CONFIG_MSNDPIN_NONPNP" = "y" ]; then - comment 'MSND Pinnacle DSP section will be configured to above parameters.' - hex 'MSND Pinnacle config port 250,260,270' CONFIG_MSNDPIN_CFG 250 - comment 'Pinnacle-specific Device Configuration (0 disables)' - hex 'MSND Pinnacle MPU I/O (e.g. 330)' CONFIG_MSNDPIN_MPU_IO 0 - int 'MSND Pinnacle MPU IRQ (e.g. 9)' CONFIG_MSNDPIN_MPU_IRQ 0 - hex 'MSND Pinnacle IDE I/O 0 (e.g. 170)' CONFIG_MSNDPIN_IDE_IO0 0 - hex 'MSND Pinnacle IDE I/O 1 (e.g. 376)' CONFIG_MSNDPIN_IDE_IO1 0 - int 'MSND Pinnacle IDE IRQ (e.g. 15)' CONFIG_MSNDPIN_IDE_IRQ 0 - hex 'MSND Pinnacle joystick I/O (e.g. 200)' CONFIG_MSNDPIN_JOYSTICK_IO 0 + comment 'MSND Pinnacle DSP section will be configured to above parameters.' + hex 'MSND Pinnacle config port 250,260,270' CONFIG_MSNDPIN_CFG 250 + comment 'Pinnacle-specific Device Configuration (0 disables)' + hex 'MSND Pinnacle MPU I/O (e.g. 330)' CONFIG_MSNDPIN_MPU_IO 0 + int 'MSND Pinnacle MPU IRQ (e.g. 9)' CONFIG_MSNDPIN_MPU_IRQ 0 + hex 'MSND Pinnacle IDE I/O 0 (e.g. 170)' CONFIG_MSNDPIN_IDE_IO0 0 + hex 'MSND Pinnacle IDE I/O 1 (e.g. 376)' CONFIG_MSNDPIN_IDE_IO1 0 + int 'MSND Pinnacle IDE IRQ (e.g. 15)' CONFIG_MSNDPIN_IDE_IRQ 0 + hex 'MSND Pinnacle joystick I/O (e.g. 200)' CONFIG_MSNDPIN_JOYSTICK_IO 0 fi fi if [ "$CONFIG_SOUND_MSNDPIN" = "y" -o "$CONFIG_SOUND_MSNDCLAS" = "y" ]; then int 'MSND buffer size (kB)' CONFIG_MSND_FIFOSIZE 128 fi -dep_tristate 'OSS sound modules' CONFIG_SOUND_OSS $CONFIG_SOUND +dep_tristate ' OSS sound modules' CONFIG_SOUND_OSS $CONFIG_SOUND if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then - if [ "$CONFIG_SOUND_OSS" = "y" ]; then - bool 'Persistent DMA buffers' CONFIG_SOUND_DMAP - fi + if [ "$CONFIG_SOUND_OSS" = "y" ]; then + bool ' Persistent DMA buffers' CONFIG_SOUND_DMAP + fi - dep_tristate 'ProAudioSpectrum 16 support' CONFIG_SOUND_PAS $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_PAS" = "y" ]; then - int 'PAS16 IRQ 3, 4, 5, 7, 9, 10, 11, 12, 14 or 15' CONFIG_PAS_IRQ 10 - int 'PAS16 DMA 0, 1, 3, 5, 6 or 7' CONFIG_PAS_DMA 3 - bool 'Enable PAS16 joystick port' CONFIG_PAS_JOYSTICK - fi - - dep_tristate '100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support' CONFIG_SOUND_SB $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_SB" = "y" ]; then - hex 'I/O base for SB Check from manual of the card' CONFIG_SB_BASE 220 - int 'Sound Blaster IRQ Check from manual of the card' CONFIG_SB_IRQ 7 - int 'Sound Blaster DMA 0, 1 or 3' CONFIG_SB_DMA 1 - int 'Sound Blaster 16 bit DMA (SB16, Jazz16, SMW) 5, 6 or 7 (use 1 for 8 bit cards)' CONFIG_SB_DMA2 5 - hex 'MPU401 I/O base of SB16, Jazz16 and ES1688 Check from manual of the card' CONFIG_SB_MPU_BASE 330 - comment 'MPU401 IRQ is only required with Jazz16, SM Wave and ESS1688.' - comment 'Enter -1 to the following question if you have something else such as SB16/32.' - int 'SB MPU401 IRQ (Jazz16, SM Wave and ES1688) Check from manual of the card' CONFIG_SB_MPU_IRQ -1 - fi - - dep_tristate 'Generic OPL2/OPL3 FM synthesizer support' CONFIG_SOUND_ADLIB $CONFIG_SOUND_OSS - - dep_tristate 'Gravis Ultrasound support' CONFIG_SOUND_GUS $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_GUS" = "y" -o "$CONFIG_SOUND_GUS" = "m" ]; then - bool '16 bit sampling option of GUS (_NOT_ GUS MAX)' CONFIG_GUS16 - bool 'GUS MAX support' CONFIG_GUSMAX - fi - if [ "$CONFIG_SOUND_GUS" = "y" ]; then - hex 'I/O base for GUS 210, 220, 230, 240, 250 or 260' CONFIG_GUS_BASE 220 - int 'GUS IRQ 3, 5, 7, 9, 11, 12 or 15' CONFIG_GUS_IRQ 15 - int 'GUS DMA 1, 3, 5, 6 or 7' CONFIG_GUS_DMA 6 - int 'Second DMA channel for GUS 1, 3, 5, 6 or 7' CONFIG_GUS_DMA2 -1 - if [ "$CONFIG_GUS16" = "y" ]; then - hex 'I/O base for the 16 bit daughtercard of GUS 530, 604, E80 or F40' CONFIG_GUS16_BASE 530 - int 'GUS 16 bit daughtercard IRQ 3, 4, 5, 7, or 9' CONFIG_GUS16_IRQ 7 - int 'GUS DMA 0, 1 or 3' CONFIG_GUS16_DMA 3 + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate ' AD1816(A) based cards (EXPERIMENTAL)' CONFIG_SOUND_AD1816 $CONFIG_SOUND + if [ "$CONFIG_SOUND_AD1816" = "y" ]; then + hex 'AD1816 audio I/O base 530, 604, E80 or F40' CONFIG_AD1816_BASE 530 + int 'AD1816 audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_AD1816_IRQ 7 + int 'AD1816 audio DMA 0, 1 or 3' CONFIG_AD1816_DMA 0 + int 'AD1816 second (duplex) DMA 0, 1 or 3' CONFIG_AD1816_DMA2 3 + int 'AD1816 clock chip frequency' CONFIG_AD1816_CLOCK 33000 fi - fi - - dep_tristate 'MPU-401 support (NOT for SB16)' CONFIG_SOUND_MPU401 $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_MPU401" = "y" ]; then - hex 'I/O base for MPU401 Check from manual of the card' CONFIG_MPU_BASE 330 - int 'MPU401 IRQ Check from manual of the card' CONFIG_MPU_IRQ 9 - fi - - dep_tristate 'PSS (AD1848, ADSP-2115, ESC614) support' CONFIG_SOUND_PSS $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_PSS" = "y" ]; then - hex 'PSS I/O base 220 or 240' CONFIG_PSS_BASE 220 - hex 'PSS audio I/O base 530, 604, E80 or F40' CONFIG_PSS_MSS_BASE 530 - int 'PSS audio IRQ 7, 9, 10 or 11' CONFIG_PSS_MSS_IRQ 11 - int 'PSS audio DMA 0, 1 or 3' CONFIG_PSS_MSS_DMA 3 - hex 'PSS MIDI I/O base ' CONFIG_PSS_MPU_BASE 330 - int 'PSS MIDI IRQ 3, 4, 5, 7, 9, 10, 11, 12' CONFIG_PSS_MPU_IRQ 9 - bool ' Have DSPxxx.LD firmware file' CONFIG_PSS_HAVE_BOOT - if [ "$CONFIG_PSS_HAVE_BOOT" = "y" ]; then - string ' Full pathname of DSPxxx.LD firmware file' CONFIG_PSS_BOOT_FILE /etc/sound/dsp001.ld - fi - fi - if [ "$CONFIG_SOUND_PSS" = "y" -o "$CONFIG_SOUND_PSS" = "m" ]; then - bool ' Enable PSS mixer (Beethoven ADSP-16 and other compatibile)' CONFIG_PSS_MIXER - fi - - dep_tristate 'Microsoft Sound System support' CONFIG_SOUND_MSS $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_MSS" = "y" ]; then - bool 'Enable support for the SoundPro mixer' CONFIG_SOUND_SPRO - hex 'MSS/WSS I/O base 530, 604, E80 or F40' CONFIG_MSS_BASE 530 - int 'MSS/WSS IRQ 7, 9, 10 or 11' CONFIG_MSS_IRQ 11 - int 'MSS/WSS DMA 0, 1 or 3' CONFIG_MSS_DMA 3 - int 'MSS/WSS second DMA (if possible) 0, 1 or 3' CONFIG_MSS_DMA2 -1 - fi - - dep_tristate 'Ensoniq SoundScape support' CONFIG_SOUND_SSCAPE $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_SSCAPE" = "y" ]; then + fi + + dep_tristate ' Aztech Sound Galaxy (non-PnP) cards' CONFIG_SOUND_SGALAXY $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_SGALAXY" = "y" ]; then + hex 'SGALAXY audio I/O base 530, 604, E80 or F40' CONFIG_SGALAXY_BASE 530 + int 'SGALAXY audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_SGALAXY_IRQ 11 + int 'SGALAXY audio DMA 0, 1 or 3' CONFIG_SGALAXY_DMA 0 + int 'SGALAXY second (duplex) DMA 0, 1 or 3' CONFIG_SGALAXY_DMA2 3 + hex 'SGALAXY SB I/O base 220 or 240' CONFIG_SGALAXY_SGBASE 220 + fi + + dep_tristate ' Crystal CS4232 based (PnP) cards' CONFIG_SOUND_CS4232 $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_CS4232" = "y" ]; then + hex 'CS4232 audio I/O base (normally 530, 604, E80 or F40)' CONFIG_CS4232_BASE 530 + int 'CS4232 audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_CS4232_IRQ 11 + int 'CS4232 audio DMA 0, 1 or 3' CONFIG_CS4232_DMA 0 + int 'CS4232 second (duplex) DMA 0, 1 or 3' CONFIG_CS4232_DMA2 3 + hex 'CS4232 MIDI I/O base 330, 370, 3B0 or 3F0' CONFIG_CS4232_MPU_BASE 330 + int 'CS4232 MIDI IRQ 5, 7, 9, 11, 12 or 15' CONFIG_CS4232_MPU_IRQ 9 + fi + + dep_tristate ' Ensoniq SoundScape support' CONFIG_SOUND_SSCAPE $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_SSCAPE" = "y" ]; then hex 'SoundScape MIDI I/O base 320, 330, 340 or 350' CONFIG_SSCAPE_BASE 330 int 'SoundScape MIDI IRQ ' CONFIG_SSCAPE_IRQ 9 int 'SoundScape initialization DMA 0, 1 or 3' CONFIG_SSCAPE_DMA 3 hex 'SoundScape audio I/O base 534, 608, E84 or F44' CONFIG_SSCAPE_MSS_BASE 534 int 'SoundScape audio IRQ 7, 9, 10 or 11' CONFIG_SSCAPE_MSS_IRQ 11 - fi - - dep_tristate 'MediaTrix AudioTrix Pro support' CONFIG_SOUND_TRIX $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_TRIX" = "y" ]; then + fi + + dep_tristate ' Gravis Ultrasound support' CONFIG_SOUND_GUS $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_GUS" = "y" -o "$CONFIG_SOUND_GUS" = "m" ]; then + bool ' 16 bit sampling option of GUS (_NOT_ GUS MAX)' CONFIG_GUS16 + bool ' GUS MAX support' CONFIG_GUSMAX + fi + if [ "$CONFIG_SOUND_GUS" = "y" ]; then + hex 'I/O base for GUS 210, 220, 230, 240, 250 or 260' CONFIG_GUS_BASE 220 + int 'GUS IRQ 3, 5, 7, 9, 11, 12 or 15' CONFIG_GUS_IRQ 15 + int 'GUS DMA 1, 3, 5, 6 or 7' CONFIG_GUS_DMA 6 + int 'Second DMA channel for GUS 1, 3, 5, 6 or 7' CONFIG_GUS_DMA2 -1 + if [ "$CONFIG_GUS16" = "y" ]; then + hex 'I/O base for the 16 bit daughtercard of GUS 530, 604, E80 or F40' CONFIG_GUS16_BASE 530 + int 'GUS 16 bit daughtercard IRQ 3, 4, 5, 7, or 9' CONFIG_GUS16_IRQ 7 + int 'GUS DMA 0, 1 or 3' CONFIG_GUS16_DMA 3 + fi + fi + + dep_tristate ' Loopback MIDI device support' CONFIG_SOUND_VMIDI $CONFIG_SOUND_OSS + + dep_tristate ' MediaTrix AudioTrix Pro support' CONFIG_SOUND_TRIX $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_TRIX" = "y" ]; then hex 'TRIX audio I/O base 530, 604, E80 or F40' CONFIG_TRIX_BASE 530 int 'TRIX audio IRQ 7, 9, 10 or 11' CONFIG_TRIX_IRQ 11 int 'TRIX audio DMA 0, 1 or 3' CONFIG_TRIX_DMA 0 @@ -172,133 +151,153 @@ hex 'TRIX SB I/O base 220, 210, 230, 240, 250, 260 or 270' CONFIG_TRIX_SB_BASE 220 int 'TRIX SB IRQ 3, 4, 5 or 7' CONFIG_TRIX_SB_IRQ 7 int 'TRIX SB DMA 1 or 3' CONFIG_TRIX_SB_DMA 1 - bool ' Have TRXPRO.HEX firmware file' CONFIG_TRIX_HAVE_BOOT + bool ' Have TRXPRO.HEX firmware file' CONFIG_TRIX_HAVE_BOOT if [ "$CONFIG_TRIX_HAVE_BOOT" = "y" ]; then string ' Full pathname of TRXPRO.HEX firmware file' CONFIG_TRIX_BOOT_FILE /etc/sound/trxpro.hex fi - fi + fi - dep_tristate 'VIA 82C686 Audio Codec' CONFIG_SOUND_VIA82CXXX $CONFIG_SOUND_OSS + dep_tristate ' Microsoft Sound System support' CONFIG_SOUND_MSS $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_MSS" = "y" ]; then + bool ' Enable support for the SoundPro mixer' CONFIG_SOUND_SPRO + hex 'MSS/WSS I/O base 530, 604, E80 or F40' CONFIG_MSS_BASE 530 + int 'MSS/WSS IRQ 7, 9, 10 or 11' CONFIG_MSS_IRQ 11 + int 'MSS/WSS DMA 0, 1 or 3' CONFIG_MSS_DMA 3 + int 'MSS/WSS second DMA (if possible) 0, 1 or 3' CONFIG_MSS_DMA2 -1 + fi + + dep_tristate ' MPU-401 support (NOT for SB16)' CONFIG_SOUND_MPU401 $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_MPU401" = "y" ]; then + hex 'I/O base for MPU401 Check from manual of the card' CONFIG_MPU_BASE 330 + int 'MPU401 IRQ Check from manual of the card' CONFIG_MPU_IRQ 9 + fi + + dep_tristate ' NM256AV/NM256ZX audio support' CONFIG_SOUND_NM256 $CONFIG_SOUND_OSS - dep_tristate 'Support for OPTi MAD16 and/or Mozart based cards' CONFIG_SOUND_MAD16 $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_MAD16" = "y" -o "$CONFIG_SOUND_MAD16" = "m" ]; then - bool 'Support MIDI in older MAD16 based cards (requires SB)' CONFIG_MAD16_OLDCARD - fi - if [ "$CONFIG_SOUND_MAD16" = "y" ]; then + dep_tristate ' OPTi MAD16 and/or Mozart based cards' CONFIG_SOUND_MAD16 $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_MAD16" = "y" -o "$CONFIG_SOUND_MAD16" = "m" ]; then + bool ' Support MIDI in older MAD16 based cards (requires SB)' CONFIG_MAD16_OLDCARD + fi + if [ "$CONFIG_SOUND_MAD16" = "y" ]; then hex 'MAD16 audio I/O base 530, 604, E80 or F40' CONFIG_MAD16_BASE 530 int 'MAD16 audio IRQ 7, 9, 10 or 11' CONFIG_MAD16_IRQ 11 int 'MAD16 audio DMA 0, 1 or 3' CONFIG_MAD16_DMA 3 int 'MAD16 second (duplex) DMA 0, 1 or 3' CONFIG_MAD16_DMA2 0 hex 'MAD16 MIDI I/O base 300, 310, 320 or 330 (0 disables)' CONFIG_MAD16_MPU_BASE 330 int 'MAD16 MIDI IRQ 5, 7, 9 or 10' CONFIG_MAD16_MPU_IRQ 9 - fi + fi + + dep_tristate ' ProAudioSpectrum 16 support' CONFIG_SOUND_PAS $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_PAS" = "y" ]; then + int 'PAS16 IRQ 3, 4, 5, 7, 9, 10, 11, 12, 14 or 15' CONFIG_PAS_IRQ 10 + int 'PAS16 DMA 0, 1, 3, 5, 6 or 7' CONFIG_PAS_DMA 3 + bool ' Enable PAS16 joystick port' CONFIG_PAS_JOYSTICK + fi + + dep_tristate ' PSS (AD1848, ADSP-2115, ESC614) support' CONFIG_SOUND_PSS $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_PSS" = "y" ]; then + hex 'PSS I/O base 220 or 240' CONFIG_PSS_BASE 220 + hex 'PSS audio I/O base 530, 604, E80 or F40' CONFIG_PSS_MSS_BASE 530 + int 'PSS audio IRQ 7, 9, 10 or 11' CONFIG_PSS_MSS_IRQ 11 + int 'PSS audio DMA 0, 1 or 3' CONFIG_PSS_MSS_DMA 3 + hex 'PSS MIDI I/O base ' CONFIG_PSS_MPU_BASE 330 + int 'PSS MIDI IRQ 3, 4, 5, 7, 9, 10, 11, 12' CONFIG_PSS_MPU_IRQ 9 + bool ' Have DSPxxx.LD firmware file' CONFIG_PSS_HAVE_BOOT + if [ "$CONFIG_PSS_HAVE_BOOT" = "y" ]; then + string ' Full pathname of DSPxxx.LD firmware file' CONFIG_PSS_BOOT_FILE /etc/sound/dsp001.ld + fi + fi + if [ "$CONFIG_SOUND_PSS" = "y" -o "$CONFIG_SOUND_PSS" = "m" ]; then + bool ' Enable PSS mixer (Beethoven ADSP-16 and other compatibile)' CONFIG_PSS_MIXER + fi + + dep_tristate ' SoftOSS software wave table engine' CONFIG_SOUND_SOFTOSS $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_SOFTOSS" = "y" ]; then + int 'Sampling rate for SoftOSS 8000 to 48000' CONFIG_SOFTOSS_RATE 22050 + int 'Max # of concurrent voices for SoftOSS 4 to 32' CONFIG_SOFTOSS_VOICES 32 + fi - dep_tristate 'Full support for Turtle Beach WaveFront (Tropez Plus, Tropez, Maui) synth/soundcards' CONFIG_SOUND_WAVEFRONT $CONFIG_SOUND_OSS m - if [ "$CONFIG_SOUND_WAVEFRONT" = "y" ]; then + dep_tristate ' 100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support' CONFIG_SOUND_SB $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_SB" = "y" ]; then + hex 'I/O base for SB Check from manual of the card' CONFIG_SB_BASE 220 + int 'Sound Blaster IRQ Check from manual of the card' CONFIG_SB_IRQ 7 + int 'Sound Blaster DMA 0, 1 or 3' CONFIG_SB_DMA 1 + int 'Sound Blaster 16 bit DMA (SB16, Jazz16, SMW) 5, 6 or 7 (use 1 for 8 bit cards)' CONFIG_SB_DMA2 5 + hex 'MPU401 I/O base of SB16, Jazz16 and ES1688 Check from manual of the card' CONFIG_SB_MPU_BASE 330 + comment 'MPU401 IRQ is only required with Jazz16, SM Wave and ESS1688.' + comment 'Enter -1 to the following question if you have something else such as SB16/32.' + int 'SB MPU401 IRQ (Jazz16, SM Wave and ES1688) Check from manual of the card' CONFIG_SB_MPU_IRQ -1 + fi + + dep_tristate ' Full support for Turtle Beach WaveFront (Tropez Plus, Tropez, Maui) synth/soundcards' CONFIG_SOUND_WAVEFRONT $CONFIG_SOUND_OSS m + if [ "$CONFIG_SOUND_WAVEFRONT" = "y" ]; then hex 'I/O base for WaveFront 210, 230, 260, 290, 300, 320, 338 or 330' CONFIG_WAVEFRONT_BASE 330 int 'WaveFront IRQ 5, 9, 12 or 15' CONFIG_WAVEFRONT_IRQ 9 - fi - - dep_tristate 'Support for Crystal CS4232 based (PnP) cards' CONFIG_SOUND_CS4232 $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_CS4232" = "y" ]; then - hex 'CS4232 audio I/O base (normally 530, 604, E80 or F40)' CONFIG_CS4232_BASE 530 - int 'CS4232 audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_CS4232_IRQ 11 - int 'CS4232 audio DMA 0, 1 or 3' CONFIG_CS4232_DMA 0 - int 'CS4232 second (duplex) DMA 0, 1 or 3' CONFIG_CS4232_DMA2 3 - hex 'CS4232 MIDI I/O base 330, 370, 3B0 or 3F0' CONFIG_CS4232_MPU_BASE 330 - int 'CS4232 MIDI IRQ 5, 7, 9, 11, 12 or 15' CONFIG_CS4232_MPU_IRQ 9 - fi - - dep_tristate 'Support for Yamaha OPL3-SA2, SA3, and SAx based PnP cards' CONFIG_SOUND_OPL3SA2 $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_OPL3SA2" = "y" ]; then - int 'Chipset (-1 for autoprobe, 2, or 3)' CONFIG_OPL3SA2_CHIPSET -1 - hex 'OPL3SA2 audio I/O base (530 - F48 valid)' CONFIG_OPL3SA2_BASE 530 - int 'OPL3SA2 audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_OPL3SA2_IRQ 9 - int 'OPL3SA2 audio DMA 0, 1 or 3' CONFIG_OPL3SA2_DMA 0 - int 'OPL3SA2 second (duplex) DMA 0, 1 or 3' CONFIG_OPL3SA2_DMA2 1 - hex 'OPL3SA2 control I/O base (100 - FFE valid)' CONFIG_OPL3SA2_CTRL_BASE 370 - hex 'OPL3SA2 MIDI I/O base (300 - 334 valid)' CONFIG_OPL3SA2_MPU_BASE 330 - int 'OPL3SA2 MIDI IRQ 5, 7, 9, 11, 12 or 15' CONFIG_OPL3SA2_MPU_IRQ 9 - fi + fi - dep_tristate 'Limited support for Turtle Beach Wave Front (Maui, Tropez) synthesizers' CONFIG_SOUND_MAUI $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_MAUI" = "y" ]; then + dep_tristate ' Limited support for Turtle Beach Wave Front (Maui, Tropez) synthesizers' CONFIG_SOUND_MAUI $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_MAUI" = "y" ]; then hex 'I/O base for Maui 210, 230, 260, 290, 300, 320, 338 or 330' CONFIG_MAUI_BASE 330 int 'Maui IRQ 5, 9, 12 or 15' CONFIG_MAUI_IRQ 9 - bool ' Have OSWF.MOT firmware file' CONFIG_MAUI_HAVE_BOOT + bool ' Have OSWF.MOT firmware file' CONFIG_MAUI_HAVE_BOOT if [ "$CONFIG_MAUI_HAVE_BOOT" = "y" ]; then - string ' Full pathname of OSWF.MOT firmware file' CONFIG_MAUI_BOOT_FILE /etc/sound/oswf.mot + string ' Full pathname of OSWF.MOT firmware file' CONFIG_MAUI_BOOT_FILE /etc/sound/oswf.mot fi - fi + fi - - dep_tristate 'Support for Aztech Sound Galaxy (non-PnP) cards' CONFIG_SOUND_SGALAXY $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_SGALAXY" = "y" ]; then - hex 'SGALAXY audio I/O base 530, 604, E80 or F40' CONFIG_SGALAXY_BASE 530 - int 'SGALAXY audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_SGALAXY_IRQ 11 - int 'SGALAXY audio DMA 0, 1 or 3' CONFIG_SGALAXY_DMA 0 - int 'SGALAXY second (duplex) DMA 0, 1 or 3' CONFIG_SGALAXY_DMA2 3 - hex 'SGALAXY SB I/O base 220 or 240' CONFIG_SGALAXY_SGBASE 220 - fi + dep_tristate ' VIA 82C686 Audio Codec' CONFIG_SOUND_VIA82CXXX $CONFIG_SOUND_OSS - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - dep_tristate 'Support for AD1816(A) based cards (EXPERIMENTAL)' CONFIG_SOUND_AD1816 $CONFIG_SOUND - if [ "$CONFIG_SOUND_AD1816" = "y" ]; then - hex 'AD1816 audio I/O base 530, 604, E80 or F40' CONFIG_AD1816_BASE 530 - int 'AD1816 audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_AD1816_IRQ 7 - int 'AD1816 audio DMA 0, 1 or 3' CONFIG_AD1816_DMA 0 - int 'AD1816 second (duplex) DMA 0, 1 or 3' CONFIG_AD1816_DMA2 3 - int 'AD1816 clock chip frequency' CONFIG_AD1816_CLOCK 33000 - fi - fi - - dep_tristate 'Yamaha OPL3-SA1 audio controller' CONFIG_SOUND_OPL3SA1 $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_OPL3SA1" = "y" ]; then + dep_tristate ' Yamaha FM synthesizer (YM3812/OPL-3) support' CONFIG_SOUND_YM3812 $CONFIG_SOUND_OSS + + dep_tristate ' Yamaha OPL3-SA1 audio controller' CONFIG_SOUND_OPL3SA1 $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_OPL3SA1" = "y" ]; then hex 'OPL3-SA1 audio I/O base 530, 604, E80 or F40' CONFIG_OPL3SA1_BASE 530 int 'OPL3-SA1 audio IRQ 7, 9, 10 or 11' CONFIG_OPL3SA1_IRQ 11 int 'OPL3-SA1 audio DMA 0, 1 or 3' CONFIG_OPL3SA1_DMA 0 int 'OPL3-SA1 second (duplex) DMA 0, 1 or 3' CONFIG_OPL3SA1_DMA2 3 hex 'OPL3-SA1 MIDI I/O base 330, 370, 3B0 or 3F0' CONFIG_OPL3SA1_MPU_BASE 330 int 'OPL3-SA1 MIDI IRQ 3, 4, 5, 7 or 9' CONFIG_OPL3SA1_MPU_IRQ 9 - fi - - dep_tristate 'SoftOSS software wave table engine' CONFIG_SOUND_SOFTOSS $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_SOFTOSS" = "y" ]; then - int 'Sampling rate for SoftOSS 8000 to 48000' CONFIG_SOFTOSS_RATE 22050 - int 'Max # of concurrent voices for SoftOSS 4 to 32' CONFIG_SOFTOSS_VOICES 32 - fi + fi - dep_tristate 'FM synthesizer (YM3812/OPL-3) support' CONFIG_SOUND_YM3812 $CONFIG_SOUND_OSS + dep_tristate ' Yamaha OPL3-SA2, SA3, and SAx based PnP cards' CONFIG_SOUND_OPL3SA2 $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_OPL3SA2" = "y" ]; then + int 'Chipset (-1 for autoprobe, 2, or 3)' CONFIG_OPL3SA2_CHIPSET -1 + hex 'OPL3SA2 audio I/O base (530 - F48 valid)' CONFIG_OPL3SA2_BASE 530 + int 'OPL3SA2 audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_OPL3SA2_IRQ 9 + int 'OPL3SA2 audio DMA 0, 1 or 3' CONFIG_OPL3SA2_DMA 0 + int 'OPL3SA2 second (duplex) DMA 0, 1 or 3' CONFIG_OPL3SA2_DMA2 1 + hex 'OPL3SA2 control I/O base (100 - FFE valid)' CONFIG_OPL3SA2_CTRL_BASE 370 + hex 'OPL3SA2 MIDI I/O base (300 - 334 valid)' CONFIG_OPL3SA2_MPU_BASE 330 + int 'OPL3SA2 MIDI IRQ 5, 7, 9, 11, 12 or 15' CONFIG_OPL3SA2_MPU_IRQ 9 + fi - dep_tristate 'Loopback MIDI device support' CONFIG_SOUND_VMIDI $CONFIG_SOUND_OSS - dep_tristate '6850 UART support' CONFIG_SOUND_UART6850 $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_UART6850" = "y" ]; then + dep_tristate ' 6850 UART support' CONFIG_SOUND_UART6850 $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_UART6850" = "y" ]; then hex 'I/O base for UART 6850 MIDI port (Unknown)' CONFIG_U6850_BASE 0 int 'UART6850 IRQ (Unknown)' CONFIG_U6850_IRQ -1 - fi - - if [ "$CONFIG_ARM" = "y" ]; then - dep_tristate 'VIDC 16-bit sound' CONFIG_SOUND_VIDC $CONFIG_SOUND_OSS - dep_tristate 'Netwinder WaveArtist' CONFIG_SOUND_WAVEARTIST $CONFIG_SOUND_OSS - if [ "$CONFIG_SOUND_WAVEARTIST" != "n" ]; then - hex ' WaveArtist I/O base' CONFIG_WAVEARTIST_BASE 250 - int ' WaveArtist IRQ' CONFIG_WAVEARTIST_IRQ 12 - int ' WaveArtist DMA' CONFIG_WAVEARTIST_DMA 3 - int ' WaveArtist second DMA' CONFIG_WAVEARTIST_DMA2 7 - fi - fi + fi + if [ "$CONFIG_ARM" = "y" ]; then + dep_tristate ' VIDC 16-bit sound' CONFIG_SOUND_VIDC $CONFIG_SOUND_OSS + dep_tristate ' Netwinder WaveArtist' CONFIG_SOUND_WAVEARTIST $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_WAVEARTIST" != "n" ]; then + hex ' WaveArtist I/O base' CONFIG_WAVEARTIST_BASE 250 + int ' WaveArtist IRQ' CONFIG_WAVEARTIST_IRQ 12 + int ' WaveArtist DMA' CONFIG_WAVEARTIST_DMA 3 + int ' WaveArtist second DMA' CONFIG_WAVEARTIST_DMA2 7 + fi + fi - # Additional low level drivers. + # Additional low level drivers. - mainmenu_option next_comment - comment 'Additional low level sound drivers' - bool 'Additional low level sound drivers' CONFIG_LOWLEVEL_SOUND $CONFIG_SOUND_OSS - if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then + mainmenu_option next_comment + comment 'Additional low level sound drivers' + bool 'Additional low level sound drivers' CONFIG_LOWLEVEL_SOUND $CONFIG_SOUND_OSS + if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then source drivers/sound/lowlevel/Config.in - fi - endmenu + fi + endmenu fi diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sound/Makefile linux.ac/drivers/sound/Makefile --- linux.vanilla/drivers/sound/Makefile Tue Sep 7 22:07:06 1999 +++ linux.ac/drivers/sound/Makefile Sun Sep 19 17:28:24 1999 @@ -24,7 +24,8 @@ export-objs := ad1848.o audio_syms.o midi_syms.o mpu401.o \ msnd.o opl3.o sb_card.o sequencer_syms.o \ - sound_core.o sound_syms.o uart401.o ad1816.o + sound_core.o sound_syms.o uart401.o ad1816.o \ + nm256_audio.o @@ -42,7 +43,6 @@ obj-$(CONFIG_SOUND) += soundcore.o obj-$(CONFIG_DMASOUND) += dmasound.o obj-$(CONFIG_SOUND_OSS) += sound.o -obj-$(CONFIG_SOUND_ADLIB) += adlib_card.o opl3.o obj-$(CONFIG_SOUND_CS4232) += cs4232.o ad1848.o # In theory, there's probably no reason to include the uart401 code @@ -65,7 +65,7 @@ obj-$(CONFIG_SOUND_PSS) += pss.o ad1848.o mpu401.o obj-$(CONFIG_SOUND_SB) += sb.o uart401.o obj-$(CONFIG_SOUND_SOFTOSS) += softoss2.o -obj-$(CONFIG_SOUND_SGALAXY) += sgalaxy.o +obj-$(CONFIG_SOUND_SGALAXY) += sgalaxy.o ad1848.o obj-$(CONFIG_SOUND_AD1816) += ad1816.o obj-$(CONFIG_SOUND_SSCAPE) += sscape.o ad1848.o mpu401.o obj-$(CONFIG_SOUND_TRIX) += trix.o ad1848.o sb.o uart401.o @@ -76,6 +76,7 @@ obj-$(CONFIG_SOUND_VWSND) += vwsnd.o obj-$(CONFIG_SOUND_WAVEARTIST) += waveartist.o obj-$(CONFIG_SOUND_WAVEFRONT) += wavefront.o +obj-$(CONFIG_SOUND_NM256) += nm256.o obj-$(CONFIG_SOUND_SONICVIBES) += sonicvibes.o obj-$(CONFIG_SOUND_CMPCI) += cmpci.o @@ -87,7 +88,7 @@ # Declare multi-part drivers. list-multi := sound.o gus.o pas2.o sb.o softoss2.o vidc_mod.o \ - soundcore.o wavefront.o + soundcore.o wavefront.o nm256.o sound-objs := \ dev_table.o soundcard.o sound_syms.o \ @@ -104,6 +105,7 @@ softoss2-objs := softoss.o softoss_rs.o vidc_mod-objs := vidc.o vidc_audio.o vidc_fill.o vidc_mixer.o vidc_synth.o wavefront-objs := wavfront.o wf_midi.o yss225.o +nm256-objs := nm256_audio.o ac97.o # Extract lists of the multi-part drivers. @@ -188,6 +190,9 @@ wavefront.o: $(wavefront-objs) $(LD) -r -o $@ $(wavefront-objs) + +nm256.o: $(nm256-objs) + $(LD) -r -o $@ $(nm256-objs) # Firmware files that need translation # diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sound/ac97.c linux.ac/drivers/sound/ac97.c --- linux.vanilla/drivers/sound/ac97.c Thu Jan 1 01:00:00 1970 +++ linux.ac/drivers/sound/ac97.c Sat Sep 18 18:23:54 1999 @@ -0,0 +1,408 @@ +#include "ac97.h" + +/* Flag for mono controls. */ +#define MO 0 +/* And for stereo. */ +#define ST 1 + +static struct ac97_chn_desc { + int ac97_regnum; + int oss_channel; + int maxval; + int is_stereo; + int oss_mask; + int recordNum; + u16 regmask; +} mixerRegs[] = { + { AC97_MASTER_VOL_STEREO, SOUND_MIXER_VOLUME, 0x3f, ST, SOUND_MASK_VOLUME, 5, 0x0000 }, + { AC97_MASTER_VOL_MONO, SOUND_MIXER_PHONEOUT, 0x3f, MO, SOUND_MASK_PHONEOUT, 6, 0x0000 }, + { AC97_MASTER_TONE, SOUND_MIXER_TREBLE, 0x0f, MO, SOUND_MASK_TREBLE, -1, 0x00ff }, + { AC97_MASTER_TONE, SOUND_MIXER_BASS, 0x0f, MO, SOUND_MASK_BASS, -1, 0xff00 }, + { AC97_PCBEEP_VOL, SOUND_MIXER_SPEAKER, 0x0f, MO, SOUND_MASK_SPEAKER, -1, 0x001e }, + { AC97_PHONE_VOL, SOUND_MIXER_PHONEIN, 0x1f, MO, SOUND_MASK_PHONEIN, 7, 0x0000 }, + { AC97_MIC_VOL, SOUND_MIXER_MIC, 0x1f, MO, SOUND_MASK_MIC, 0, 0x0000 }, + { AC97_LINEIN_VOL, SOUND_MIXER_LINE, 0x1f, ST, SOUND_MASK_LINE, 4, 0x0000 }, + { AC97_CD_VOL, SOUND_MIXER_CD, 0x1f, ST, SOUND_MASK_CD, 1, 0x0000 }, + { AC97_VIDEO_VOL, SOUND_MIXER_VIDEO, 0x1f, ST, SOUND_MASK_VIDEO, 2, 0x0000 }, + { AC97_AUX_VOL, SOUND_MIXER_LINE1, 0x1f, ST, SOUND_MASK_LINE1, 3, 0x0000 }, + { AC97_PCMOUT_VOL, SOUND_MIXER_PCM, 0x1f, ST, SOUND_MASK_PCM, -1, 0x0000 }, + { AC97_RECORD_GAIN, SOUND_MIXER_IGAIN, 0x0f, ST, SOUND_MASK_IGAIN, -1, 0x0000 }, + { -1, -1, 0xff, 0, 0, -1, 0x0000 }, +}; + +static struct ac97_chn_desc * +ac97_find_chndesc (struct ac97_hwint *dev, int oss_channel) +{ + int x; + + for (x = 0; mixerRegs[x].oss_channel != -1; x++) { + if (mixerRegs[x].oss_channel == oss_channel) + return mixerRegs + x; + } + + return NULL; +} + +static inline int +ac97_is_valid_channel (struct ac97_hwint *dev, struct ac97_chn_desc *chn) +{ + return (dev->last_written_mixer_values[chn->ac97_regnum / 2] + != AC97_REG_UNSUPPORTED); +} + +int +ac97_init (struct ac97_hwint *dev) +{ + int x; + int reg0; + + /* Clear out the arrays of cached values. */ + for (x = 0; x < AC97_REG_CNT; x++) + dev->last_written_mixer_values[x] = AC97_REGVAL_UNKNOWN; + + for (x = 0; x < SOUND_MIXER_NRDEVICES; x++) + dev->last_written_OSS_values[x] = AC97_REGVAL_UNKNOWN; + + /* Clear the device masks. */ + dev->mixer_devmask = 0; + dev->mixer_stereomask = 0; + dev->mixer_recmask = 0; + + /* ??? Do a "standard reset" via register 0? */ + + /* Hardware-dependent reset. */ + if (dev->reset_device (dev)) + return -1; + + /* Check the mixer device capabilities. */ + reg0 = dev->read_reg (dev, AC97_RESET); + + if (reg0 < 0) + return -1; + + /* Check for support for treble/bass controls. */ + if (! (reg0 & 4)) { + dev->last_written_mixer_values[AC97_MASTER_TONE / 2] + = AC97_REG_UNSUPPORTED; + } + + /* ??? There may be other tests here? */ + + /* Fill in the device masks. */ + for (x = 0; mixerRegs[x].ac97_regnum != -1; x++) { + if (ac97_is_valid_channel (dev, mixerRegs + x)) { + dev->mixer_devmask |= mixerRegs[x].oss_mask; + + if (mixerRegs[x].is_stereo) + dev->mixer_stereomask |= mixerRegs[x].oss_mask; + + if (mixerRegs[x].recordNum != -1) + dev->mixer_recmask |= mixerRegs[x].oss_mask; + } + } + + return 0; +} + +/* Return the contents of register REG; use the cache if the value in it + is valid. Returns a negative error code on failure. */ +int +ac97_get_register (struct ac97_hwint *dev, u8 reg) +{ + if (reg > 127 || (reg & 1)) + return -EINVAL; + + /* See if it's in the cache, or if it's just plain invalid. */ + switch (dev->last_written_mixer_values[reg / 2]) { + case AC97_REG_UNSUPPORTED: + return -EINVAL; + break; + case AC97_REGVAL_UNKNOWN: + dev->last_written_mixer_values[reg / 2] = dev->read_reg (dev, reg); + break; + default: + break; + } + return dev->last_written_mixer_values[reg / 2]; +} + +/* Write VALUE to AC97 register REG, and cache its value in the last-written + cache. Returns a negative error code on failure, or 0 on success. */ +int +ac97_put_register (struct ac97_hwint *dev, u8 reg, u16 value) +{ + if (reg > 127 || (reg & 1)) + return -EINVAL; + + if (dev->last_written_mixer_values[reg / 2] == AC97_REG_UNSUPPORTED) + return -EINVAL; + else { + int res = dev->write_reg (dev, reg, value); + if (res >= 0) { + dev->last_written_mixer_values[reg / 2] = value; + return 0; + } + else + return res; + } +} + +/* Scale VALUE (a value fro 0 to MAXVAL) to a value from 0-100. If + IS_STEREO is set, VALUE is a stereo value; the left channel value + is in the lower 8 bits, and the right channel value is in the upper + 8 bits. + + A negative error code is returned on failure, or the unsigned + scaled value on success. */ + +static int +ac97_scale_to_oss_val (int value, int maxval, int is_stereo) +{ + /* Muted? */ + if (value & AC97_MUTE) + return 0; + + if (is_stereo) + return (ac97_scale_to_oss_val (value & 255, maxval, 0) << 8) + | (ac97_scale_to_oss_val ((value >> 8) & 255, maxval, 0) << 0); + else { + int i; + + /* Inverted. */ + value = maxval - value; + + i = (value * 100 + (maxval / 2)) / maxval; + if (i > 100) + i = 100; + return i; + } +} + +static int +ac97_scale_from_oss_val (int value, int maxval, int is_stereo) +{ + if (is_stereo) + return (ac97_scale_from_oss_val (value & 255, maxval, 0) << 8) + | (ac97_scale_from_oss_val ((value >> 8) & 255, maxval, 0) << 0); + else { + int i = maxval - ((value & 255) * maxval + 50) / 100; + if (i < 0) + i = 0; + return i; + } +} + +int +ac97_set_mixer (struct ac97_hwint *dev, int oss_channel, u16 oss_value) +{ + int scaled_value; + struct ac97_chn_desc *channel = ac97_find_chndesc (dev, oss_channel); + int result; + + if (channel == NULL) + return -ENODEV; + if (! ac97_is_valid_channel (dev, channel)) + return -ENODEV; + scaled_value = ac97_scale_from_oss_val (oss_value, channel->maxval, + channel->is_stereo); + if (scaled_value < 0) + return scaled_value; + + if (channel->regmask != 0) { + int mv; + + int oldval = ac97_get_register (dev, channel->ac97_regnum); + if (oldval < 0) + return oldval; + + for (mv = channel->regmask; ! (mv & 1); mv >>= 1) + scaled_value <<= 1; + + scaled_value &= channel->regmask; + scaled_value |= (oldval & ~channel->regmask); + } + result = ac97_put_register (dev, channel->ac97_regnum, scaled_value); + if (result == 0) + dev->last_written_OSS_values[oss_channel] = oss_value; + return result; +} + +int +ac97_get_mixer_scaled (struct ac97_hwint *dev, int oss_channel) +{ + struct ac97_chn_desc *channel = ac97_find_chndesc (dev, oss_channel); + int regval; + + if (channel == NULL) + return -ENODEV; + + if (! ac97_is_valid_channel (dev, channel)) + return -ENODEV; + + regval = ac97_get_register (dev, channel->ac97_regnum); + + if (regval < 0) + return regval; + + if (channel->regmask != 0) { + int mv; + + regval &= channel->regmask; + + for (mv = channel->regmask; ! (mv & 1); mv >>= 1) + regval >>= 1; + } + return ac97_scale_to_oss_val (regval, channel->maxval, + channel->is_stereo); +} + +int +ac97_get_recmask (struct ac97_hwint *dev) +{ + int recReg = ac97_get_register (dev, AC97_RECORD_SELECT); + + if (recReg < 0) + return recReg; + else { + int x; + for (x = 0; mixerRegs[x].ac97_regnum >= 0; x++) { + if (mixerRegs[x].recordNum == (recReg & 7)) + return mixerRegs[x].oss_mask; + } + return -ENODEV; + } +} + +int +ac97_set_recmask (struct ac97_hwint *dev, int oss_recmask) +{ + int x; + + if (oss_recmask == 0) + oss_recmask = SOUND_MIXER_MIC; + + for (x = 0; mixerRegs[x].ac97_regnum >= 0; x++) { + if ((mixerRegs[x].recordNum >= 0) + && (oss_recmask & mixerRegs[x].oss_mask)) + break; + } + if (mixerRegs[x].ac97_regnum < 0) + return -ENODEV; + else { + int regval = (mixerRegs[x].recordNum << 8) | mixerRegs[x].recordNum; + int res = ac97_put_register (dev, AC97_RECORD_SELECT, regval); + if (res == 0) + return ac97_get_recmask (dev); + else + return res; + } +} + +/* Set the mixer DEV to the list of values in VALUE_LIST. Return 0 on + success, or a negative error code. */ +int +ac97_set_values (struct ac97_hwint *dev, + struct ac97_mixer_value_list *value_list) +{ + int x; + + for (x = 0; value_list[x].oss_channel != -1; x++) { + int chnum = value_list[x].oss_channel; + struct ac97_chn_desc *chent = ac97_find_chndesc (dev, chnum); + if (chent != NULL) { + u16 val; + int res; + + if (chent->is_stereo) + val = (value_list[x].value.stereo.right << 8) + | value_list[x].value.stereo.left; + else { + /* We do this so the returned value looks OK in the + mixer app. It's not necessary otherwise. */ + val = (value_list[x].value.mono << 8) + | value_list[x].value.mono; + } + res = ac97_set_mixer (dev, chnum, val); + if (res < 0) + return res; + } + else + return -ENODEV; + } + return 0; +} + +int +ac97_mixer_ioctl (struct ac97_hwint *dev, unsigned int cmd, caddr_t arg) +{ + int ret; + + switch (cmd) { + case SOUND_MIXER_READ_RECSRC: + ret = ac97_get_recmask (dev); + break; + + case SOUND_MIXER_WRITE_RECSRC: + { + if (get_user (ret, (int *) arg)) + ret = -EFAULT; + else + ret = ac97_set_recmask (dev, ret); + } + break; + + case SOUND_MIXER_READ_CAPS: + ret = SOUND_CAP_EXCL_INPUT; + break; + + case SOUND_MIXER_READ_DEVMASK: + ret = dev->mixer_devmask; + break; + + case SOUND_MIXER_READ_RECMASK: + ret = dev->mixer_recmask; + break; + + case SOUND_MIXER_READ_STEREODEVS: + ret = dev->mixer_stereomask; + break; + + default: + /* Read or write request. */ + ret = -EINVAL; + if (_IOC_TYPE (cmd) == 'M') { + int dir = _IOC_DIR (cmd); + int channel = _IOC_NR (cmd); + + if (channel >= 0 && channel < SOUND_MIXER_NRDEVICES) { + ret = 0; + if (dir & _IOC_WRITE) { + int val; + if (get_user (val, (int *) arg) == 0) + ret = ac97_set_mixer (dev, channel, val); + else + ret = -EFAULT; + } + if (ret >= 0) { + if (dev->last_written_OSS_values[channel] == AC97_REGVAL_UNKNOWN) + dev->last_written_OSS_values[channel] + = ac97_get_mixer_scaled (dev, channel); + ret = dev->last_written_OSS_values[channel]; + } + } + } + break; + } + + if (ret < 0) + return ret; + else + return put_user(ret, (int *) arg); +} + + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sound/ac97.h linux.ac/drivers/sound/ac97.h --- linux.vanilla/drivers/sound/ac97.h Thu Aug 26 14:42:15 1999 +++ linux.ac/drivers/sound/ac97.h Mon Sep 20 20:58:08 1999 @@ -2,12 +2,14 @@ * ac97.h * * definitions for the AC97, Intel's Audio Codec 97 Spec + * also includes support for a generic AC97 interface */ #ifndef _AC97_H_ #define _AC97_H_ +#include "sound_config.h" +#include "sound_calls.h" - // conections on concert 97 */ #define AC97_RESET 0x0000 // */ #define AC97_MASTER_VOL_STEREO 0x0002 // Line Out #define AC97_HEADPHONE_VOL 0x0004 // @@ -36,7 +38,6 @@ #define AC97_VENDOR_ID1 0x007c #define AC97_VENDOR_ID2 0x007e - /* volume control bit defines */ #define AC97_MUTE 0x8000 @@ -95,7 +96,108 @@ #define AC97_PWR_D3 AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR2|AC97_PWR_PR3|AC97_PWR_PR4 #define AC97_PWR_ANLOFF AC97_PWR_PR2|AC97_PWR_PR3 /* analog section off */ -#endif /* _AC97_H_ */ - +/* Total number of defined registers. */ +#define AC97_REG_CNT 64 +/* Generic AC97 mixer interface. */ +/* Structure describing access to the hardware. */ +struct ac97_hwint +{ + /* Perform any hardware-specific reset and initialization. Returns + 0 on success, or a negative error code. */ + int (*reset_device) (struct ac97_hwint *dev); + + /* Returns the contents of the specified register REG. The caller + should check to see if the desired contents are available in + the cache first, if applicable. Returns a positive unsigned value + representing the contents of the register, or a negative error + code. */ + int (*read_reg) (struct ac97_hwint *dev, u8 reg); + + /* Writes VALUE to register REG. Returns 0 on success, or a + negative error code. */ + int (*write_reg) (struct ac97_hwint *dev, u8 reg, u16 value); + + /* Hardware-specific information. */ + void *driver_private; + + /* Three OSS masks. */ + int mixer_devmask; + int mixer_stereomask; + int mixer_recmask; + + /* The mixer cache. The indices correspond to the AC97 hardware register + number / 2, since the register numbers are always an even number. + + Unknown values are set to -1; unsupported registers contain a + -2. */ + int last_written_mixer_values[AC97_REG_CNT]; + + /* A cache of values written via OSS; we need these so we can return + the values originally written by the user. + + Why the original user values? Because the real-world hardware + has less precision, and some existing applications assume that + they will get back the exact value that they wrote (aumix). + + A -1 value indicates that no value has been written to this mixer + channel via OSS. */ + int last_written_OSS_values[SOUND_MIXER_NRDEVICES]; +}; + +/* Values stored in the register cache. */ +#define AC97_REGVAL_UNKNOWN -1 +#define AC97_REG_UNSUPPORTED -2 + +struct ac97_mixer_value_list +{ + /* Mixer channel to set. List is terminated by a value of -1. */ + int oss_channel; + /* The scaled value to set it to; values generally range from 0-100. */ + union { + struct { + u8 left, right; + } stereo; + u8 mono; + } value; +}; + +/* Initialize the ac97 mixer by resetting it. */ +extern int ac97_init (struct ac97_hwint *dev); + +/* Sets the mixer DEV to the values in VALUE_LIST. Returns 0 on success, + or a negative error code. */ +extern int ac97_set_values (struct ac97_hwint *dev, + struct ac97_mixer_value_list *value_list); + +/* Sets one mixer channel OSS_CHANNEL to the scaled value OSS_VALUE. + Returns the resulting (rescaled) value, or a negative value + representing an error code. + + Stereo channels have two values in OSS_VALUE (the left value is in the + lower 8 bits, the right value is in the upper 8 bits). */ +extern int ac97_set_mixer (struct ac97_hwint *dev, int oss_channel, + u16 oss_value); + +/* Return the contents of the specified AC97 register REG; it uses the + last-written value if it is available. */ +extern int ac97_get_register (struct ac97_hwint *dev, u8 reg); + +/* Writes the specified VALUE to the AC97 register REG in the mixer. + Takes care of setting the last-written cache as well. */ +extern int ac97_put_register (struct ac97_hwint *dev, u8 reg, u16 value); + +/* Returns the last OSS value written to the OSS_CHANNEL mixer channel. */ +extern int ac97_get_mixer_scaled (struct ac97_hwint *dev, int oss_channel); + +/* Default ioctl. */ +extern int ac97_mixer_ioctl (struct ac97_hwint *dev, unsigned int cmd, + caddr_t arg); +#endif + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sound/ad1848.c linux.ac/drivers/sound/ad1848.c --- linux.vanilla/drivers/sound/ad1848.c Tue Apr 13 00:18:27 1999 +++ linux.ac/drivers/sound/ad1848.c Tue Sep 14 21:23:55 1999 @@ -106,7 +106,7 @@ int soundpro = 0; #endif -static volatile char irq2dev[17] = { +static volatile signed char irq2dev[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; @@ -2434,11 +2434,12 @@ void attach_ms_sound(struct address_info *hw_config) { - static char interrupt_bits[12] = + static signed char interrupt_bits[12] = { -1, -1, -1, -1, -1, 0x00, -1, 0x08, -1, 0x10, 0x18, 0x20 }; - char bits, dma2_bit = 0; + signed char bits; + char dma2_bit = 0; static char dma_bits[4] = { diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sound/adlib_card.c linux.ac/drivers/sound/adlib_card.c --- linux.vanilla/drivers/sound/adlib_card.c Thu May 14 18:33:17 1998 +++ linux.ac/drivers/sound/adlib_card.c Sun Sep 19 17:28:24 1999 @@ -16,8 +16,6 @@ #include "sound_config.h" #include "soundmodule.h" -#ifdef CONFIG_YM3812 - void attach_adlib_card(struct address_info *hw_config) { hw_config->slots[0] = opl3_init(hw_config->io_base, hw_config->osp); @@ -69,5 +67,4 @@ SOUND_LOCK_END; } -#endif #endif diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sound/cmpci.c linux.ac/drivers/sound/cmpci.c --- linux.vanilla/drivers/sound/cmpci.c Sat Sep 11 00:54:10 1999 +++ linux.ac/drivers/sound/cmpci.c Mon Sep 20 16:18:43 1999 @@ -57,7 +57,8 @@ * reported by Johan Maes * 22.03.99 0.12 return EAGAIN instead of EBUSY when O_NONBLOCK * read/write cannot be executed - * + * 20 09 99 0.13 merged the generic changes in sonicvibes since this + * diverged. */ /*****************************************************************************/ @@ -585,8 +586,9 @@ db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0; if (!db->rawbuf) { db->ready = db->mapped = 0; - for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER && !db->rawbuf; order--) - db->rawbuf = (void *)__get_free_pages(GFP_KERNEL | GFP_DMA, order); + for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--) + if ((db->rawbuf = (void *)__get_free_pages(GFP_KERNEL | GFP_DMA, order))) + break; if (!db->rawbuf) return -ENOMEM; db->buforder = order; @@ -1152,9 +1154,9 @@ current->state = TASK_RUNNING; return -EBUSY; } - tmo = (count * HZ) / s->ratedac; + tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->ratedac; tmo >>= sample_shift[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK]; - if (!schedule_timeout(tmo ? : 1) && tmo) + if (!schedule_timeout(tmo + 1)) printk(KERN_DEBUG "cm: dma timed out??\n"); } remove_wait_queue(&s->dma_dac.wait, &wait); @@ -1630,9 +1632,11 @@ case SOUND_PCM_READ_BITS: return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_ADCSHIFT) : (CM_CFMT_16BIT << CM_CFMT_DACSHIFT))) ? 16 : 8, (int *)arg); + case SOUND_PCM_READ_FILTER: + return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg); + case SOUND_PCM_WRITE_FILTER: case SNDCTL_DSP_SETSYNCRO: - case SOUND_PCM_READ_FILTER: return -EINVAL; } @@ -1732,6 +1736,7 @@ static ssize_t cm_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { struct cm_state *s = (struct cm_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); ssize_t ret; unsigned long flags; unsigned ptr; @@ -1742,7 +1747,10 @@ return -ESPIPE; if (!access_ok(VERIFY_WRITE, buffer, count)) return -EFAULT; + if (count == 0) + return 0; ret = 0; + add_wait_queue(&s->midi.iwait, &wait); while (count > 0) { spin_lock_irqsave(&s->lock, flags); ptr = s->midi.ird; @@ -1753,15 +1761,27 @@ if (cnt > count) cnt = count; if (cnt <= 0) { - if (file->f_flags & O_NONBLOCK) - return ret ? ret : -EAGAIN; - interruptible_sleep_on(&s->midi.iwait); - if (signal_pending(current)) - return ret ? ret : -ERESTARTSYS; + if (file->f_flags & O_NONBLOCK) + { + if (!ret) + ret = -EAGAIN; + break; + } + __set_current_state(TASK_INTERRUPTIBLE); + schedule(); + if (signal_pending(current)) + { + if (!ret) + ret = -ERESTARTSYS; + break; + } continue; } - if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) - return ret ? ret : -EFAULT; + if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } ptr = (ptr + cnt) % MIDIINBUF; spin_lock_irqsave(&s->lock, flags); s->midi.ird = ptr; @@ -1770,13 +1790,17 @@ count -= cnt; buffer += cnt; ret += cnt; + break; } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&s->midi.iwait, &wait); return ret; } static ssize_t cm_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) { struct cm_state *s = (struct cm_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); ssize_t ret; unsigned long flags; unsigned ptr; @@ -1787,7 +1811,10 @@ return -ESPIPE; if (!access_ok(VERIFY_READ, buffer, count)) return -EFAULT; + if (count == 0) + return 0; ret = 0; + add_wait_queue(&s->midi.owait, &wait); while (count > 0) { spin_lock_irqsave(&s->lock, flags); ptr = s->midi.owr; @@ -1800,15 +1827,25 @@ if (cnt > count) cnt = count; if (cnt <= 0) { - if (file->f_flags & O_NONBLOCK) - return ret ? ret : -EAGAIN; - interruptible_sleep_on(&s->midi.owait); - if (signal_pending(current)) - return ret ? ret : -ERESTARTSYS; + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + __set_current_state(TASK_INTERRUPTIBLE); + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } continue; } - if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) - return ret ? ret : -EFAULT; + if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } ptr = (ptr + cnt) % MIDIOUTBUF; spin_lock_irqsave(&s->lock, flags); s->midi.owr = ptr; @@ -1821,6 +1858,8 @@ cm_handle_midi(s); spin_unlock_irqrestore(&s->lock, flags); } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&s->midi.owait, &wait); return ret; } @@ -1915,7 +1954,7 @@ VALIDATE_STATE(s); if (file->f_mode & FMODE_WRITE) { - current->state = TASK_INTERRUPTIBLE; + __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&s->midi.owait, &wait); for (;;) { spin_lock_irqsave(&s->lock, flags); @@ -1927,7 +1966,7 @@ break; if (file->f_flags & O_NONBLOCK) { remove_wait_queue(&s->midi.owait, &wait); - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); return -EBUSY; } tmo = (count * HZ) / 3100; @@ -1935,7 +1974,7 @@ printk(KERN_DEBUG "cm: midi timed out??\n"); } remove_wait_queue(&s->midi.owait, &wait); - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); } down(&s->open_sem); s->open_mode &= (~(file->f_mode << FMODE_MIDI_SHIFT)) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE); @@ -2344,11 +2383,6 @@ /* --------------------------------------------------------------------- */ #ifdef MODULE - -#if 0 -MODULE_PARM(wavetable, "1-" __MODULE_STRING(NR_DEVICE) "i"); -MODULE_PARM_DESC(wavetable, "if 1 the wavetable synth is enabled"); -#endif MODULE_AUTHOR("ChenLi Tien, cltien@home.com"); MODULE_DESCRIPTION("CMPCI Audio Driver"); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sound/dmabuf.c linux.ac/drivers/sound/dmabuf.c --- linux.vanilla/drivers/sound/dmabuf.c Tue Apr 13 00:18:27 1999 +++ linux.ac/drivers/sound/dmabuf.c Tue Sep 14 21:24:08 1999 @@ -187,7 +187,7 @@ printk(KERN_WARNING "Sound: DMA buffers not available\n"); return -ENOSPC; /* Memory allocation failed during boot */ } - if (sound_open_dma(dmap->dma, adev->name)) { + if (dmap->dma >= 0 && sound_open_dma(dmap->dma, adev->name)) { printk(KERN_WARNING "Unable to grab(2) DMA%d for the audio driver\n", dmap->dma); return -EBUSY; } @@ -209,14 +209,15 @@ { unsigned long flags; - sound_close_dma(dmap->dma); + if (dmap->dma >= 0) { + sound_close_dma(dmap->dma); + flags=claim_dma_lock(); + disable_dma(dmap->dma); + release_dma_lock(flags); + } if (dmap->flags & DMA_BUSY) dmap->dma_mode = DMODE_NONE; dmap->flags &= ~DMA_BUSY; - - flags=claim_dma_lock(); - disable_dma(dmap->dma); - release_dma_lock(flags); if (sound_dmap_flag == DMAP_FREE_ON_CLOSE) sound_free_dmap(dmap); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sound/lowlevel/Config.in linux.ac/drivers/sound/lowlevel/Config.in --- linux.vanilla/drivers/sound/lowlevel/Config.in Sun Dec 27 18:53:45 1998 +++ linux.ac/drivers/sound/lowlevel/Config.in Mon Sep 13 00:22:42 1999 @@ -1,57 +1,57 @@ -dep_tristate 'ACI mixer (miroPCM12)' CONFIG_ACI_MIXER $CONFIG_SOUND_OSS +dep_tristate ' ACI mixer (miroPCM12)' CONFIG_ACI_MIXER $CONFIG_SOUND_OSS -dep_tristate 'AWE32 synth' CONFIG_AWE32_SYNTH $CONFIG_SOUND_OSS +dep_tristate ' AWE32 synth' CONFIG_AWE32_SYNTH $CONFIG_SOUND_OSS if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND" = "m" ]; then - dep_tristate 'Gallant Audio Cards (SC-6000 and SC-6600 based)' CONFIG_AEDSP16 $CONFIG_SOUND_OSS - if [ "$CONFIG_AEDSP16" = "y" -o "$CONFIG_AEDSP16" = "m" ]; then - hex ' I/O base for Audio Excel DSP 16 220 or 240' CONFIG_AEDSP16_BASE 220 - hex 'I/O base for MPU401 Check from manual of the card' CONFIG_MPU_BASE 330 - fi - - if [ "$CONFIG_AEDSP16" = "y" -o "$CONFIG_AEDSP16" = "m" ]; then - comment 'SC-6600 Audio Cards have no jumper switches at all' - bool 'SC-6600 based audio cards (new Audio Excel DSP 16)' CONFIG_SC6600 - if [ "$CONFIG_SC6600" = "y" ]; then - comment 'SC-6600 specific configuration' - bool 'Activate SC-6600 Joystick Interface' CONFIG_SC6600_JOY - int 'SC-6600 CDROM Interface (4=None, 3=IDE, 1=Panasonic, 0=?Sony?)' CONFIG_SC6600_CDROM 4 - hex 'SC-6600 CDROM Interface I/O Address' CONFIG_SC6600_CDROMBASE 0 - fi - - if [ "$CONFIG_SOUND_SB" = "y" -o "$CONFIG_SOUND_SB" = "m" ]; then - if [ "$CONFIG_AEDSP16_MSS" != "y" ]; then - bool 'Audio Excel DSP 16 (SBPro emulation)' CONFIG_AEDSP16_SBPRO - if [ "$CONFIG_AEDSP16_SBPRO" = "y" ]; then - comment 'Audio Excel DSP 16 [Sound Blaster Pro]' - hex 'I/O base for Audio Excel DSP 16 220, 240' CONFIG_AEDSP16_BASE $CONFIG_SB_BASE 220 - int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' CONFIG_AEDSP16_SB_IRQ $CONFIG_SB_IRQ 5 - int 'Audio Excel DSP 16 DMA 0, 1 or 3' CONFIG_AEDSP16_SB_DMA $CONFIG_SB_DMA 0 - fi + dep_tristate ' Gallant Audio Cards (SC-6000 and SC-6600 based)' CONFIG_AEDSP16 $CONFIG_SOUND_OSS + if [ "$CONFIG_AEDSP16" = "y" -o "$CONFIG_AEDSP16" = "m" ]; then + hex 'I/O base for Audio Excel DSP 16 220 or 240' CONFIG_AEDSP16_BASE 220 + hex 'I/O base for MPU401 Check from manual of the card' CONFIG_MPU_BASE 330 + fi + + if [ "$CONFIG_AEDSP16" = "y" -o "$CONFIG_AEDSP16" = "m" ]; then + comment 'SC-6600 Audio Cards have no jumper switches at all' + bool ' SC-6600 based audio cards (new Audio Excel DSP 16)' CONFIG_SC6600 + if [ "$CONFIG_SC6600" = "y" ]; then + comment 'SC-6600 specific configuration' + bool ' Activate SC-6600 Joystick Interface' CONFIG_SC6600_JOY + int 'SC-6600 CDROM Interface (4=None, 3=IDE, 1=Panasonic, 0=?Sony?)' CONFIG_SC6600_CDROM 4 + hex 'SC-6600 CDROM Interface I/O Address' CONFIG_SC6600_CDROMBASE 0 + fi + + if [ "$CONFIG_SOUND_SB" = "y" -o "$CONFIG_SOUND_SB" = "m" ]; then + if [ "$CONFIG_AEDSP16_MSS" != "y" ]; then + bool 'Audio Excel DSP 16 (SBPro emulation)' CONFIG_AEDSP16_SBPRO + if [ "$CONFIG_AEDSP16_SBPRO" = "y" ]; then + comment 'Audio Excel DSP 16 [Sound Blaster Pro]' + hex 'I/O base for Audio Excel DSP 16 220, 240' CONFIG_AEDSP16_BASE $CONFIG_SB_BASE 220 + int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' CONFIG_AEDSP16_SB_IRQ $CONFIG_SB_IRQ 5 + int 'Audio Excel DSP 16 DMA 0, 1 or 3' CONFIG_AEDSP16_SB_DMA $CONFIG_SB_DMA 0 fi - fi + fi + fi - if [ "$CONFIG_SOUND_MSS" = "y" -o "$CONFIG_SOUND_MSS" = "m" ]; then - if [ "$CONFIG_AEDSP16_SBPRO" != "y" ]; then - bool 'Audio Excel DSP 16 (MSS emulation)' CONFIG_AEDSP16_MSS - if [ "$CONFIG_AEDSP16_MSS" = "y" ]; then - comment 'Audio Excel DSP 16 [Microsoft Sound System]' - hex 'I/O base for Audio Excel DSP 16 220 or 240' CONFIG_AEDSP16_BASE 220 - int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' CONFIG_AEDSP16_MSS_IRQ $CONFIG_MSS_IRQ 5 - int 'Audio Excel DSP 16 DMA 0, 1 or 3' CONFIG_AEDSP16_MSS_DMA $CONFIG_MSS_DMA 1 - fi + if [ "$CONFIG_SOUND_MSS" = "y" -o "$CONFIG_SOUND_MSS" = "m" ]; then + if [ "$CONFIG_AEDSP16_SBPRO" != "y" ]; then + bool ' Audio Excel DSP 16 (MSS emulation)' CONFIG_AEDSP16_MSS + if [ "$CONFIG_AEDSP16_MSS" = "y" ]; then + comment 'Audio Excel DSP 16 [Microsoft Sound System]' + hex 'I/O base for Audio Excel DSP 16 220 or 240' CONFIG_AEDSP16_BASE 220 + int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' CONFIG_AEDSP16_MSS_IRQ $CONFIG_MSS_IRQ 5 + int 'Audio Excel DSP 16 DMA 0, 1 or 3' CONFIG_AEDSP16_MSS_DMA $CONFIG_MSS_DMA 1 fi - fi + fi + fi - if [ "$CONFIG_SOUND_MPU401" = "y" -o "$CONFIG_SOUND_MPU401" = "m" ]; then - bool 'Audio Excel DSP 16 (MPU401 emulation)' CONFIG_AEDSP16_MPU401 - if [ "$CONFIG_AEDSP16_MPU401" = "y" ]; then - comment 'Audio Excel DSP 16 [MPU-401]' - if [ "$CONFIG_AEDSP16_SBPRO" != "y" -a "$CONFIG_AEDSP16_MSS" != "y" ]; then - hex 'I/O base for Audio Excel DSP 16 220 or 240' CONFIG_AEDSP16_BASE 220 - fi - int 'MPU401 IRQ for Audio Excel DSP 16 5, 7, 9, 10 or 0 (disable)' CONFIG_AEDSP16_MPU_IRQ $CONFIG_MPU_IRQ + if [ "$CONFIG_SOUND_MPU401" = "y" -o "$CONFIG_SOUND_MPU401" = "m" ]; then + bool 'Audio Excel DSP 16 (MPU401 emulation)' CONFIG_AEDSP16_MPU401 + if [ "$CONFIG_AEDSP16_MPU401" = "y" ]; then + comment 'Audio Excel DSP 16 [MPU-401]' + if [ "$CONFIG_AEDSP16_SBPRO" != "y" -a "$CONFIG_AEDSP16_MSS" != "y" ]; then + hex 'I/O base for Audio Excel DSP 16 220 or 240' CONFIG_AEDSP16_BASE 220 fi - fi - fi + int 'MPU401 IRQ for Audio Excel DSP 16 5, 7, 9, 10 or 0 (disable)' CONFIG_AEDSP16_MPU_IRQ $CONFIG_MPU_IRQ + fi + fi + fi fi diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sound/maestro.c linux.ac/drivers/sound/maestro.c --- linux.vanilla/drivers/sound/maestro.c Sat Sep 11 00:54:10 1999 +++ linux.ac/drivers/sound/maestro.c Mon Sep 20 19:45:49 1999 @@ -24,7 +24,9 @@ * Heavily modified by Zach Brown based on lunch * with ESS engineers. Many thanks to Howard Kim for providing * contacts and hardware. Honorable mention goes to Eric - * Brombaugh for the BOB routines and nice hacking in general. + * Brombaugh for the BOB routines and great record code hacking. + * Best regards to the proprietors of Hack Central for fine + * lodging. * * Supported devices: * /dev/dsp0-7 standard /dev/dsp device, (mostly) OSS compatible @@ -50,10 +52,11 @@ * Driver Operation * * We only drive the APU/Wavecache as typical DACs and drive the - * mixers in the codecs. There are 64 APUs. We assign 4 to each - * /dev/dsp? device. 2 channels for both in and out. + * mixers in the codecs. There are 64 APUs. We assign 6 to each + * /dev/dsp? device. 2 channels for output, and 4 channels for + * input. * - * For output we maintain a ring buffer of data that we are dmaing + * For output we maintain a ring buffer of data that we are DMAing * to the card. In mono operation this is nice and easy. When * we receive data we tack it onto the ring buffer and make sure * the APU assigned to it is playing over the data. When we fill @@ -66,44 +69,94 @@ * mono encoded data. This requires us to split the input from * the client and complicates the buffer maths tremendously. Ick. * - * Once input is actually written, it will be worth pointing out - * that only 44/16 input actually works. + * This also pollutes the recording paths as well. We have to use + * 2 l/r incoming APUs that are fixed at 16bit/48khz. We then pipe + * these through 2 rate converion apus that mix them down to the + * requested frequency and write them to memory through the wavecache. + * We also apparently need a 512byte region thats used as temp space + * between the incoming APUs and the rate converters. * + * The wavecache makes our life even more fun. First off, it can + * only address the first 28 bits of PCI address space, making it + * useless on quite a few architectures. Secondly, its insane. + * It can only fetch from 4 regions of PCI space, each 2 meg in length + * and 4k aligned. It then uses high bits of the address in the APU + * to decide which buffer to use, but as far as I can tell can only + * choose between 2 of the 4 available when you really want to hit + * PCI space. So all the memory we're touching has to fit in 2 regions + * of 4 meg under 256meg. So much for dynamic allocation of multiple + * /dev/dsps. So we force only 1 /dev/dsp, allocate both its read + * and write buffers contiguously at open(), and allocate the weird + * mixbuf input APU buffers on another page. The first 2meg region + * goes to the input/output buffers, and the second region goes to + * the weird mixbuf. Long term fixes? Get an allocator that lets + * us try and allocate from zones. Alleviate pain by putting the mixbuf + * in onboard ram rather than in system memory. Buy a real sound card. + * * History + * v0.06 - Sep 20 1999 - Zach Brown + * fix wavecache thinkos. limit to 1 /dev/dsp. + * eric is wearing his thinking toque this week. + * spotted apu mode bugs and gain ramping problem + * don't touch weird mixer regs, make recmask optional + * fixed igain inversion, defaults for mixers, clean up rec_start + * make mono recording work. + * report subsystem stuff, please send reports. + * littles: parallel out, amp now + * v0.05 - Sep 17 1999 - Zach Brown + * merged and fixed up Eric's initial recording code + * munged format handling to catch misuse, needs rewrite. + * revert ring bus init, fixup shared int, add pci busmaster setting + * fix mixer oss interface, fix mic mute and recmask + * mask off unsupported mixers, reset with all 1s, modularize defaults + * make sure bob is running while we need it + * got rid of device limit, initial minimal apm hooks + * pull out dead code/includes, only allow multimedia/audio maestros * v0.04 - Sep 01 1999 - Zach Brown * copied memory leak fix from sonicvibes driver * different ac97 reset, play with 2.0 ac97, simplify ring bus setup - * bob freq code, region sanity, jitter sync fix; all from eric + * bob freq code, region sanity, jitter sync fix; all from Eric * * TODO - * recording is horribly broken - * codec timeouts (we're way under the example source's 20ms(!?)) * some people get indir reg timeouts? - * mixer interface broken? * anyone have a pt101 codec? - * ess's ac97 codec (es1921) doesn't work * mmap(), but beware stereo encoding nastiness. * actually post pci writes - * check for bogon bios set irq/io windows - * compare our pci setup to the dos one, explains register timeouts? * look really hard at the apu/bob/dma buffer code paths. + * fix bob frequency + * do smart things with ac97 2.0 bits. + * fix wavecache so multiple /dev/dsps work + * test different sized writes + * fixup latencies ? + * get apm save/restore working? + * allocate dma bounce page + * start_adc is called way too often + * sort out 0x34->0x36 crap in init + * wavecache needs to be looked at, multiple + * dsps and recording seem confused * * the entire issue of smp safety needs to be looked at. cli() needs * to be replaced with spinlock_irqsave, being very careful of call * paths avoiding deadlock. if lock hold times are quick just * use one big ass per device spinlock.. + * + * apm is kind of a mess. I doubt we can rely on the machine keeping + * power to the maestro/codecs when we suspend. This means we have + * to keep full mixer/wavecache/apu state. bother. if we could rely + * on the chips being powered we would simply turn down the apus and + * bob and it would all just work out. That last bit I've implemented + * before I realized how much it was all going to suck :). + * + * it also would be fun to have a mode that would not use pci dma at all + * but would copy into the wavecache on board memory and use that + * on architectures that don't like the maestro's pci dma ickiness + * throughout. */ /*****************************************************************************/ -#ifdef MODULE #include -#ifdef MODVERSIONS -#include -#endif -#endif - #include #include #include @@ -122,8 +175,11 @@ #include #include +#ifdef CONFIG_APM +#include +#endif + #include "maestro.h" -#include "maestro_tables.h" /* --------------------------------------------------------------------- */ @@ -137,25 +193,30 @@ #endif /* --------------------------------------------------------------------- */ - -#define DRIVER_VERSION "0.04" +#define DRIVER_VERSION "0.06" #ifndef PCI_VENDOR_ESS #define PCI_VENDOR_ESS 0x125D #define PCI_DEVICE_ID_ESS_ESS1968 0x1968 /* Maestro 2 */ #define PCI_DEVICE_ID_ESS_ESS1978 0x1978 /* Maestro 2E */ -#define PCI_VENDOR_ESS_OLD 0x1285 /* vendor id for maestro 1 */ +#define PCI_VENDOR_ESS_OLD 0x1285 /* Platform Tech, + the people the maestro + was bought from */ #define PCI_DEVICE_ID_ESS_ESS0100 0x0100 /* maestro 1 */ #endif /* PCI_VENDOR_ESS */ #define ESS_CHAN_HARD 0x100 -#define ESS_CFMT_STEREO 0x01 -#define ESS_CFMT_16BIT 0x02 -#define ESS_CFMT_MASK 0x03 -#define ESS_CFMT_ASHIFT 0 -#define ESS_CFMT_CSHIFT 4 +#undef CONFIG_APM /* see notes above */ + +/* changed so that I could actually find all the + references and fix them up. its a little more readable now. */ +#define ESS_FMT_STEREO 0x01 +#define ESS_FMT_16BIT 0x02 +#define ESS_FMT_MASK 0x03 +#define ESS_DAC_SHIFT 0 +#define ESS_ADC_SHIFT 4 #define ESS_ENABLE_PE 1 #define ESS_ENABLE_RE 2 @@ -166,6 +227,10 @@ #define DAC_RUNNING 1 #define ADC_RUNNING 2 +#define NR_DSPS 1 /* our wavecache setup demands this. */ + +#define SND_DEV_DSP16 5 + static const unsigned sample_size[] = { 1, 2, 2, 4 }; static const unsigned sample_shift[] = { 0, 1, 1, 2 }; @@ -181,16 +246,15 @@ [TYPE_MAESTRO2E] = "ESS Maestro 2E" }; -#define SND_DEV_DSP16 5 /* --------------------------------------------------------------------- */ struct ess_state { unsigned int magic; /* FIXME: we probably want submixers in here, but only one record pair */ - u8 apu[4]; /* Left, Right, Left In, Right In */ - u8 apu_mode[4]; /* Running mode for this APU */ - u8 apu_pan[4]; /* Panning setup for this APU */ + u8 apu[6]; /* l/r output, l/r intput converters, l/r input apus */ + u8 apu_mode[6]; /* Running mode for this APU */ + u8 apu_pan[6]; /* Panning setup for this APU */ struct ess_card *card; /* Card info */ /* wave stuff */ unsigned int rateadc, ratedac; @@ -209,6 +273,8 @@ unsigned buforder; unsigned numfrag; unsigned fragshift; + /* XXX zab - swptr only in here so that it can be referenced by + clear_advance, as far as I can tell :( */ unsigned hwptr, swptr; unsigned total_bytes; int count; @@ -227,6 +293,10 @@ unsigned subdivision; u16 base; /* Offset for ptr */ } dma_dac, dma_adc; + + + /* pointer to each dsp?s piece of the apu->src buffer page */ + void *mixbuf; }; struct ess_card { @@ -247,18 +317,30 @@ int stereo_mixers; int record_sources; /* the caller must guarantee arg sanity before calling these */ - int (*read_mixer)(struct ess_card *card, int index); - void (*write_mixer)(struct ess_card *card,int mixer, int vol); +/* int (*read_mixer)(struct ess_card *card, int index);*/ + void (*write_mixer)(struct ess_card *card,int mixer, unsigned int left,unsigned int right); int (*recmask_io)(struct ess_card *card,int rw,int mask); + unsigned int mixer_state[SOUND_MIXER_NRDEVICES]; } mix; - struct ess_state channels[8]; + struct ess_state channels[NR_DSPS]; u16 maestro_map[32]; /* Register map */ +#ifdef CONFIG_APM + /* we have to store this junk so that we can come back from a + suspend */ + u16 apu_map[64][16]; /* contents of apu regs */ +#endif + + /* 1 page of DMA-able memory for mixer apu buffers, + shared amongst dsp?s. */ + void *mixpage; /* hardware resources */ u32 iobase; u32 irq; + int bob_freq; + char bob_running; }; extern __inline__ unsigned ld2(unsigned int x) @@ -343,7 +425,7 @@ sanity--; if(!sanity) { - printk(KERN_ERR "maestro: ac97 codec read timeout.\n"); + printk(KERN_ERR "maestro: ac97 codec timeout reading 0x%x.\n",cmd); return 0; } } @@ -352,6 +434,219 @@ return data; } +/* OSS interface to the ac97s.. */ + +#define AC97_STEREO_MASK (SOUND_MASK_VOLUME|\ + SOUND_MASK_PCM|SOUND_MASK_LINE|SOUND_MASK_CD|\ + SOUND_MASK_VIDEO|SOUND_MASK_LINE1|SOUND_MASK_IGAIN) + +#define AC97_SUPPORTED_MASK (AC97_STEREO_MASK | \ + SOUND_MASK_BASS|SOUND_MASK_TREBLE|SOUND_MASK_MIC|\ + SOUND_MASK_SPEAKER) + +#define AC97_RECORD_MASK (SOUND_MASK_MIC|\ + SOUND_MASK_CD| SOUND_MASK_VIDEO| SOUND_MASK_LINE1| SOUND_MASK_LINE|\ + SOUND_MASK_PHONEIN) + +#define supported_mixer(CARD,FOO) ( CARD->mix.supported_mixers & (1< 100 in bytes */ + {SOUND_MIXER_VOLUME, 0x3232}, + {SOUND_MIXER_BASS, 0x3232}, + {SOUND_MIXER_TREBLE, 0x3232}, + {SOUND_MIXER_SPEAKER, 0x3232}, + {SOUND_MIXER_MIC, 0x3232}, + {SOUND_MIXER_LINE, 0x3232}, + {SOUND_MIXER_CD, 0x3232}, + {SOUND_MIXER_VIDEO, 0x3232}, + {SOUND_MIXER_LINE1, 0x3232}, + {SOUND_MIXER_PCM, 0x3232}, + {SOUND_MIXER_IGAIN, 0x3232}, + {-1,0} +}; + +static struct ac97_mixer_hw { + unsigned char offset; + int scale; +} ac97_hw[SOUND_MIXER_NRDEVICES]= { + [SOUND_MIXER_VOLUME] = {0x02,63}, + [SOUND_MIXER_BASS] = {0x08,15}, + [SOUND_MIXER_TREBLE] = {0x08,15}, + [SOUND_MIXER_SPEAKER] = {0x0a,15}, + [SOUND_MIXER_MIC] = {0x0e,31}, + [SOUND_MIXER_LINE] = {0x10,31}, + [SOUND_MIXER_CD] = {0x12,31}, + [SOUND_MIXER_VIDEO] = {0x14,31}, + [SOUND_MIXER_LINE1] = {0x16,31}, + [SOUND_MIXER_PCM] = {0x18,31}, + [SOUND_MIXER_IGAIN] = {0x1c,31} +}; + +#if 0 /* *shrug* removed simply because we never used it. + feel free to implement again if needed */ + +/* reads the given OSS mixer from the ac97 + the caller must have insured that the ac97 knows + about that given mixer, and should be holding a + spinlock for the card */ +static int ac97_read_mixer(struct ess_card *card, int mixer) +{ + u16 val; + int ret=0; + struct ac97_mixer_hw *mh = &ac97_hw[mixer]; + + val = maestro_ac97_get(card->iobase , mh->offset); + + if(AC97_STEREO_MASK & (1<> 8) & 0x7f; + right = val & 0x7f; + + if (mixer == SOUND_MIXER_IGAIN) { + right = (right * 100) / mh->scale; + left = (left * 100) / mh->scale; + else { + right = 100 - ((right * 100) / mh->scale); + left = 100 - ((left * 100) / mh->scale); + } + + ret = left | (right << 8); + } else if (mixer == SOUND_MIXER_SPEAKER) { + ret = 100 - ((((val & 0x1e)>>1) * 100) / mh->scale); + } else if (mixer == SOUND_MIXER_MIC) { + ret = 100 - (((val & 0x1f) * 100) / mh->scale); + /* the low bit is optional in the tone sliders and masking + it lets is avoid the 0xf 'bypass'.. */ + } else if (mixer == SOUND_MIXER_BASS) { + ret = 100 - ((((val >> 8) & 0xe) * 100) / mh->scale); + } else if (mixer == SOUND_MIXER_TREBLE) { + ret = 100 - (((val & 0xe) * 100) / mh->scale); + } + + M_printk("read mixer %d (0x%x) %x -> %x\n",mixer,mh->offset,val,ret); + + return ret; +} +#endif + +/* write the OSS encoded volume to the given OSS encoded mixer, + again caller's job to make sure all is well in arg land, + call with spinlock held */ +static void ac97_write_mixer(struct ess_card *card,int mixer, unsigned int left, unsigned int right) +{ + u16 val=0; + struct ac97_mixer_hw *mh = &ac97_hw[mixer]; + + M_printk("wrote mixer %d (0x%x) %d,%d",mixer,mh->offset,left,right); + + if(AC97_STEREO_MASK & (1<scale) / 100; + left = (left * mh->scale) / 100; + } else { + right = ((100 - right) * mh->scale) / 100; + left = ((100 - left) * mh->scale) / 100; + } + + val = (left << 8) | right; + + } else if (mixer == SOUND_MIXER_SPEAKER) { + val = (((100 - left) * mh->scale) / 100) << 1; + } else if (mixer == SOUND_MIXER_MIC) { + val = maestro_ac97_get(card->iobase , mh->offset) & ~0x801f; + val |= (((100 - left) * mh->scale) / 100); + /* the low bit is optional in the tone sliders and masking + it lets is avoid the 0xf 'bypass'.. */ + } else if (mixer == SOUND_MIXER_BASS) { + val = maestro_ac97_get(card->iobase , mh->offset) & ~0x0f00; + val |= ((((100 - left) * mh->scale) / 100) << 8) & 0x0e00; + } else if (mixer == SOUND_MIXER_TREBLE) { + val = maestro_ac97_get(card->iobase , mh->offset) & ~0x000f; + val |= (((100 - left) * mh->scale) / 100) & 0x000e; + } + + maestro_ac97_set(card->iobase , mh->offset, val); + + M_printk(" -> %x\n",val); +} + +/* the following tables allow us to go from + OSS <-> ac97 quickly. */ + +enum ac97_recsettings { + AC97_REC_MIC=0, + AC97_REC_CD, + AC97_REC_VIDEO, + AC97_REC_AUX, + AC97_REC_LINE, + AC97_REC_STEREO, /* combination of all enabled outputs.. */ + AC97_REC_MONO, /*.. or the mono equivalent */ + AC97_REC_PHONE +}; + +static unsigned int ac97_rm2oss[] = { + [AC97_REC_MIC] = SOUND_MIXER_MIC, + [AC97_REC_CD] = SOUND_MIXER_CD, + [AC97_REC_VIDEO] = SOUND_MIXER_VIDEO, + [AC97_REC_AUX] = SOUND_MIXER_LINE1, + [AC97_REC_LINE] = SOUND_MIXER_LINE, + [AC97_REC_PHONE] = SOUND_MIXER_PHONEIN +}; + +/* indexed by bit position */ +static unsigned int ac97_oss_rm[] = { + [SOUND_MIXER_MIC] = AC97_REC_MIC, + [SOUND_MIXER_CD] = AC97_REC_CD, + [SOUND_MIXER_VIDEO] = AC97_REC_VIDEO, + [SOUND_MIXER_LINE1] = AC97_REC_AUX, + [SOUND_MIXER_LINE] = AC97_REC_LINE, + [SOUND_MIXER_PHONEIN] = AC97_REC_PHONE +}; + +/* read or write the recmask + the ac97 can really have left and right recording + inputs independantly set, but OSS doesn't seem to + want us to express that to the user. + the caller guarantees that we have a supported bit set, + and they must be holding the card's spinlock */ +static int ac97_recmask_io(struct ess_card *card, int rw, int mask) +{ + unsigned int val; + + if (rw) { + /* read it from the card */ + val = maestro_ac97_get(card->iobase, 0x1a) & 0x7; + return ac97_rm2oss[val]; + } + + /* else, write the first set in the mask as the + output */ + + val = ffs(mask); + val = ac97_oss_rm[val-1]; + val |= val << 8; /* set both channels */ + + M_printk("maestro: setting ac97 recmask to 0x%x\n",val); + + maestro_ac97_set(card->iobase,0x1a,val); + + return 0; +}; + /* * The Maestro can be wired to a standard AC97 compliant codec * (see www.intel.com for the pdf's on this), or to a PT101 codec @@ -360,10 +655,16 @@ * The PT101 setup is untested. */ -static u16 maestro_ac97_init(int iobase) +static u16 maestro_ac97_init(struct ess_card *card, int iobase) { - int val, seid, caps; - u16 vend1, vend2; + u16 vend1, vend2, caps; + + card->mix.supported_mixers = AC97_SUPPORTED_MASK; + card->mix.stereo_mixers = AC97_STEREO_MASK; + card->mix.record_sources = AC97_RECORD_MASK; +/* card->mix.read_mixer = ac97_read_mixer;*/ + card->mix.write_mixer = ac97_write_mixer; + card->mix.recmask_io = ac97_recmask_io; #if 0 /* this needs to be thought about harder */ /* aim at the second codec */ @@ -390,29 +691,37 @@ #endif /* perform codec reset */ - maestro_ac97_set(iobase, 0x00, 0x0000); + maestro_ac97_set(iobase, 0x00, 0xFFFF); - /* should make sure we're ac97 2.1? */ vend1 = maestro_ac97_get(iobase, 0x7c); vend2 = maestro_ac97_get(iobase, 0x7e); - val = maestro_ac97_get(iobase, 0x00); - seid = val >> 8; - caps = val & 255; + caps = maestro_ac97_get(iobase, 0x00); - printk(KERN_INFO "maestro: AC97 Codec detected: v: 0x%2x%2x 3d: 0x%x caps: 0x%x\n", - vend1,vend2,seid, caps); + printk(KERN_INFO "maestro: AC97 Codec detected: v: 0x%2x%2x caps: 0x%x pwr: 0x%x\n", + vend1,vend2,caps,maestro_ac97_get(iobase,0x26) & 0xf); + + if (! (caps & 0x4) ) { + /* no bass/treble nobs */ + card->mix.supported_mixers &= ~(SOUND_MASK_BASS|SOUND_MASK_TREBLE); + } /* XXX endianness, dork head. */ - /* magic vendor specifc init code, _no_ idea what these do */ + /* vendor specifc bits.. */ switch ((long)(vend1 << 16) | vend2) { case 0x545200ff: /* TriTech */ - + /* no idea what this does */ maestro_ac97_set(iobase,0x2a,0x0001); maestro_ac97_set(iobase,0x2c,0x0000); maestro_ac97_set(iobase,0x2c,0xffff); break; case 0x83847609: /* ESS 1921 */ + /* writing to 0xe (mic) or 0x1a (recmask) seems + to hang this codec */ + card->mix.supported_mixers &= ~(SOUND_MASK_MIC); + card->mix.record_sources = 0; + card->mix.recmask_io = NULL; + /* no idea what these do */ maestro_ac97_set(iobase,0x76,0xABBA); /* o/~ Take a chance on me o/~ */ udelay(20); maestro_ac97_set(iobase,0x78,0x3002); @@ -423,34 +732,23 @@ default: break; } - /* set master, headphone, master mono */ - maestro_ac97_set(iobase, 0x02, 0x0000); +#if 0 /* used to be set, lets try using the codec defaults */ /* always set headphones to max unmuted, OSS won't let us change it :( */ maestro_ac97_set(iobase, 0x04, 0x0000); maestro_ac97_set(iobase, 0x06, 0x0000); - maestro_ac97_set(iobase, 0x08, 0x0606); - /* beep, phone, mic, line, cd video, aux */ - maestro_ac97_set(iobase, 0x0A, 0x1F1F); maestro_ac97_set(iobase, 0x0C, 0x1F1F); - maestro_ac97_set(iobase, 0x0E, 0x1F1F); - maestro_ac97_set(iobase, 0x10, 0x1F1F); - maestro_ac97_set(iobase, 0x12, 0x1F1F); - maestro_ac97_set(iobase, 0x14, 0x1F1F); - maestro_ac97_set(iobase, 0x16, 0x1F1F); - /* unmute, but set pcm out to 1/2 */ - maestro_ac97_set(iobase, 0x18, 0x0808); /* null record select */ maestro_ac97_set(iobase, 0x1A, 0x0000); - /* record gain, record gain mic.. */ - maestro_ac97_set(iobase, 0x1C, 0x0404); +#endif maestro_ac97_set(iobase, 0x1E, 0x0404); /* null misc stuff */ maestro_ac97_set(iobase, 0x20, 0x0000); - /* power up various units? */ - maestro_ac97_set(iobase, 0x26, 0x000F); + /* the regs are read only, duh :) */ +/* maestro_ac97_set(iobase, 0x26, 0x000F);*/ - /* lets see if they actually default to the spec :) */ +#if 0 /* this is a really good way to hang + codecs. we need a better way. */ if(maestro_ac97_get(iobase,0x36) ==0x8080) { int reg; printk("maestro: your ac97 might be 2.0, see if this makes sense:\n"); @@ -458,11 +756,12 @@ printk(" 0x%2x: %4x\n",reg,maestro_ac97_get(iobase,reg)); } } +#endif return 0; } -static u16 maestro_pt101_init(int iobase) +static u16 maestro_pt101_init(struct ess_card *card,int iobase) { printk(KERN_INFO "maestro: PT101 Codec detected, initializing but _not_ installing mixer device.\n"); /* who knows.. */ @@ -493,7 +792,9 @@ mdelay(1);*/ /* well this seems to work a little - better on the 2e */ + better on my pci board.. probably + because gpio is wired to ac97 reset */ + /* this screws around with the gpio mask/input/direction.. */ outw(0x0000, ioaddr+0x36); @@ -617,12 +918,15 @@ channel&=~ESS_CHAN_HARD; else { - if(channel>3) + if(channel>5) printk("BAD CHANNEL %d.\n",channel); else channel = ess->apu[channel]; } - +#ifdef CONFIG_APM + /* store based on real hardware apu/reg */ + ess->card->apu_map[channel][reg]=data; +#endif reg|=(channel<<4); save_flags(flags); @@ -654,9 +958,8 @@ /* - * The wavecache does pci fetches for us and feeds - * them to the APUs.. - * XXX describe interface + * The wavecache buffers between the APUs and + * pci bus mastering */ static void wave_set_register(struct ess_state *ess, u16 reg, u16 value) @@ -694,9 +997,10 @@ udelay(1); } +/* sets the play formats of these apus, should be passed the already shifted format */ static void set_apu_fmt(struct ess_state *s, int apu, int mode) { - if(mode&ESS_CFMT_16BIT) { + if(mode&ESS_FMT_16BIT) { s->apu_mode[apu] = 0x10; s->apu_mode[apu+1] = 0x10; } else { @@ -705,11 +1009,12 @@ } } +/* this only fixes the output apu mode to be later set by start_dac and + company. output apu modes are set in ess_rec_setup */ static void set_fmt(struct ess_state *s, unsigned char mask, unsigned char data) { s->fmt = (s->fmt & mask) | data; - set_apu_fmt(s, 0, s->fmt & ESS_CFMT_MASK); - set_apu_fmt(s, 2, (s->fmt >> ESS_CFMT_CSHIFT) & ESS_CFMT_MASK); + set_apu_fmt(s, 0, (s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK); } static u16 compute_rate(u32 freq) @@ -732,17 +1037,19 @@ s->ratedac = rate; - if(!(s->fmt & ESS_CFMT_16BIT)) + if(!((s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_16BIT)) rate >>= 1; /* who knows */ /* M_printk("computing dac rate %d with mode %d\n",rate,s->fmt);*/ freq = compute_rate(rate); - /* Load the frequency, turn on 6dB, turn off the effects */ - apu_set_register(s, 0, 2, (freq&0xFF)<<8|0x10); + /* Load the frequency, turn on 6dB */ + apu_set_register(s, 0, 2,(apu_get_register(s, 0, 2)&0x00FF)| + ( ((freq&0xFF)<<8)|0x10 )); apu_set_register(s, 0, 3, freq>>8); - apu_set_register(s, 1, 2, (freq&0xFF)<<8|0x10); + apu_set_register(s, 1, 2,(apu_get_register(s, 1, 2)&0x00FF)| + ( ((freq&0xFF)<<8)|0x10 )); apu_set_register(s, 1, 3, freq>>8); } @@ -759,11 +1066,23 @@ freq = compute_rate(rate); - /* Load the frequency, turn on 6dB, turn off the effects */ - apu_set_register(s, 2, 2, (freq&0xFF)<<8|0x10); + /* Load the frequency, turn on 6dB */ + apu_set_register(s, 2, 2,(apu_get_register(s, 2, 2)&0x00FF)| + ( ((freq&0xFF)<<8)|0x10 )); apu_set_register(s, 2, 3, freq>>8); - apu_set_register(s, 3, 2, (freq&0xFF)<<8|0x10); + apu_set_register(s, 3, 2,(apu_get_register(s, 3, 2)&0x00FF)| + ( ((freq&0xFF)<<8)|0x10 )); apu_set_register(s, 3, 3, freq>>8); + + /* fix mixer rate at 48khz. and its _must_ be 0x10000. */ + freq = 0x10000; + + apu_set_register(s, 4, 2,(apu_get_register(s, 4, 2)&0x00FF)| + ( ((freq&0xFF)<<8)|0x10 )); + apu_set_register(s, 4, 3, freq>>8); + apu_set_register(s, 5, 2,(apu_get_register(s, 5, 2)&0x00FF)| + ( ((freq&0xFF)<<8)|0x10 )); + apu_set_register(s, 5, 3, freq>>8); } @@ -771,6 +1090,7 @@ * Native play back driver */ +/* the mode passed should be already shifted and masked */ static void ess_play_setup(struct ess_state *ess, int mode, u32 rate, void *buffer, int size) { u32 pa; @@ -786,7 +1106,7 @@ /* we're given the full size of the buffer, but in stereo each channel will only play its half */ - if(mode&ESS_CFMT_STEREO) { + if(mode&ESS_FMT_STEREO) { size >>=1; high_apu++; } @@ -825,9 +1145,8 @@ *2 accomodates for rampant shifting earlier */ pa = virt_to_bus(buffer + size*2); - M_printk("sending pa %x to %d\n",pa,channel); - - wave_set_register(ess, 0x01FC, (pa&0xFFE00000)>>12); + /* play bufs are in the same first region as record bufs */ + wave_set_register(ess, 0x01FC , (pa&0xFFE00000)>>12); /* set the wavecache control reg */ tmpval = (pa - 0x10) & 0xFFF8; @@ -845,7 +1164,7 @@ if(!channel) ess->dma_dac.base = pa&0xFFFF; #if 0 - if(mode&ESS_CFMT_STEREO) /* Enable stereo */ + if(mode&ESS_FMT_STEREO) /* Enable stereo */ pa|=0x00800000; #endif pa|=0x00400000; /* System RAM */ @@ -854,11 +1173,8 @@ for(i=0;i<15;i++) /* clear all PBRs */ apu_set_register(ess, channel, i, 0x0000); - /* Load the frequency, turn on 6dB, turn off the effects */ -/* apu_set_register(ess, channel, 2, (rate&0xFF)<<8|0x10); - apu_set_register(ess, channel, 3, rate>>8);*/ - /* XXX think about endianess when writing these registers */ + M_printk("maestro: ess_play_setup: APU[%d] pa = 0x%x\n", ess->apu[channel], pa); /* Load the buffer into the wave engine */ apu_set_register(ess, channel, 4, ((pa>>16)&0xFF)<<8); apu_set_register(ess, channel, 5, pa&0xFFFF); @@ -878,7 +1194,7 @@ /* mark dma and turn on filter stuff? */ apu_set_register(ess, channel, 0, 0x400F); - if(mode&ESS_CFMT_STEREO) + if(mode&ESS_FMT_STEREO) /* set panning: left or right */ apu_set_register(ess, channel, 10, 0x8F00 | (channel ? 0x10 : 0)); else @@ -896,7 +1212,7 @@ for(channel=0; channel<=high_apu; channel++) { /* Turn on the DMA */ - if(mode&ESS_CFMT_16BIT) + if(mode&ESS_FMT_16BIT) { apu_set_register(ess, channel, 0, (apu_get_register(ess, channel, 0)&0xFF0F)|0x10); @@ -911,14 +1227,160 @@ } } +/* + * Native record driver + */ + +/* again, passed mode is alrady shifted/masked */ +static void ess_rec_setup(struct ess_state *ess, int mode, u32 rate, void *buffer, int size) +{ + int apu_step = 2; + int channel; + u8 apu_type; + + M_printk("maestro: ess_rec_setup: mode=%d rate=%d buf=0x%p len=%d.\n", + mode, rate, buffer, size); + + /* all maestro sizes are in 16bit words */ + size >>=1; + + /* we're given the full size of the buffer, but + in stereo each channel will only use its half */ + if(mode&ESS_FMT_STEREO) { + size >>=1; + apu_step = 1; + } + + /* APU assignments: 2 = mono/left SRC + 3 = right SRC + 4 = mono/left Input Mixer + 5 = right Input Mixer */ + for(channel=2;channel<6;channel+=apu_step) + { + int i; + int bsize, route; + u32 pa; + u32 tmpval; + + /* data seems to flow from the codec, through an apu into + the 'mixbuf' bit of page, then through the SRC apu + and out to the real 'buffer'. ok. sure. */ + + if(channel & 0x04) { + /* ok, we're an input mixer going from adc + through the mixbuf to the other apus */ + + if(!(channel & 0x01)) { + pa = virt_to_bus(ess->mixbuf); + } else { + pa = virt_to_bus(ess->mixbuf + (PAGE_SIZE >> 4)); + } + + /* we source from a 'magic' apu */ + bsize = PAGE_SIZE >> 5; /* half of this channels alloc, in words */ + route = 0x14 + (channel - 4); /* parallel in crap, see maestro reg 0xC [8-11] */ + + } else { + /* we're a rate converter taking + input from the input apus and outputing it to + system memory */ + if(!(channel & 0x01)) { + pa = virt_to_bus(buffer); + } else { + /* right channel records its split half. + *2 accomodates for rampant shifting earlier */ + pa = virt_to_bus(buffer + size*2); + } + + bsize = size; + /* get input from inputing apu */ + route = channel + 2; + } + + M_printk("maestro: ess_rec_setup: getting pa 0x%x from %d\n",pa,channel); + + /* put our base address in the right region */ + wave_set_register(ess, 0x01FC + (channel >> 2), (pa&0xFFE00000)>>12); + + /* set the wavecache control reg */ + tmpval = (pa - 0x10) & 0xFFF8; + wave_set_register(ess, ess->apu[channel]<<3, tmpval); + + pa&=0x1FFFFF; /* Low 21 bits*/ + pa>>=1; /* words */ + + /* base offset of dma calcs when reading the pointer + on this left one */ + if(channel==2) ess->dma_adc.base = pa&0xFFFF; + + pa|=0x00400000; /* bit 22 -> System RAM */ + + if ( channel & 4) + pa|=0x00200000; /* bit 21 -> second region for mixbuf */ + + M_printk("maestro: ess_rec_setup: APU[%d] pa = 0x%x size = 0x%x route = 0x%x\n", + ess->apu[channel], pa, bsize, route); + + /* Begin loading the APU */ + for(i=0;i<15;i++) /* clear all PBRs */ + apu_set_register(ess, channel, i, 0x0000); + + apu_set_register(ess, channel, 0, 0x400F); + + /* need to enable subgroups.. and we should probably + have different groups for different /dev/dsps.. */ + apu_set_register(ess, channel, 2, 0x8); + + /* Load the buffer into the wave engine */ + apu_set_register(ess, channel, 4, ((pa>>16)&0xFF)<<8); + /* XXX reg is little endian.. */ + apu_set_register(ess, channel, 5, pa&0xFFFF); + apu_set_register(ess, channel, 6, (pa+bsize)&0xFFFF); + apu_set_register(ess, channel, 7, bsize); + + /* clear effects/env.. */ + apu_set_register(ess, channel, 8, 0x00F0); + + /* amplitude now? sure. why not. */ + apu_set_register(ess, channel, 9, 0x0000); + + /* set filter tune, radius, polar pan */ + apu_set_register(ess, channel, 10, 0x8F08); + + /* route input */ + apu_set_register(ess, channel, 11, route); + } + + /* clear WP interupts */ + outw(1, ess->card->iobase+0x04); + /* enable WP ints */ + outw(inw(ess->card->iobase+0x18)|4, ess->card->iobase+0x18); + + set_adc_rate(ess,rate); + + for(channel=2; channel<6; channel+=apu_step) + { + if(channel & 0x04) { + apu_type = 0x90; /* Input Mixer */ + } else { + apu_type = 0xB0; /* Sample Rate Converter */ + } + + apu_set_register(ess, channel, 0, + (apu_get_register(ess, channel, 0)&0xFF0F) | apu_type); + ess->apu_mode[channel] = apu_type; + } +} /* --------------------------------------------------------------------- */ static void set_dmaa(struct ess_state *s, unsigned int addr, unsigned int count) { + M_printk("set_dmaa??\n"); } static void set_dmac(struct ess_state *s, unsigned int addr, unsigned int count) { + M_printk("set_dmac??\n"); } /* Playback pointer */ @@ -932,11 +1394,11 @@ outw(0, ioport+2); offset=inw(ioport); -/* M_printk("dmaa: offset: %d, base: %d\n",offset,s->dma_dac.base);*/ +/* M_printk("dmaa: offset: %d, base: %d\n",offset,s->dma_dac.base); */ offset-=s->dma_dac.base; - return (offset&0xFFFE)/*<<1*/; /* XXX printk didn't have it */ + return (offset&0xFFFE)<<1; /* hardware is in words */ } /* Record pointer */ @@ -949,8 +1411,11 @@ outw(s->apu[2]<<4|5, ioport); outw(0, ioport+2); offset=inw(ioport); + +/* M_printk("dmac: offset: %d, base: %d\n",offset,s->dma_adc.base); */ /* The offset is an address not a position relative to base */ + offset-=s->dma_adc.base; return (offset&0xFFFE)<<1; /* hardware is in words */ } @@ -961,64 +1426,6 @@ static void ess_interrupt(int irq, void *dev_id, struct pt_regs *regs); -#define ESS_HW_TIMER - -#ifndef ESS_HW_TIMER - -/* old kernel timer based timer ints, should BOB prove flakey */ - -static struct timer_list tmp_timer; - -static int bob_stopped; - -static void ess_interrupt_fake(unsigned long v) -{ - ess_interrupt(5, (void *)v, NULL); - del_timer(&tmp_timer); - if(!bob_stopped) - { - tmp_timer.expires=jiffies+1; - add_timer(&tmp_timer); - } - else - M_printk("Stopping bob (SW)\n"); -} - -static void stop_bob(struct ess_state *s) -{ - bob_stopped=1; -} - -static void kill_bob(struct ess_state *s) -{ - del_timer(&tmp_timer); - M_printk("Killing bob (SW)\n"); -} - -static void start_bob(struct ess_state *s) -{ - static int init=1; - if(init) - { - init=0; - init_timer(&tmp_timer); - tmp_timer.function = ess_interrupt_fake; - } - bob_stopped = 0; - if(!timer_pending(&tmp_timer)) - { - del_timer(&tmp_timer); - tmp_timer.expires = jiffies+1; - tmp_timer.data = (unsigned long)s->card; - add_timer(&tmp_timer); - M_printk("Starting bob (SW)\n"); - } -} - -#else - -/* nice HW BOB implementation. */ - static void stop_bob(struct ess_state *s) { /* Mask IDR 11,17 */ @@ -1035,9 +1442,8 @@ int prescale; int divide; - int freq = 200; /* requested frequency - calculate what we want here. */ - - stop_bob(s); /* make sure bob's not already running */ + /* XXX make freq selector much smarter, see calc_bob_rate */ + int freq = 150; /* requested frequency - calculate what we want here. */ /* compute ideal interrupt frequency for buffer size & play rate */ /* first, find best prescaler value to match freq */ @@ -1073,26 +1479,69 @@ maestro_write(s, 0x11, maestro_read(s, 0x11)|1); maestro_write(s, 0x17, maestro_read(s, 0x17)|1); } -#endif /* ESS_HW_TIMER */ /* --------------------------------------------------------------------- */ -static int adc_active = 0; +/* this quickly calculates the frequency needed for bob + and sets it if its different than what bob is + currently running at. its called often so + needs to be fairly quick. */ +#define BOB_MIN 50 +#define BOB_MAX 400 +static void calc_bob_rate(struct ess_state *s) { +#if 0 /* this thing tries to set the frequency of bob such that + there are 2 interrupts / buffer walked by the dac/adc. That + is probably very wrong for people who actually care about + mid buffer positioning. it should be calculated as bytes/interrupt + and that needs to be decided :) so for now just use the static 150 + in start_bob.*/ + + unsigned int dac_rate=2,adc_rate=1,newrate; + static int israte=-1; + + if (s->dma_dac.fragsize == 0) dac_rate = BOB_MIN; + else { + dac_rate = (2 * s->ratedac * sample_size[(s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK]) / + (s->dma_dac.fragsize) ; + } + + if (s->dma_adc.fragsize == 0) adc_rate = BOB_MIN; + else { + adc_rate = (2 * s->rateadc * sample_size[(s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK]) / + (s->dma_adc.fragsize) ; + } + + if(dac_rate > adc_rate) newrate = adc_rate; + else newrate=dac_rate; + + if(newrate > BOB_MAX) newrate = BOB_MAX; + else { + if(newrate < BOB_MIN) + newrate = BOB_MIN; + } + + if( israte != newrate) { + printk("dac: %d adc: %d rate: %d\n",dac_rate,adc_rate,israte); + israte=newrate; + } +#endif + +} +/* Stop our host of recording apus */ extern inline void stop_adc(struct ess_state *s) { unsigned long flags; spin_lock_irqsave(&s->lock, flags); - /* Stop left and right recording APU */ s->enable &= ~ADC_RUNNING; apu_set_register(s, 2, 0, apu_get_register(s, 2, 0)&0xFF0F); apu_set_register(s, 3, 0, apu_get_register(s, 3, 0)&0xFF0F); - adc_active&=~1; -/* if(!adc_active) - stop_bob(s); */ + apu_set_register(s, 4, 0, apu_get_register(s, 2, 0)&0xFF0F); + apu_set_register(s, 5, 0, apu_get_register(s, 3, 0)&0xFF0F); spin_unlock_irqrestore(&s->lock, flags); } +/* stop output apus */ extern inline void stop_dac(struct ess_state *s) { unsigned long flags; @@ -1101,9 +1550,6 @@ s->enable &= ~DAC_RUNNING; apu_set_register(s, 0, 0, apu_get_register(s, 0, 0)&0xFF0F); apu_set_register(s, 1, 0, apu_get_register(s, 1, 0)&0xFF0F); - adc_active&=~2; -/* if(!adc_active) - stop_bob(s); */ spin_unlock_irqrestore(&s->lock, flags); } @@ -1118,13 +1564,10 @@ apu_set_register(s, 0, 0, (apu_get_register(s, 0, 0)&0xFF0F)|s->apu_mode[0]); - if(s->fmt & ESS_CFMT_STEREO) + if((s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_STEREO) apu_set_register(s, 1, 0, (apu_get_register(s, 1, 0)&0xFF0F)|s->apu_mode[1]); } -/* if(!adc_active) - start_bob(s);*/ - adc_active|=2; spin_unlock_irqrestore(&s->lock, flags); } @@ -1138,25 +1581,31 @@ s->enable |= ADC_RUNNING; apu_set_register(s, 2, 0, (apu_get_register(s, 2, 0)&0xFF0F)|s->apu_mode[2]); - apu_set_register(s, 3, 0, - (apu_get_register(s, 3, 0)&0xFF0F)|s->apu_mode[3]); + apu_set_register(s, 4, 0, + (apu_get_register(s, 4, 0)&0xFF0F)|s->apu_mode[4]); + if( s->fmt & (ESS_FMT_STEREO << ESS_ADC_SHIFT)) { + apu_set_register(s, 3, 0, + (apu_get_register(s, 3, 0)&0xFF0F)|s->apu_mode[3]); + apu_set_register(s, 5, 0, + (apu_get_register(s, 5, 0)&0xFF0F)|s->apu_mode[5]); + } + } -/* if(!adc_active) - start_bob(s); */ - adc_active|=1; spin_unlock_irqrestore(&s->lock, flags); } /* --------------------------------------------------------------------- */ +/* we allocate both buffers at once */ #define DMABUF_DEFAULTORDER (15-PAGE_SHIFT) -#define DMABUF_MINORDER 1 +#define DMABUF_MINORDER 2 static void dealloc_dmabuf(struct dmabuf *db) { unsigned long map, mapend; if (db->rawbuf) { + M_printk("maestro: freeing %p\n",db->rawbuf); /* undo marking the pages as reserved */ mapend = MAP_NR(db->rawbuf + (PAGE_SIZE << db->buforder) - 1); for (map = MAP_NR(db->rawbuf); map <= mapend; map++) @@ -1167,7 +1616,6 @@ db->mapped = db->ready = 0; } - static int prog_dmabuf(struct ess_state *s, unsigned rec) { struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac; @@ -1183,38 +1631,54 @@ fmt = s->fmt; if (rec) { s->enable &= ~ESS_ENABLE_RE; - fmt >>= ESS_CFMT_CSHIFT; + fmt >>= ESS_ADC_SHIFT; } else { s->enable &= ~ESS_ENABLE_PE; - fmt >>= ESS_CFMT_ASHIFT; + fmt >>= ESS_DAC_SHIFT; } spin_unlock_irqrestore(&s->lock, flags); + fmt &= ESS_FMT_MASK; db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0; if (!db->rawbuf) { - db->ready = db->mapped = 0; + void *rawbuf; + /* haha, this thing is hacked to hell and back. + this is so ugly. */ + s->dma_dac.ready = s->dma_dac.mapped = 0; + s->dma_adc.ready = s->dma_adc.mapped = 0; /* alloc as big a chunk as we can */ for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--) - if((db->rawbuf = (void *)__get_free_pages(GFP_KERNEL|GFP_DMA, order))) + if((rawbuf = (void *)__get_free_pages(GFP_KERNEL|GFP_DMA, order))) + break; - if (!db->rawbuf) + if (!rawbuf) return -ENOMEM; - db->buforder = order; - if ((virt_to_bus(db->rawbuf) ^ (virt_to_bus(db->rawbuf) + (PAGE_SIZE << db->buforder) - 1)) & ~0xffff) + /* we allocated both buffers */ + s->dma_adc.rawbuf = rawbuf; + s->dma_dac.rawbuf = rawbuf + ( PAGE_SIZE << (order - 1) ); + + M_printk("maestro: allocated %ld bytes at %p\n",PAGE_SIZE<rawbuf); + + s->dma_adc.buforder = s->dma_dac.buforder = order - 1; + + /* XXX these checks are silly now */ +#if 0 + if ((virt_to_bus(db->rawbuf) ^ (virt_to_bus(db->rawbuf) + (PAGE_SIZE << order) - 1)) & ~0xffff) printk(KERN_DEBUG "maestro: DMA buffer crosses 64k boundary: busaddr 0x%lx size %ld\n", - virt_to_bus(db->rawbuf), PAGE_SIZE << db->buforder); + virt_to_bus(db->rawbuf), PAGE_SIZE << order); - if ((virt_to_bus(db->rawbuf) + (PAGE_SIZE << db->buforder) - 1) & ~0xffffff) +#endif + if ((virt_to_bus(db->rawbuf) + (PAGE_SIZE << order) - 1) & ~0xffffff) printk(KERN_DEBUG "maestro: DMA buffer beyond 16MB: busaddr 0x%lx size %ld\n", - virt_to_bus(db->rawbuf), PAGE_SIZE << db->buforder); + virt_to_bus(db->rawbuf), PAGE_SIZE << order); /* now mark the pages as reserved; otherwise remap_page_range doesn't do what we want */ - mapend = MAP_NR(db->rawbuf + (PAGE_SIZE << db->buforder) - 1); + mapend = MAP_NR(db->rawbuf + (PAGE_SIZE << order) - 1); for (map = MAP_NR(db->rawbuf); map <= mapend; map++) set_bit(PG_reserved, &mem_map[map].flags); } @@ -1226,9 +1690,13 @@ else db->fragshift = db->ossfragshift; } else { + /* lets hand out reasonable big ass buffers by default */ + db->fragshift = (db->buforder + PAGE_SHIFT -2); +#if 0 db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1)); if (db->fragshift < 3) - db->fragshift = 3; + db->fragshift = 3; +#endif } db->numfrag = bufs >> db->fragshift; while (db->numfrag < 4 && db->fragshift > 3) { @@ -1240,29 +1708,28 @@ db->numfrag = db->ossmaxfrags; db->fragsamples = db->fragsize >> sample_shift[fmt]; db->dmasize = db->numfrag << db->fragshift; - memset(db->rawbuf, (fmt & ESS_CFMT_16BIT) ? 0 : 0x80, db->dmasize); + + memset(db->rawbuf, (fmt & ESS_FMT_16BIT) ? 0 : 0x80, db->dmasize); + spin_lock_irqsave(&s->lock, flags); if (rec) { - set_dmac(s, virt_to_bus(db->rawbuf), db->numfrag << db->fragshift); - /* program enhanced mode registers */ - /* FILL */ + ess_rec_setup(s, fmt, s->rateadc, + db->rawbuf, db->numfrag << db->fragshift); } else { - /* set_dmaa(s, virt_to_bus(db->rawbuf), db->numfrag << db->fragshift); */ - /* program enhanced mode registers */ - /* FILL */ - /*set_dac_rate(s, s->ratedac); redundant */ ess_play_setup(s, fmt, s->ratedac, db->rawbuf, db->numfrag << db->fragshift); } spin_unlock_irqrestore(&s->lock, flags); db->ready = 1; + return 0; } /* XXX haha, way broken with our split stereo setup. giggle. */ +/* only called by ess_write (dac ness ) */ extern __inline__ void clear_advance(struct ess_state *s) { - unsigned char c = (s->fmt & (ESS_CFMT_16BIT << ESS_CFMT_ASHIFT)) ? 0 : 0x80; + unsigned char c = ((s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_16BIT) ? 0 : 0x80; unsigned char *buf = s->dma_dac.rawbuf; unsigned bsize = s->dma_dac.dmasize; unsigned bptr = s->dma_dac.swptr; @@ -1284,10 +1751,18 @@ unsigned hwptr; int diff; -/* ADC is way broken. compare to DAC.. */ /* update ADC pointer */ if (s->dma_adc.ready) { - hwptr = (/*s->dma_adc.dmasize - */get_dmac(s)) % s->dma_adc.dmasize; + /* oh boy should this all be re-written. everything in the current code paths think + that the various counters/pointers are expressed in bytes to the user but we have + two apus doing stereo stuff so we fix it up here.. it propogates to all the various + counters from here. Notice that this means that mono recording is very very + broken right now. */ + if ( s->fmt & (ESS_FMT_STEREO << ESS_ADC_SHIFT)) { + hwptr = (get_dmac(s)*2) % s->dma_adc.dmasize; + } else { + hwptr = get_dmac(s) % s->dma_adc.dmasize; + } diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize; s->dma_adc.hwptr = hwptr; s->dma_adc.total_bytes += diff; @@ -1314,8 +1789,9 @@ s->dma_dac.total_bytes += diff; if (s->dma_dac.mapped) { s->dma_dac.count += diff; - if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) + if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) { wake_up(&s->dma_dac.wait); + } } else { s->dma_dac.count -= diff; /* M_printk("maestro: ess_update_ptr: diff: %d, count: %d\n", diff, s->dma_dac.count); */ @@ -1334,8 +1810,9 @@ clear_advance(s); s->dma_dac.endcleared = 1; } - if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize) + if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize) { wake_up(&s->dma_dac.wait); + } } } } @@ -1347,8 +1824,8 @@ int i; u32 event; - event = inb(c->iobase+0x1A); - + if ( ! (event = inb(c->iobase+0x1A)) ) return; + outw(inw(c->iobase+4)&1, c->iobase+4); /* M_printk("maestro int: %x\n",event);*/ @@ -1358,221 +1835,59 @@ /* XXX if we have a hw volume control int enable all the ints? doesn't make sense.. */ event = inw(c->iobase+0x18); - outb(0xFF, c->iobase+0x1A); - } - else - { - /* else ack 'em all, i imagine */ - outb(0xFF, c->iobase+0x1A); - } - - /* - * Update the pointers for all APU's we are running. - */ - for(i=0;i<8;i++) - { - s=&c->channels[i]; - if(s->dev_audio == -1) - break; - spin_lock(&s->lock); - ess_update_ptr(s); - spin_unlock(&s->lock); - } -} - - -/* --------------------------------------------------------------------- */ - -static const char invalid_magic[] = KERN_CRIT "maestro: invalid magic value in %s\n"; - -#define VALIDATE_MAGIC(FOO,MAG) \ -({ \ - if (!(FOO) || (FOO)->magic != MAG) { \ - printk(invalid_magic,__FUNCTION__); \ - return -ENXIO; \ - } \ -}) - -#define VALIDATE_STATE(a) VALIDATE_MAGIC(a,ESS_STATE_MAGIC) -#define VALIDATE_CARD(a) VALIDATE_MAGIC(a,ESS_CARD_MAGIC) - -/* --------------------------------------------------------------------- */ - -/* ac97 mixer routines. */ - -#define AC97_STEREO_MASK (SOUND_MASK_VOLUME|\ - SOUND_MASK_PCM|SOUND_MASK_LINE|SOUND_MASK_CD|\ - SOUND_MASK_VIDEO|SOUND_MASK_LINE1|SOUND_MASK_IGAIN) - -#define AC97_SUPPORTED_MASK (AC97_STEREO_MASK | \ - SOUND_MASK_BASS|SOUND_MASK_TREBLE|SOUND_MASK_MIC|\ - SOUND_MASK_SPEAKER) - -#define AC97_RECORD_MASK (SOUND_MASK_MIC|\ - SOUND_MASK_CD| SOUND_MASK_VIDEO| SOUND_MASK_LINE1| SOUND_MASK_LINE|\ - SOUND_MASK_PHONEIN) - -#define supported_mixer(CARD,FOO) ( CARD->mix.supported_mixers & (1<iobase , mh->offset); - - if(AC97_STEREO_MASK & (1<> 8) & 0x7f; - right = val & 0x7f; - - right = 100 - ((right * 100) / mh->scale); - left = 100 - ((left * 100) / mh->scale); - ret = left | (right << 8); - } else if (mixer == SOUND_MIXER_SPEAKER) { - ret = 100 - ((((val & 0x1e)>>1) * 100) / mh->scale); - } else if (mixer == SOUND_MIXER_MIC) { - ret = 100 - (((val & 0x1f) * 100) / mh->scale); - /* the low bit is optional in the tone sliders and masking - it lets is avoid the 0xf 'bypass'.. */ - } else if (mixer == SOUND_MIXER_BASS) { - ret = 100 - ((((val >> 8) & 0xe) * 100) / mh->scale); - } else if (mixer == SOUND_MIXER_TREBLE) { - ret = 100 - (((val & 0xe) * 100) / mh->scale); - } - - M_printk("read mixer %d (0x%x) %x -> %x\n",mixer,mh->offset,val,ret); - - return ret; -} - -/* write the OSS encoded volume to the given OSS encoded mixer, - again caller's job to make sure all is well in arg land, - call with spinlock held */ -static void ac97_write_mixer(struct ess_card *card,int mixer, int vol) -{ - u16 val=0; - unsigned left, right; - struct ac97_mixer_hw *mh = &ac97_hw[mixer]; - - /* cleanse input a little */ - right = ((vol >> 8) & 0x7f) ; - left = (vol & 0x7f) ; - - if(right > 100) right = 100; - if(left > 100) left = 100; - - M_printk("wrote mixer %d (0x%x) %d,%d",mixer,mh->offset,left,right); - - if(AC97_STEREO_MASK & (1<scale) / 100; - left = ((100 - left) * mh->scale) / 100; - - val = (left << 8) | right; - } else if (mixer == SOUND_MIXER_SPEAKER) { - val = (((100 - left) * mh->scale) / 100) << 1; - } else if (mixer == SOUND_MIXER_MIC) { - val = maestro_ac97_get(card->iobase , mh->offset) & ~0x001f; - val |= (((100 - left) * mh->scale) / 100); - /* the low bit is optional in the tone sliders and masking - it lets is avoid the 0xf 'bypass'.. */ - } else if (mixer == SOUND_MIXER_BASS) { - val = maestro_ac97_get(card->iobase , mh->offset) & ~0x0f00; - val |= ((((100 - left) * mh->scale) / 100) << 8) & 0xe0; - } else if (mixer == SOUND_MIXER_TREBLE) { - val = maestro_ac97_get(card->iobase , mh->offset) & ~0x000f; - val |= (((100 - left) * mh->scale) / 100) & 0xe; + outb(0xFF, c->iobase+0x1A); + } + else + { + /* else ack 'em all, i imagine */ + outb(0xFF, c->iobase+0x1A); + } + + /* + * Update the pointers for all APU's we are running. + */ + for(i=0;ichannels[i]; + if(s->dev_audio == -1) + break; + spin_lock(&s->lock); + ess_update_ptr(s); + spin_unlock(&s->lock); } - - maestro_ac97_set(card->iobase , mh->offset, val); - - M_printk(" -> %x\n",val); } -enum ac97_recsettings { - AC97_REC_MIC=0, - AC97_REC_CD, - AC97_REC_VIDEO, - AC97_REC_AUX, - AC97_REC_LINE, - AC97_REC_STEREO, /* combination of all enabled outputs.. */ - AC97_REC_MONO, /*.. or the mono equivalent */ - AC97_REC_PHONE -}; -static unsigned int ac97_rm2oss[] = { - [AC97_REC_MIC] = SOUND_MASK_MIC, - [AC97_REC_CD] = SOUND_MASK_CD, - [AC97_REC_VIDEO] = SOUND_MASK_VIDEO, - [AC97_REC_AUX] = SOUND_MASK_LINE1, - [AC97_REC_LINE] = SOUND_MASK_LINE, - [AC97_REC_PHONE] = SOUND_MASK_PHONEIN -}; -/* indexed by bit position, XXX dependant on OSS header internals */ -static unsigned int ac97_oss_rm[] = { - [SOUND_MIXER_MIC] = AC97_REC_MIC, - [SOUND_MIXER_CD] = AC97_REC_CD, - [SOUND_MIXER_VIDEO] = AC97_REC_VIDEO, - [SOUND_MIXER_LINE1] = AC97_REC_AUX, - [SOUND_MIXER_LINE] = AC97_REC_LINE, - [SOUND_MIXER_PHONEIN] = AC97_REC_PHONE -}; - -/* read or write the recmask - the ac97 can really have left and right recording - inputs independantly set, but OSS doesn't seem to - want us to express that to the user. - the caller guarantees that we have a supported bit set, - and they must be holding the card's spinlock */ -static int ac97_recmask_io(struct ess_card *card, int rw, int mask) -{ - unsigned int val; +/* --------------------------------------------------------------------- */ - if (rw) { - /* read it from the card */ - val = maestro_ac97_get(card->iobase, 0x1a) & 0x7; - return ac97_rm2oss[val]; - } +static const char invalid_magic[] = KERN_CRIT "maestro: invalid magic value in %s\n"; - /* else, write the first set in the mask as the - output */ +#define VALIDATE_MAGIC(FOO,MAG) \ +({ \ + if (!(FOO) || (FOO)->magic != MAG) { \ + printk(invalid_magic,__FUNCTION__); \ + return -ENXIO; \ + } \ +}) - val = ffs(mask); - val = ac97_oss_rm[val-1]; - val |= val << 8; /* set both channels */ +#define VALIDATE_STATE(a) VALIDATE_MAGIC(a,ESS_STATE_MAGIC) +#define VALIDATE_CARD(a) VALIDATE_MAGIC(a,ESS_CARD_MAGIC) - maestro_ac97_set(card->iobase,0x1a,val); +static void set_mixer(struct ess_card *card,unsigned int mixer, unsigned int val ) +{ + unsigned int left,right; + /* cleanse input a little */ + right = ((val >> 8) & 0xff) ; + left = (val & 0xff) ; - return 0; -}; + if(right > 100) right = 100; + if(left > 100) left = 100; -static int ac97_mixer_ioctl(struct ess_card *card, unsigned int cmd, unsigned long arg) + card->mix.mixer_state[mixer]=(right << 8) | left; + card->mix.write_mixer(card,mixer,left,right); +} + +static int mixer_ioctl(struct ess_card *card, unsigned int cmd, unsigned long arg) { unsigned long flags; int i, val=0; @@ -1605,9 +1920,14 @@ if (_IOC_DIR(cmd) == _IOC_READ) { switch (_IOC_NR(cmd)) { case SOUND_MIXER_RECSRC: /* give them the current record source */ - spin_lock_irqsave(&s->lock, flags); - val = card->mix.recmask_io(card,1,0); - spin_unlock_irqrestore(&s->lock, flags); + + if(!card->mix.recmask_io) { + val = 0; + } else { + spin_lock_irqsave(&s->lock, flags); + val = card->mix.recmask_io(card,1,0); + spin_unlock_irqrestore(&s->lock, flags); + } break; case SOUND_MIXER_DEVMASK: /* give them the supported mixers */ @@ -1632,9 +1952,13 @@ if ( ! supported_mixer(card,i)) return -EINVAL; - spin_lock_irqsave(&s->lock, flags); + /* do we ever want to touch the hardware? */ +/* spin_lock_irqsave(&s->lock, flags); val = card->mix.read_mixer(card,i); - spin_unlock_irqrestore(&s->lock, flags); + spin_unlock_irqrestore(&s->lock, flags);*/ + + val = card->mix.mixer_state[i]; +/* M_printk("returned 0x%x for mixer %d\n",val,i);*/ break; } @@ -1651,6 +1975,7 @@ switch (_IOC_NR(cmd)) { case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ + if (!card->mix.recmask_io) return -EINVAL; if(! (val &= card->mix.record_sources)) return -EINVAL; spin_lock_irqsave(&s->lock, flags); @@ -1665,7 +1990,7 @@ return -EINVAL; spin_lock_irqsave(&s->lock, flags); - card->mix.write_mixer(card,i,val); + set_mixer(card,i,val); spin_unlock_irqrestore(&s->lock, flags); return 0; @@ -1712,7 +2037,7 @@ VALIDATE_CARD(card); - return ac97_mixer_ioctl(card, cmd, arg); + return mixer_ioctl(card, cmd, arg); } static /*const*/ struct file_operations ess_mixer_fops = { @@ -1737,9 +2062,10 @@ static int drain_dac(struct ess_state *s, int nonblock) { - DECLARE_WAITQUEUE(wait,current); + DECLARE_WAITQUEUE(wait, current); unsigned long flags; - int count, tmo; + int count; + signed long tmo; if (s->dma_dac.mapped || !s->dma_dac.ready) return 0; @@ -1759,9 +2085,11 @@ return -EBUSY; } tmo = (count * HZ) / s->ratedac; - tmo >>= sample_shift[(s->fmt >> ESS_CFMT_ASHIFT) & ESS_CFMT_MASK]; - if (!schedule_timeout(tmo ? : 1) && tmo) - printk(KERN_DEBUG "maestro: dma timed out??\n"); + tmo >>= sample_shift[(s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK]; + /* XXX this is just broken. someone is waking us up alot, or schedule_timeout is broken. + or something. who cares. - zach */ + if (!schedule_timeout(tmo ? tmo : 1) && tmo) + M_printk(KERN_DEBUG "maestro: dma timed out?? %ld\n",jiffies); } remove_wait_queue(&s->dma_dac.wait, &wait); current->state = TASK_RUNNING; @@ -1771,16 +2099,48 @@ } /* --------------------------------------------------------------------- */ +/* Zach sez: "god this is gross.." */ +int comb_stereo(unsigned char *real_buffer,unsigned char *tmp_buffer, int offset, + int count, int bufsize) +{ + /* No such thing as stereo recording, so we + use dual input mixers. which means we have to + combine mono to stereo buffer. yuck. + + but we don't have to be able to work a byte at a time..*/ + + unsigned char *so,*left,*right; + int i; + + so = tmp_buffer; + left = real_buffer + offset; + right = real_buffer + bufsize/2 + offset; +/* M_printk("comb_stereo writing %d to %p from %p and %p, offset: %d size: %d\n",count/2, tmp_buffer,left,right,offset,bufsize);*/ + + for(i=count/4; i ; i--) { + (*(so+2)) = *(right++); + (*(so+3)) = *(right++); + (*so) = *(left++); + (*(so+1)) = *(left++); + so+=4; + } + + return 0; +} + +/* in this loop, dma_adc.count signifies the amount of data thats waiting + to be copied to the user's buffer. it is filled by the interrupt + handler and drained by this loop. */ static ssize_t ess_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { struct ess_state *s = (struct ess_state *)file->private_data; ssize_t ret; unsigned long flags; unsigned swptr; - /* for damned dual players */ int cnt; - + unsigned char *combbuf = NULL; + VALIDATE_STATE(s); if (ppos != &file->f_pos) return -ESPIPE; @@ -1790,25 +2150,34 @@ return ret; if (!access_ok(VERIFY_WRITE, buffer, count)) return -EFAULT; + if(!(combbuf = kmalloc(count,GFP_KERNEL))) + return -ENOMEM; ret = 0; -#if 0 - spin_lock_irqsave(&s->lock, flags); - ess_update_ptr(s); - spin_unlock_irqrestore(&s->lock, flags); -#endif + + calc_bob_rate(s); + while (count > 0) { spin_lock_irqsave(&s->lock, flags); + /* remember, all these things are expressed in bytes to be + sent to the user.. hence the evil / 2 down below */ swptr = s->dma_adc.swptr; cnt = s->dma_adc.dmasize-swptr; if (s->dma_adc.count < cnt) cnt = s->dma_adc.count; spin_unlock_irqrestore(&s->lock, flags); + if (cnt > count) cnt = count; + + if ( cnt > 0 ) cnt &= ~3; + if (cnt <= 0) { start_adc(s); if (file->f_flags & O_NONBLOCK) - return ret ? ret : -EAGAIN; + { + ret = ret ? ret : -EAGAIN; + goto rec_return_free; + } if (!interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ)) { printk(KERN_DEBUG "maestro: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n", s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count, @@ -1824,11 +2193,27 @@ spin_unlock_irqrestore(&s->lock, flags); } if (signal_pending(current)) - return ret ? ret : -ERESTARTSYS; + { + ret = ret ? ret : -ERESTARTSYS; + goto rec_return_free; + } continue; } - if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) - return ret ? ret : -EFAULT; + + if(s->fmt & (ESS_FMT_STEREO << ESS_ADC_SHIFT)) { + /* swptr/2 so that we know the real offset in each apu's buffer */ + comb_stereo(s->dma_adc.rawbuf,combbuf,swptr/2,cnt,s->dma_adc.dmasize); + if (copy_to_user(buffer, combbuf, cnt)) { + ret = ret ? ret : -EFAULT; + goto rec_return_free; + } + } else { + if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) { + ret = ret ? ret : -EFAULT; + goto rec_return_free; + } + } + swptr = (swptr + cnt) % s->dma_adc.dmasize; spin_lock_irqsave(&s->lock, flags); s->dma_adc.swptr = swptr; @@ -1840,10 +2225,13 @@ start_adc(s); } +rec_return_free: + if(combbuf) kfree(combbuf); return ret; } /* god this is gross..*/ +/* again, the mode passed is shifted/masked */ int split_stereo(unsigned char *real_buffer,unsigned char *tmp_buffer, int offset, int count, int bufsize, int mode) { @@ -1858,9 +2246,9 @@ left = real_buffer + offset; right = real_buffer + bufsize/2 + offset; - M_printk("writing %d to %p and %p from %p:%d bufs: %d\n",count/2, left,right,real_buffer,offset,bufsize); +/* M_printk("writing %d to %p and %p from %p:%d bufs: %d\n",count/2, left,right,real_buffer,offset,bufsize);*/ - if(mode & ESS_CFMT_16BIT) { + if(mode & ESS_FMT_16BIT) { for(i=count/4; i ; i--) { *(right++) = (*(so+2)); *(right++) = (*(so+3)); @@ -1887,6 +2275,7 @@ unsigned swptr; unsigned char *splitbuf = NULL; int cnt; + int mode = (s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK; /* printk("maestro: ess_write: count %d\n", count);*/ @@ -1903,11 +2292,9 @@ if (!(splitbuf = kmalloc(count,GFP_KERNEL))) return -ENOMEM; ret = 0; -#if 0 - spin_lock_irqsave(&s->lock, flags); - ess_update_ptr(s); - spin_unlock_irqrestore(&s->lock, flags); -#endif + + calc_bob_rate(s); + while (count > 0) { spin_lock_irqsave(&s->lock, flags); @@ -1917,7 +2304,7 @@ } swptr = s->dma_dac.swptr; - if(s->fmt & ESS_CFMT_STEREO) { + if(mode & ESS_FMT_STEREO) { /* in stereo we have the 'dual' buffers.. */ cnt = ((s->dma_dac.dmasize/2)-swptr)*2; } else { @@ -1962,12 +2349,13 @@ } continue; } - if(s->fmt & ESS_CFMT_STEREO) { + if(mode & ESS_FMT_STEREO) { if (copy_from_user(splitbuf, buffer, cnt)) { if (!ret) ret = -EFAULT; goto return_free; } - split_stereo(s->dma_dac.rawbuf,splitbuf,swptr,cnt,s->dma_dac.dmasize,s->fmt); + split_stereo(s->dma_dac.rawbuf,splitbuf,swptr,cnt,s->dma_dac.dmasize, + mode); } else { if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) { if (!ret) ret = -EFAULT; @@ -1975,7 +2363,7 @@ } } - if(s->fmt & ESS_CFMT_STEREO) { + if(mode & ESS_FMT_STEREO) { /* again with the weird pointer magic*/ swptr = (swptr + (cnt/2)) % (s->dma_dac.dmasize/2); } else { @@ -2026,7 +2414,7 @@ return mask; } -/* this needs to be fixed to deal with the dualing apus/buffers */ +/* this needs to be fixed to deal with the dual apus/buffers */ #if 0 static int ess_mmap(struct file *file, struct vm_area_struct *vma) { @@ -2078,10 +2466,11 @@ case SNDCTL_DSP_SYNC: if (file->f_mode & FMODE_WRITE) - return drain_dac(s, 0/*file->f_flags & O_NONBLOCK*/); + return drain_dac(s, file->f_flags & O_NONBLOCK); return 0; case SNDCTL_DSP_SETDUPLEX: + /* XXX fix */ return 0; case SNDCTL_DSP_GETCAPS: @@ -2124,17 +2513,17 @@ stop_adc(s); s->dma_adc.ready = 0; if (val) - fmtd |= ESS_CFMT_STEREO << ESS_CFMT_CSHIFT; + fmtd |= ESS_FMT_STEREO << ESS_ADC_SHIFT; else - fmtm &= ~(ESS_CFMT_STEREO << ESS_CFMT_CSHIFT); + fmtm &= ~(ESS_FMT_STEREO << ESS_ADC_SHIFT); } if (file->f_mode & FMODE_WRITE) { stop_dac(s); s->dma_dac.ready = 0; if (val) - fmtd |= ESS_CFMT_STEREO << ESS_CFMT_ASHIFT; + fmtd |= ESS_FMT_STEREO << ESS_DAC_SHIFT; else - fmtm &= ~(ESS_CFMT_STEREO << ESS_CFMT_ASHIFT); + fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT); } set_fmt(s, fmtm, fmtd); return 0; @@ -2148,22 +2537,22 @@ stop_adc(s); s->dma_adc.ready = 0; if (val >= 2) - fmtd |= ESS_CFMT_STEREO << ESS_CFMT_CSHIFT; + fmtd |= ESS_FMT_STEREO << ESS_ADC_SHIFT; else - fmtm &= ~(ESS_CFMT_STEREO << ESS_CFMT_CSHIFT); + fmtm &= ~(ESS_FMT_STEREO << ESS_ADC_SHIFT); } if (file->f_mode & FMODE_WRITE) { stop_dac(s); s->dma_dac.ready = 0; if (val >= 2) - fmtd |= ESS_CFMT_STEREO << ESS_CFMT_ASHIFT; + fmtd |= ESS_FMT_STEREO << ESS_DAC_SHIFT; else - fmtm &= ~(ESS_CFMT_STEREO << ESS_CFMT_ASHIFT); + fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT); } set_fmt(s, fmtm, fmtd); } - return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_CFMT_STEREO << ESS_CFMT_CSHIFT) - : (ESS_CFMT_STEREO << ESS_CFMT_ASHIFT))) ? 2 : 1, (int *)arg); + return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT) + : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, (int *)arg); case SNDCTL_DSP_GETFMTS: /* Returns a mask */ return put_user(AFMT_S8|AFMT_S16_LE, (int *)arg); @@ -2176,24 +2565,28 @@ if (file->f_mode & FMODE_READ) { stop_adc(s); s->dma_adc.ready = 0; + /* fixed at 16bit for now */ + fmtd |= ESS_FMT_16BIT << ESS_ADC_SHIFT; +#if 0 if (val == AFMT_S16_LE) - fmtd |= ESS_CFMT_16BIT << ESS_CFMT_CSHIFT; + fmtd |= ESS_FMT_16BIT << ESS_ADC_SHIFT; else - fmtm &= ~(ESS_CFMT_16BIT << ESS_CFMT_CSHIFT); + fmtm &= ~(ESS_FMT_16BIT << ESS_ADC_SHIFT); +#endif } if (file->f_mode & FMODE_WRITE) { stop_dac(s); s->dma_dac.ready = 0; if (val == AFMT_S16_LE) - fmtd |= ESS_CFMT_16BIT << ESS_CFMT_ASHIFT; + fmtd |= ESS_FMT_16BIT << ESS_DAC_SHIFT; else - fmtm &= ~(ESS_CFMT_16BIT << ESS_CFMT_ASHIFT); + fmtm &= ~(ESS_FMT_16BIT << ESS_DAC_SHIFT); } set_fmt(s, fmtm, fmtd); } return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? - (ESS_CFMT_16BIT << ESS_CFMT_CSHIFT) - : (ESS_CFMT_16BIT << ESS_CFMT_ASHIFT))) ? + (ESS_FMT_16BIT << ESS_ADC_SHIFT) + : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? AFMT_S16_LE : AFMT_S8, (int *)arg); @@ -2347,12 +2740,12 @@ return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg); case SOUND_PCM_READ_CHANNELS: - return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_CFMT_STEREO << ESS_CFMT_CSHIFT) - : (ESS_CFMT_STEREO << ESS_CFMT_ASHIFT))) ? 2 : 1, (int *)arg); + return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT) + : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, (int *)arg); case SOUND_PCM_READ_BITS: - return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_CFMT_16BIT << ESS_CFMT_CSHIFT) - : (ESS_CFMT_16BIT << ESS_CFMT_ASHIFT))) ? 16 : 8, (int *)arg); + return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_16BIT << ESS_ADC_SHIFT) + : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 16 : 8, (int *)arg); case SOUND_PCM_WRITE_FILTER: case SNDCTL_DSP_SETSYNCRO: @@ -2378,7 +2771,7 @@ while (c!=NULL) { - for(i=0;i<8;i++) + for(i=0;ichannels[i]; if(sp->dev_audio < 0) @@ -2409,22 +2802,32 @@ down(&s->open_sem); } if (file->f_mode & FMODE_READ) { - fmtm &= ~((ESS_CFMT_STEREO | ESS_CFMT_16BIT) << ESS_CFMT_CSHIFT); +/* + fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_ADC_SHIFT); if ((minor & 0xf) == SND_DEV_DSP16) - fmts |= ESS_CFMT_16BIT << ESS_CFMT_CSHIFT; + fmts |= ESS_FMT_16BIT << ESS_ADC_SHIFT; */ + + fmtm = (ESS_FMT_STEREO|ESS_FMT_16BIT) << ESS_ADC_SHIFT; + s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0; set_adc_rate(s, 8000); } if (file->f_mode & FMODE_WRITE) { - fmtm &= ~((ESS_CFMT_STEREO | ESS_CFMT_16BIT) << ESS_CFMT_ASHIFT); + fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_DAC_SHIFT); if ((minor & 0xf) == SND_DEV_DSP16) - fmts |= ESS_CFMT_16BIT << ESS_CFMT_ASHIFT; + fmts |= ESS_FMT_16BIT << ESS_DAC_SHIFT; s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0; set_dac_rate(s, 8000); } set_fmt(s, fmtm, fmts); s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); - start_bob(s); + + /* we're covered by the open_sem */ + if( ! s->card->bob_running ) + start_bob(s); + s->card->bob_running++; + M_printk("maestro: open, %d bobs now\n",s->card->bob_running); + up(&s->open_sem); MOD_INC_USE_COUNT; return 0; @@ -2440,14 +2843,21 @@ down(&s->open_sem); if (file->f_mode & FMODE_WRITE) { stop_dac(s); - dealloc_dmabuf(&s->dma_dac); } if (file->f_mode & FMODE_READ) { stop_adc(s); - dealloc_dmabuf(&s->dma_adc); } + + /* free our shared dma buffers */ + dealloc_dmabuf(&s->dma_adc); + dealloc_dmabuf(&s->dma_dac); + s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); - stop_bob(s); + /* we're covered by the open_sem */ + M_printk("maestro: %d -1 bob clients\n",s->card->bob_running); + if( --s->card->bob_running <= 0) { + stop_bob(s); + } up(&s->open_sem); wake_up(&s->open_wait); MOD_DEC_USE_COUNT; @@ -2472,35 +2882,85 @@ NULL, /* lock */ }; +#ifdef CONFIG_APM +int maestro_apm_callback(apm_event_t ae) { -/* --------------------------------------------------------------------- */ + struct ess_card *s; -/* XXX get rid of this - * maximum number of devices - */ -#define NR_DEVICE 4 + if(ae != APM_USER_SUSPEND) + return 0; + + printk("suspending.. blowing away apus\n"); + + while ((s = devs)) { + int i; + devs = devs->next; + + for(i=0;ichannels[i]; + int j; + + if(ess->dev_audio == -1) + continue; + + for(j=0;j<6;j++) { + apu_set_register(ess, ess->apu[j], 0, + (apu_get_register(ess, ess->apu[j], 0)&0xFF0F)); + } + + } + } + if(devs) { + printk("suspending.. stopping bob\n"); + stop_bob(devs); + } + + return 0; +} +#endif +void free_mixpage(struct ess_card *card) { + if (card->mixpage) { + /* undo marking the page as reserved */ + clear_bit(PG_reserved, &mem_map[MAP_NR(card->mixpage)].flags); + /* free mixpage */ + free_pages((unsigned long)card->mixpage, 1); + } +} /* --------------------------------------------------------------------- */ -static int maestro_install(struct pci_dev *pcidev, int card_type, int index) +static int maestro_install(struct pci_dev *pcidev, int card_type) { u16 w; -/* u32 n;*/ + u32 n; int iobase; int i; struct ess_card *card; struct ess_state *ess; int apu; int num = 0; + + /* don't pick up weird modem maestros */ + if(((pcidev->class >> 8) & 0xffff) != PCI_CLASS_MULTIMEDIA_AUDIO) + return 0; iobase = pcidev->resource[0].start; - + if(check_region(iobase, 256)) { printk(KERN_WARNING "maestro: can't allocate 256 bytes I/O at 0x%4.4x\n", iobase); return 0; } + /* this was tripping up some machines */ + if(pcidev->irq == 0) + { + printk(KERN_WARNING "maestro: pci subsystem reports irq 0, this might not be correct.\n"); + } + + /* just to be sure */ + pci_set_master(pcidev); + card = kmalloc(sizeof(struct ess_card), GFP_KERNEL); if(card == NULL) { @@ -2510,6 +2970,21 @@ memset(card, 0, sizeof(*card)); + /* allocate a page for the input mixer APUs + 512 * NR_DSPS must fit in here !!*/ + if(!(card->mixpage = (void *)__get_free_pages(GFP_KERNEL|GFP_DMA, 1))) + { + printk(KERN_WARNING "maestro: can't allocate mixer page.\n"); + kfree(card); + return 0; + } + +#ifdef CONFIG_APM + printk("reg_callback: %d\n",apm_register_callback(maestro_apm_callback)); +#endif + /* mark the page reserved */ + set_bit(PG_reserved, &mem_map[MAP_NR(card->mixpage)].flags); + card->iobase = iobase; card->card_type = card_type; card->irq = pcidev->irq; @@ -2517,11 +2992,11 @@ card->magic = ESS_CARD_MAGIC; devs = card; - /* init our 8 groups of 4 apus */ - for(i=0;i<8;i++) + /* init our groups of 6 apus */ + for(i=0;ichannels[i]; - + s->card = card; init_waitqueue_head(&s->dma_adc.wait); init_waitqueue_head(&s->dma_dac.wait); @@ -2529,34 +3004,41 @@ init_MUTEX(&s->open_sem); s->magic = ESS_STATE_MAGIC; - s->apu[0] = 4*i; - s->apu[1] = (4*i)+1; - s->apu[2] = (4*i)+2; - s->apu[3] = (4*i)+3; + s->apu[0] = 6*i; + s->apu[1] = (6*i)+1; + s->apu[2] = (6*i)+2; + s->apu[3] = (6*i)+3; + s->apu[4] = (6*i)+4; + s->apu[5] = (6*i)+5; if(s->dma_adc.ready || s->dma_dac.ready || s->dma_adc.rawbuf) - printk("BOTCH!\n"); + printk("maestro: BOTCH!\n"); /* register devices */ if ((s->dev_audio = register_sound_dsp(&ess_audio_fops, -1)) < 0) break; + /* divide the page into smaller chunks */ + s->mixbuf = card->mixpage + (i * 512); } num = i; /* clear the rest if we ran out of slots to register */ - for(;i<8;i++) + for(;ichannels[i]; s->dev_audio = -1; } ess = &card->channels[0]; - + /* * Ok card ready. Begin setup proper */ - - printk(KERN_INFO "maestro: Configuring %s at 0x%04X\n", card_names[card_type], iobase); + + printk(KERN_INFO "maestro: Configuring %s found at IO 0x%04X IRQ %d\n", + card_names[card_type],iobase,card->irq); + pci_read_config_dword(pcidev, PCI_SUBSYSTEM_VENDOR_ID, &n); + printk(KERN_INFO "maestro: subvendor id: 0x%08x\n",n); /* * Disable ACPI @@ -2652,15 +3134,7 @@ request_region(iobase, 256, card_names[card_type]); sound_reset(iobase); -#if 0 - - /* reset the ring bus */ - outw(inw(iobase + 0x36) & 0xdfff, iobase+0x36); /* disable */ - outw(0xC090, iobase+0x34); - udelay(20); - outw(inw(iobase + 0x36) |0x2000, iobase+0x36); /* enable */ -#endif /* * Ring Bus Setup */ @@ -2678,7 +3152,6 @@ maestro_ac97_reset(iobase); -#if 0 /* * Ring Bus Setup */ @@ -2746,11 +3219,9 @@ w=inw(iobase+0x18); w|=(1<<0); /* SB IRQ on */ outw(w, iobase+0x18); -#endif -#if 0 - /* asp crap */ +#if 0 /* asp crap */ outb(0, iobase+0xA4); outb(3, iobase+0xA2); outb(0, iobase+0xA6); @@ -2798,8 +3269,10 @@ maestro_write(ess, 0x0B, 0x3F37); maestro_write(ess, 0x0C, 0x0098); + /* parallel out ?? */ maestro_write(ess, 0x0C, - (maestro_read(ess, 0x0C)&~0xF000)|0x8000); + (maestro_read(ess, 0x0C)&~0xF000)|0x8000); + /* parallel in, has something to do with recording :) */ maestro_write(ess, 0x0C, (maestro_read(ess, 0x0C)&~0x0F00)|0x0500); @@ -2815,22 +3288,23 @@ outw(0xA1A0, 0x14+iobase); /* 0300 ? */ - if(maestro_ac97_get(iobase, 0x00)==0x0080) - { - maestro_pt101_init(iobase); + if(maestro_ac97_get(iobase, 0x00)==0x0080) { + maestro_pt101_init(card,iobase); + } else { + maestro_ac97_init(card,iobase); } - else - { - maestro_ac97_init(iobase); - card->mix.supported_mixers = AC97_SUPPORTED_MASK; - card->mix.stereo_mixers = AC97_STEREO_MASK; - card->mix.record_sources = AC97_RECORD_MASK; - card->mix.read_mixer = ac97_read_mixer; - card->mix.write_mixer = ac97_write_mixer; - card->mix.recmask_io = ac97_recmask_io; - if ((card->dev_mixer = register_sound_mixer(&ess_mixer_fops, -1)) < 0) - printk("maestro: couldn't register mixer!\n"); + if ((card->dev_mixer = register_sound_mixer(&ess_mixer_fops, -1)) < 0) { + printk("maestro: couldn't register mixer!\n"); + } else { + int i; + for(i = 0 ; i < SOUND_MIXER_NRDEVICES ; i++) { + struct mixer_defaults *md = &mixer_defaults[i]; + + if(md->mixer == -1) break; + if( ! supported_mixer(card,md->mixer)) continue; + set_mixer(card,md->mixer,md->value); + } } /* Now clear the channel data */ @@ -2844,12 +3318,13 @@ { printk(KERN_ERR "maestro: unable to allocate irq %d,\n", card->irq); unregister_sound_mixer(card->dev_mixer); - for(i=0;i<8;i++) + for(i=0;ichannels[i]; if(s->dev_audio != -1) unregister_sound_dsp(s->dev_audio); } + free_mixpage(card); release_region(card->iobase, 256); kfree(card); return 0; @@ -2860,14 +3335,13 @@ } #ifdef MODULE - -int __init init_module(void) +int init_module(void) #else int __init init_maestro(void) #endif { struct pci_dev *pcidev = NULL; - int index = 0; + int foundone = 0; if (!pci_present()) /* No PCI bus in this machine! */ return -ENODEV; @@ -2879,35 +3353,32 @@ * Find the ESS Maestro 2. */ - while((pcidev = pci_find_device(PCI_VENDOR_ESS, PCI_DEVICE_ID_ESS_ESS1968, pcidev))!=NULL) - { - index+=maestro_install(pcidev, TYPE_MAESTRO2, index); - if(index == NR_DEVICE) - return index; + while( (pcidev = pci_find_device(PCI_VENDOR_ESS, PCI_DEVICE_ID_ESS_ESS1968, pcidev))!=NULL + && + ( maestro_install(pcidev, TYPE_MAESTRO2) )) { + foundone=1; } /* * Find the ESS Maestro 2E */ - while((pcidev = pci_find_device(PCI_VENDOR_ESS, PCI_DEVICE_ID_ESS_ESS1978, pcidev))!=NULL) - { - index+=maestro_install(pcidev, TYPE_MAESTRO2E, index); - if(index == NR_DEVICE) - return index; + while((pcidev = pci_find_device(PCI_VENDOR_ESS, PCI_DEVICE_ID_ESS_ESS1978, pcidev))!=NULL + && + ( maestro_install(pcidev, TYPE_MAESTRO2E) )) { + foundone=1; } /* * ESS Maestro 1 */ - while((pcidev = pci_find_device(PCI_VENDOR_ESS_OLD, PCI_DEVICE_ID_ESS_ESS0100, pcidev))!=NULL) - { - index+=maestro_install(pcidev, TYPE_MAESTRO, index); - if(index == NR_DEVICE) - return index; + while((pcidev = pci_find_device(PCI_VENDOR_ESS_OLD, PCI_DEVICE_ID_ESS_ESS0100, pcidev))!=NULL + && + ( maestro_install(pcidev, TYPE_MAESTRO) )) { + foundone=1; } - if(index==0) + if( ! foundone ) return -ENODEV; return 0; } @@ -2916,7 +3387,7 @@ #ifdef MODULE -MODULE_AUTHOR("Alan Cox "); +MODULE_AUTHOR("Zach Brown , Alan Cox "); MODULE_DESCRIPTION("ESS Maestro Driver"); #ifdef M_DEBUG MODULE_PARM(debug,"i"); @@ -2926,22 +3397,24 @@ { struct ess_card *s; +#ifdef CONFIG_APM + apm_unregister_callback(maestro_apm_callback); +#endif while ((s = devs)) { int i; devs = devs->next; -#ifndef ESS_HW_TIMER - kill_bob(&s->channels[0]); -#else - stop_bob(&s->channels[0]); -#endif + + /* XXX maybe should force stop bob, but should be all + stopped by _release by now */ free_irq(s->irq, s); unregister_sound_mixer(s->dev_mixer); - for(i=0;i<8;i++) + for(i=0;ichannels[i]; if(ess->dev_audio != -1) unregister_sound_dsp(ess->dev_audio); } + free_mixpage(s); release_region(s->iobase, 256); kfree(s); } @@ -2950,117 +3423,3 @@ #endif /* MODULE */ -#if 0 -/*============================================================================ - * ex-code that we're not using anymore.. - *============================================================================ - */ - -/* - * The ASSP is fortunately not double indexed - */ - -static void assp_set_register(int ioaddr, u32 reg, u32 value) -{ - unsigned long flags; - - save_flags(flags); - cli(); - outl(reg, ioaddr+0x80); - outl(value, ioaddr+0x84); - restore_flags(flags); -} - -static u32 assp_get_register(int ioaddr, u32 reg) -{ - unsigned long flags; - u32 value; - - save_flags(flags); - cli(); - outl(reg, ioaddr+0x80); - value=inl(ioaddr+0x84); - restore_flags(flags); - - return value; -} - -/* the ASP is basically a DSP that one can dma instructions - into. it can do things like surround encoding or - fm synth in sb emul mode. It is highly proprietary - and the ESS dudes are none too excited about telling - us about it. so screw it, we'll just turn it off and - not bother with it. Its not needed for apu/dac work. */ - - -static void asp_load(int ioaddr, u16 l, u16 h, u16 *data, int len) -{ - int i; - outw(l, ioaddr+0x80); - outw(h, ioaddr+0x82); - for(i=0;i 2 || card == NULL) \ + return -1; \ +\ + if (port == 1) { \ + if (offset < card->port1_start || offset >= card->port1_end) { \ + printk (KERN_ERR "Bad port request port 1:0x%x\n", offset); \ + return -1; \ + } \ + offset -= card->port1_start; \ + } else if (offset < 0 || offset > 4096) { \ + printk (KERN_ERR "Bad port request port 2: 0x%x\n", offset); \ + return -1; \ + } + +#define DEFwritePortX(X, func) \ +static inline int nm256_writePort##X (struct nm256_info *card,\ + int port, int offset, int value)\ +{\ + u##X *addr;\ +\ + NM_FIX_PORT;\ +\ + addr = (u##X *)(card->ports[port - 1] + offset);\ + func (value, addr);\ + return 0;\ +} + +DEFwritePortX (8, writeb) +DEFwritePortX (16, writew) +DEFwritePortX (32, writel) + +#define DEFreadPortX(X) \ +static inline u##X nm256_readPort##X (struct nm256_info *card,\ + int port, int offset)\ +{\ + u##X *addr, res;\ +\ + NM_FIX_PORT\ +\ + addr = (u##X *)(card->ports[port - 1] + offset);\ + memcpy_fromio (&res, addr, sizeof (res));\ + return res;\ +} + +DEFreadPortX (8) +DEFreadPortX (16) +DEFreadPortX (32) + +static inline int +nm256_writeBuffer8 (struct nm256_info *card, u8 *src, int port, int offset, + int amt) +{ + NM_FIX_PORT; + memcpy_toio (card->ports[port - 1] + offset, src, amt); + return 0; +} + +static inline int +nm256_readBuffer8 (struct nm256_info *card, u8 *dst, int port, int offset, + int amt) +{ + NM_FIX_PORT; + memcpy_fromio (dst, card->ports[port - 1] + offset, amt); + return 0; +} + +/* Returns a non-zero value if we should use the coefficient cache. */ +extern int nm256_cachedCoefficients (struct nm256_info *card); + +#endif + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sound/nm256_audio.c linux.ac/drivers/sound/nm256_audio.c --- linux.vanilla/drivers/sound/nm256_audio.c Thu Jan 1 01:00:00 1970 +++ linux.ac/drivers/sound/nm256_audio.c Sat Sep 18 19:39:06 1999 @@ -0,0 +1,1393 @@ +/* Audio driver for the NeoMagic 256AV and 256ZX chipsets in native + mode, with AC97 mixer support. + + Overall design and parts of this code stolen from vidc_*.c and + skeleton.c. + + Yeah, there are a lot of magic constants in here. You tell ME what + they are. I just get this stuff psychically, remember? + + This driver was written by someone who wishes to remain anonymous. + It is in the public domain, so share and enjoy. Try to make a profit + off of it; go on, I dare you. */ + +#include +#include +#include +#include "sound_config.h" +#include "soundmodule.h" +#include "nm256.h" +#include "nm256_coeff.h" + +int nm256_debug = 0; + +/* The size of the playback reserve. */ +#define NM256_PLAY_WMARK_SIZE 512 + +static struct audio_driver nm256_audio_driver; + +static int nm256_grabInterrupt (struct nm256_info *card); +static int nm256_releaseInterrupt (struct nm256_info *card); +static void nm256_interrupt (int irq, void *dev_id, struct pt_regs *dummy); +static void nm256_interrupt_zx (int irq, void *dev_id, + struct pt_regs *dummy); + +/* These belong in linux/pci.h. */ +#define PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO 0x8005 +#define PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO 0x8006 + +/* List of cards. */ +static struct nm256_info *nmcard_list; + +/* Locate the card in our list. */ +static struct nm256_info * +nm256_find_card (int dev) +{ + struct nm256_info *card; + + for (card = nmcard_list; card != NULL; card = card->next_card) + if (card->dev[0] == dev || card->dev[1] == dev) + return card; + + return NULL; +} + +/* Ditto, but find the card struct corresponding to the mixer device DEV + instead. */ +static struct nm256_info * +nm256_find_card_for_mixer (int dev) +{ + struct nm256_info *card; + + for (card = nmcard_list; card != NULL; card = card->next_card) + if (card->mixer_oss_dev == dev) + return card; + + return NULL; +} + +static int usecache = 0; +static int buffertop = 0; + +/* Check to see if we're using the bank of cached coefficients. */ +int +nm256_cachedCoefficients (struct nm256_info *card) +{ + return usecache; +} + +/* The actual rates supported by the card. */ +static int samplerates[9] = { + 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 99999999 +}; + +/* Set the card samplerate, word size and stereo mode to correspond to + the settings in the CARD struct for the specified device in DEV. + We keep two separate sets of information, one for each device; the + hardware is not actually configured until a read or write is + attempted. */ + +int +nm256_setInfo (int dev, struct nm256_info *card) +{ + int x; + int w; + int targetrate; + + if (card->dev[0] == dev) + w = 0; + else if (card->dev[1] == dev) + w = 1; + else + return -ENODEV; + + targetrate = card->sinfo[w].samplerate; + + if ((card->sinfo[w].bits != 8 && card->sinfo[w].bits != 16) + || targetrate < samplerates[0] + || targetrate > samplerates[7]) + return -EINVAL; + + for (x = 0; x < 8; x++) + if (targetrate < ((samplerates[x] + samplerates[x + 1]) / 2)) + break; + + if (x < 8) { + u8 speedbits = ((x << 4) & NM_RATE_MASK) + | (card->sinfo[w].bits == 16 ? NM_RATE_BITS_16: 0) + | (card->sinfo[w].stereo ? NM_RATE_STEREO : 0); + + card->sinfo[w].samplerate = samplerates[x]; + + if (card->dev_for_play == dev && card->playing) { + nm256_loadCoefficient (card, 0, x); + nm256_writePort8 (card, 2, + NM_PLAYBACK_REG_OFFSET + NM_RATE_REG_OFFSET, + speedbits); + } + + if (card->dev_for_record == dev && card->recording) { + nm256_loadCoefficient (card, 1, x); + nm256_writePort8 (card, 2, + NM_RECORD_REG_OFFSET + NM_RATE_REG_OFFSET, + speedbits); + } + return 0; + } + else + return -EINVAL; +} + +/* Start the play process going. */ +static void +startPlay (struct nm256_info *card) +{ + if (! card->playing) { + card->playing = 1; + if (nm256_grabInterrupt (card) == 0) { + nm256_setInfo (card->dev_for_play, card); + + /* Enable playback engine and interrupts. */ + nm256_writePort8 (card, 2, NM_PLAYBACK_ENABLE_REG, + NM_PLAYBACK_ENABLE_FLAG | NM_PLAYBACK_FREERUN); + + /* Enable both channels. */ + nm256_writePort16 (card, 2, NM_AUDIO_MUTE_REG, 0x0); + } + } +} + +/* Request one chunk of AMT bytes from the recording device. When the + operation is complete, the data will be copied into BUFFER and the + function DMAbuf_inputintr will be invoked. */ + +static void +nm256_startRecording (struct nm256_info *card, char *buffer, u32 amt) +{ + u32 endpos; + int enableEngine = 0; + u32 ringsize = card->recordBufferSize; + + if (amt > (ringsize / 2)) { + /* Of course this won't actually work right, because the + caller is going to assume we will give what we got asked + for. */ + printk (KERN_ERR "NM256: Read request too large: %d\n", amt); + amt = ringsize / 2; + } + + if (amt < 8) { + printk (KERN_ERR "NM256: Read request too small; %d\n", amt); + return; + } + + /* If we're not currently recording, set up the start and end registers + for the recording engine. */ + if (! card->recording) { + card->recording = 1; + if (nm256_grabInterrupt (card) == 0) { + card->curRecPos = 0; + nm256_setInfo (card->dev_for_record, card); + nm256_writePort32 (card, 2, NM_RBUFFER_START, card->abuf2); + nm256_writePort32 (card, 2, NM_RBUFFER_END, + card->abuf2 + ringsize); + + nm256_writePort32 (card, 2, NM_RBUFFER_CURRP, + card->abuf2 + card->curRecPos); + enableEngine = 1; + } + else { + /* Not sure what else to do here. */ + return; + } + } + + endpos = card->abuf2 + ((card->curRecPos + amt) % ringsize); + + card->recBuf = buffer; + card->requestedRecAmt = amt; + nm256_writePort32 (card, 2, NM_RBUFFER_WMARK, endpos); + /* Enable recording engine and interrupts. */ + if (enableEngine) + nm256_writePort8 (card, 2, NM_RECORD_ENABLE_REG, + NM_RECORD_ENABLE_FLAG | NM_RECORD_FREERUN); +} + +/* Stop the play engine. */ +static void +stopPlay (struct nm256_info *card) +{ + /* Shut off sound from both channels. */ + nm256_writePort16 (card, 2, NM_AUDIO_MUTE_REG, + NM_AUDIO_MUTE_LEFT | NM_AUDIO_MUTE_RIGHT); + /* Disable play engine. */ + nm256_writePort8 (card, 2, NM_PLAYBACK_ENABLE_REG, 0); + if (card->playing) { + nm256_releaseInterrupt (card); + + /* Reset the relevant state bits. */ + card->playing = 0; + card->curPlayPos = 0; + } +} + +/* Stop recording. */ +static void +stopRecord (struct nm256_info *card) +{ + /* Disable recording engine. */ + nm256_writePort8 (card, 2, NM_RECORD_ENABLE_REG, 0); + + if (card->recording) { + nm256_releaseInterrupt (card); + + card->recording = 0; + card->curRecPos = 0; + } +} + +/* Ring buffers, man. That's where the hip-hop, wild-n-wooly action's at. + 1972? + + Write AMT bytes of BUFFER to the playback ring buffer, and start the + playback engine running. It will only accept up to 1/2 of the total + size of the ring buffer. */ + +static void +nm256_write_block (struct nm256_info *card, char *buffer, u32 amt) +{ + u32 ringsize = card->playbackBufferSize; + u32 endstop; + + if (amt > (ringsize / 2)) { + printk (KERN_ERR "NM256: Write request too large: %d\n", amt); + amt = (ringsize / 2); + } + + if (amt < NM256_PLAY_WMARK_SIZE) { + printk (KERN_ERR "NM256: Write request too small: %d\n", amt); + return; + } + + card->curPlayPos %= ringsize; + + card->requested_amt = amt; + + if ((card->curPlayPos + amt) >= ringsize) { + u32 rem = ringsize - card->curPlayPos; + + nm256_writeBuffer8 (card, buffer, 1, + card->abuf1 + card->curPlayPos, + rem); + if (amt > rem) + nm256_writeBuffer8 (card, buffer, 1, card->abuf1, + amt - rem); + } + else + nm256_writeBuffer8 (card, buffer, 1, + card->abuf1 + card->curPlayPos, + amt); + + /* Setup the start-n-stop-n-limit registers, and start that engine + goin'. + + Normally we just let it wrap around to avoid the click-click + action scene. */ + if (! card->playing) { + /* The PBUFFER_END register in this case points to one "word" + before the end of the buffer. */ + int w = (card->dev_for_play == card->dev[0] ? 0 : 1); + int wordsize = (card->sinfo[w].bits == 16 ? 2 : 1) + * (card->sinfo[w].stereo ? 2 : 1); + + /* Need to set the not-normally-changing-registers up. */ + nm256_writePort32 (card, 2, NM_PBUFFER_START, + card->abuf1 + card->curPlayPos); + nm256_writePort32 (card, 2, NM_PBUFFER_END, + card->abuf1 + ringsize - wordsize); + nm256_writePort32 (card, 2, NM_PBUFFER_CURRP, + card->abuf1 + card->curPlayPos); + } + endstop = (card->curPlayPos + amt - NM256_PLAY_WMARK_SIZE) % ringsize; + nm256_writePort32 (card, 2, NM_PBUFFER_WMARK, card->abuf1 + endstop); + if (! card->playing) + startPlay (card); +} + +/* We just got a card playback interrupt; process it. */ +static void +nm256_get_new_block (struct nm256_info *card) +{ + /* Check to see how much got played so far. */ + u32 amt = nm256_readPort32 (card, 2, NM_PBUFFER_CURRP) - card->abuf1; + + if (amt >= card->playbackBufferSize) { + printk (KERN_ERR "NM256: Sound playback pointer invalid!\n"); + amt = 0; + } + + if (amt < card->curPlayPos) + amt = (card->playbackBufferSize - card->curPlayPos) + amt; + else + amt -= card->curPlayPos; + + if (card->requested_amt > (amt + NM256_PLAY_WMARK_SIZE)) { + u32 endstop = + card->curPlayPos + card->requested_amt - NM256_PLAY_WMARK_SIZE; + nm256_writePort32 (card, 2, NM_PBUFFER_WMARK, card->abuf1 + endstop); + } else { + card->curPlayPos += card->requested_amt; + /* Get a new block to write. This will eventually invoke + nm256_write_block (). */ + DMAbuf_outputintr (card->dev_for_play, 1); + } +} + +/* Ultra cheez-whiz. But I'm too lazy to grep headers. */ +#define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) + +/* Read the last-recorded block from the ring buffer, copy it into the + saved buffer pointer, and invoke DMAuf_inputintr() with the recording + device. */ + +static void +nm256_read_block (struct nm256_info *card) +{ + /* Grab the current position of the recording pointer. */ + u32 currptr = nm256_readPort32 (card, 2, NM_RBUFFER_CURRP) - card->abuf2; + u32 amtToRead = card->requestedRecAmt; + u32 ringsize = card->recordBufferSize; + + if (currptr >= card->recordBufferSize) { + printk (KERN_ERR "NM256: Sound buffer record pointer invalid!\n"); + currptr = 0; + } + + /* This test is probably redundant; we shouldn't be here unless + it's true. */ + if (card->recording) { + /* If we wrapped around, copy everything from the start of our + recording buffer to the end of the buffer. */ + if (currptr < card->curRecPos) { + u32 amt = MIN (ringsize - card->curRecPos, amtToRead); + + nm256_readBuffer8 (card, card->recBuf, 1, + card->abuf2 + card->curRecPos, + amt); + amtToRead -= amt; + card->curRecPos += amt; + card->recBuf += amt; + if (card->curRecPos == ringsize) + card->curRecPos = 0; + } + + if ((card->curRecPos < currptr) && (amtToRead > 0)) { + u32 amt = MIN (currptr - card->curRecPos, amtToRead); + nm256_readBuffer8 (card, card->recBuf, 1, + card->abuf2 + card->curRecPos, amt); + card->curRecPos = ((card->curRecPos + amt) % ringsize); + } + card->recBuf = NULL; + card->requestedRecAmt = 0; + DMAbuf_inputintr (card->dev_for_record); + } +} +#undef MIN + +/* Initialize the hardware and various other card data we'll need + later. */ +static void +nm256_initHw (struct nm256_info *card) +{ + int x; + + card->playbackBufferSize = 16384; + card->recordBufferSize = 16384; + + card->coeffBuf = card->bufend - NM_MAX_COEFFICIENT; + card->abuf2 = card->coeffBuf - card->recordBufferSize; + card->abuf1 = card->abuf2 - card->playbackBufferSize; + card->allCoeffBuf = card->abuf2 - (NM_TOTAL_COEFF_COUNT * 4); + + /* Fixed setting. */ + card->mixer = NM_MIXER_BASE; + + card->playing = 0; + card->is_open_play = 0; + card->curPlayPos = 0; + + card->recording = 0; + card->is_open_record = 0; + card->curRecPos = 0; + + card->coeffsCurrent = 0; + + card->opencnt[0] = 0; card->opencnt[1] = 0; + + /* Reset everything. */ + nm256_writePort8 (card, 2, 0, 0x11); + + /* Disable recording. */ + nm256_writePort8 (card, 2, NM_RECORD_ENABLE_REG, 0); + nm256_writePort16 (card, 2, 0x214, 0); + + /* Reasonable default settings, but largely unnecessary. */ + for (x = 0; x < 2; x++) { + card->sinfo[x].bits = 8; + card->sinfo[x].stereo = 0; + card->sinfo[x].samplerate = 8000; + } +} + +/* Handle a potential interrupt for the device referred to by DEV_ID. */ + +static void +nm256_interrupt (int irq, void *dev_id, struct pt_regs *dummy) +{ + struct nm256_info *card = (struct nm256_info *)dev_id; + u16 status; + static int badintrcount = 0; + + if ((card == NULL) || (card->magsig != NM_MAGIC_SIG)) { + printk (KERN_ERR "NM256: Bad card pointer\n"); + return; + } + + status = nm256_readPort16 (card, 2, NM_INT_REG); + + /* Not ours. */ + if (status == 0) { + if (badintrcount++ > 1000) { + printk (KERN_ERR "NM256: Releasing interrupt, over 1000 invalid interrupts\n"); + nm256_releaseInterrupt (card); + } + return; + } + + badintrcount = 0; + + if (status & NM_PLAYBACK_INT) { + status &= ~NM_PLAYBACK_INT; + NM_ACK_INT (card, NM_PLAYBACK_INT); + + if (card->playing) + nm256_get_new_block (card); + } + + if (status & NM_RECORD_INT) { + status &= ~NM_RECORD_INT; + NM_ACK_INT (card, NM_RECORD_INT); + + if (card->recording) + nm256_read_block (card); + } + + if (status & NM_MISC_INT_1) { + u8 cbyte; + + status &= ~NM_MISC_INT_1; + printk (KERN_ERR "NM256: Got misc interrupt #1\n"); + NM_ACK_INT (card, NM_MISC_INT_1); + nm256_writePort16 (card, 2, NM_INT_REG, 0x8000); + cbyte = nm256_readPort8 (card, 2, 0x400); + nm256_writePort8 (card, 2, 0x400, cbyte | 2); + } + + if (status & NM_MISC_INT_2) { + u8 cbyte; + + status &= ~NM_MISC_INT_2; + printk (KERN_ERR "NM256: Got misc interrupt #2\n"); + NM_ACK_INT (card, NM_MISC_INT_2); + cbyte = nm256_readPort8 (card, 2, 0x400); + nm256_writePort8 (card, 2, 0x400, cbyte & ~2); + } + + if (status) { + printk (KERN_ERR "NM256: Fire in the hole! Unknown status 0x%x\n", + status); + /* Pray. */ + NM_ACK_INT (card, status); + } +} + +/* Handle a potential interrupt for the device referred to by DEV_ID. + This handler is for the 256ZX. */ + +static void +nm256_interrupt_zx (int irq, void *dev_id, struct pt_regs *dummy) +{ + struct nm256_info *card = (struct nm256_info *)dev_id; + u32 status; + static int badintrcount = 0; + + if ((card == NULL) || (card->magsig != NM_MAGIC_SIG)) { + printk (KERN_ERR "NM256: Bad card pointer\n"); + return; + } + + status = nm256_readPort32 (card, 2, NM_INT_REG); + + /* Not ours. */ + if (status == 0) { + if (badintrcount++ > 1000) { + printk (KERN_ERR "NM256: Releasing interrupt, over 1000 invalid interrupts\n"); + nm256_releaseInterrupt (card); + } + return; + } + + badintrcount = 0; + + if (status & NM2_PLAYBACK_INT) { + status &= ~NM2_PLAYBACK_INT; + NM2_ACK_INT (card, NM2_PLAYBACK_INT); + + if (card->playing) + nm256_get_new_block (card); + } + + if (status & NM2_RECORD_INT) { + status &= ~NM2_RECORD_INT; + NM2_ACK_INT (card, NM2_RECORD_INT); + + if (card->recording) + nm256_read_block (card); + } + + if (status & NM2_MISC_INT_1) { + u8 cbyte; + + status &= ~NM2_MISC_INT_1; + printk (KERN_ERR "NM256: Got misc interrupt #1\n"); + NM2_ACK_INT (card, NM2_MISC_INT_1); + cbyte = nm256_readPort8 (card, 2, 0x400); + nm256_writePort8 (card, 2, 0x400, cbyte | 2); + } + + if (status & NM2_MISC_INT_2) { + u8 cbyte; + + status &= ~NM2_MISC_INT_2; + printk (KERN_ERR "NM256: Got misc interrupt #2\n"); + NM2_ACK_INT (card, NM2_MISC_INT_2); + cbyte = nm256_readPort8 (card, 2, 0x400); + nm256_writePort8 (card, 2, 0x400, cbyte & ~2); + } + + if (status) { + printk (KERN_ERR "NM256: Fire in the hole! Unknown status 0x%x\n", + status); + /* Pray. */ + NM2_ACK_INT (card, status); + } +} + +/* Request our interrupt. */ +static int +nm256_grabInterrupt (struct nm256_info *card) +{ + if (card->has_irq++ == 0) { + if (request_irq (card->irq, card->introutine, SA_SHIRQ, + "NM256_audio", card) < 0) { + printk (KERN_ERR "NM256: can't obtain IRQ %d\n", card->irq); + return -1; + } + } + return 0; +} + +/* Release our interrupt. */ +static int +nm256_releaseInterrupt (struct nm256_info *card) +{ + if (card->has_irq <= 0) { + printk (KERN_ERR "nm256: too many calls to releaseInterrupt\n"); + return -1; + } + card->has_irq--; + if (card->has_irq == 0) { + free_irq (card->irq, card); + } + return 0; +} + +static int +nm256_isReady (struct ac97_hwint *dev) +{ + struct nm256_info *card = (struct nm256_info *)dev->driver_private; + int t2 = 10; + u32 testaddr; + u16 testb; + int done = 0; + + if (card->magsig != NM_MAGIC_SIG) { + printk (KERN_ERR "NM256: Bad magic signature in isReady!\n"); + return 0; + } + + if (card->rev == REV_NM256AV) { + testaddr = 0xa06; + testb = 0x0100; + } else if (card->rev == REV_NM256ZX) { + testaddr = 0xa08; + testb = 0x0800; + } else { + return -1; + } + + while (t2-- > 0) { + if ((nm256_readPort16 (card, 2, testaddr) & testb) == 0) { + done = 1; + break; + } + udelay (100); + } + return done; +} + +static int +nm256_readAC97Reg (struct ac97_hwint *dev, u8 reg) +{ + struct nm256_info *card = (struct nm256_info *)dev->driver_private; + + if (card->magsig != NM_MAGIC_SIG) { + printk (KERN_ERR "NM256: Bad magic signature in readAC97Reg!\n"); + return -EINVAL; + } + + if (reg < 128) { + int res; + + nm256_isReady (dev); + res = nm256_readPort16 (card, 2, card->mixer + reg); + udelay (1000); + return res; + } + else + return -EINVAL; +} + +static int +nm256_writeAC97Reg (struct ac97_hwint *dev, u8 reg, u16 value) +{ + unsigned long flags; + int tries = 2; + int done = 0; + u32 base; + + struct nm256_info *card = (struct nm256_info *)dev->driver_private; + + if (card->magsig != NM_MAGIC_SIG) { + printk (KERN_ERR "NM256: Bad magic signature in writeAC97Reg!\n"); + return -EINVAL; + } + + base = card->mixer; + + save_flags (flags); + cli (); + + nm256_isReady (dev); + + /* Wait for the write to take, too. */ + while ((tries-- > 0) && !done) { + nm256_writePort16 (card, 2, base + reg, value); + if (nm256_isReady (dev)) { + done = 1; + break; + } + + } + + restore_flags (flags); + udelay (1000); + + return ! done; +} + +struct initialValues +{ + unsigned short port; + unsigned short value; +}; + +static struct initialValues nm256_ac97_initial_values[] = +{ + { 0x0002, 0x8000 }, + { 0x0004, 0x0000 }, + { 0x0006, 0x0000 }, + { 0x000A, 0x0000 }, + { 0x000C, 0x0008 }, + { 0x000E, 0x8008 }, + { 0x0010, 0x8808 }, + { 0x0012, 0x8808 }, + { 0x0014, 0x8808 }, + { 0x0016, 0x8808 }, + { 0x0018, 0x0808 }, + { 0x001A, 0x0000 }, + { 0x001C, 0x0B0B }, + { 0x0020, 0x0000 }, + { 0xffff, 0xffff } +}; + +static int +nm256_resetAC97 (struct ac97_hwint *dev) +{ + struct nm256_info *card = (struct nm256_info *)dev->driver_private; + int x; + + if (card->magsig != NM_MAGIC_SIG) { + printk (KERN_ERR "NM256: Bad magic signature in resetAC97!\n"); + return -EINVAL; + } + + /* Reset the card. 'Tis magic! */ + nm256_writePort8 (card, 2, 0x6c0, 1); + nm256_writePort8 (card, 2, 0x6cc, 0x87); + nm256_writePort8 (card, 2, 0x6cc, 0x80); + nm256_writePort8 (card, 2, 0x6cc, 0x0); + + for (x = 0; nm256_ac97_initial_values[x].port != 0xffff; x++) { + ac97_put_register (dev, + nm256_ac97_initial_values[x].port, + nm256_ac97_initial_values[x].value); + } + + return 0; +} + +/* We don't do anything special here. */ +static int +nm256_default_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg) +{ + struct nm256_info *card = nm256_find_card_for_mixer (dev); + if (card != NULL) + return ac97_mixer_ioctl (&(card->mdev), cmd, arg); + else + return -ENODEV; +} + +static struct mixer_operations nm256_mixer_operations = { + "NeoMagic", + "NM256AC97Mixer", + nm256_default_mixer_ioctl +}; + +/* I "love" C sometimes. Got braces? */ +static struct ac97_mixer_value_list mixer_defaults[] = { + { SOUND_MIXER_VOLUME, { { 85, 85 } } }, + { SOUND_MIXER_SPEAKER, { { 100 } } }, + { SOUND_MIXER_PCM, { { 65, 65 } } }, + { SOUND_MIXER_CD, { { 65, 65 } } }, + { -1, { { 0, 0 } } } +}; + +static int +nm256_install_mixer (struct nm256_info *card) +{ + int mixer; + + card->mdev.reset_device = nm256_resetAC97; + card->mdev.read_reg = nm256_readAC97Reg; + card->mdev.write_reg = nm256_writeAC97Reg; + card->mdev.driver_private = (void *)card; + + if (ac97_init (&(card->mdev))) + return -1; + + mixer = sound_alloc_mixerdev(); + if (num_mixers >= MAX_MIXER_DEV) { + printk ("NM256 mixer: Unable to alloc mixerdev\n"); + return -1; + } + + mixer_devs[mixer] = &nm256_mixer_operations; + card->mixer_oss_dev = mixer; + + /* Some reasonable default values. */ + ac97_set_values (&(card->mdev), mixer_defaults); + + printk(KERN_INFO "Initialized AC97 mixer\n"); + return 0; +} + +/* See if the signature left by the NM256 BIOS is intact; if so, we use + the associated address as the end of our buffer. */ +static void +nm256_peek_for_sig (struct nm256_info *card, u32 port1addr) +{ + char *temp = ioremap_nocache (port1addr + card->port1_end - 0x0400, 16); + u32 sig; + + if (temp == NULL) { + printk (KERN_ERR "NM256: Unable to scan for card signature in video RAM\n"); + return; + } + memcpy_fromio (&sig, temp, sizeof (u32)); + if ((sig & 0xffff0000) == 0x4e4d0000) { + memcpy_fromio (&(card->bufend), temp + 4, sizeof (u32)); + printk (KERN_INFO "NM256: Found card signature in video RAM: 0x%x\n", + card->bufend); + } + + release_region ((unsigned long) temp, 16); +} + +/* Install a driver for the soundcard referenced by PCIDEV. */ + +static int +nm256_install(struct pci_dev *pcidev, enum nm256rev rev, char *verstr) +{ + struct nm256_info *card; + u32 port1addr = pcidev->resource[0].start; + u32 port2addr = pcidev->resource[1].start; + int x; + + card = kmalloc (sizeof (struct nm256_info), GFP_KERNEL); + if (card == NULL) { + printk (KERN_ERR "NM256: out of memory!\n"); + return 0; + } + + card->magsig = NM_MAGIC_SIG; + card->playing = 0; + card->recording = 0; + card->rev = rev; + + /* The NM256 has two memory ports. The first port is nothing + more than a chunk of video RAM, which is used as the I/O ring + buffer. The second port has the actual juicy stuff (like the + mixer and the playback engine control registers). */ + + card->ports[1] = ioremap_nocache (port2addr, NM_PORT2_SIZE); + + if (card->ports[1] == NULL) { + printk (KERN_ERR "NM256: Unable to remap port 2\n"); + kfree_s (card, sizeof (struct nm256_info)); + return 0; + } + + if (card->rev == REV_NM256AV) { + card->port1_end = 2560 * 1024; + card->introutine = nm256_interrupt; + } + else { + if (nm256_readPort8 (card, 2, 0xa0b) != 0) + card->port1_end = 6144 * 1024; + else + card->port1_end = 4096 * 1024; + + card->introutine = nm256_interrupt_zx; + } + + /* Default value. */ + card->bufend = card->port1_end - 0x1400; + + if (buffertop >= 98304 && buffertop < card->port1_end) + card->bufend = buffertop; + else + nm256_peek_for_sig (card, port1addr); + + card->port1_start = card->bufend - 98304; + + printk (KERN_INFO "NM256: Mapping port 1 from 0x%x - 0x%x\n", + card->port1_start, card->port1_end); + + card->ports[0] = + ioremap_nocache (port1addr + card->port1_start, + card->port1_end - card->port1_start); + + if (card->ports[0] == NULL) { + printk (KERN_ERR "NM256: Unable to remap port 1\n"); + release_region ((unsigned long) card->ports[1], NM_PORT2_SIZE); + kfree_s (card, sizeof (struct nm256_info)); + return 0; + } + + /* See if we can get the interrupt. */ + + card->irq = pcidev->irq; + card->has_irq = 0; + + if (nm256_grabInterrupt (card) != 0) { + release_region ((unsigned long) card->ports[0], + card->port1_end - card->port1_start); + release_region ((unsigned long) card->ports[1], NM_PORT2_SIZE); + kfree_s (card, sizeof (struct nm256_info)); + return 0; + } + + nm256_releaseInterrupt (card); + + /* + * Init the board. + */ + + nm256_initHw (card); + + for (x = 0; x < 2; x++) { + if ((card->dev[x] = + sound_install_audiodrv(AUDIO_DRIVER_VERSION, + "NM256", &nm256_audio_driver, + sizeof(struct audio_driver), + DMA_NODMA, AFMT_U8 | AFMT_S16_LE, + NULL, -1, -1)) >= 0) { + /* 1K minimum buffer size. */ + audio_devs[card->dev[x]]->min_fragment = 10; + /* Maximum of 8K buffer size. */ + audio_devs[card->dev[x]]->max_fragment = 13; + } + else { + printk(KERN_ERR "NM256: Too many PCM devices available\n"); + release_region ((unsigned long) card->ports[0], + card->port1_end - card->port1_start); + release_region ((unsigned long) card->ports[1], NM_PORT2_SIZE); + kfree_s (card, sizeof (struct nm256_info)); + return 0; + } + } + + /* Insert the card in the list. */ + card->next_card = nmcard_list; + nmcard_list = card; + + printk(KERN_INFO "Initialized NeoMagic %s audio in PCI native mode\n", + verstr); + + /* + * And our mixer. (We should allow support for other mixers, maybe.) + */ + + nm256_install_mixer (card); + + return 1; +} + +/* + * This loop walks the PCI configuration database and finds where + * the sound cards are. + */ + +int +init_nm256(void) +{ + struct pci_dev *pcidev = NULL; + int count = 0; + + if(! pci_present()) + return -ENODEV; + + while((pcidev = pci_find_device(PCI_VENDOR_ID_NEOMAGIC, + PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO, + pcidev)) != NULL) { + count += nm256_install(pcidev, REV_NM256AV, "256AV"); + } + + while((pcidev = pci_find_device(PCI_VENDOR_ID_NEOMAGIC, + PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO, + pcidev)) != NULL) { + count += nm256_install(pcidev, REV_NM256ZX, "256ZX"); + } + + if (count == 0) + return -ENODEV; + + printk (KERN_INFO "Done installing NM256 audio driver.\n"); + return 0; +} + +/* + * Open the device + * + * DEV - device + * MODE - mode to open device (logical OR of OPEN_READ and OPEN_WRITE) + * + * Called when opening the DMAbuf (dmabuf.c:259) + */ +static int +nm256_audio_open(int dev, int mode) +{ + struct nm256_info *card = nm256_find_card (dev); + int w; + + if (card == NULL) + return -ENODEV; + + if (card->dev[0] == dev) + w = 0; + else if (card->dev[1] == dev) + w = 1; + else + return -ENODEV; + + if (card->opencnt[w] > 0) + return -EBUSY; + + /* No bits set? Huh? */ + if (! ((mode & OPEN_READ) || (mode & OPEN_WRITE))) + return -EIO; + + /* If it's open for both read and write, and the card's currently + being read or written to, then do the opposite of what has + already been done. Otherwise, don't specify any mode until the + user actually tries to do I/O. */ + + if ((mode & OPEN_WRITE) && (mode & OPEN_READ)) { + if (card->is_open_play) + mode = OPEN_WRITE; + else if (card->is_open_record) + mode = OPEN_READ; + else mode = 0; + } + + if (mode & OPEN_WRITE) { + if (card->is_open_play == 0) { + card->dev_for_play = dev; + card->is_open_play = 1; + } + else + return -EBUSY; + } + + if (mode & OPEN_READ) { + if (card->is_open_record == 0) { + card->dev_for_record = dev; + card->is_open_record = 1; + } + else + return -EBUSY; + } + + card->opencnt[w]++; + return 0; +} + +/* + * Close the device + * + * DEV - device + * + * Called when closing the DMAbuf (dmabuf.c:477) + * after halt_xfer + */ +static void +nm256_audio_close(int dev) +{ + struct nm256_info *card = nm256_find_card (dev); + + if (card != NULL) { + int w; + + if (card->dev[0] == dev) + w = 0; + else if (card->dev[1] == dev) + w = 1; + else + return; + + card->opencnt[w]--; + if (card->opencnt[w] <= 0) { + card->opencnt[w] = 0; + + if (card->dev_for_play == dev) { + stopPlay (card); + card->is_open_play = 0; + card->dev_for_play = -1; + } + + if (card->dev_for_record == dev) { + stopRecord (card); + card->is_open_record = 0; + card->dev_for_record = -1; + } + } + } +} + +static int +nm256_audio_ioctl(int dev, unsigned int cmd, caddr_t arg) +{ + int ret; + u32 oldinfo; + int w; + + struct nm256_info *card = nm256_find_card (dev); + + if (card == NULL) + return -ENODEV; + + if (dev == card->dev[0]) + w = 0; + else + w = 1; + + switch (cmd) + { + case SOUND_PCM_WRITE_RATE: + get_user_ret(ret, (int *) arg, -EFAULT); + + if (ret != 0) { + oldinfo = card->sinfo[w].samplerate; + card->sinfo[w].samplerate = ret; + ret = nm256_setInfo(dev, card); + if (ret != 0) + card->sinfo[w].samplerate = oldinfo; + } + if (ret == 0) + ret = card->sinfo[w].samplerate; + break; + + case SOUND_PCM_READ_RATE: + ret = card->sinfo[w].samplerate; + break; + + case SNDCTL_DSP_STEREO: + get_user_ret(ret, (int *) arg, -EFAULT); + + card->sinfo[w].stereo = ret ? 1 : 0; + ret = nm256_setInfo (dev, card); + if (ret == 0) + ret = card->sinfo[w].stereo; + + break; + + case SOUND_PCM_WRITE_CHANNELS: + get_user_ret(ret, (int *) arg, -EFAULT); + + if (ret < 1 || ret > 3) + ret = card->sinfo[w].stereo + 1; + else { + card->sinfo[w].stereo = ret - 1; + ret = nm256_setInfo (dev, card); + if (ret == 0) + ret = card->sinfo[w].stereo + 1; + } + break; + + case SOUND_PCM_READ_CHANNELS: + ret = card->sinfo[w].stereo + 1; + break; + + case SNDCTL_DSP_SETFMT: + get_user_ret(ret, (int *) arg, -EFAULT); + + if (ret != 0) { + oldinfo = card->sinfo[w].bits; + card->sinfo[w].bits = ret; + ret = nm256_setInfo (dev, card); + if (ret != 0) + card->sinfo[w].bits = oldinfo; + } + if (ret == 0) + ret = card->sinfo[w].bits; + break; + + case SOUND_PCM_READ_BITS: + ret = card->sinfo[w].bits; + break; + + default: + return -EINVAL; + } + return put_user(ret, (int *) arg); +} + +/* Given the dev DEV and an associated physical buffer PHYSBUF, return + a pointer to the actual buffer in kernel space. */ + +static char * +nm256_getDMAbuffer (int dev, unsigned long physbuf) +{ + struct audio_operations *adev = audio_devs[dev]; + struct dma_buffparms *dmap = adev->dmap_out; + char *dma_start = + (char *)(physbuf - (unsigned long)dmap->raw_buf_phys + + (unsigned long)dmap->raw_buf); + + return dma_start; +} + + +/* + * Output a block to sound device + * + * dev - device number + * buf - physical address of buffer + * total_count - total byte count in buffer + * intrflag - set if this has been called from an interrupt + * (via DMAbuf_outputintr) + * restart_dma - set if engine needs to be re-initialised + * + * Called when: + * 1. Starting output (dmabuf.c:1327) + * 2. (dmabuf.c:1504) + * 3. A new buffer needs to be sent to the device (dmabuf.c:1579) + */ +static void +nm256_audio_output_block(int dev, unsigned long physbuf, + int total_count, int intrflag) +{ + struct nm256_info *card = nm256_find_card (dev); + + if (card != NULL) { + char *dma_buf = nm256_getDMAbuffer (dev, physbuf); + card->is_open_play = 1; + card->dev_for_play = dev; + nm256_write_block (card, dma_buf, total_count); + } +} + +static void +nm256_audio_start_input(int dev, unsigned long physbuf, int count, + int intrflag) +{ + struct nm256_info *card = nm256_find_card (dev); + + if (card != NULL) { + char *dma_buf = nm256_getDMAbuffer (dev, physbuf); + card->is_open_record = 1; + card->dev_for_record = dev; + nm256_startRecording (card, dma_buf, count); + } +} + +static int +nm256_audio_prepare_for_input(int dev, int bsize, int bcount) +{ + struct nm256_info *card = nm256_find_card (dev); + + if (card == NULL) + return -ENODEV; + + if (card->is_open_record && card->dev_for_record != dev) + return -EBUSY; + + audio_devs[dev]->dmap_in->flags |= DMA_NODMA; + return 0; +} + +/* + * Prepare for outputting samples to `dev' + * + * Each buffer that will be passed will be `bsize' bytes long, + * with a total of `bcount' buffers. + * + * Called when: + * 1. A trigger enables audio output (dmabuf.c:978) + * 2. We get a write buffer without dma_mode setup (dmabuf.c:1152) + * 3. We restart a transfer (dmabuf.c:1324) + */ +static int +nm256_audio_prepare_for_output(int dev, int bsize, int bcount) +{ + struct nm256_info *card = nm256_find_card (dev); + + if (card == NULL) + return -ENODEV; + + if (card->is_open_play && card->dev_for_play != dev) + return -EBUSY; + + audio_devs[dev]->dmap_out->flags |= DMA_NODMA; + return 0; +} + +/* Stop the current operations associated with DEV. */ +static void +nm256_audio_reset(int dev) +{ + struct nm256_info *card = nm256_find_card (dev); + + if (card != NULL) { + if (card->dev_for_play == dev) + stopPlay (card); + if (card->dev_for_record == dev) + stopRecord (card); + } +} + +static int +nm256_audio_local_qlen(int dev) +{ + return 0; +} + +static struct audio_driver nm256_audio_driver = +{ + nm256_audio_open, /* open */ + nm256_audio_close, /* close */ + nm256_audio_output_block, /* output_block */ + nm256_audio_start_input, /* start_input */ + nm256_audio_ioctl, /* ioctl */ + nm256_audio_prepare_for_input, /* prepare_for_input */ + nm256_audio_prepare_for_output, /* prepare_for_output */ + nm256_audio_reset, /* reset */ + nm256_audio_local_qlen, /*+local_qlen */ + NULL, /*+copy_from_user */ + NULL, /*+halt_input */ + NULL, /* halt_output */ + NULL, /*+trigger */ + NULL, /*+set_speed */ + NULL, /*+set_bits */ + NULL, /*+set_channels */ +}; + +EXPORT_SYMBOL(init_nm256); + +#ifdef MODULE + +static int loaded = 0; + +MODULE_PARM (usecache, "i"); +MODULE_PARM (buffertop, "i"); +MODULE_PARM (nm256_debug, "i"); + +int +init_module (void) +{ + nmcard_list = NULL; + printk (KERN_INFO "NeoMagic 256AV/256ZX audio driver, version 1.0\n"); + + if (init_nm256 () == 0) { + SOUND_LOCK; + loaded = 1; + return 0; + } + else + return -ENODEV; +} + +void +cleanup_module (void) +{ + if (loaded) { + struct nm256_info *card; + struct nm256_info *next_card; + + SOUND_LOCK_END; + + for (card = nmcard_list; card != NULL; card = next_card) { + stopPlay (card); + stopRecord (card); + if (card->has_irq) + free_irq (card->irq, card); + release_region ((unsigned long) card->ports[0], + card->port1_end - card->port1_start); + release_region ((unsigned long) card->ports[1], NM_PORT2_SIZE); + sound_unload_mixerdev (card->mixer_oss_dev); + sound_unload_audiodev (card->dev[0]); + sound_unload_audiodev (card->dev[1]); + next_card = card->next_card; + kfree_s (card, sizeof (struct nm256_info)); + } + nmcard_list = NULL; + } +} +#endif + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sound/nm256_coeff.h linux.ac/drivers/sound/nm256_coeff.h --- linux.vanilla/drivers/sound/nm256_coeff.h Thu Jan 1 01:00:00 1970 +++ linux.ac/drivers/sound/nm256_coeff.h Sat Sep 18 18:23:54 1999 @@ -0,0 +1,4693 @@ +#ifndef NM256_COEFF_H +#define NM256_COEFF_H + +#define NM_TOTAL_COEFF_COUNT 0x3158 + +static char coefficients[NM_TOTAL_COEFF_COUNT * 4] = { + 0xFF, 0xFF, 0x2F, 0x00, 0x4B, 0xFF, 0xA5, 0x01, 0xEF, 0xFC, 0x21, + 0x05, 0x87, 0xF7, 0x62, 0x11, 0xE9, 0x45, 0x5E, 0xF9, 0xB5, 0x01, + 0xDE, 0xFF, 0xA4, 0xFF, 0x60, 0x00, 0xCA, 0xFF, 0x0D, 0x00, 0xFD, + 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3D, 0xFC, 0xD6, 0x06, + 0x4C, 0xF3, 0xED, 0x20, 0x3D, 0x3D, 0x4A, 0xF3, 0x4E, 0x05, 0xB1, + 0xFD, 0xE1, 0x00, 0xC3, 0xFF, 0x05, 0x00, 0x02, 0x00, 0xFD, 0xFF, + 0x2A, 0x00, 0x5C, 0xFF, 0xAA, 0x01, 0x71, 0xFC, 0x07, 0x07, 0x7E, + 0xF1, 0x44, 0x30, 0x44, 0x30, 0x7E, 0xF1, 0x07, 0x07, 0x71, 0xFC, + 0xAA, 0x01, 0x5C, 0xFF, 0x2A, 0x00, 0xFD, 0xFF, 0x02, 0x00, 0x05, + 0x00, 0xC3, 0xFF, 0xE1, 0x00, 0xB1, 0xFD, 0x4E, 0x05, 0x4A, 0xF3, + 0x3D, 0x3D, 0xED, 0x20, 0x4C, 0xF3, 0xD6, 0x06, 0x3D, 0xFC, 0xE6, + 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x0D, 0x00, 0xCA, 0xFF, + 0x60, 0x00, 0xA4, 0xFF, 0xDE, 0xFF, 0xB5, 0x01, 0x5E, 0xF9, 0xE9, + 0x45, 0x62, 0x11, 0x87, 0xF7, 0x21, 0x05, 0xEF, 0xFC, 0xA5, 0x01, + 0x4B, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x1E, 0x00, 0x84, + 0xFF, 0x11, 0x01, 0x34, 0xFE, 0x8F, 0x02, 0xC7, 0xFC, 0xAE, 0x03, + 0xF7, 0x48, 0xAE, 0x03, 0xC7, 0xFC, 0x8F, 0x02, 0x34, 0xFE, 0x11, + 0x01, 0x84, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3D, 0xFF, + 0xCA, 0x01, 0x95, 0xFC, 0xEA, 0x05, 0xBB, 0xF5, 0x25, 0x17, 0x3C, + 0x43, 0x8D, 0xF6, 0x43, 0x03, 0xF5, 0xFE, 0x26, 0x00, 0x20, 0x00, + 0xE2, 0xFF, 0x08, 0x00, 0xFD, 0xFF, 0x30, 0x00, 0x4D, 0xFF, 0xC5, + 0x01, 0x4C, 0xFC, 0x26, 0x07, 0xA3, 0xF1, 0xAB, 0x2C, 0xBB, 0x33, + 0x8F, 0xF1, 0xCA, 0x06, 0xA6, 0xFC, 0x85, 0x01, 0x6F, 0xFF, 0x24, + 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFE, 0xFF, 0xD5, 0xFF, 0xBC, 0x00, + 0xF0, 0xFD, 0xEC, 0x04, 0xD9, 0xF3, 0xB1, 0x3E, 0xCD, 0x1E, 0xC1, + 0xF3, 0xAF, 0x06, 0x49, 0xFC, 0xE4, 0x01, 0x36, 0xFF, 0x36, 0x00, + 0xFE, 0xFF, 0x16, 0x00, 0xA6, 0xFF, 0xBB, 0x00, 0xE9, 0xFE, 0x38, + 0x01, 0x4B, 0xFF, 0x28, 0xFE, 0x3A, 0x48, 0x04, 0x0A, 0x2E, 0xFA, + 0xDF, 0x03, 0x8A, 0xFD, 0x60, 0x01, 0x65, 0xFF, 0x27, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0x2E, 0x00, 0x50, 0xFF, 0x98, 0x01, 0x0D, 0xFD, + 0xE0, 0x04, 0x14, 0xF8, 0xC3, 0x0F, 0x89, 0x46, 0x4C, 0xFA, 0x38, + 0x01, 0x25, 0x00, 0x7D, 0xFF, 0x73, 0x00, 0xC2, 0xFF, 0x0F, 0x00, + 0xFD, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xE3, 0x01, 0x31, 0xFC, 0x0F, + 0x07, 0x84, 0xF2, 0x29, 0x25, 0x1A, 0x3A, 0x67, 0xF2, 0xF6, 0x05, + 0x41, 0xFD, 0x24, 0x01, 0xA1, 0xFF, 0x12, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0x15, 0x00, 0x97, 0xFF, 0x37, 0x01, 0x22, 0xFD, 0x23, 0x06, + 0x2F, 0xF2, 0x11, 0x39, 0x7B, 0x26, 0x50, 0xF2, 0x1B, 0x07, 0x32, + 0xFC, 0xE1, 0x01, 0x3C, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0E, 0x00, + 0xC8, 0xFF, 0x64, 0x00, 0x9B, 0xFF, 0xEE, 0xFF, 0x98, 0x01, 0x93, + 0xF9, 0x10, 0x46, 0x03, 0x11, 0xA7, 0xF7, 0x12, 0x05, 0xF6, 0xFC, + 0xA2, 0x01, 0x4C, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x26, + 0x00, 0x6A, 0xFF, 0x53, 0x01, 0xA6, 0xFD, 0xA6, 0x03, 0xA1, 0xFA, + 0xDE, 0x08, 0x76, 0x48, 0x0C, 0xFF, 0xDE, 0xFE, 0x73, 0x01, 0xC9, + 0xFE, 0xCA, 0x00, 0xA0, 0xFF, 0x17, 0x00, 0xFE, 0xFF, 0x36, 0x00, + 0x36, 0xFF, 0xE1, 0x01, 0x52, 0xFC, 0x93, 0x06, 0x10, 0xF4, 0x78, + 0x1D, 0x90, 0x3F, 0x3E, 0xF4, 0xAA, 0x04, 0x19, 0xFE, 0xA4, 0x00, + 0xE2, 0xFF, 0xFA, 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0x26, 0x00, 0x68, + 0xFF, 0x93, 0x01, 0x92, 0xFC, 0xE2, 0x06, 0x83, 0xF1, 0x8C, 0x32, + 0xED, 0x2D, 0x90, 0xF1, 0x1E, 0x07, 0x57, 0xFC, 0xBD, 0x01, 0x51, + 0xFF, 0x2E, 0x00, 0xFD, 0xFF, 0x07, 0x00, 0xE8, 0xFF, 0x12, 0x00, + 0x42, 0x00, 0xC4, 0xFE, 0x94, 0x03, 0x02, 0xF6, 0x89, 0x42, 0x76, + 0x18, 0x5C, 0xF5, 0x12, 0x06, 0x84, 0xFC, 0xD1, 0x01, 0x3B, 0xFF, + 0x34, 0x00, 0xFE, 0xFF, 0x1D, 0x00, 0x8A, 0xFF, 0x03, 0x01, 0x53, + 0xFE, 0x53, 0x02, 0x39, 0xFD, 0xA9, 0x02, 0xF2, 0x48, 0xB9, 0x04, + 0x54, 0xFC, 0xCA, 0x02, 0x16, 0xFE, 0x20, 0x01, 0x7F, 0xFF, 0x20, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x40, 0xFF, 0xC3, 0x01, + 0xA7, 0xFC, 0xC0, 0x05, 0x1E, 0xF6, 0xD8, 0x15, 0xE7, 0x43, 0x20, + 0xF7, 0xEF, 0x02, 0x27, 0xFF, 0x0A, 0x00, 0x2E, 0x00, 0xDD, 0xFF, + 0x09, 0x00, 0xFD, 0xFF, 0x31, 0x00, 0x48, 0xFF, 0xCD, 0x01, 0x43, + 0xFC, 0x2A, 0x07, 0xBC, 0xF1, 0x64, 0x2B, 0xE3, 0x34, 0xA3, 0xF1, + 0xAE, 0x06, 0xBD, 0xFC, 0x77, 0x01, 0x77, 0xFF, 0x21, 0x00, 0xFE, + 0xFF, 0x02, 0x00, 0x03, 0x00, 0xCA, 0xFF, 0xD4, 0x00, 0xC8, 0xFD, + 0x2A, 0x05, 0x7D, 0xF3, 0xCA, 0x3D, 0x22, 0x20, 0x76, 0xF3, 0xC8, + 0x06, 0x41, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, + 0x14, 0x00, 0xAC, 0xFF, 0xAC, 0x00, 0x08, 0xFF, 0xFD, 0x00, 0xB5, + 0xFF, 0x4B, 0xFD, 0xF4, 0x47, 0x30, 0x0B, 0xBC, 0xF9, 0x17, 0x04, + 0x6E, 0xFD, 0x6D, 0x01, 0x60, 0xFF, 0x29, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0x2C, 0x00, 0x54, 0xFF, 0x8D, 0x01, 0x26, 0xFD, 0xAD, 0x04, + 0x82, 0xF8, 0x87, 0x0E, 0xF9, 0x46, 0x0C, 0xFB, 0xD4, 0x00, 0x5D, + 0x00, 0x5E, 0xFF, 0x82, 0x00, 0xBD, 0xFF, 0x10, 0x00, 0xFD, 0xFF, + 0x36, 0x00, 0x38, 0xFF, 0xE5, 0x01, 0x33, 0xFC, 0x01, 0x07, 0xBE, + 0xF2, 0xD6, 0x23, 0x1F, 0x3B, 0xA5, 0xF2, 0xC5, 0x05, 0x62, 0xFD, + 0x10, 0x01, 0xAB, 0xFF, 0x0E, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x19, + 0x00, 0x8E, 0xFF, 0x49, 0x01, 0x04, 0xFD, 0x4D, 0x06, 0x00, 0xF2, + 0xFE, 0x37, 0xCB, 0x27, 0x21, 0xF2, 0x23, 0x07, 0x34, 0xFC, 0xDD, + 0x01, 0x3F, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0C, 0x00, 0xCE, 0xFF, + 0x56, 0x00, 0xB9, 0xFF, 0xB8, 0xFF, 0xF7, 0x01, 0xE2, 0xF8, 0x8D, + 0x45, 0x46, 0x12, 0x3C, 0xF7, 0x43, 0x05, 0xDF, 0xFC, 0xAC, 0x01, + 0x48, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x24, 0x00, 0x70, + 0xFF, 0x46, 0x01, 0xC3, 0xFD, 0x6D, 0x03, 0x14, 0xFB, 0xBE, 0x07, + 0xA6, 0x48, 0xF8, 0xFF, 0x70, 0xFE, 0xAE, 0x01, 0xAA, 0xFE, 0xD9, + 0x00, 0x9A, 0xFF, 0x19, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, + 0xDE, 0x01, 0x5D, 0xFC, 0x74, 0x06, 0x63, 0xF4, 0x23, 0x1C, 0x66, + 0x40, 0xAA, 0xF4, 0x65, 0x04, 0x44, 0xFE, 0x8B, 0x00, 0xEE, 0xFF, + 0xF5, 0xFF, 0x04, 0x00, 0xFD, 0xFF, 0x29, 0x00, 0x61, 0xFF, 0x9F, + 0x01, 0x80, 0xFC, 0xF7, 0x06, 0x7D, 0xF1, 0x5A, 0x31, 0x2C, 0x2F, + 0x83, 0xF1, 0x13, 0x07, 0x64, 0xFC, 0xB3, 0x01, 0x57, 0xFF, 0x2C, + 0x00, 0xFD, 0xFF, 0x06, 0x00, 0xED, 0xFF, 0x05, 0x00, 0x5D, 0x00, + 0x95, 0xFE, 0xE2, 0x03, 0x7F, 0xF5, 0xCC, 0x41, 0xC7, 0x19, 0xFF, + 0xF4, 0x37, 0x06, 0x75, 0xFC, 0xD6, 0x01, 0x39, 0xFF, 0x35, 0x00, + 0xFE, 0xFF, 0x1B, 0x00, 0x90, 0xFF, 0xF4, 0x00, 0x72, 0xFE, 0x18, + 0x02, 0xAA, 0xFD, 0xAB, 0x01, 0xDF, 0x48, 0xCA, 0x05, 0xE1, 0xFB, + 0x05, 0x03, 0xF7, 0xFD, 0x2E, 0x01, 0x79, 0xFF, 0x21, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x43, 0xFF, 0xBB, 0x01, 0xBA, 0xFC, + 0x95, 0x05, 0x83, 0xF6, 0x8C, 0x14, 0x87, 0x44, 0xBB, 0xF7, 0x98, + 0x02, 0x5A, 0xFF, 0xEE, 0xFF, 0x3C, 0x00, 0xD8, 0xFF, 0x0A, 0x00, + 0xFD, 0xFF, 0x32, 0x00, 0x44, 0xFF, 0xD3, 0x01, 0x3C, 0xFC, 0x2A, + 0x07, 0xDC, 0xF1, 0x1A, 0x2A, 0x06, 0x36, 0xBE, 0xF1, 0x8E, 0x06, + 0xD5, 0xFC, 0x67, 0x01, 0x7F, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x01, + 0x00, 0x07, 0x00, 0xBE, 0xFF, 0xEA, 0x00, 0xA2, 0xFD, 0x65, 0x05, + 0x28, 0xF3, 0xDB, 0x3C, 0x78, 0x21, 0x30, 0xF3, 0xDF, 0x06, 0x3A, + 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x13, 0x00, + 0xB2, 0xFF, 0x9D, 0x00, 0x27, 0xFF, 0xC3, 0x00, 0x1F, 0x00, 0x76, + 0xFC, 0xA3, 0x47, 0x60, 0x0C, 0x4A, 0xF9, 0x4E, 0x04, 0x53, 0xFD, + 0x79, 0x01, 0x5C, 0xFF, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, + 0x00, 0x58, 0xFF, 0x82, 0x01, 0x3F, 0xFD, 0x78, 0x04, 0xF2, 0xF8, + 0x50, 0x0D, 0x5E, 0x47, 0xD5, 0xFB, 0x6F, 0x00, 0x96, 0x00, 0x40, + 0xFF, 0x91, 0x00, 0xB7, 0xFF, 0x12, 0x00, 0xFD, 0xFF, 0x36, 0x00, + 0x37, 0xFF, 0xE6, 0x01, 0x36, 0xFC, 0xEF, 0x06, 0xFC, 0xF2, 0x81, + 0x22, 0x1C, 0x3C, 0xEC, 0xF2, 0x90, 0x05, 0x85, 0xFD, 0xFB, 0x00, + 0xB6, 0xFF, 0x0A, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1C, 0x00, 0x85, + 0xFF, 0x5B, 0x01, 0xE9, 0xFC, 0x73, 0x06, 0xD8, 0xF1, 0xE5, 0x36, + 0x19, 0x29, 0xF8, 0xF1, 0x29, 0x07, 0x37, 0xFC, 0xD8, 0x01, 0x42, + 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0x0B, 0x00, 0xD3, 0xFF, 0x47, 0x00, + 0xD7, 0xFF, 0x82, 0xFF, 0x53, 0x02, 0x39, 0xF8, 0xFD, 0x44, 0x8D, + 0x13, 0xD3, 0xF6, 0x72, 0x05, 0xCA, 0xFC, 0xB5, 0x01, 0x45, 0xFF, + 0x31, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x23, 0x00, 0x75, 0xFF, 0x39, + 0x01, 0xE0, 0xFD, 0x33, 0x03, 0x87, 0xFB, 0xA2, 0x06, 0xCB, 0x48, + 0xEA, 0x00, 0x01, 0xFE, 0xE9, 0x01, 0x8A, 0xFE, 0xE8, 0x00, 0x95, + 0xFF, 0x1A, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x38, 0xFF, 0xDA, 0x01, + 0x6A, 0xFC, 0x53, 0x06, 0xBA, 0xF4, 0xCE, 0x1A, 0x32, 0x41, 0x1F, + 0xF5, 0x1D, 0x04, 0x71, 0xFE, 0x71, 0x00, 0xFB, 0xFF, 0xF0, 0xFF, + 0x05, 0x00, 0xFD, 0xFF, 0x2B, 0x00, 0x5B, 0xFF, 0xAB, 0x01, 0x6F, + 0xFC, 0x08, 0x07, 0x7E, 0xF1, 0x21, 0x30, 0x67, 0x30, 0x7D, 0xF1, + 0x05, 0x07, 0x73, 0xFC, 0xA8, 0x01, 0x5C, 0xFF, 0x2A, 0x00, 0xFD, + 0xFF, 0x05, 0x00, 0xF2, 0xFF, 0xF8, 0xFF, 0x77, 0x00, 0x67, 0xFE, + 0x2D, 0x04, 0x04, 0xF5, 0x07, 0x41, 0x1B, 0x1B, 0xA6, 0xF4, 0x5A, + 0x06, 0x67, 0xFC, 0xDB, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, + 0x1A, 0x00, 0x96, 0xFF, 0xE5, 0x00, 0x91, 0xFE, 0xDC, 0x01, 0x1A, + 0xFE, 0xB3, 0x00, 0xC3, 0x48, 0xE1, 0x06, 0x6E, 0xFB, 0x40, 0x03, + 0xDA, 0xFD, 0x3C, 0x01, 0x74, 0xFF, 0x23, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0x31, 0x00, 0x46, 0xFF, 0xB3, 0x01, 0xCF, 0xFC, 0x67, 0x05, + 0xEA, 0xF6, 0x44, 0x13, 0x1E, 0x45, 0x5E, 0xF8, 0x3F, 0x02, 0x8E, + 0xFF, 0xD0, 0xFF, 0x4A, 0x00, 0xD2, 0xFF, 0x0B, 0x00, 0xFD, 0xFF, + 0x33, 0x00, 0x41, 0xFF, 0xD9, 0x01, 0x36, 0xFC, 0x28, 0x07, 0x01, + 0xF2, 0xCE, 0x28, 0x23, 0x37, 0xE0, 0xF1, 0x6B, 0x06, 0xEF, 0xFC, + 0x57, 0x01, 0x87, 0xFF, 0x1B, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x0B, + 0x00, 0xB4, 0xFF, 0x00, 0x01, 0x7E, 0xFD, 0x9C, 0x05, 0xDC, 0xF2, + 0xE4, 0x3B, 0xCD, 0x22, 0xEE, 0xF2, 0xF3, 0x06, 0x35, 0xFC, 0xE6, + 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x11, 0x00, 0xB8, 0xFF, + 0x8E, 0x00, 0x46, 0xFF, 0x8A, 0x00, 0x86, 0x00, 0xA7, 0xFB, 0x48, + 0x47, 0x95, 0x0D, 0xD9, 0xF8, 0x84, 0x04, 0x39, 0xFD, 0x85, 0x01, + 0x57, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5D, + 0xFF, 0x76, 0x01, 0x59, 0xFD, 0x42, 0x04, 0x63, 0xF9, 0x1C, 0x0C, + 0xB6, 0x47, 0xA4, 0xFC, 0x07, 0x00, 0xD0, 0x00, 0x20, 0xFF, 0xA0, + 0x00, 0xB1, 0xFF, 0x13, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, + 0xE6, 0x01, 0x3B, 0xFC, 0xDA, 0x06, 0x3F, 0xF3, 0x2C, 0x21, 0x11, + 0x3D, 0x3A, 0xF3, 0x58, 0x05, 0xAA, 0xFD, 0xE5, 0x00, 0xC1, 0xFF, + 0x06, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1F, 0x00, 0x7D, 0xFF, 0x6B, + 0x01, 0xCF, 0xFC, 0x96, 0x06, 0xB7, 0xF1, 0xC6, 0x35, 0x64, 0x2A, + 0xD4, 0xF1, 0x2B, 0x07, 0x3D, 0xFC, 0xD2, 0x01, 0x45, 0xFF, 0x32, + 0x00, 0xFD, 0xFF, 0x0A, 0x00, 0xD9, 0xFF, 0x39, 0x00, 0xF4, 0xFF, + 0x4E, 0xFF, 0xAC, 0x02, 0x98, 0xF7, 0x65, 0x44, 0xD6, 0x14, 0x6C, + 0xF6, 0x9F, 0x05, 0xB6, 0xFC, 0xBD, 0x01, 0x42, 0xFF, 0x32, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x21, 0x00, 0x7A, 0xFF, 0x2B, 0x01, 0xFE, + 0xFD, 0xF8, 0x02, 0xFB, 0xFB, 0x8D, 0x05, 0xE5, 0x48, 0xE3, 0x01, + 0x91, 0xFD, 0x25, 0x02, 0x6B, 0xFE, 0xF7, 0x00, 0x8F, 0xFF, 0x1C, + 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD5, 0x01, 0x78, 0xFC, + 0x2F, 0x06, 0x13, 0xF5, 0x7C, 0x19, 0xF7, 0x41, 0x9B, 0xF5, 0xD1, + 0x03, 0x9F, 0xFE, 0x57, 0x00, 0x08, 0x00, 0xEC, 0xFF, 0x06, 0x00, + 0xFD, 0xFF, 0x2D, 0x00, 0x55, 0xFF, 0xB5, 0x01, 0x61, 0xFC, 0x16, + 0x07, 0x85, 0xF1, 0xE6, 0x2E, 0x9E, 0x31, 0x7D, 0xF1, 0xF3, 0x06, + 0x84, 0xFC, 0x9D, 0x01, 0x63, 0xFF, 0x28, 0x00, 0xFD, 0xFF, 0x04, + 0x00, 0xF6, 0xFF, 0xEB, 0xFF, 0x91, 0x00, 0x3B, 0xFE, 0x75, 0x04, + 0x92, 0xF4, 0x36, 0x40, 0x6E, 0x1C, 0x50, 0xF4, 0x7B, 0x06, 0x5B, + 0xFC, 0xDF, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x18, 0x00, + 0x9C, 0xFF, 0xD6, 0x00, 0xB1, 0xFE, 0xA1, 0x01, 0x89, 0xFE, 0xC3, + 0xFF, 0x9C, 0x48, 0xFD, 0x07, 0xFA, 0xFA, 0x7A, 0x03, 0xBC, 0xFD, + 0x49, 0x01, 0x6E, 0xFF, 0x24, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30, + 0x00, 0x49, 0xFF, 0xAA, 0x01, 0xE4, 0xFC, 0x38, 0x05, 0x54, 0xF7, + 0xFE, 0x11, 0xAA, 0x45, 0x09, 0xF9, 0xE2, 0x01, 0xC4, 0xFF, 0xB3, + 0xFF, 0x59, 0x00, 0xCD, 0xFF, 0x0D, 0x00, 0xFD, 0xFF, 0x34, 0x00, + 0x3E, 0xFF, 0xDE, 0x01, 0x33, 0xFC, 0x22, 0x07, 0x2B, 0xF2, 0x80, + 0x27, 0x3B, 0x38, 0x0A, 0xF2, 0x44, 0x06, 0x0B, 0xFD, 0x45, 0x01, + 0x90, 0xFF, 0x18, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0x00, 0xA9, + 0xFF, 0x15, 0x01, 0x5B, 0xFD, 0xD0, 0x05, 0x97, 0xF2, 0xE6, 0x3A, + 0x21, 0x24, 0xB1, 0xF2, 0x04, 0x07, 0x33, 0xFC, 0xE5, 0x01, 0x39, + 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x10, 0x00, 0xBE, 0xFF, 0x7F, 0x00, + 0x65, 0xFF, 0x51, 0x00, 0xEB, 0x00, 0xE1, 0xFA, 0xE1, 0x46, 0xCD, + 0x0E, 0x6A, 0xF8, 0xB8, 0x04, 0x20, 0xFD, 0x90, 0x01, 0x53, 0xFF, + 0x2D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x28, 0x00, 0x62, 0xFF, 0x6A, + 0x01, 0x74, 0xFD, 0x0A, 0x04, 0xD5, 0xF9, 0xED, 0x0A, 0x03, 0x48, + 0x7C, 0xFD, 0x9E, 0xFF, 0x0A, 0x01, 0x01, 0xFF, 0xAF, 0x00, 0xAB, + 0xFF, 0x14, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE5, 0x01, + 0x42, 0xFC, 0xC3, 0x06, 0x87, 0xF3, 0xD7, 0x1F, 0xFE, 0x3D, 0x91, + 0xF3, 0x1D, 0x05, 0xD1, 0xFD, 0xCE, 0x00, 0xCC, 0xFF, 0x02, 0x00, + 0x02, 0x00, 0xFE, 0xFF, 0x22, 0x00, 0x75, 0xFF, 0x7A, 0x01, 0xB8, + 0xFC, 0xB4, 0x06, 0x9E, 0xF1, 0xA2, 0x34, 0xAD, 0x2B, 0xB6, 0xF1, + 0x29, 0x07, 0x45, 0xFC, 0xCB, 0x01, 0x49, 0xFF, 0x31, 0x00, 0xFD, + 0xFF, 0x09, 0x00, 0xDE, 0xFF, 0x2B, 0x00, 0x11, 0x00, 0x1B, 0xFF, + 0x02, 0x03, 0xFE, 0xF6, 0xC3, 0x43, 0x22, 0x16, 0x07, 0xF6, 0xCA, + 0x05, 0xA3, 0xFC, 0xC5, 0x01, 0x3F, 0xFF, 0x33, 0x00, 0xFF, 0xFF, + 0x00, 0x00, 0x20, 0x00, 0x80, 0xFF, 0x1C, 0x01, 0x1C, 0xFE, 0xBD, + 0x02, 0x6E, 0xFC, 0x7D, 0x04, 0xF3, 0x48, 0xE2, 0x02, 0x1F, 0xFD, + 0x60, 0x02, 0x4C, 0xFE, 0x06, 0x01, 0x89, 0xFF, 0x1D, 0x00, 0xFE, + 0xFF, 0x34, 0x00, 0x3C, 0xFF, 0xCF, 0x01, 0x88, 0xFC, 0x09, 0x06, + 0x71, 0xF5, 0x2B, 0x18, 0xB2, 0x42, 0x20, 0xF6, 0x83, 0x03, 0xCF, + 0xFE, 0x3C, 0x00, 0x15, 0x00, 0xE6, 0xFF, 0x07, 0x00, 0xFD, 0xFF, + 0x2E, 0x00, 0x50, 0xFF, 0xBF, 0x01, 0x54, 0xFC, 0x20, 0x07, 0x94, + 0xF1, 0xA6, 0x2D, 0xD0, 0x32, 0x85, 0xF1, 0xDD, 0x06, 0x96, 0xFC, + 0x90, 0x01, 0x69, 0xFF, 0x26, 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFB, + 0xFF, 0xDF, 0xFF, 0xA9, 0x00, 0x10, 0xFE, 0xB9, 0x04, 0x27, 0xF4, + 0x5E, 0x3F, 0xC3, 0x1D, 0xFE, 0xF3, 0x99, 0x06, 0x50, 0xFC, 0xE2, + 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x17, 0x00, 0xA2, 0xFF, + 0xC7, 0x00, 0xD0, 0xFE, 0x65, 0x01, 0xF6, 0xFE, 0xD9, 0xFE, 0x6A, + 0x48, 0x1F, 0x09, 0x87, 0xFA, 0xB3, 0x03, 0xA0, 0xFD, 0x56, 0x01, + 0x69, 0xFF, 0x26, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4D, + 0xFF, 0xA0, 0x01, 0xFB, 0xFC, 0x07, 0x05, 0xBF, 0xF7, 0xBB, 0x10, + 0x2B, 0x46, 0xBB, 0xF9, 0x83, 0x01, 0xFA, 0xFF, 0x95, 0xFF, 0x68, + 0x00, 0xC7, 0xFF, 0x0E, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3C, 0xFF, + 0xE1, 0x01, 0x31, 0xFC, 0x19, 0x07, 0x5B, 0xF2, 0x30, 0x26, 0x4B, + 0x39, 0x3B, 0xF2, 0x1A, 0x06, 0x29, 0xFD, 0x33, 0x01, 0x99, 0xFF, + 0x15, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x13, 0x00, 0x9F, 0xFF, 0x28, + 0x01, 0x3A, 0xFD, 0x00, 0x06, 0x5A, 0xF2, 0xDF, 0x39, 0x73, 0x25, + 0x79, 0xF2, 0x12, 0x07, 0x31, 0xFC, 0xE3, 0x01, 0x3B, 0xFF, 0x35, + 0x00, 0xFD, 0xFF, 0x0F, 0x00, 0xC4, 0xFF, 0x70, 0x00, 0x84, 0xFF, + 0x19, 0x00, 0x4D, 0x01, 0x22, 0xFA, 0x70, 0x46, 0x0A, 0x10, 0xFC, + 0xF7, 0xEB, 0x04, 0x08, 0xFD, 0x9A, 0x01, 0x4F, 0xFF, 0x2E, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x27, 0x00, 0x66, 0xFF, 0x5E, 0x01, 0x90, + 0xFD, 0xD2, 0x03, 0x47, 0xFA, 0xC3, 0x09, 0x48, 0x48, 0x5A, 0xFE, + 0x33, 0xFF, 0x45, 0x01, 0xE2, 0xFE, 0xBE, 0x00, 0xA5, 0xFF, 0x16, + 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE3, 0x01, 0x4B, 0xFC, + 0xA9, 0x06, 0xD2, 0xF3, 0x81, 0x1E, 0xE4, 0x3E, 0xEF, 0xF3, 0xDE, + 0x04, 0xF9, 0xFD, 0xB7, 0x00, 0xD8, 0xFF, 0xFD, 0xFF, 0x03, 0x00, + 0xFD, 0xFF, 0x24, 0x00, 0x6D, 0xFF, 0x88, 0x01, 0xA2, 0xFC, 0xD0, + 0x06, 0x8C, 0xF1, 0x78, 0x33, 0xF2, 0x2C, 0x9E, 0xF1, 0x24, 0x07, + 0x4E, 0xFC, 0xC3, 0x01, 0x4E, 0xFF, 0x2F, 0x00, 0xFD, 0xFF, 0x08, + 0x00, 0xE4, 0xFF, 0x1D, 0x00, 0x2D, 0x00, 0xEA, 0xFE, 0x56, 0x03, + 0x6D, 0xF6, 0x17, 0x43, 0x70, 0x17, 0xA6, 0xF5, 0xF3, 0x05, 0x91, + 0xFC, 0xCC, 0x01, 0x3D, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x1E, 0x00, + 0x86, 0xFF, 0x0E, 0x01, 0x3B, 0xFE, 0x82, 0x02, 0xE0, 0xFC, 0x73, + 0x03, 0xF6, 0x48, 0xE9, 0x03, 0xAD, 0xFC, 0x9C, 0x02, 0x2D, 0xFE, + 0x14, 0x01, 0x83, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, + 0x00, 0x3E, 0xFF, 0xC9, 0x01, 0x99, 0xFC, 0xE1, 0x05, 0xD1, 0xF5, + 0xDC, 0x16, 0x65, 0x43, 0xAD, 0xF6, 0x31, 0x03, 0x00, 0xFF, 0x20, + 0x00, 0x23, 0x00, 0xE1, 0xFF, 0x08, 0x00, 0xFD, 0xFF, 0x30, 0x00, + 0x4C, 0xFF, 0xC7, 0x01, 0x4A, 0xFC, 0x27, 0x07, 0xA8, 0xF1, 0x62, + 0x2C, 0xFD, 0x33, 0x93, 0xF1, 0xC4, 0x06, 0xAB, 0xFC, 0x82, 0x01, + 0x71, 0xFF, 0x23, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0xFF, 0xFF, 0xD3, + 0xFF, 0xC1, 0x00, 0xE7, 0xFD, 0xFA, 0x04, 0xC4, 0xF3, 0x7E, 0x3E, + 0x19, 0x1F, 0xB0, 0xF3, 0xB5, 0x06, 0x47, 0xFC, 0xE4, 0x01, 0x36, + 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x15, 0x00, 0xA8, 0xFF, 0xB8, 0x00, + 0xF0, 0xFE, 0x2B, 0x01, 0x63, 0xFF, 0xF6, 0xFD, 0x2C, 0x48, 0x47, + 0x0A, 0x14, 0xFA, 0xEB, 0x03, 0x84, 0xFD, 0x63, 0x01, 0x64, 0xFF, + 0x27, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2D, 0x00, 0x51, 0xFF, 0x96, + 0x01, 0x13, 0xFD, 0xD5, 0x04, 0x2C, 0xF8, 0x7D, 0x0F, 0xA3, 0x46, + 0x76, 0xFA, 0x22, 0x01, 0x32, 0x00, 0x76, 0xFF, 0x76, 0x00, 0xC1, + 0xFF, 0x0F, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x3A, 0xFF, 0xE4, 0x01, + 0x32, 0xFC, 0x0C, 0x07, 0x91, 0xF2, 0xDD, 0x24, 0x54, 0x3A, 0x74, + 0xF2, 0xEB, 0x05, 0x49, 0xFD, 0x20, 0x01, 0xA3, 0xFF, 0x11, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0x16, 0x00, 0x95, 0xFF, 0x3B, 0x01, 0x1B, + 0xFD, 0x2D, 0x06, 0x24, 0xF2, 0xD3, 0x38, 0xC6, 0x26, 0x45, 0xF2, + 0x1D, 0x07, 0x32, 0xFC, 0xE0, 0x01, 0x3D, 0xFF, 0x35, 0x00, 0xFD, + 0xFF, 0x0D, 0x00, 0xC9, 0xFF, 0x61, 0x00, 0xA2, 0xFF, 0xE2, 0xFF, + 0xAE, 0x01, 0x6B, 0xF9, 0xF2, 0x45, 0x4A, 0x11, 0x8F, 0xF7, 0x1D, + 0x05, 0xF1, 0xFC, 0xA4, 0x01, 0x4B, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, + 0x00, 0x00, 0x25, 0x00, 0x6C, 0xFF, 0x51, 0x01, 0xAC, 0xFD, 0x9A, + 0x03, 0xBA, 0xFA, 0x9E, 0x08, 0x81, 0x48, 0x40, 0xFF, 0xC6, 0xFE, + 0x80, 0x01, 0xC2, 0xFE, 0xCE, 0x00, 0x9F, 0xFF, 0x17, 0x00, 0xFE, + 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE1, 0x01, 0x55, 0xFC, 0x8C, 0x06, + 0x22, 0xF4, 0x2C, 0x1D, 0xC0, 0x3F, 0x55, 0xF4, 0x9B, 0x04, 0x23, + 0xFE, 0x9F, 0x00, 0xE4, 0xFF, 0xF9, 0xFF, 0x04, 0x00, 0xFD, 0xFF, + 0x27, 0x00, 0x66, 0xFF, 0x96, 0x01, 0x8E, 0xFC, 0xE7, 0x06, 0x81, + 0xF1, 0x48, 0x32, 0x34, 0x2E, 0x8D, 0xF1, 0x1C, 0x07, 0x5A, 0xFC, + 0xBB, 0x01, 0x53, 0xFF, 0x2E, 0x00, 0xFD, 0xFF, 0x07, 0x00, 0xE9, + 0xFF, 0x0F, 0x00, 0x48, 0x00, 0xB9, 0xFE, 0xA6, 0x03, 0xE4, 0xF5, + 0x60, 0x42, 0xC1, 0x18, 0x47, 0xF5, 0x1A, 0x06, 0x81, 0xFC, 0xD2, + 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1C, 0x00, 0x8B, 0xFF, + 0xFF, 0x00, 0x5A, 0xFE, 0x46, 0x02, 0x52, 0xFD, 0x70, 0x02, 0xED, + 0x48, 0xF5, 0x04, 0x3B, 0xFC, 0xD7, 0x02, 0x0F, 0xFE, 0x23, 0x01, + 0x7E, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x40, + 0xFF, 0xC1, 0x01, 0xAB, 0xFC, 0xB7, 0x05, 0x34, 0xF6, 0x8E, 0x15, + 0x0B, 0x44, 0x42, 0xF7, 0xDC, 0x02, 0x32, 0xFF, 0x04, 0x00, 0x31, + 0x00, 0xDC, 0xFF, 0x09, 0x00, 0xFD, 0xFF, 0x31, 0x00, 0x47, 0xFF, + 0xCE, 0x01, 0x41, 0xFC, 0x2A, 0x07, 0xC2, 0xF1, 0x1B, 0x2B, 0x25, + 0x35, 0xA8, 0xF1, 0xA7, 0x06, 0xC2, 0xFC, 0x74, 0x01, 0x78, 0xFF, + 0x20, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0x04, 0x00, 0xC7, 0xFF, 0xD9, + 0x00, 0xBF, 0xFD, 0x38, 0x05, 0x69, 0xF3, 0x96, 0x3D, 0x6F, 0x20, + 0x66, 0xF3, 0xCE, 0x06, 0x3F, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, + 0x00, 0xFD, 0xFF, 0x14, 0x00, 0xAE, 0xFF, 0xA9, 0x00, 0x0F, 0xFF, + 0xF0, 0x00, 0xCD, 0xFF, 0x1B, 0xFD, 0xE4, 0x47, 0x73, 0x0B, 0xA2, + 0xF9, 0x23, 0x04, 0x68, 0xFD, 0x70, 0x01, 0x5F, 0xFF, 0x29, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0x2C, 0x00, 0x55, 0xFF, 0x8B, 0x01, 0x2B, + 0xFD, 0xA1, 0x04, 0x9B, 0xF8, 0x42, 0x0E, 0x0F, 0x47, 0x38, 0xFB, + 0xBE, 0x00, 0x6A, 0x00, 0x58, 0xFF, 0x85, 0x00, 0xBB, 0xFF, 0x10, + 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE6, 0x01, 0x34, 0xFC, + 0xFD, 0x06, 0xCB, 0xF2, 0x8A, 0x23, 0x58, 0x3B, 0xB4, 0xF2, 0xBA, + 0x05, 0x6A, 0xFD, 0x0B, 0x01, 0xAE, 0xFF, 0x0D, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x19, 0x00, 0x8C, 0xFF, 0x4D, 0x01, 0xFE, 0xFC, 0x56, + 0x06, 0xF7, 0xF1, 0xBF, 0x37, 0x15, 0x28, 0x18, 0xF2, 0x25, 0x07, + 0x34, 0xFC, 0xDC, 0x01, 0x3F, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0C, + 0x00, 0xCF, 0xFF, 0x52, 0x00, 0xC0, 0xFF, 0xAC, 0xFF, 0x0C, 0x02, + 0xBC, 0xF8, 0x6D, 0x45, 0x8E, 0x12, 0x24, 0xF7, 0x4D, 0x05, 0xDB, + 0xFC, 0xAE, 0x01, 0x48, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0x00, 0x00, + 0x24, 0x00, 0x71, 0xFF, 0x43, 0x01, 0xC9, 0xFD, 0x60, 0x03, 0x2E, + 0xFB, 0x7E, 0x07, 0xAF, 0x48, 0x2D, 0x00, 0x58, 0xFE, 0xBB, 0x01, + 0xA3, 0xFE, 0xDD, 0x00, 0x99, 0xFF, 0x19, 0x00, 0xFE, 0xFF, 0x36, + 0x00, 0x37, 0xFF, 0xDD, 0x01, 0x60, 0xFC, 0x6D, 0x06, 0x76, 0xF4, + 0xD8, 0x1B, 0x95, 0x40, 0xC3, 0xF4, 0x56, 0x04, 0x4E, 0xFE, 0x85, + 0x00, 0xF1, 0xFF, 0xF4, 0xFF, 0x04, 0x00, 0xFD, 0xFF, 0x29, 0x00, + 0x60, 0xFF, 0xA2, 0x01, 0x7C, 0xFC, 0xFB, 0x06, 0x7C, 0xF1, 0x15, + 0x31, 0x73, 0x2F, 0x81, 0xF1, 0x10, 0x07, 0x67, 0xFC, 0xB1, 0x01, + 0x58, 0xFF, 0x2C, 0x00, 0xFD, 0xFF, 0x06, 0x00, 0xEE, 0xFF, 0x02, + 0x00, 0x63, 0x00, 0x8A, 0xFE, 0xF3, 0x03, 0x63, 0xF5, 0xA1, 0x41, + 0x12, 0x1A, 0xEB, 0xF4, 0x3F, 0x06, 0x72, 0xFC, 0xD7, 0x01, 0x39, + 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x91, 0xFF, 0xF1, 0x00, + 0x79, 0xFE, 0x0A, 0x02, 0xC3, 0xFD, 0x73, 0x01, 0xDB, 0x48, 0x07, + 0x06, 0xC7, 0xFB, 0x12, 0x03, 0xF1, 0xFD, 0x31, 0x01, 0x78, 0xFF, + 0x22, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x43, 0xFF, 0xBA, + 0x01, 0xBF, 0xFC, 0x8B, 0x05, 0x99, 0xF6, 0x43, 0x14, 0xA9, 0x44, + 0xDE, 0xF7, 0x85, 0x02, 0x65, 0xFF, 0xE7, 0xFF, 0x3F, 0x00, 0xD6, + 0xFF, 0x0A, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x44, 0xFF, 0xD5, 0x01, + 0x3A, 0xFC, 0x2A, 0x07, 0xE3, 0xF1, 0xD1, 0x29, 0x46, 0x36, 0xC5, + 0xF1, 0x87, 0x06, 0xDA, 0xFC, 0x64, 0x01, 0x80, 0xFF, 0x1E, 0x00, + 0xFE, 0xFF, 0x01, 0x00, 0x08, 0x00, 0xBC, 0xFF, 0xEF, 0x00, 0x9A, + 0xFD, 0x72, 0x05, 0x16, 0xF3, 0xA5, 0x3C, 0xC4, 0x21, 0x21, 0xF3, + 0xE4, 0x06, 0x39, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, + 0xFF, 0x12, 0x00, 0xB3, 0xFF, 0x99, 0x00, 0x2E, 0xFF, 0xB6, 0x00, + 0x36, 0x00, 0x47, 0xFC, 0x90, 0x47, 0xA4, 0x0C, 0x31, 0xF9, 0x5A, + 0x04, 0x4E, 0xFD, 0x7C, 0x01, 0x5B, 0xFF, 0x2A, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2B, 0x00, 0x59, 0xFF, 0x80, 0x01, 0x45, 0xFD, 0x6C, + 0x04, 0x0B, 0xF9, 0x0B, 0x0D, 0x73, 0x47, 0x02, 0xFC, 0x58, 0x00, + 0xA3, 0x00, 0x39, 0xFF, 0x94, 0x00, 0xB5, 0xFF, 0x12, 0x00, 0xFD, + 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x37, 0xFC, 0xEB, 0x06, + 0x0B, 0xF3, 0x35, 0x22, 0x52, 0x3C, 0xFD, 0xF2, 0x84, 0x05, 0x8D, + 0xFD, 0xF6, 0x00, 0xB8, 0xFF, 0x09, 0x00, 0x01, 0x00, 0xFE, 0xFF, + 0x1D, 0x00, 0x83, 0xFF, 0x5E, 0x01, 0xE3, 0xFC, 0x7B, 0x06, 0xD0, + 0xF1, 0xA5, 0x36, 0x62, 0x29, 0xEF, 0xF1, 0x29, 0x07, 0x39, 0xFC, + 0xD7, 0x01, 0x42, 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0x0B, 0x00, 0xD5, + 0xFF, 0x44, 0x00, 0xDD, 0xFF, 0x77, 0xFF, 0x67, 0x02, 0x14, 0xF8, + 0xDC, 0x44, 0xD5, 0x13, 0xBC, 0xF6, 0x7C, 0x05, 0xC5, 0xFC, 0xB7, + 0x01, 0x44, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x22, 0x00, + 0x76, 0xFF, 0x35, 0x01, 0xE7, 0xFD, 0x26, 0x03, 0xA1, 0xFB, 0x64, + 0x06, 0xD2, 0x48, 0x21, 0x01, 0xE8, 0xFD, 0xF7, 0x01, 0x83, 0xFE, + 0xEC, 0x00, 0x93, 0xFF, 0x1A, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x39, + 0xFF, 0xD9, 0x01, 0x6D, 0xFC, 0x4B, 0x06, 0xCD, 0xF4, 0x83, 0x1A, + 0x5F, 0x41, 0x3A, 0xF5, 0x0C, 0x04, 0x7B, 0xFE, 0x6C, 0x00, 0xFE, + 0xFF, 0xEF, 0xFF, 0x05, 0x00, 0xFD, 0xFF, 0x2B, 0x00, 0x5A, 0xFF, + 0xAD, 0x01, 0x6C, 0xFC, 0x0C, 0x07, 0x7F, 0xF1, 0xDC, 0x2F, 0xAD, + 0x30, 0x7D, 0xF1, 0x01, 0x07, 0x76, 0xFC, 0xA6, 0x01, 0x5E, 0xFF, + 0x2A, 0x00, 0xFD, 0xFF, 0x05, 0x00, 0xF3, 0xFF, 0xF5, 0xFF, 0x7D, + 0x00, 0x5D, 0xFE, 0x3E, 0x04, 0xEA, 0xF4, 0xD9, 0x40, 0x66, 0x1B, + 0x93, 0xF4, 0x62, 0x06, 0x64, 0xFC, 0xDC, 0x01, 0x38, 0xFF, 0x36, + 0x00, 0xFE, 0xFF, 0x19, 0x00, 0x97, 0xFF, 0xE2, 0x00, 0x98, 0xFE, + 0xCF, 0x01, 0x33, 0xFE, 0x7D, 0x00, 0xBB, 0x48, 0x1F, 0x07, 0x54, + 0xFB, 0x4C, 0x03, 0xD3, 0xFD, 0x3F, 0x01, 0x73, 0xFF, 0x23, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x00, 0x46, 0xFF, 0xB1, 0x01, 0xD3, + 0xFC, 0x5D, 0x05, 0x01, 0xF7, 0xFB, 0x12, 0x3F, 0x45, 0x83, 0xF8, + 0x2A, 0x02, 0x9A, 0xFF, 0xCA, 0xFF, 0x4E, 0x00, 0xD1, 0xFF, 0x0C, + 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x40, 0xFF, 0xDA, 0x01, 0x35, 0xFC, + 0x27, 0x07, 0x09, 0xF2, 0x85, 0x28, 0x63, 0x37, 0xE9, 0xF1, 0x63, + 0x06, 0xF5, 0xFC, 0x53, 0x01, 0x89, 0xFF, 0x1A, 0x00, 0xFE, 0xFF, + 0x00, 0x00, 0x0C, 0x00, 0xB1, 0xFF, 0x04, 0x01, 0x76, 0xFD, 0xA8, + 0x05, 0xCC, 0xF2, 0xAB, 0x3B, 0x18, 0x23, 0xE0, 0xF2, 0xF7, 0x06, + 0x35, 0xFC, 0xE6, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x11, + 0x00, 0xB9, 0xFF, 0x8A, 0x00, 0x4D, 0xFF, 0x7D, 0x00, 0x9C, 0x00, + 0x7B, 0xFB, 0x31, 0x47, 0xD9, 0x0D, 0xC0, 0xF8, 0x8F, 0x04, 0x34, + 0xFD, 0x87, 0x01, 0x56, 0xFF, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x29, 0x00, 0x5E, 0xFF, 0x74, 0x01, 0x5F, 0xFD, 0x35, 0x04, 0x7C, + 0xF9, 0xD8, 0x0B, 0xC9, 0x47, 0xD4, 0xFC, 0xF0, 0xFF, 0xDD, 0x00, + 0x19, 0xFF, 0xA4, 0x00, 0xAF, 0xFF, 0x13, 0x00, 0xFD, 0xFF, 0x36, + 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3D, 0xFC, 0xD5, 0x06, 0x4F, 0xF3, + 0xE0, 0x20, 0x45, 0x3D, 0x4D, 0xF3, 0x4B, 0x05, 0xB3, 0xFD, 0xE0, + 0x00, 0xC3, 0xFF, 0x05, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x20, 0x00, + 0x7B, 0xFF, 0x6E, 0x01, 0xCA, 0xFC, 0x9D, 0x06, 0xB1, 0xF1, 0x86, + 0x35, 0xAE, 0x2A, 0xCD, 0xF1, 0x2B, 0x07, 0x3F, 0xFC, 0xD1, 0x01, + 0x46, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x0A, 0x00, 0xDA, 0xFF, 0x36, + 0x00, 0xFA, 0xFF, 0x43, 0xFF, 0xBF, 0x02, 0x75, 0xF7, 0x42, 0x44, + 0x20, 0x15, 0x55, 0xF6, 0xA9, 0x05, 0xB2, 0xFC, 0xBF, 0x01, 0x41, + 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x21, 0x00, 0x7C, 0xFF, + 0x27, 0x01, 0x05, 0xFE, 0xEB, 0x02, 0x14, 0xFC, 0x50, 0x05, 0xEA, + 0x48, 0x1B, 0x02, 0x78, 0xFD, 0x32, 0x02, 0x64, 0xFE, 0xFA, 0x00, + 0x8D, 0xFF, 0x1C, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD4, + 0x01, 0x7C, 0xFC, 0x27, 0x06, 0x28, 0xF5, 0x31, 0x19, 0x21, 0x42, + 0xB8, 0xF5, 0xC0, 0x03, 0xAA, 0xFE, 0x51, 0x00, 0x0B, 0x00, 0xEA, + 0xFF, 0x06, 0x00, 0xFD, 0xFF, 0x2D, 0x00, 0x54, 0xFF, 0xB7, 0x01, + 0x5E, 0xFC, 0x19, 0x07, 0x88, 0xF1, 0x9F, 0x2E, 0xE3, 0x31, 0x7E, + 0xF1, 0xEE, 0x06, 0x88, 0xFC, 0x9A, 0x01, 0x64, 0xFF, 0x28, 0x00, + 0xFD, 0xFF, 0x04, 0x00, 0xF7, 0xFF, 0xE8, 0xFF, 0x96, 0x00, 0x31, + 0xFE, 0x84, 0x04, 0x79, 0xF4, 0x07, 0x40, 0xBA, 0x1C, 0x3E, 0xF4, + 0x82, 0x06, 0x58, 0xFC, 0xE0, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, + 0xFF, 0x18, 0x00, 0x9D, 0xFF, 0xD3, 0x00, 0xB8, 0xFE, 0x93, 0x01, + 0xA1, 0xFE, 0x8E, 0xFF, 0x92, 0x48, 0x3D, 0x08, 0xE1, 0xFA, 0x86, + 0x03, 0xB6, 0xFD, 0x4C, 0x01, 0x6D, 0xFF, 0x25, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x30, 0x00, 0x4A, 0xFF, 0xA8, 0x01, 0xE9, 0xFC, 0x2D, + 0x05, 0x6B, 0xF7, 0xB6, 0x11, 0xC8, 0x45, 0x30, 0xF9, 0xCD, 0x01, + 0xD0, 0xFF, 0xAC, 0xFF, 0x5C, 0x00, 0xCB, 0xFF, 0x0D, 0x00, 0xFD, + 0xFF, 0x34, 0x00, 0x3E, 0xFF, 0xDF, 0x01, 0x33, 0xFC, 0x20, 0x07, + 0x35, 0xF2, 0x36, 0x27, 0x78, 0x38, 0x14, 0xF2, 0x3B, 0x06, 0x11, + 0xFD, 0x41, 0x01, 0x92, 0xFF, 0x17, 0x00, 0xFF, 0xFF, 0x00, 0x00, + 0x10, 0x00, 0xA7, 0xFF, 0x19, 0x01, 0x53, 0xFD, 0xDB, 0x05, 0x88, + 0xF2, 0xAD, 0x3A, 0x6D, 0x24, 0xA4, 0xF2, 0x08, 0x07, 0x32, 0xFC, + 0xE5, 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x10, 0x00, 0xBF, + 0xFF, 0x7B, 0x00, 0x6C, 0xFF, 0x44, 0x00, 0x01, 0x01, 0xB6, 0xFA, + 0xC8, 0x46, 0x13, 0x0F, 0x51, 0xF8, 0xC4, 0x04, 0x1B, 0xFD, 0x92, + 0x01, 0x52, 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x28, 0x00, + 0x63, 0xFF, 0x67, 0x01, 0x7A, 0xFD, 0xFE, 0x03, 0xEE, 0xF9, 0xAA, + 0x0A, 0x16, 0x48, 0xAC, 0xFD, 0x86, 0xFF, 0x17, 0x01, 0xFA, 0xFE, + 0xB3, 0x00, 0xAA, 0xFF, 0x15, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, + 0xFF, 0xE5, 0x01, 0x44, 0xFC, 0xBD, 0x06, 0x97, 0xF3, 0x8A, 0x1F, + 0x31, 0x3E, 0xA5, 0xF3, 0x0F, 0x05, 0xDA, 0xFD, 0xC9, 0x00, 0xCF, + 0xFF, 0x01, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x22, 0x00, 0x73, 0xFF, + 0x7D, 0x01, 0xB3, 0xFC, 0xBB, 0x06, 0x9A, 0xF1, 0x60, 0x34, 0xF5, + 0x2B, 0xB0, 0xF1, 0x28, 0x07, 0x47, 0xFC, 0xCA, 0x01, 0x4A, 0xFF, + 0x30, 0x00, 0xFD, 0xFF, 0x09, 0x00, 0xDF, 0xFF, 0x28, 0x00, 0x17, + 0x00, 0x10, 0xFF, 0x15, 0x03, 0xDD, 0xF6, 0x9E, 0x43, 0x6C, 0x16, + 0xF1, 0xF5, 0xD3, 0x05, 0x9F, 0xFC, 0xC6, 0x01, 0x3F, 0xFF, 0x33, + 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x81, 0xFF, 0x19, 0x01, + 0x23, 0xFE, 0xB0, 0x02, 0x87, 0xFC, 0x41, 0x04, 0xF4, 0x48, 0x1C, + 0x03, 0x06, 0xFD, 0x6E, 0x02, 0x45, 0xFE, 0x09, 0x01, 0x88, 0xFF, + 0x1D, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3C, 0xFF, 0xCE, 0x01, 0x8C, + 0xFC, 0x00, 0x06, 0x86, 0xF5, 0xE0, 0x17, 0xDB, 0x42, 0x3F, 0xF6, + 0x71, 0x03, 0xD9, 0xFE, 0x36, 0x00, 0x18, 0x00, 0xE5, 0xFF, 0x07, + 0x00, 0xFD, 0xFF, 0x2F, 0x00, 0x4F, 0xFF, 0xC1, 0x01, 0x52, 0xFC, + 0x22, 0x07, 0x98, 0xF1, 0x5E, 0x2D, 0x13, 0x33, 0x87, 0xF1, 0xD8, + 0x06, 0x9B, 0xFC, 0x8D, 0x01, 0x6B, 0xFF, 0x25, 0x00, 0xFD, 0xFF, + 0x03, 0x00, 0xFC, 0xFF, 0xDC, 0xFF, 0xAF, 0x00, 0x07, 0xFE, 0xC8, + 0x04, 0x10, 0xF4, 0x2D, 0x3F, 0x0F, 0x1E, 0xED, 0xF3, 0xA0, 0x06, + 0x4E, 0xFC, 0xE3, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x16, + 0x00, 0xA3, 0xFF, 0xC3, 0x00, 0xD7, 0xFE, 0x58, 0x01, 0x0F, 0xFF, + 0xA6, 0xFE, 0x5D, 0x48, 0x61, 0x09, 0x6E, 0xFA, 0xC0, 0x03, 0x99, + 0xFD, 0x59, 0x01, 0x68, 0xFF, 0x26, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x2E, 0x00, 0x4E, 0xFF, 0x9E, 0x01, 0x00, 0xFD, 0xFC, 0x04, 0xD7, + 0xF7, 0x75, 0x10, 0x48, 0x46, 0xE4, 0xF9, 0x6E, 0x01, 0x06, 0x00, + 0x8E, 0xFF, 0x6B, 0x00, 0xC6, 0xFF, 0x0E, 0x00, 0xFD, 0xFF, 0x35, + 0x00, 0x3B, 0xFF, 0xE2, 0x01, 0x31, 0xFC, 0x16, 0x07, 0x67, 0xF2, + 0xE5, 0x25, 0x87, 0x39, 0x47, 0xF2, 0x10, 0x06, 0x30, 0xFD, 0x2F, + 0x01, 0x9C, 0xFF, 0x14, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x13, 0x00, + 0x9D, 0xFF, 0x2D, 0x01, 0x33, 0xFD, 0x0B, 0x06, 0x4D, 0xF2, 0xA5, + 0x39, 0xBF, 0x25, 0x6D, 0xF2, 0x15, 0x07, 0x31, 0xFC, 0xE2, 0x01, + 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0E, 0x00, 0xC5, 0xFF, 0x6D, + 0x00, 0x8B, 0xFF, 0x0D, 0x00, 0x63, 0x01, 0xF9, 0xF9, 0x55, 0x46, + 0x51, 0x10, 0xE3, 0xF7, 0xF7, 0x04, 0x03, 0xFD, 0x9D, 0x01, 0x4E, + 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x26, 0x00, 0x68, 0xFF, + 0x5B, 0x01, 0x96, 0xFD, 0xC6, 0x03, 0x61, 0xFA, 0x81, 0x09, 0x57, + 0x48, 0x8D, 0xFE, 0x1B, 0xFF, 0x52, 0x01, 0xDB, 0xFE, 0xC2, 0x00, + 0xA4, 0xFF, 0x16, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE3, + 0x01, 0x4D, 0xFC, 0xA3, 0x06, 0xE4, 0xF3, 0x36, 0x1E, 0x16, 0x3F, + 0x05, 0xF4, 0xCF, 0x04, 0x02, 0xFE, 0xB2, 0x00, 0xDB, 0xFF, 0xFC, + 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0x25, 0x00, 0x6C, 0xFF, 0x8B, 0x01, + 0x9D, 0xFC, 0xD5, 0x06, 0x89, 0xF1, 0x35, 0x33, 0x3A, 0x2D, 0x9A, + 0xF1, 0x23, 0x07, 0x51, 0xFC, 0xC2, 0x01, 0x4F, 0xFF, 0x2F, 0x00, + 0xFD, 0xFF, 0x07, 0x00, 0xE5, 0xFF, 0x1A, 0x00, 0x33, 0x00, 0xDF, + 0xFE, 0x68, 0x03, 0x4E, 0xF6, 0xEE, 0x42, 0xBB, 0x17, 0x90, 0xF5, + 0xFC, 0x05, 0x8E, 0xFC, 0xCD, 0x01, 0x3C, 0xFF, 0x34, 0x00, 0xFE, + 0xFF, 0x1E, 0x00, 0x87, 0xFF, 0x0B, 0x01, 0x42, 0xFE, 0x74, 0x02, + 0xF9, 0xFC, 0x39, 0x03, 0xF5, 0x48, 0x24, 0x04, 0x94, 0xFC, 0xA9, + 0x02, 0x27, 0xFE, 0x18, 0x01, 0x82, 0xFF, 0x1F, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x33, 0x00, 0x3E, 0xFF, 0xC7, 0x01, 0x9D, 0xFC, 0xD8, + 0x05, 0xE7, 0xF5, 0x91, 0x16, 0x89, 0x43, 0xCD, 0xF6, 0x1E, 0x03, + 0x0B, 0xFF, 0x1A, 0x00, 0x26, 0x00, 0xE0, 0xFF, 0x08, 0x00, 0xFD, + 0xFF, 0x30, 0x00, 0x4B, 0xFF, 0xC9, 0x01, 0x48, 0xFC, 0x28, 0x07, + 0xAD, 0xF1, 0x19, 0x2C, 0x3F, 0x34, 0x97, 0xF1, 0xBE, 0x06, 0xB0, + 0xFC, 0x7F, 0x01, 0x72, 0xFF, 0x23, 0x00, 0xFE, 0xFF, 0x02, 0x00, + 0x00, 0x00, 0xD0, 0xFF, 0xC7, 0x00, 0xDE, 0xFD, 0x08, 0x05, 0xB0, + 0xF3, 0x4A, 0x3E, 0x64, 0x1F, 0xA0, 0xF3, 0xBB, 0x06, 0x45, 0xFC, + 0xE5, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x15, 0x00, 0xA9, + 0xFF, 0xB4, 0x00, 0xF7, 0xFE, 0x1D, 0x01, 0x7A, 0xFF, 0xC5, 0xFD, + 0x1D, 0x48, 0x89, 0x0A, 0xFB, 0xF9, 0xF8, 0x03, 0x7D, 0xFD, 0x66, + 0x01, 0x63, 0xFF, 0x28, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2D, 0x00, + 0x52, 0xFF, 0x93, 0x01, 0x18, 0xFD, 0xC9, 0x04, 0x45, 0xF8, 0x36, + 0x0F, 0xBB, 0x46, 0xA1, 0xFA, 0x0C, 0x01, 0x3E, 0x00, 0x70, 0xFF, + 0x7A, 0x00, 0xC0, 0xFF, 0x0F, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x39, + 0xFF, 0xE4, 0x01, 0x32, 0xFC, 0x09, 0x07, 0x9D, 0xF2, 0x92, 0x24, + 0x8F, 0x3A, 0x82, 0xF2, 0xE1, 0x05, 0x50, 0xFD, 0x1B, 0x01, 0xA6, + 0xFF, 0x10, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x17, 0x00, 0x93, 0xFF, + 0x3F, 0x01, 0x15, 0xFD, 0x36, 0x06, 0x19, 0xF2, 0x97, 0x38, 0x11, + 0x27, 0x3B, 0xF2, 0x1F, 0x07, 0x32, 0xFC, 0xDF, 0x01, 0x3D, 0xFF, + 0x34, 0x00, 0xFD, 0xFF, 0x0D, 0x00, 0xCB, 0xFF, 0x5E, 0x00, 0xA9, + 0xFF, 0xD6, 0xFF, 0xC3, 0x01, 0x43, 0xF9, 0xD7, 0x45, 0x92, 0x11, + 0x77, 0xF7, 0x28, 0x05, 0xEC, 0xFC, 0xA7, 0x01, 0x4A, 0xFF, 0x2F, + 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x25, 0x00, 0x6D, 0xFF, 0x4E, 0x01, + 0xB3, 0xFD, 0x8D, 0x03, 0xD4, 0xFA, 0x5D, 0x08, 0x8D, 0x48, 0x74, + 0xFF, 0xAE, 0xFE, 0x8D, 0x01, 0xBB, 0xFE, 0xD1, 0x00, 0x9E, 0xFF, + 0x18, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE0, 0x01, 0x57, + 0xFC, 0x85, 0x06, 0x34, 0xF4, 0xE0, 0x1C, 0xF0, 0x3F, 0x6D, 0xF4, + 0x8C, 0x04, 0x2C, 0xFE, 0x99, 0x00, 0xE7, 0xFF, 0xF8, 0xFF, 0x04, + 0x00, 0xFD, 0xFF, 0x27, 0x00, 0x65, 0xFF, 0x98, 0x01, 0x8A, 0xFC, + 0xEC, 0x06, 0x7F, 0xF1, 0x04, 0x32, 0x7B, 0x2E, 0x8A, 0xF1, 0x1A, + 0x07, 0x5D, 0xFC, 0xB8, 0x01, 0x54, 0xFF, 0x2D, 0x00, 0xFD, 0xFF, + 0x06, 0x00, 0xEA, 0xFF, 0x0C, 0x00, 0x4E, 0x00, 0xAF, 0xFE, 0xB8, + 0x03, 0xC7, 0xF5, 0x38, 0x42, 0x0C, 0x19, 0x32, 0xF5, 0x23, 0x06, + 0x7D, 0xFC, 0xD3, 0x01, 0x3A, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1C, + 0x00, 0x8D, 0xFF, 0xFC, 0x00, 0x61, 0xFE, 0x39, 0x02, 0x6B, 0xFD, + 0x37, 0x02, 0xEB, 0x48, 0x31, 0x05, 0x21, 0xFC, 0xE4, 0x02, 0x08, + 0xFE, 0x26, 0x01, 0x7C, 0xFF, 0x21, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x32, 0x00, 0x41, 0xFF, 0xC0, 0x01, 0xAF, 0xFC, 0xAD, 0x05, 0x4A, + 0xF6, 0x44, 0x15, 0x2F, 0x44, 0x64, 0xF7, 0xC9, 0x02, 0x3D, 0xFF, + 0xFE, 0xFF, 0x34, 0x00, 0xDB, 0xFF, 0x09, 0x00, 0xFD, 0xFF, 0x32, + 0x00, 0x47, 0xFF, 0xD0, 0x01, 0x40, 0xFC, 0x2A, 0x07, 0xCA, 0xF1, + 0xD1, 0x2A, 0x65, 0x35, 0xAE, 0xF1, 0xA0, 0x06, 0xC7, 0xFC, 0x70, + 0x01, 0x7A, 0xFF, 0x20, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0x05, 0x00, + 0xC5, 0xFF, 0xDE, 0x00, 0xB7, 0xFD, 0x45, 0x05, 0x56, 0xF3, 0x61, + 0x3D, 0xBA, 0x20, 0x56, 0xF3, 0xD3, 0x06, 0x3E, 0xFC, 0xE6, 0x01, + 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x13, 0x00, 0xAF, 0xFF, 0xA5, + 0x00, 0x16, 0xFF, 0xE3, 0x00, 0xE4, 0xFF, 0xEB, 0xFC, 0xD2, 0x47, + 0xB6, 0x0B, 0x89, 0xF9, 0x2F, 0x04, 0x62, 0xFD, 0x72, 0x01, 0x5E, + 0xFF, 0x29, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2C, 0x00, 0x56, 0xFF, + 0x88, 0x01, 0x31, 0xFD, 0x95, 0x04, 0xB4, 0xF8, 0xFC, 0x0D, 0x26, + 0x47, 0x64, 0xFB, 0xA7, 0x00, 0x77, 0x00, 0x51, 0xFF, 0x89, 0x00, + 0xBA, 0xFF, 0x11, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE6, + 0x01, 0x34, 0xFC, 0xF9, 0x06, 0xD9, 0xF2, 0x3F, 0x23, 0x90, 0x3B, + 0xC4, 0xF2, 0xAE, 0x05, 0x72, 0xFD, 0x07, 0x01, 0xB0, 0xFF, 0x0C, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1A, 0x00, 0x8A, 0xFF, 0x51, 0x01, + 0xF8, 0xFC, 0x5E, 0x06, 0xED, 0xF1, 0x82, 0x37, 0x60, 0x28, 0x0E, + 0xF2, 0x26, 0x07, 0x35, 0xFC, 0xDB, 0x01, 0x40, 0xFF, 0x34, 0x00, + 0xFD, 0xFF, 0x0C, 0x00, 0xD0, 0xFF, 0x4F, 0x00, 0xC7, 0xFF, 0xA0, + 0xFF, 0x20, 0x02, 0x96, 0xF8, 0x4E, 0x45, 0xD7, 0x12, 0x0D, 0xF7, + 0x58, 0x05, 0xD6, 0xFC, 0xB0, 0x01, 0x47, 0xFF, 0x30, 0x00, 0xFF, + 0xFF, 0x00, 0x00, 0x23, 0x00, 0x72, 0xFF, 0x40, 0x01, 0xD0, 0xFD, + 0x53, 0x03, 0x47, 0xFB, 0x3F, 0x07, 0xB8, 0x48, 0x62, 0x00, 0x3F, + 0xFE, 0xC8, 0x01, 0x9C, 0xFE, 0xE0, 0x00, 0x98, 0xFF, 0x19, 0x00, + 0xFE, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xDC, 0x01, 0x63, 0xFC, 0x66, + 0x06, 0x89, 0xF4, 0x8C, 0x1B, 0xC3, 0x40, 0xDD, 0xF4, 0x46, 0x04, + 0x58, 0xFE, 0x80, 0x00, 0xF4, 0xFF, 0xF3, 0xFF, 0x05, 0x00, 0xFD, + 0xFF, 0x29, 0x00, 0x5F, 0xFF, 0xA5, 0x01, 0x78, 0xFC, 0xFF, 0x06, + 0x7D, 0xF1, 0xCF, 0x30, 0xB8, 0x2F, 0x80, 0xF1, 0x0D, 0x07, 0x6A, + 0xFC, 0xAE, 0x01, 0x59, 0xFF, 0x2B, 0x00, 0xFD, 0xFF, 0x05, 0x00, + 0xEF, 0xFF, 0xFF, 0xFF, 0x69, 0x00, 0x80, 0xFE, 0x04, 0x04, 0x48, + 0xF5, 0x74, 0x41, 0x5D, 0x1A, 0xD7, 0xF4, 0x47, 0x06, 0x6F, 0xFC, + 0xD8, 0x01, 0x39, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x93, + 0xFF, 0xED, 0x00, 0x80, 0xFE, 0xFD, 0x01, 0xDC, 0xFD, 0x3C, 0x01, + 0xD5, 0x48, 0x45, 0x06, 0xAE, 0xFB, 0x1F, 0x03, 0xEA, 0xFD, 0x34, + 0x01, 0x77, 0xFF, 0x22, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x00, + 0x44, 0xFF, 0xB8, 0x01, 0xC3, 0xFC, 0x81, 0x05, 0xB0, 0xF6, 0xFA, + 0x13, 0xCC, 0x44, 0x02, 0xF8, 0x71, 0x02, 0x71, 0xFF, 0xE1, 0xFF, + 0x42, 0x00, 0xD5, 0xFF, 0x0B, 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x43, + 0xFF, 0xD6, 0x01, 0x39, 0xFC, 0x2A, 0x07, 0xEB, 0xF1, 0x87, 0x29, + 0x85, 0x36, 0xCC, 0xF1, 0x7F, 0x06, 0xE0, 0xFC, 0x60, 0x01, 0x82, + 0xFF, 0x1D, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x09, 0x00, 0xBA, 0xFF, + 0xF4, 0x00, 0x91, 0xFD, 0x7E, 0x05, 0x05, 0xF3, 0x6E, 0x3C, 0x10, + 0x22, 0x12, 0xF3, 0xE9, 0x06, 0x38, 0xFC, 0xE6, 0x01, 0x37, 0xFF, + 0x36, 0x00, 0xFD, 0xFF, 0x12, 0x00, 0xB5, 0xFF, 0x96, 0x00, 0x35, + 0xFF, 0xA9, 0x00, 0x4D, 0x00, 0x19, 0xFC, 0x7C, 0x47, 0xE8, 0x0C, + 0x18, 0xF9, 0x66, 0x04, 0x48, 0xFD, 0x7E, 0x01, 0x5A, 0xFF, 0x2B, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5A, 0xFF, 0x7D, 0x01, + 0x4B, 0xFD, 0x60, 0x04, 0x24, 0xF9, 0xC6, 0x0C, 0x86, 0x47, 0x30, + 0xFC, 0x41, 0x00, 0xB0, 0x00, 0x32, 0xFF, 0x98, 0x00, 0xB4, 0xFF, + 0x12, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x38, + 0xFC, 0xE6, 0x06, 0x19, 0xF3, 0xEA, 0x21, 0x8A, 0x3C, 0x0E, 0xF3, + 0x78, 0x05, 0x96, 0xFD, 0xF1, 0x00, 0xBB, 0xFF, 0x08, 0x00, 0x01, + 0x00, 0xFE, 0xFF, 0x1D, 0x00, 0x81, 0xFF, 0x62, 0x01, 0xDD, 0xFC, + 0x83, 0x06, 0xC9, 0xF1, 0x66, 0x36, 0xAC, 0x29, 0xE7, 0xF1, 0x2A, + 0x07, 0x3A, 0xFC, 0xD5, 0x01, 0x43, 0xFF, 0x33, 0x00, 0xFD, 0xFF, + 0x0B, 0x00, 0xD6, 0xFF, 0x41, 0x00, 0xE4, 0xFF, 0x6B, 0xFF, 0x7B, + 0x02, 0xF0, 0xF7, 0xBA, 0x44, 0x1E, 0x14, 0xA5, 0xF6, 0x86, 0x05, + 0xC1, 0xFC, 0xB9, 0x01, 0x44, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0x22, 0x00, 0x77, 0xFF, 0x32, 0x01, 0xED, 0xFD, 0x19, 0x03, + 0xBB, 0xFB, 0x26, 0x06, 0xD7, 0x48, 0x58, 0x01, 0xCF, 0xFD, 0x04, + 0x02, 0x7D, 0xFE, 0xEF, 0x00, 0x92, 0xFF, 0x1B, 0x00, 0xFE, 0xFF, + 0x35, 0x00, 0x39, 0xFF, 0xD8, 0x01, 0x70, 0xFC, 0x43, 0x06, 0xE1, + 0xF4, 0x38, 0x1A, 0x8C, 0x41, 0x55, 0xF5, 0xFC, 0x03, 0x85, 0xFE, + 0x66, 0x00, 0x01, 0x00, 0xEE, 0xFF, 0x06, 0x00, 0xFD, 0xFF, 0x2B, + 0x00, 0x59, 0xFF, 0xB0, 0x01, 0x69, 0xFC, 0x0F, 0x07, 0x80, 0xF1, + 0x96, 0x2F, 0xF2, 0x30, 0x7C, 0xF1, 0xFD, 0x06, 0x7A, 0xFC, 0xA3, + 0x01, 0x5F, 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0x05, 0x00, 0xF4, 0xFF, + 0xF2, 0xFF, 0x83, 0x00, 0x53, 0xFE, 0x4E, 0x04, 0xD0, 0xF4, 0xAB, + 0x40, 0xB2, 0x1B, 0x7F, 0xF4, 0x69, 0x06, 0x62, 0xFC, 0xDD, 0x01, + 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x19, 0x00, 0x98, 0xFF, 0xDE, + 0x00, 0x9F, 0xFE, 0xC2, 0x01, 0x4B, 0xFE, 0x48, 0x00, 0xB3, 0x48, + 0x5E, 0x07, 0x3B, 0xFB, 0x59, 0x03, 0xCD, 0xFD, 0x42, 0x01, 0x71, + 0xFF, 0x24, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30, 0x00, 0x47, 0xFF, + 0xAF, 0x01, 0xD8, 0xFC, 0x52, 0x05, 0x19, 0xF7, 0xB2, 0x12, 0x5C, + 0x45, 0xA9, 0xF8, 0x16, 0x02, 0xA6, 0xFF, 0xC3, 0xFF, 0x51, 0x00, + 0xD0, 0xFF, 0x0C, 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x40, 0xFF, 0xDB, + 0x01, 0x35, 0xFC, 0x25, 0x07, 0x13, 0xF2, 0x3A, 0x28, 0xA0, 0x37, + 0xF2, 0xF1, 0x5A, 0x06, 0xFB, 0xFC, 0x4F, 0x01, 0x8B, 0xFF, 0x1A, + 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0D, 0x00, 0xAF, 0xFF, 0x09, 0x01, + 0x6E, 0xFD, 0xB4, 0x05, 0xBC, 0xF2, 0x73, 0x3B, 0x64, 0x23, 0xD2, + 0xF2, 0xFB, 0x06, 0x34, 0xFC, 0xE6, 0x01, 0x38, 0xFF, 0x36, 0x00, + 0xFD, 0xFF, 0x11, 0x00, 0xBB, 0xFF, 0x87, 0x00, 0x54, 0xFF, 0x70, + 0x00, 0xB3, 0x00, 0x4E, 0xFB, 0x1A, 0x47, 0x1F, 0x0E, 0xA8, 0xF8, + 0x9B, 0x04, 0x2E, 0xFD, 0x8A, 0x01, 0x55, 0xFF, 0x2C, 0x00, 0xFF, + 0xFF, 0x00, 0x00, 0x29, 0x00, 0x5F, 0xFF, 0x71, 0x01, 0x65, 0xFD, + 0x29, 0x04, 0x96, 0xF9, 0x95, 0x0B, 0xDC, 0x47, 0x03, 0xFD, 0xD9, + 0xFF, 0xEA, 0x00, 0x12, 0xFF, 0xA7, 0x00, 0xAE, 0xFF, 0x14, 0x00, + 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3E, 0xFC, 0xD0, + 0x06, 0x5E, 0xF3, 0x94, 0x20, 0x7B, 0x3D, 0x60, 0xF3, 0x3E, 0x05, + 0xBB, 0xFD, 0xDB, 0x00, 0xC6, 0xFF, 0x04, 0x00, 0x02, 0x00, 0xFE, + 0xFF, 0x20, 0x00, 0x79, 0xFF, 0x72, 0x01, 0xC4, 0xFC, 0xA4, 0x06, + 0xAB, 0xF1, 0x46, 0x35, 0xF7, 0x2A, 0xC6, 0xF1, 0x2A, 0x07, 0x40, + 0xFC, 0xCF, 0x01, 0x47, 0xFF, 0x31, 0x00, 0xFD, 0xFF, 0x09, 0x00, + 0xDB, 0xFF, 0x33, 0x00, 0x01, 0x00, 0x38, 0xFF, 0xD3, 0x02, 0x53, + 0xF7, 0x1F, 0x44, 0x69, 0x15, 0x3F, 0xF6, 0xB2, 0x05, 0xAD, 0xFC, + 0xC1, 0x01, 0x41, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x20, + 0x00, 0x7D, 0xFF, 0x24, 0x01, 0x0C, 0xFE, 0xDE, 0x02, 0x2E, 0xFC, + 0x13, 0x05, 0xEC, 0x48, 0x54, 0x02, 0x5E, 0xFD, 0x3F, 0x02, 0x5D, + 0xFE, 0xFE, 0x00, 0x8C, 0xFF, 0x1C, 0x00, 0xFE, 0xFF, 0x35, 0x00, + 0x3B, 0xFF, 0xD3, 0x01, 0x7F, 0xFC, 0x1F, 0x06, 0x3C, 0xF5, 0xE6, + 0x18, 0x4D, 0x42, 0xD5, 0xF5, 0xAF, 0x03, 0xB4, 0xFE, 0x4B, 0x00, + 0x0E, 0x00, 0xE9, 0xFF, 0x07, 0x00, 0xFD, 0xFF, 0x2D, 0x00, 0x53, + 0xFF, 0xBA, 0x01, 0x5B, 0xFC, 0x1B, 0x07, 0x8B, 0xF1, 0x58, 0x2E, + 0x26, 0x32, 0x80, 0xF1, 0xEA, 0x06, 0x8C, 0xFC, 0x97, 0x01, 0x66, + 0xFF, 0x27, 0x00, 0xFD, 0xFF, 0x04, 0x00, 0xF8, 0xFF, 0xE6, 0xFF, + 0x9C, 0x00, 0x27, 0xFE, 0x94, 0x04, 0x61, 0xF4, 0xD7, 0x3F, 0x06, + 0x1D, 0x2B, 0xF4, 0x89, 0x06, 0x56, 0xFC, 0xE0, 0x01, 0x37, 0xFF, + 0x36, 0x00, 0xFE, 0xFF, 0x17, 0x00, 0x9E, 0xFF, 0xCF, 0x00, 0xBF, + 0xFE, 0x86, 0x01, 0xBA, 0xFE, 0x5A, 0xFF, 0x86, 0x48, 0x7D, 0x08, + 0xC7, 0xFA, 0x93, 0x03, 0xB0, 0xFD, 0x4F, 0x01, 0x6C, 0xFF, 0x25, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4B, 0xFF, 0xA6, 0x01, + 0xEE, 0xFC, 0x23, 0x05, 0x83, 0xF7, 0x6E, 0x11, 0xE5, 0x45, 0x57, + 0xF9, 0xB8, 0x01, 0xDC, 0xFF, 0xA5, 0xFF, 0x5F, 0x00, 0xCA, 0xFF, + 0x0D, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3D, 0xFF, 0xDF, 0x01, 0x32, + 0xFC, 0x1E, 0x07, 0x40, 0xF2, 0xEB, 0x26, 0xB5, 0x38, 0x1F, 0xF2, + 0x32, 0x06, 0x18, 0xFD, 0x3D, 0x01, 0x94, 0xFF, 0x16, 0x00, 0xFF, + 0xFF, 0x00, 0x00, 0x11, 0x00, 0xA4, 0xFF, 0x1D, 0x01, 0x4C, 0xFD, + 0xE6, 0x05, 0x7B, 0xF2, 0x71, 0x3A, 0xB8, 0x24, 0x97, 0xF2, 0x0B, + 0x07, 0x32, 0xFC, 0xE4, 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, 0xFF, + 0x0F, 0x00, 0xC0, 0xFF, 0x78, 0x00, 0x73, 0xFF, 0x38, 0x00, 0x17, + 0x01, 0x8B, 0xFA, 0xAF, 0x46, 0x59, 0x0F, 0x39, 0xF8, 0xCF, 0x04, + 0x15, 0xFD, 0x95, 0x01, 0x51, 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0x28, 0x00, 0x64, 0xFF, 0x65, 0x01, 0x81, 0xFD, 0xF2, 0x03, + 0x08, 0xFA, 0x68, 0x0A, 0x25, 0x48, 0xDE, 0xFD, 0x6E, 0xFF, 0x24, + 0x01, 0xF3, 0xFE, 0xB6, 0x00, 0xA8, 0xFF, 0x15, 0x00, 0xFD, 0xFF, + 0x36, 0x00, 0x36, 0xFF, 0xE5, 0x01, 0x46, 0xFC, 0xB8, 0x06, 0xA8, + 0xF3, 0x3F, 0x1F, 0x64, 0x3E, 0xBA, 0xF3, 0x01, 0x05, 0xE2, 0xFD, + 0xC4, 0x00, 0xD2, 0xFF, 0x00, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x23, + 0x00, 0x71, 0xFF, 0x81, 0x01, 0xAE, 0xFC, 0xC1, 0x06, 0x95, 0xF1, + 0x1E, 0x34, 0x3E, 0x2C, 0xAB, 0xF1, 0x27, 0x07, 0x49, 0xFC, 0xC8, + 0x01, 0x4B, 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0x08, 0x00, 0xE1, 0xFF, + 0x25, 0x00, 0x1D, 0x00, 0x05, 0xFF, 0x28, 0x03, 0xBD, 0xF6, 0x77, + 0x43, 0xB6, 0x16, 0xDC, 0xF5, 0xDD, 0x05, 0x9B, 0xFC, 0xC8, 0x01, + 0x3E, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x83, + 0xFF, 0x16, 0x01, 0x2A, 0xFE, 0xA3, 0x02, 0xA1, 0xFC, 0x06, 0x04, + 0xF5, 0x48, 0x56, 0x03, 0xED, 0xFC, 0x7B, 0x02, 0x3E, 0xFE, 0x0C, + 0x01, 0x86, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3D, 0xFF, + 0xCC, 0x01, 0x8F, 0xFC, 0xF8, 0x05, 0x9B, 0xF5, 0x96, 0x17, 0x02, + 0x43, 0x5E, 0xF6, 0x5F, 0x03, 0xE4, 0xFE, 0x30, 0x00, 0x1B, 0x00, + 0xE4, 0xFF, 0x08, 0x00, 0xFD, 0xFF, 0x2F, 0x00, 0x4E, 0xFF, 0xC3, + 0x01, 0x4F, 0xFC, 0x24, 0x07, 0x9C, 0xF1, 0x17, 0x2D, 0x57, 0x33, + 0x8A, 0xF1, 0xD3, 0x06, 0x9F, 0xFC, 0x8A, 0x01, 0x6D, 0xFF, 0x25, + 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0xD9, 0xFF, 0xB4, 0x00, + 0xFD, 0xFD, 0xD7, 0x04, 0xFA, 0xF3, 0xFC, 0x3E, 0x5B, 0x1E, 0xDB, + 0xF3, 0xA6, 0x06, 0x4C, 0xFC, 0xE3, 0x01, 0x36, 0xFF, 0x36, 0x00, + 0xFE, 0xFF, 0x16, 0x00, 0xA4, 0xFF, 0xC0, 0x00, 0xDE, 0xFE, 0x4B, + 0x01, 0x27, 0xFF, 0x73, 0xFE, 0x4F, 0x48, 0xA2, 0x09, 0x54, 0xFA, + 0xCC, 0x03, 0x93, 0xFD, 0x5C, 0x01, 0x67, 0xFF, 0x27, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0x2E, 0x00, 0x4E, 0xFF, 0x9C, 0x01, 0x05, 0xFD, + 0xF1, 0x04, 0xF0, 0xF7, 0x2D, 0x10, 0x61, 0x46, 0x0D, 0xFA, 0x58, + 0x01, 0x13, 0x00, 0x87, 0xFF, 0x6E, 0x00, 0xC4, 0xFF, 0x0E, 0x00, + 0xFD, 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xE3, 0x01, 0x31, 0xFC, 0x14, + 0x07, 0x73, 0xF2, 0x99, 0x25, 0xC2, 0x39, 0x54, 0xF2, 0x05, 0x06, + 0x37, 0xFD, 0x2B, 0x01, 0x9E, 0xFF, 0x13, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0x14, 0x00, 0x9B, 0xFF, 0x31, 0x01, 0x2C, 0xFD, 0x15, 0x06, + 0x41, 0xF2, 0x6A, 0x39, 0x0A, 0x26, 0x61, 0xF2, 0x17, 0x07, 0x31, + 0xFC, 0xE2, 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0E, 0x00, + 0xC6, 0xFF, 0x69, 0x00, 0x91, 0xFF, 0x00, 0x00, 0x78, 0x01, 0xD0, + 0xF9, 0x39, 0x46, 0x98, 0x10, 0xCB, 0xF7, 0x02, 0x05, 0xFE, 0xFC, + 0x9F, 0x01, 0x4D, 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x26, + 0x00, 0x69, 0xFF, 0x58, 0x01, 0x9D, 0xFD, 0xB9, 0x03, 0x7B, 0xFA, + 0x40, 0x09, 0x63, 0x48, 0xBF, 0xFE, 0x03, 0xFF, 0x5F, 0x01, 0xD4, + 0xFE, 0xC5, 0x00, 0xA2, 0xFF, 0x16, 0x00, 0xFE, 0xFF, 0x36, 0x00, + 0x36, 0xFF, 0xE2, 0x01, 0x4F, 0xFC, 0x9C, 0x06, 0xF5, 0xF3, 0xEA, + 0x1D, 0x47, 0x3F, 0x1B, 0xF4, 0xC1, 0x04, 0x0B, 0xFE, 0xAC, 0x00, + 0xDE, 0xFF, 0xFB, 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0x25, 0x00, 0x6A, + 0xFF, 0x8E, 0x01, 0x99, 0xFC, 0xDB, 0x06, 0x86, 0xF1, 0xF2, 0x32, + 0x82, 0x2D, 0x96, 0xF1, 0x21, 0x07, 0x53, 0xFC, 0xC0, 0x01, 0x50, + 0xFF, 0x2E, 0x00, 0xFD, 0xFF, 0x07, 0x00, 0xE6, 0xFF, 0x17, 0x00, + 0x39, 0x00, 0xD4, 0xFE, 0x7A, 0x03, 0x2F, 0xF6, 0xC7, 0x42, 0x06, + 0x18, 0x7B, 0xF5, 0x05, 0x06, 0x8A, 0xFC, 0xCF, 0x01, 0x3C, 0xFF, + 0x34, 0x00, 0xFE, 0xFF, 0x1D, 0x00, 0x88, 0xFF, 0x07, 0x01, 0x49, + 0xFE, 0x67, 0x02, 0x13, 0xFD, 0xFF, 0x02, 0xF4, 0x48, 0x5F, 0x04, + 0x7A, 0xFC, 0xB6, 0x02, 0x20, 0xFE, 0x1B, 0x01, 0x81, 0xFF, 0x1F, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x3F, 0xFF, 0xC6, 0x01, + 0xA1, 0xFC, 0xCF, 0x05, 0xFC, 0xF5, 0x47, 0x16, 0xB0, 0x43, 0xEE, + 0xF6, 0x0C, 0x03, 0x16, 0xFF, 0x14, 0x00, 0x29, 0x00, 0xDF, 0xFF, + 0x09, 0x00, 0xFD, 0xFF, 0x30, 0x00, 0x4A, 0xFF, 0xCA, 0x01, 0x46, + 0xFC, 0x29, 0x07, 0xB3, 0xF1, 0xD1, 0x2B, 0x81, 0x34, 0x9C, 0xF1, + 0xB8, 0x06, 0xB5, 0xFC, 0x7C, 0x01, 0x74, 0xFF, 0x22, 0x00, 0xFE, + 0xFF, 0x02, 0x00, 0x01, 0x00, 0xCE, 0xFF, 0xCC, 0x00, 0xD5, 0xFD, + 0x16, 0x05, 0x9B, 0xF3, 0x18, 0x3E, 0xB1, 0x1F, 0x8F, 0xF3, 0xC0, + 0x06, 0x43, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, + 0x15, 0x00, 0xAA, 0xFF, 0xB1, 0x00, 0xFE, 0xFE, 0x10, 0x01, 0x92, + 0xFF, 0x94, 0xFD, 0x0D, 0x48, 0xCB, 0x0A, 0xE2, 0xF9, 0x04, 0x04, + 0x77, 0xFD, 0x69, 0x01, 0x62, 0xFF, 0x28, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0x2D, 0x00, 0x52, 0xFF, 0x91, 0x01, 0x1E, 0xFD, 0xBE, 0x04, + 0x5E, 0xF8, 0xF0, 0x0E, 0xD3, 0x46, 0xCB, 0xFA, 0xF6, 0x00, 0x4B, + 0x00, 0x69, 0xFF, 0x7D, 0x00, 0xBE, 0xFF, 0x10, 0x00, 0xFD, 0xFF, + 0x36, 0x00, 0x39, 0xFF, 0xE5, 0x01, 0x32, 0xFC, 0x06, 0x07, 0xAA, + 0xF2, 0x46, 0x24, 0xC8, 0x3A, 0x90, 0xF2, 0xD6, 0x05, 0x57, 0xFD, + 0x17, 0x01, 0xA8, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x18, + 0x00, 0x91, 0xFF, 0x43, 0x01, 0x0E, 0xFD, 0x40, 0x06, 0x0F, 0xF2, + 0x5B, 0x38, 0x5C, 0x27, 0x30, 0xF2, 0x21, 0x07, 0x33, 0xFC, 0xDE, + 0x01, 0x3E, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0D, 0x00, 0xCC, 0xFF, + 0x5A, 0x00, 0xAF, 0xFF, 0xCA, 0xFF, 0xD8, 0x01, 0x1C, 0xF9, 0xB8, + 0x45, 0xDA, 0x11, 0x60, 0xF7, 0x33, 0x05, 0xE7, 0xFC, 0xA9, 0x01, + 0x4A, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x25, 0x00, 0x6E, + 0xFF, 0x4B, 0x01, 0xB9, 0xFD, 0x80, 0x03, 0xEE, 0xFA, 0x1D, 0x08, + 0x98, 0x48, 0xA8, 0xFF, 0x95, 0xFE, 0x9A, 0x01, 0xB4, 0xFE, 0xD4, + 0x00, 0x9C, 0xFF, 0x18, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, + 0xDF, 0x01, 0x5A, 0xFC, 0x7E, 0x06, 0x47, 0xF4, 0x94, 0x1C, 0x1F, + 0x40, 0x85, 0xF4, 0x7D, 0x04, 0x36, 0xFE, 0x93, 0x00, 0xEA, 0xFF, + 0xF7, 0xFF, 0x04, 0x00, 0xFD, 0xFF, 0x28, 0x00, 0x63, 0xFF, 0x9B, + 0x01, 0x86, 0xFC, 0xF1, 0x06, 0x7E, 0xF1, 0xC0, 0x31, 0xC2, 0x2E, + 0x87, 0xF1, 0x17, 0x07, 0x5F, 0xFC, 0xB6, 0x01, 0x55, 0xFF, 0x2D, + 0x00, 0xFD, 0xFF, 0x06, 0x00, 0xEB, 0xFF, 0x09, 0x00, 0x54, 0x00, + 0xA4, 0xFE, 0xC9, 0x03, 0xAA, 0xF5, 0x0C, 0x42, 0x56, 0x19, 0x1E, + 0xF5, 0x2B, 0x06, 0x7A, 0xFC, 0xD4, 0x01, 0x3A, 0xFF, 0x35, 0x00, + 0xFE, 0xFF, 0x1C, 0x00, 0x8E, 0xFF, 0xF9, 0x00, 0x68, 0xFE, 0x2C, + 0x02, 0x84, 0xFD, 0xFF, 0x01, 0xE6, 0x48, 0x6E, 0x05, 0x07, 0xFC, + 0xF1, 0x02, 0x01, 0xFE, 0x29, 0x01, 0x7B, 0xFF, 0x21, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x42, 0xFF, 0xBE, 0x01, 0xB4, 0xFC, + 0xA4, 0x05, 0x61, 0xF6, 0xFB, 0x14, 0x53, 0x44, 0x86, 0xF7, 0xB6, + 0x02, 0x49, 0xFF, 0xF7, 0xFF, 0x37, 0x00, 0xD9, 0xFF, 0x0A, 0x00, + 0xFD, 0xFF, 0x32, 0x00, 0x46, 0xFF, 0xD1, 0x01, 0x3E, 0xFC, 0x2B, + 0x07, 0xD0, 0xF1, 0x89, 0x2A, 0xA6, 0x35, 0xB4, 0xF1, 0x99, 0x06, + 0xCD, 0xFC, 0x6D, 0x01, 0x7C, 0xFF, 0x1F, 0x00, 0xFE, 0xFF, 0x01, + 0x00, 0x06, 0x00, 0xC2, 0xFF, 0xE3, 0x00, 0xAE, 0xFD, 0x52, 0x05, + 0x44, 0xF3, 0x2A, 0x3D, 0x06, 0x21, 0x47, 0xF3, 0xD8, 0x06, 0x3C, + 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x13, 0x00, + 0xB0, 0xFF, 0xA2, 0x00, 0x1D, 0xFF, 0xD6, 0x00, 0xFC, 0xFF, 0xBC, + 0xFC, 0xC0, 0x47, 0xFA, 0x0B, 0x70, 0xF9, 0x3C, 0x04, 0x5C, 0xFD, + 0x75, 0x01, 0x5D, 0xFF, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, + 0x00, 0x57, 0xFF, 0x86, 0x01, 0x36, 0xFD, 0x89, 0x04, 0xCD, 0xF8, + 0xB7, 0x0D, 0x3D, 0x47, 0x91, 0xFB, 0x91, 0x00, 0x83, 0x00, 0x4A, + 0xFF, 0x8C, 0x00, 0xB9, 0xFF, 0x11, 0x00, 0xFD, 0xFF, 0x36, 0x00, + 0x38, 0xFF, 0xE6, 0x01, 0x35, 0xFC, 0xF5, 0x06, 0xE7, 0xF2, 0xF2, + 0x22, 0xC7, 0x3B, 0xD4, 0xF2, 0xA2, 0x05, 0x7A, 0xFD, 0x02, 0x01, + 0xB2, 0xFF, 0x0B, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x88, + 0xFF, 0x55, 0x01, 0xF2, 0xFC, 0x67, 0x06, 0xE4, 0xF1, 0x44, 0x37, + 0xAA, 0x28, 0x05, 0xF2, 0x27, 0x07, 0x36, 0xFC, 0xDA, 0x01, 0x41, + 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0x0B, 0x00, 0xD2, 0xFF, 0x4C, 0x00, + 0xCD, 0xFF, 0x94, 0xFF, 0x34, 0x02, 0x70, 0xF8, 0x2E, 0x45, 0x20, + 0x13, 0xF6, 0xF6, 0x62, 0x05, 0xD1, 0xFC, 0xB2, 0x01, 0x46, 0xFF, + 0x31, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x23, 0x00, 0x73, 0xFF, 0x3D, + 0x01, 0xD6, 0xFD, 0x46, 0x03, 0x61, 0xFB, 0x00, 0x07, 0xBF, 0x48, + 0x98, 0x00, 0x26, 0xFE, 0xD5, 0x01, 0x95, 0xFE, 0xE3, 0x00, 0x96, + 0xFF, 0x1A, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xDB, 0x01, + 0x66, 0xFC, 0x5E, 0x06, 0x9C, 0xF4, 0x40, 0x1B, 0xEF, 0x40, 0xF7, + 0xF4, 0x35, 0x04, 0x62, 0xFE, 0x7A, 0x00, 0xF7, 0xFF, 0xF2, 0xFF, + 0x05, 0x00, 0xFD, 0xFF, 0x2A, 0x00, 0x5D, 0xFF, 0xA7, 0x01, 0x75, + 0xFC, 0x03, 0x07, 0x7D, 0xF1, 0x8A, 0x30, 0xFF, 0x2F, 0x7E, 0xF1, + 0x0A, 0x07, 0x6E, 0xFC, 0xAC, 0x01, 0x5A, 0xFF, 0x2B, 0x00, 0xFD, + 0xFF, 0x05, 0x00, 0xF0, 0xFF, 0xFC, 0xFF, 0x6E, 0x00, 0x76, 0xFE, + 0x15, 0x04, 0x2C, 0xF5, 0x49, 0x41, 0xA9, 0x1A, 0xC3, 0xF4, 0x4F, + 0x06, 0x6C, 0xFC, 0xD9, 0x01, 0x38, 0xFF, 0x35, 0x00, 0xFE, 0xFF, + 0x1A, 0x00, 0x94, 0xFF, 0xEA, 0x00, 0x87, 0xFE, 0xF0, 0x01, 0xF5, + 0xFD, 0x05, 0x01, 0xCE, 0x48, 0x83, 0x06, 0x94, 0xFB, 0x2C, 0x03, + 0xE4, 0xFD, 0x37, 0x01, 0x76, 0xFF, 0x22, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0x31, 0x00, 0x45, 0xFF, 0xB6, 0x01, 0xC8, 0xFC, 0x77, 0x05, + 0xC7, 0xF6, 0xB1, 0x13, 0xED, 0x44, 0x26, 0xF8, 0x5D, 0x02, 0x7D, + 0xFF, 0xDA, 0xFF, 0x46, 0x00, 0xD4, 0xFF, 0x0B, 0x00, 0xFD, 0xFF, + 0x33, 0x00, 0x42, 0xFF, 0xD7, 0x01, 0x38, 0xFC, 0x29, 0x07, 0xF3, + 0xF1, 0x3E, 0x29, 0xC6, 0x36, 0xD4, 0xF1, 0x77, 0x06, 0xE6, 0xFC, + 0x5C, 0x01, 0x84, 0xFF, 0x1C, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x0A, + 0x00, 0xB7, 0xFF, 0xF9, 0x00, 0x89, 0xFD, 0x8A, 0x05, 0xF4, 0xF2, + 0x37, 0x3C, 0x5B, 0x22, 0x03, 0xF3, 0xED, 0x06, 0x37, 0xFC, 0xE6, + 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x12, 0x00, 0xB6, 0xFF, + 0x93, 0x00, 0x3C, 0xFF, 0x9D, 0x00, 0x63, 0x00, 0xEB, 0xFB, 0x69, + 0x47, 0x2D, 0x0D, 0xFF, 0xF8, 0x72, 0x04, 0x42, 0xFD, 0x81, 0x01, + 0x59, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5B, + 0xFF, 0x7A, 0x01, 0x50, 0xFD, 0x54, 0x04, 0x3D, 0xF9, 0x82, 0x0C, + 0x9A, 0x47, 0x5E, 0xFC, 0x2A, 0x00, 0xBD, 0x00, 0x2B, 0xFF, 0x9B, + 0x00, 0xB3, 0xFF, 0x12, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, + 0xE6, 0x01, 0x3A, 0xFC, 0xE2, 0x06, 0x28, 0xF3, 0x9E, 0x21, 0xC0, + 0x3C, 0x1F, 0xF3, 0x6C, 0x05, 0x9E, 0xFD, 0xED, 0x00, 0xBD, 0xFF, + 0x07, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1E, 0x00, 0x80, 0xFF, 0x66, + 0x01, 0xD8, 0xFC, 0x8B, 0x06, 0xC1, 0xF1, 0x27, 0x36, 0xF6, 0x29, + 0xDF, 0xF1, 0x2A, 0x07, 0x3B, 0xFC, 0xD4, 0x01, 0x44, 0xFF, 0x32, + 0x00, 0xFD, 0xFF, 0x0A, 0x00, 0xD7, 0xFF, 0x3E, 0x00, 0xEA, 0xFF, + 0x60, 0xFF, 0x8F, 0x02, 0xCD, 0xF7, 0x99, 0x44, 0x68, 0x14, 0x8E, + 0xF6, 0x90, 0x05, 0xBC, 0xFC, 0xBA, 0x01, 0x43, 0xFF, 0x32, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x22, 0x00, 0x79, 0xFF, 0x2F, 0x01, 0xF4, + 0xFD, 0x0C, 0x03, 0xD4, 0xFB, 0xE9, 0x05, 0xDE, 0x48, 0x8F, 0x01, + 0xB6, 0xFD, 0x11, 0x02, 0x76, 0xFE, 0xF2, 0x00, 0x91, 0xFF, 0x1B, + 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x39, 0xFF, 0xD7, 0x01, 0x73, 0xFC, + 0x3B, 0x06, 0xF5, 0xF4, 0xED, 0x19, 0xB7, 0x41, 0x71, 0xF5, 0xEB, + 0x03, 0x90, 0xFE, 0x60, 0x00, 0x04, 0x00, 0xED, 0xFF, 0x06, 0x00, + 0xFD, 0xFF, 0x2C, 0x00, 0x57, 0xFF, 0xB2, 0x01, 0x65, 0xFC, 0x12, + 0x07, 0x82, 0xF1, 0x50, 0x2F, 0x38, 0x31, 0x7C, 0xF1, 0xF9, 0x06, + 0x7E, 0xFC, 0xA1, 0x01, 0x61, 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0x04, + 0x00, 0xF5, 0xFF, 0xEF, 0xFF, 0x88, 0x00, 0x49, 0xFE, 0x5D, 0x04, + 0xB7, 0xF4, 0x7D, 0x40, 0xFD, 0x1B, 0x6C, 0xF4, 0x70, 0x06, 0x5F, + 0xFC, 0xDE, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x19, 0x00, + 0x9A, 0xFF, 0xDB, 0x00, 0xA6, 0xFE, 0xB4, 0x01, 0x64, 0xFE, 0x12, + 0x00, 0xAA, 0x48, 0x9E, 0x07, 0x21, 0xFB, 0x66, 0x03, 0xC6, 0xFD, + 0x45, 0x01, 0x70, 0xFF, 0x24, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30, + 0x00, 0x48, 0xFF, 0xAD, 0x01, 0xDD, 0xFC, 0x48, 0x05, 0x30, 0xF7, + 0x6B, 0x12, 0x7D, 0x45, 0xCF, 0xF8, 0x01, 0x02, 0xB2, 0xFF, 0xBD, + 0xFF, 0x54, 0x00, 0xCE, 0xFF, 0x0C, 0x00, 0xFD, 0xFF, 0x34, 0x00, + 0x3F, 0xFF, 0xDC, 0x01, 0x34, 0xFC, 0x24, 0x07, 0x1C, 0xF2, 0xF0, + 0x27, 0xDF, 0x37, 0xFB, 0xF1, 0x51, 0x06, 0x01, 0xFD, 0x4B, 0x01, + 0x8D, 0xFF, 0x19, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0E, 0x00, 0xAC, + 0xFF, 0x0E, 0x01, 0x66, 0xFD, 0xBF, 0x05, 0xAD, 0xF2, 0x3B, 0x3B, + 0xB0, 0x23, 0xC4, 0xF2, 0xFF, 0x06, 0x33, 0xFC, 0xE5, 0x01, 0x38, + 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x10, 0x00, 0xBC, 0xFF, 0x84, 0x00, + 0x5B, 0xFF, 0x64, 0x00, 0xC9, 0x00, 0x22, 0xFB, 0x02, 0x47, 0x64, + 0x0E, 0x8F, 0xF8, 0xA7, 0x04, 0x29, 0xFD, 0x8C, 0x01, 0x54, 0xFF, + 0x2C, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x29, 0x00, 0x60, 0xFF, 0x6E, + 0x01, 0x6B, 0xFD, 0x1D, 0x04, 0xAF, 0xF9, 0x51, 0x0B, 0xEC, 0x47, + 0x33, 0xFD, 0xC1, 0xFF, 0xF7, 0x00, 0x0C, 0xFF, 0xAA, 0x00, 0xAD, + 0xFF, 0x14, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, + 0x40, 0xFC, 0xCB, 0x06, 0x6E, 0xF3, 0x49, 0x20, 0xB0, 0x3D, 0x73, + 0xF3, 0x31, 0x05, 0xC4, 0xFD, 0xD6, 0x00, 0xC8, 0xFF, 0x03, 0x00, + 0x02, 0x00, 0xFE, 0xFF, 0x21, 0x00, 0x77, 0xFF, 0x75, 0x01, 0xBF, + 0xFC, 0xAB, 0x06, 0xA6, 0xF1, 0x05, 0x35, 0x40, 0x2B, 0xBF, 0xF1, + 0x2A, 0x07, 0x42, 0xFC, 0xCE, 0x01, 0x48, 0xFF, 0x31, 0x00, 0xFD, + 0xFF, 0x09, 0x00, 0xDC, 0xFF, 0x2F, 0x00, 0x07, 0x00, 0x2C, 0xFF, + 0xE6, 0x02, 0x31, 0xF7, 0xFA, 0x43, 0xB3, 0x15, 0x29, 0xF6, 0xBC, + 0x05, 0xA9, 0xFC, 0xC2, 0x01, 0x40, 0xFF, 0x33, 0x00, 0xFF, 0xFF, + 0x00, 0x00, 0x20, 0x00, 0x7E, 0xFF, 0x21, 0x01, 0x12, 0xFE, 0xD1, + 0x02, 0x47, 0xFC, 0xD7, 0x04, 0xF0, 0x48, 0x8D, 0x02, 0x45, 0xFD, + 0x4D, 0x02, 0x56, 0xFE, 0x01, 0x01, 0x8B, 0xFF, 0x1D, 0x00, 0xFE, + 0xFF, 0x34, 0x00, 0x3B, 0xFF, 0xD1, 0x01, 0x83, 0xFC, 0x16, 0x06, + 0x51, 0xF5, 0x9B, 0x18, 0x75, 0x42, 0xF3, 0xF5, 0x9D, 0x03, 0xBF, + 0xFE, 0x45, 0x00, 0x11, 0x00, 0xE8, 0xFF, 0x07, 0x00, 0xFD, 0xFF, + 0x2E, 0x00, 0x52, 0xFF, 0xBC, 0x01, 0x58, 0xFC, 0x1D, 0x07, 0x8E, + 0xF1, 0x11, 0x2E, 0x6B, 0x32, 0x81, 0xF1, 0xE5, 0x06, 0x90, 0xFC, + 0x94, 0x01, 0x67, 0xFF, 0x26, 0x00, 0xFD, 0xFF, 0x04, 0x00, 0xF9, + 0xFF, 0xE3, 0xFF, 0xA1, 0x00, 0x1E, 0xFE, 0xA3, 0x04, 0x49, 0xF4, + 0xA8, 0x3F, 0x52, 0x1D, 0x19, 0xF4, 0x90, 0x06, 0x53, 0xFC, 0xE1, + 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x17, 0x00, 0xA0, 0xFF, + 0xCC, 0x00, 0xC6, 0xFE, 0x79, 0x01, 0xD2, 0xFE, 0x26, 0xFF, 0x7C, + 0x48, 0xBE, 0x08, 0xAE, 0xFA, 0xA0, 0x03, 0xA9, 0xFD, 0x52, 0x01, + 0x6B, 0xFF, 0x25, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4C, + 0xFF, 0xA3, 0x01, 0xF3, 0xFC, 0x18, 0x05, 0x9B, 0xF7, 0x27, 0x11, + 0x02, 0x46, 0x7F, 0xF9, 0xA3, 0x01, 0xE8, 0xFF, 0x9F, 0xFF, 0x63, + 0x00, 0xC9, 0xFF, 0x0D, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3C, 0xFF, + 0xE0, 0x01, 0x32, 0xFC, 0x1C, 0x07, 0x4B, 0xF2, 0xA0, 0x26, 0xF2, + 0x38, 0x2A, 0xF2, 0x28, 0x06, 0x1F, 0xFD, 0x39, 0x01, 0x96, 0xFF, + 0x16, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x11, 0x00, 0xA2, 0xFF, 0x22, + 0x01, 0x45, 0xFD, 0xF1, 0x05, 0x6D, 0xF2, 0x38, 0x3A, 0x03, 0x25, + 0x8B, 0xF2, 0x0E, 0x07, 0x32, 0xFC, 0xE4, 0x01, 0x3A, 0xFF, 0x36, + 0x00, 0xFD, 0xFF, 0x0F, 0x00, 0xC2, 0xFF, 0x75, 0x00, 0x7A, 0xFF, + 0x2B, 0x00, 0x2D, 0x01, 0x61, 0xFA, 0x97, 0x46, 0xA0, 0x0F, 0x20, + 0xF8, 0xDA, 0x04, 0x10, 0xFD, 0x97, 0x01, 0x50, 0xFF, 0x2E, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x27, 0x00, 0x65, 0xFF, 0x62, 0x01, 0x87, + 0xFD, 0xE5, 0x03, 0x21, 0xFA, 0x25, 0x0A, 0x33, 0x48, 0x0F, 0xFE, + 0x57, 0xFF, 0x31, 0x01, 0xEC, 0xFE, 0xB9, 0x00, 0xA7, 0xFF, 0x15, + 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE4, 0x01, 0x48, 0xFC, + 0xB2, 0x06, 0xB9, 0xF3, 0xF3, 0x1E, 0x98, 0x3E, 0xCF, 0xF3, 0xF3, + 0x04, 0xEB, 0xFD, 0xBF, 0x00, 0xD4, 0xFF, 0xFF, 0xFF, 0x03, 0x00, + 0xFE, 0xFF, 0x23, 0x00, 0x70, 0xFF, 0x84, 0x01, 0xA9, 0xFC, 0xC7, + 0x06, 0x91, 0xF1, 0xDC, 0x33, 0x87, 0x2C, 0xA5, 0xF1, 0x26, 0x07, + 0x4B, 0xFC, 0xC6, 0x01, 0x4C, 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0x08, + 0x00, 0xE2, 0xFF, 0x21, 0x00, 0x23, 0x00, 0xFA, 0xFE, 0x3A, 0x03, + 0x9D, 0xF6, 0x50, 0x43, 0x00, 0x17, 0xC6, 0xF5, 0xE6, 0x05, 0x97, + 0xFC, 0xC9, 0x01, 0x3E, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x00, 0x00, + 0x1E, 0x00, 0x84, 0xFF, 0x13, 0x01, 0x31, 0xFE, 0x95, 0x02, 0xBA, + 0xFC, 0xCB, 0x03, 0xF7, 0x48, 0x91, 0x03, 0xD3, 0xFC, 0x88, 0x02, + 0x38, 0xFE, 0x10, 0x01, 0x85, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x34, + 0x00, 0x3D, 0xFF, 0xCB, 0x01, 0x93, 0xFC, 0xEF, 0x05, 0xB0, 0xF5, + 0x4B, 0x17, 0x2A, 0x43, 0x7D, 0xF6, 0x4D, 0x03, 0xEF, 0xFE, 0x2A, + 0x00, 0x1E, 0x00, 0xE3, 0xFF, 0x08, 0x00, 0xFD, 0xFF, 0x2F, 0x00, + 0x4D, 0xFF, 0xC4, 0x01, 0x4D, 0xFC, 0x25, 0x07, 0xA1, 0xF1, 0xCE, + 0x2C, 0x99, 0x33, 0x8E, 0xF1, 0xCD, 0x06, 0xA4, 0xFC, 0x87, 0x01, + 0x6E, 0xFF, 0x24, 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFE, 0xFF, 0xD7, + 0xFF, 0xBA, 0x00, 0xF4, 0xFD, 0xE5, 0x04, 0xE4, 0xF3, 0xCA, 0x3E, + 0xA7, 0x1E, 0xCA, 0xF3, 0xAC, 0x06, 0x4A, 0xFC, 0xE4, 0x01, 0x36, + 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x16, 0x00, 0xA6, 0xFF, 0xBD, 0x00, + 0xE5, 0xFE, 0x3E, 0x01, 0x3F, 0xFF, 0x41, 0xFE, 0x41, 0x48, 0xE4, + 0x09, 0x3B, 0xFA, 0xD9, 0x03, 0x8D, 0xFD, 0x5F, 0x01, 0x66, 0xFF, + 0x27, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2E, 0x00, 0x4F, 0xFF, 0x99, + 0x01, 0x0B, 0xFD, 0xE6, 0x04, 0x08, 0xF8, 0xE7, 0x0F, 0x7C, 0x46, + 0x37, 0xFA, 0x42, 0x01, 0x1F, 0x00, 0x81, 0xFF, 0x71, 0x00, 0xC3, + 0xFF, 0x0F, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xE3, 0x01, + 0x31, 0xFC, 0x11, 0x07, 0x7F, 0xF2, 0x4E, 0x25, 0xFD, 0x39, 0x60, + 0xF2, 0xFB, 0x05, 0x3E, 0xFD, 0x26, 0x01, 0xA0, 0xFF, 0x12, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0x15, 0x00, 0x98, 0xFF, 0x35, 0x01, 0x25, + 0xFD, 0x1E, 0x06, 0x35, 0xF2, 0x2E, 0x39, 0x55, 0x26, 0x56, 0xF2, + 0x1A, 0x07, 0x31, 0xFC, 0xE1, 0x01, 0x3C, 0xFF, 0x35, 0x00, 0xFD, + 0xFF, 0x0E, 0x00, 0xC7, 0xFF, 0x66, 0x00, 0x98, 0xFF, 0xF4, 0xFF, + 0x8E, 0x01, 0xA7, 0xF9, 0x1D, 0x46, 0xDF, 0x10, 0xB3, 0xF7, 0x0D, + 0x05, 0xF8, 0xFC, 0xA1, 0x01, 0x4C, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, + 0x00, 0x00, 0x26, 0x00, 0x6A, 0xFF, 0x55, 0x01, 0xA3, 0xFD, 0xAD, + 0x03, 0x94, 0xFA, 0xFF, 0x08, 0x70, 0x48, 0xF3, 0xFE, 0xEA, 0xFE, + 0x6C, 0x01, 0xCD, 0xFE, 0xC9, 0x00, 0xA1, 0xFF, 0x17, 0x00, 0xFE, + 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE2, 0x01, 0x51, 0xFC, 0x96, 0x06, + 0x07, 0xF4, 0x9E, 0x1D, 0x77, 0x3F, 0x32, 0xF4, 0xB2, 0x04, 0x15, + 0xFE, 0xA7, 0x00, 0xE0, 0xFF, 0xFA, 0xFF, 0x03, 0x00, 0xFD, 0xFF, + 0x26, 0x00, 0x69, 0xFF, 0x91, 0x01, 0x94, 0xFC, 0xE0, 0x06, 0x84, + 0xF1, 0xAF, 0x32, 0xCA, 0x2D, 0x92, 0xF1, 0x1F, 0x07, 0x56, 0xFC, + 0xBE, 0x01, 0x51, 0xFF, 0x2E, 0x00, 0xFD, 0xFF, 0x07, 0x00, 0xE7, + 0xFF, 0x14, 0x00, 0x3F, 0x00, 0xC9, 0xFE, 0x8C, 0x03, 0x11, 0xF6, + 0x9E, 0x42, 0x50, 0x18, 0x66, 0xF5, 0x0D, 0x06, 0x86, 0xFC, 0xD0, + 0x01, 0x3B, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x1D, 0x00, 0x8A, 0xFF, + 0x04, 0x01, 0x50, 0xFE, 0x5A, 0x02, 0x2C, 0xFD, 0xC6, 0x02, 0xF2, + 0x48, 0x9B, 0x04, 0x61, 0xFC, 0xC3, 0x02, 0x19, 0xFE, 0x1E, 0x01, + 0x7F, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x40, + 0xFF, 0xC4, 0x01, 0xA5, 0xFC, 0xC5, 0x05, 0x13, 0xF6, 0xFD, 0x15, + 0xD4, 0x43, 0x0F, 0xF7, 0xF9, 0x02, 0x21, 0xFF, 0x0D, 0x00, 0x2C, + 0x00, 0xDE, 0xFF, 0x09, 0x00, 0xFD, 0xFF, 0x31, 0x00, 0x49, 0xFF, + 0xCC, 0x01, 0x44, 0xFC, 0x29, 0x07, 0xB9, 0xF1, 0x89, 0x2B, 0xC3, + 0x34, 0xA0, 0xF1, 0xB1, 0x06, 0xBA, 0xFC, 0x79, 0x01, 0x76, 0xFF, + 0x21, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0x02, 0x00, 0xCB, 0xFF, 0xD1, + 0x00, 0xCC, 0xFD, 0x24, 0x05, 0x87, 0xF3, 0xE4, 0x3D, 0xFD, 0x1F, + 0x7F, 0xF3, 0xC6, 0x06, 0x41, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36, + 0x00, 0xFD, 0xFF, 0x14, 0x00, 0xAC, 0xFF, 0xAE, 0x00, 0x05, 0xFF, + 0x03, 0x01, 0xAA, 0xFF, 0x63, 0xFD, 0xFD, 0x47, 0x0E, 0x0B, 0xC8, + 0xF9, 0x11, 0x04, 0x71, 0xFD, 0x6C, 0x01, 0x61, 0xFF, 0x28, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0x2D, 0x00, 0x53, 0xFF, 0x8F, 0x01, 0x23, + 0xFD, 0xB2, 0x04, 0x76, 0xF8, 0xAA, 0x0E, 0xED, 0x46, 0xF7, 0xFA, + 0xDF, 0x00, 0x57, 0x00, 0x62, 0xFF, 0x80, 0x00, 0xBD, 0xFF, 0x10, + 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x39, 0xFF, 0xE5, 0x01, 0x33, 0xFC, + 0x03, 0x07, 0xB7, 0xF2, 0xFC, 0x23, 0x03, 0x3B, 0x9E, 0xF2, 0xCB, + 0x05, 0x5F, 0xFD, 0x12, 0x01, 0xAA, 0xFF, 0x0E, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x18, 0x00, 0x8F, 0xFF, 0x47, 0x01, 0x08, 0xFD, 0x49, + 0x06, 0x05, 0xF2, 0x1D, 0x38, 0xA6, 0x27, 0x26, 0xF2, 0x23, 0x07, + 0x33, 0xFC, 0xDD, 0x01, 0x3E, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0C, + 0x00, 0xCD, 0xFF, 0x57, 0x00, 0xB6, 0xFF, 0xBE, 0xFF, 0xED, 0x01, + 0xF5, 0xF8, 0x9B, 0x45, 0x22, 0x12, 0x48, 0xF7, 0x3D, 0x05, 0xE2, + 0xFC, 0xAB, 0x01, 0x49, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0x00, 0x00, + 0x24, 0x00, 0x6F, 0xFF, 0x48, 0x01, 0xC0, 0xFD, 0x73, 0x03, 0x07, + 0xFB, 0xDD, 0x07, 0xA1, 0x48, 0xDD, 0xFF, 0x7D, 0xFE, 0xA7, 0x01, + 0xAD, 0xFE, 0xD8, 0x00, 0x9B, 0xFF, 0x18, 0x00, 0xFE, 0xFF, 0x36, + 0x00, 0x37, 0xFF, 0xDF, 0x01, 0x5C, 0xFC, 0x78, 0x06, 0x5A, 0xF4, + 0x49, 0x1C, 0x4E, 0x40, 0x9E, 0xF4, 0x6D, 0x04, 0x3F, 0xFE, 0x8E, + 0x00, 0xED, 0xFF, 0xF6, 0xFF, 0x04, 0x00, 0xFD, 0xFF, 0x28, 0x00, + 0x62, 0xFF, 0x9E, 0x01, 0x82, 0xFC, 0xF5, 0x06, 0x7D, 0xF1, 0x7B, + 0x31, 0x09, 0x2F, 0x84, 0xF1, 0x15, 0x07, 0x62, 0xFC, 0xB4, 0x01, + 0x56, 0xFF, 0x2C, 0x00, 0xFD, 0xFF, 0x06, 0x00, 0xEC, 0xFF, 0x06, + 0x00, 0x5A, 0x00, 0x9A, 0xFE, 0xDA, 0x03, 0x8D, 0xF5, 0xE1, 0x41, + 0xA1, 0x19, 0x09, 0xF5, 0x33, 0x06, 0x77, 0xFC, 0xD6, 0x01, 0x3A, + 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x8F, 0xFF, 0xF5, 0x00, + 0x6F, 0xFE, 0x1E, 0x02, 0x9D, 0xFD, 0xC7, 0x01, 0xE1, 0x48, 0xAB, + 0x05, 0xEE, 0xFB, 0xFE, 0x02, 0xFB, 0xFD, 0x2C, 0x01, 0x7A, 0xFF, + 0x21, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x42, 0xFF, 0xBC, + 0x01, 0xB8, 0xFC, 0x9A, 0x05, 0x77, 0xF6, 0xB1, 0x14, 0x77, 0x44, + 0xA9, 0xF7, 0xA2, 0x02, 0x54, 0xFF, 0xF1, 0xFF, 0x3A, 0x00, 0xD8, + 0xFF, 0x0A, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x45, 0xFF, 0xD3, 0x01, + 0x3C, 0xFC, 0x2A, 0x07, 0xD8, 0xF1, 0x3F, 0x2A, 0xE6, 0x35, 0xBB, + 0xF1, 0x92, 0x06, 0xD2, 0xFC, 0x69, 0x01, 0x7E, 0xFF, 0x1F, 0x00, + 0xFE, 0xFF, 0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xE8, 0x00, 0xA6, + 0xFD, 0x5F, 0x05, 0x31, 0xF3, 0xF6, 0x3C, 0x52, 0x21, 0x37, 0xF3, + 0xDD, 0x06, 0x3B, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, + 0xFF, 0x13, 0x00, 0xB1, 0xFF, 0x9F, 0x00, 0x24, 0xFF, 0xC9, 0x00, + 0x13, 0x00, 0x8D, 0xFC, 0xAE, 0x47, 0x3E, 0x0C, 0x56, 0xF9, 0x48, + 0x04, 0x56, 0xFD, 0x78, 0x01, 0x5C, 0xFF, 0x2A, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2B, 0x00, 0x58, 0xFF, 0x83, 0x01, 0x3C, 0xFD, 0x7E, + 0x04, 0xE6, 0xF8, 0x72, 0x0D, 0x52, 0x47, 0xBE, 0xFB, 0x7A, 0x00, + 0x90, 0x00, 0x43, 0xFF, 0x8F, 0x00, 0xB7, 0xFF, 0x11, 0x00, 0xFD, + 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x36, 0xFC, 0xF1, 0x06, + 0xF5, 0xF2, 0xA7, 0x22, 0xFF, 0x3B, 0xE4, 0xF2, 0x96, 0x05, 0x81, + 0xFD, 0xFD, 0x00, 0xB5, 0xFF, 0x0B, 0x00, 0x01, 0x00, 0xFE, 0xFF, + 0x1C, 0x00, 0x86, 0xFF, 0x59, 0x01, 0xEC, 0xFC, 0x6F, 0x06, 0xDC, + 0xF1, 0x04, 0x37, 0xF3, 0x28, 0xFC, 0xF1, 0x28, 0x07, 0x37, 0xFC, + 0xD8, 0x01, 0x41, 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0x0B, 0x00, 0xD3, + 0xFF, 0x49, 0x00, 0xD4, 0xFF, 0x88, 0xFF, 0x49, 0x02, 0x4B, 0xF8, + 0x0D, 0x45, 0x68, 0x13, 0xDF, 0xF6, 0x6C, 0x05, 0xCC, 0xFC, 0xB4, + 0x01, 0x45, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x23, 0x00, + 0x74, 0xFF, 0x3A, 0x01, 0xDD, 0xFD, 0x39, 0x03, 0x7B, 0xFB, 0xC1, + 0x06, 0xC7, 0x48, 0xCF, 0x00, 0x0D, 0xFE, 0xE3, 0x01, 0x8E, 0xFE, + 0xE7, 0x00, 0x95, 0xFF, 0x1A, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x38, + 0xFF, 0xDA, 0x01, 0x69, 0xFC, 0x57, 0x06, 0xAF, 0xF4, 0xF5, 0x1A, + 0x1D, 0x41, 0x11, 0xF5, 0x25, 0x04, 0x6C, 0xFE, 0x74, 0x00, 0xF9, + 0xFF, 0xF1, 0xFF, 0x05, 0x00, 0xFD, 0xFF, 0x2A, 0x00, 0x5C, 0xFF, + 0xAA, 0x01, 0x71, 0xFC, 0x07, 0x07, 0x7E, 0xF1, 0x44, 0x30, 0x44, + 0x30, 0x7E, 0xF1, 0x07, 0x07, 0x71, 0xFC, 0xAA, 0x01, 0x5C, 0xFF, + 0x2A, 0x00, 0xFD, 0xFF, 0x05, 0x00, 0xF1, 0xFF, 0xF9, 0xFF, 0x74, + 0x00, 0x6C, 0xFE, 0x25, 0x04, 0x11, 0xF5, 0x1D, 0x41, 0xF5, 0x1A, + 0xAF, 0xF4, 0x57, 0x06, 0x69, 0xFC, 0xDA, 0x01, 0x38, 0xFF, 0x36, + 0x00, 0xFE, 0xFF, 0x1A, 0x00, 0x95, 0xFF, 0xE7, 0x00, 0x8E, 0xFE, + 0xE3, 0x01, 0x0D, 0xFE, 0xCF, 0x00, 0xC7, 0x48, 0xC1, 0x06, 0x7B, + 0xFB, 0x39, 0x03, 0xDD, 0xFD, 0x3A, 0x01, 0x74, 0xFF, 0x23, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x00, 0x45, 0xFF, 0xB4, 0x01, 0xCC, + 0xFC, 0x6C, 0x05, 0xDF, 0xF6, 0x68, 0x13, 0x0D, 0x45, 0x4B, 0xF8, + 0x49, 0x02, 0x88, 0xFF, 0xD4, 0xFF, 0x49, 0x00, 0xD3, 0xFF, 0x0B, + 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x41, 0xFF, 0xD8, 0x01, 0x37, 0xFC, + 0x28, 0x07, 0xFC, 0xF1, 0xF3, 0x28, 0x04, 0x37, 0xDC, 0xF1, 0x6F, + 0x06, 0xEC, 0xFC, 0x59, 0x01, 0x86, 0xFF, 0x1C, 0x00, 0xFE, 0xFF, + 0x01, 0x00, 0x0B, 0x00, 0xB5, 0xFF, 0xFD, 0x00, 0x81, 0xFD, 0x96, + 0x05, 0xE4, 0xF2, 0xFF, 0x3B, 0xA7, 0x22, 0xF5, 0xF2, 0xF1, 0x06, + 0x36, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x11, + 0x00, 0xB7, 0xFF, 0x8F, 0x00, 0x43, 0xFF, 0x90, 0x00, 0x7A, 0x00, + 0xBE, 0xFB, 0x52, 0x47, 0x72, 0x0D, 0xE6, 0xF8, 0x7E, 0x04, 0x3C, + 0xFD, 0x83, 0x01, 0x58, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2A, 0x00, 0x5C, 0xFF, 0x78, 0x01, 0x56, 0xFD, 0x48, 0x04, 0x56, + 0xF9, 0x3E, 0x0C, 0xAE, 0x47, 0x8D, 0xFC, 0x13, 0x00, 0xC9, 0x00, + 0x24, 0xFF, 0x9F, 0x00, 0xB1, 0xFF, 0x13, 0x00, 0xFD, 0xFF, 0x36, + 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3B, 0xFC, 0xDD, 0x06, 0x37, 0xF3, + 0x52, 0x21, 0xF6, 0x3C, 0x31, 0xF3, 0x5F, 0x05, 0xA6, 0xFD, 0xE8, + 0x00, 0xC0, 0xFF, 0x07, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1F, 0x00, + 0x7E, 0xFF, 0x69, 0x01, 0xD2, 0xFC, 0x92, 0x06, 0xBB, 0xF1, 0xE6, + 0x35, 0x3F, 0x2A, 0xD8, 0xF1, 0x2A, 0x07, 0x3C, 0xFC, 0xD3, 0x01, + 0x45, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x0A, 0x00, 0xD8, 0xFF, 0x3A, + 0x00, 0xF1, 0xFF, 0x54, 0xFF, 0xA2, 0x02, 0xA9, 0xF7, 0x77, 0x44, + 0xB1, 0x14, 0x77, 0xF6, 0x9A, 0x05, 0xB8, 0xFC, 0xBC, 0x01, 0x42, + 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x21, 0x00, 0x7A, 0xFF, + 0x2C, 0x01, 0xFB, 0xFD, 0xFE, 0x02, 0xEE, 0xFB, 0xAB, 0x05, 0xE1, + 0x48, 0xC7, 0x01, 0x9D, 0xFD, 0x1E, 0x02, 0x6F, 0xFE, 0xF5, 0x00, + 0x8F, 0xFF, 0x1B, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD6, + 0x01, 0x77, 0xFC, 0x33, 0x06, 0x09, 0xF5, 0xA1, 0x19, 0xE1, 0x41, + 0x8D, 0xF5, 0xDA, 0x03, 0x9A, 0xFE, 0x5A, 0x00, 0x06, 0x00, 0xEC, + 0xFF, 0x06, 0x00, 0xFD, 0xFF, 0x2C, 0x00, 0x56, 0xFF, 0xB4, 0x01, + 0x62, 0xFC, 0x15, 0x07, 0x84, 0xF1, 0x09, 0x2F, 0x7B, 0x31, 0x7D, + 0xF1, 0xF5, 0x06, 0x82, 0xFC, 0x9E, 0x01, 0x62, 0xFF, 0x28, 0x00, + 0xFD, 0xFF, 0x04, 0x00, 0xF6, 0xFF, 0xED, 0xFF, 0x8E, 0x00, 0x3F, + 0xFE, 0x6D, 0x04, 0x9E, 0xF4, 0x4E, 0x40, 0x49, 0x1C, 0x5A, 0xF4, + 0x78, 0x06, 0x5C, 0xFC, 0xDF, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, + 0xFF, 0x18, 0x00, 0x9B, 0xFF, 0xD8, 0x00, 0xAD, 0xFE, 0xA7, 0x01, + 0x7D, 0xFE, 0xDD, 0xFF, 0xA1, 0x48, 0xDD, 0x07, 0x07, 0xFB, 0x73, + 0x03, 0xC0, 0xFD, 0x48, 0x01, 0x6F, 0xFF, 0x24, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x30, 0x00, 0x49, 0xFF, 0xAB, 0x01, 0xE2, 0xFC, 0x3D, + 0x05, 0x48, 0xF7, 0x22, 0x12, 0x9B, 0x45, 0xF5, 0xF8, 0xED, 0x01, + 0xBE, 0xFF, 0xB6, 0xFF, 0x57, 0x00, 0xCD, 0xFF, 0x0C, 0x00, 0xFD, + 0xFF, 0x34, 0x00, 0x3E, 0xFF, 0xDD, 0x01, 0x33, 0xFC, 0x23, 0x07, + 0x26, 0xF2, 0xA6, 0x27, 0x1D, 0x38, 0x05, 0xF2, 0x49, 0x06, 0x08, + 0xFD, 0x47, 0x01, 0x8F, 0xFF, 0x18, 0x00, 0xFF, 0xFF, 0x00, 0x00, + 0x0E, 0x00, 0xAA, 0xFF, 0x12, 0x01, 0x5F, 0xFD, 0xCB, 0x05, 0x9E, + 0xF2, 0x03, 0x3B, 0xFC, 0x23, 0xB7, 0xF2, 0x03, 0x07, 0x33, 0xFC, + 0xE5, 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x10, 0x00, 0xBD, + 0xFF, 0x80, 0x00, 0x62, 0xFF, 0x57, 0x00, 0xDF, 0x00, 0xF7, 0xFA, + 0xED, 0x46, 0xAA, 0x0E, 0x76, 0xF8, 0xB2, 0x04, 0x23, 0xFD, 0x8F, + 0x01, 0x53, 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x28, 0x00, + 0x61, 0xFF, 0x6C, 0x01, 0x71, 0xFD, 0x11, 0x04, 0xC8, 0xF9, 0x0E, + 0x0B, 0xFD, 0x47, 0x63, 0xFD, 0xAA, 0xFF, 0x03, 0x01, 0x05, 0xFF, + 0xAE, 0x00, 0xAC, 0xFF, 0x14, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, + 0xFF, 0xE5, 0x01, 0x41, 0xFC, 0xC6, 0x06, 0x7F, 0xF3, 0xFD, 0x1F, + 0xE4, 0x3D, 0x87, 0xF3, 0x24, 0x05, 0xCC, 0xFD, 0xD1, 0x00, 0xCB, + 0xFF, 0x02, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x21, 0x00, 0x76, 0xFF, + 0x79, 0x01, 0xBA, 0xFC, 0xB1, 0x06, 0xA0, 0xF1, 0xC3, 0x34, 0x89, + 0x2B, 0xB9, 0xF1, 0x29, 0x07, 0x44, 0xFC, 0xCC, 0x01, 0x49, 0xFF, + 0x31, 0x00, 0xFD, 0xFF, 0x09, 0x00, 0xDE, 0xFF, 0x2C, 0x00, 0x0D, + 0x00, 0x21, 0xFF, 0xF9, 0x02, 0x0F, 0xF7, 0xD4, 0x43, 0xFD, 0x15, + 0x13, 0xF6, 0xC5, 0x05, 0xA5, 0xFC, 0xC4, 0x01, 0x40, 0xFF, 0x33, + 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x20, 0x00, 0x7F, 0xFF, 0x1E, 0x01, + 0x19, 0xFE, 0xC3, 0x02, 0x61, 0xFC, 0x9B, 0x04, 0xF2, 0x48, 0xC6, + 0x02, 0x2C, 0xFD, 0x5A, 0x02, 0x50, 0xFE, 0x04, 0x01, 0x8A, 0xFF, + 0x1D, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3B, 0xFF, 0xD0, 0x01, 0x86, + 0xFC, 0x0D, 0x06, 0x66, 0xF5, 0x50, 0x18, 0x9E, 0x42, 0x11, 0xF6, + 0x8C, 0x03, 0xC9, 0xFE, 0x3F, 0x00, 0x14, 0x00, 0xE7, 0xFF, 0x07, + 0x00, 0xFD, 0xFF, 0x2E, 0x00, 0x51, 0xFF, 0xBE, 0x01, 0x56, 0xFC, + 0x1F, 0x07, 0x92, 0xF1, 0xCA, 0x2D, 0xAF, 0x32, 0x84, 0xF1, 0xE0, + 0x06, 0x94, 0xFC, 0x91, 0x01, 0x69, 0xFF, 0x26, 0x00, 0xFD, 0xFF, + 0x03, 0x00, 0xFA, 0xFF, 0xE0, 0xFF, 0xA7, 0x00, 0x15, 0xFE, 0xB2, + 0x04, 0x32, 0xF4, 0x77, 0x3F, 0x9E, 0x1D, 0x07, 0xF4, 0x96, 0x06, + 0x51, 0xFC, 0xE2, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x17, + 0x00, 0xA1, 0xFF, 0xC9, 0x00, 0xCD, 0xFE, 0x6C, 0x01, 0xEA, 0xFE, + 0xF3, 0xFE, 0x70, 0x48, 0xFF, 0x08, 0x94, 0xFA, 0xAD, 0x03, 0xA3, + 0xFD, 0x55, 0x01, 0x6A, 0xFF, 0x26, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x2F, 0x00, 0x4C, 0xFF, 0xA1, 0x01, 0xF8, 0xFC, 0x0D, 0x05, 0xB3, + 0xF7, 0xDF, 0x10, 0x1D, 0x46, 0xA7, 0xF9, 0x8E, 0x01, 0xF4, 0xFF, + 0x98, 0xFF, 0x66, 0x00, 0xC7, 0xFF, 0x0E, 0x00, 0xFD, 0xFF, 0x35, + 0x00, 0x3C, 0xFF, 0xE1, 0x01, 0x31, 0xFC, 0x1A, 0x07, 0x56, 0xF2, + 0x55, 0x26, 0x2E, 0x39, 0x35, 0xF2, 0x1E, 0x06, 0x25, 0xFD, 0x35, + 0x01, 0x98, 0xFF, 0x15, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x12, 0x00, + 0xA0, 0xFF, 0x26, 0x01, 0x3E, 0xFD, 0xFB, 0x05, 0x60, 0xF2, 0xFD, + 0x39, 0x4E, 0x25, 0x7F, 0xF2, 0x11, 0x07, 0x31, 0xFC, 0xE3, 0x01, + 0x3A, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0F, 0x00, 0xC3, 0xFF, 0x71, + 0x00, 0x81, 0xFF, 0x1F, 0x00, 0x42, 0x01, 0x37, 0xFA, 0x7C, 0x46, + 0xE7, 0x0F, 0x08, 0xF8, 0xE6, 0x04, 0x0B, 0xFD, 0x99, 0x01, 0x4F, + 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x27, 0x00, 0x66, 0xFF, + 0x5F, 0x01, 0x8D, 0xFD, 0xD9, 0x03, 0x3B, 0xFA, 0xE4, 0x09, 0x41, + 0x48, 0x41, 0xFE, 0x3F, 0xFF, 0x3E, 0x01, 0xE5, 0xFE, 0xBD, 0x00, + 0xA6, 0xFF, 0x16, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE4, + 0x01, 0x4A, 0xFC, 0xAC, 0x06, 0xCA, 0xF3, 0xA7, 0x1E, 0xCA, 0x3E, + 0xE4, 0xF3, 0xE5, 0x04, 0xF4, 0xFD, 0xBA, 0x00, 0xD7, 0xFF, 0xFE, + 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0x24, 0x00, 0x6E, 0xFF, 0x87, 0x01, + 0xA4, 0xFC, 0xCD, 0x06, 0x8E, 0xF1, 0x99, 0x33, 0xCE, 0x2C, 0xA1, + 0xF1, 0x25, 0x07, 0x4D, 0xFC, 0xC4, 0x01, 0x4D, 0xFF, 0x2F, 0x00, + 0xFD, 0xFF, 0x08, 0x00, 0xE3, 0xFF, 0x1E, 0x00, 0x2A, 0x00, 0xEF, + 0xFE, 0x4D, 0x03, 0x7D, 0xF6, 0x2A, 0x43, 0x4B, 0x17, 0xB0, 0xF5, + 0xEF, 0x05, 0x93, 0xFC, 0xCB, 0x01, 0x3D, 0xFF, 0x34, 0x00, 0xFE, + 0xFF, 0x1E, 0x00, 0x85, 0xFF, 0x10, 0x01, 0x38, 0xFE, 0x88, 0x02, + 0xD3, 0xFC, 0x91, 0x03, 0xF7, 0x48, 0xCB, 0x03, 0xBA, 0xFC, 0x95, + 0x02, 0x31, 0xFE, 0x13, 0x01, 0x84, 0xFF, 0x1E, 0x00, 0x00, 0x00, + 0xFE, 0xFF, 0x34, 0x00, 0x3E, 0xFF, 0xC9, 0x01, 0x97, 0xFC, 0xE6, + 0x05, 0xC6, 0xF5, 0x00, 0x17, 0x50, 0x43, 0x9D, 0xF6, 0x3A, 0x03, + 0xFA, 0xFE, 0x23, 0x00, 0x21, 0x00, 0xE2, 0xFF, 0x08, 0x00, 0xFD, + 0xFF, 0x30, 0x00, 0x4C, 0xFF, 0xC6, 0x01, 0x4B, 0xFC, 0x26, 0x07, + 0xA5, 0xF1, 0x87, 0x2C, 0xDC, 0x33, 0x91, 0xF1, 0xC7, 0x06, 0xA9, + 0xFC, 0x84, 0x01, 0x70, 0xFF, 0x23, 0x00, 0xFE, 0xFF, 0x03, 0x00, + 0xFF, 0xFF, 0xD4, 0xFF, 0xBF, 0x00, 0xEB, 0xFD, 0xF3, 0x04, 0xCF, + 0xF3, 0x98, 0x3E, 0xF3, 0x1E, 0xB9, 0xF3, 0xB2, 0x06, 0x48, 0xFC, + 0xE4, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x15, 0x00, 0xA7, + 0xFF, 0xB9, 0x00, 0xEC, 0xFE, 0x31, 0x01, 0x57, 0xFF, 0x0F, 0xFE, + 0x33, 0x48, 0x25, 0x0A, 0x21, 0xFA, 0xE5, 0x03, 0x87, 0xFD, 0x62, + 0x01, 0x65, 0xFF, 0x27, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2E, 0x00, + 0x50, 0xFF, 0x97, 0x01, 0x10, 0xFD, 0xDA, 0x04, 0x20, 0xF8, 0xA0, + 0x0F, 0x97, 0x46, 0x61, 0xFA, 0x2D, 0x01, 0x2B, 0x00, 0x7A, 0xFF, + 0x75, 0x00, 0xC2, 0xFF, 0x0F, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x3A, + 0xFF, 0xE4, 0x01, 0x32, 0xFC, 0x0E, 0x07, 0x8B, 0xF2, 0x03, 0x25, + 0x38, 0x3A, 0x6D, 0xF2, 0xF1, 0x05, 0x45, 0xFD, 0x22, 0x01, 0xA2, + 0xFF, 0x11, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x16, 0x00, 0x96, 0xFF, + 0x39, 0x01, 0x1F, 0xFD, 0x28, 0x06, 0x2A, 0xF2, 0xF2, 0x38, 0xA0, + 0x26, 0x4B, 0xF2, 0x1C, 0x07, 0x32, 0xFC, 0xE0, 0x01, 0x3C, 0xFF, + 0x35, 0x00, 0xFD, 0xFF, 0x0D, 0x00, 0xC9, 0xFF, 0x63, 0x00, 0x9F, + 0xFF, 0xE8, 0xFF, 0xA3, 0x01, 0x7F, 0xF9, 0x02, 0x46, 0x27, 0x11, + 0x9B, 0xF7, 0x18, 0x05, 0xF3, 0xFC, 0xA3, 0x01, 0x4C, 0xFF, 0x2F, + 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x25, 0x00, 0x6B, 0xFF, 0x52, 0x01, + 0xA9, 0xFD, 0xA0, 0x03, 0xAE, 0xFA, 0xBE, 0x08, 0x7C, 0x48, 0x26, + 0xFF, 0xD2, 0xFE, 0x79, 0x01, 0xC6, 0xFE, 0xCC, 0x00, 0xA0, 0xFF, + 0x17, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE1, 0x01, 0x53, + 0xFC, 0x90, 0x06, 0x19, 0xF4, 0x52, 0x1D, 0xA8, 0x3F, 0x49, 0xF4, + 0xA3, 0x04, 0x1E, 0xFE, 0xA1, 0x00, 0xE3, 0xFF, 0xF9, 0xFF, 0x04, + 0x00, 0xFD, 0xFF, 0x26, 0x00, 0x67, 0xFF, 0x94, 0x01, 0x90, 0xFC, + 0xE5, 0x06, 0x81, 0xF1, 0x6B, 0x32, 0x11, 0x2E, 0x8E, 0xF1, 0x1D, + 0x07, 0x58, 0xFC, 0xBC, 0x01, 0x52, 0xFF, 0x2E, 0x00, 0xFD, 0xFF, + 0x07, 0x00, 0xE8, 0xFF, 0x11, 0x00, 0x45, 0x00, 0xBF, 0xFE, 0x9D, + 0x03, 0xF3, 0xF5, 0x75, 0x42, 0x9B, 0x18, 0x51, 0xF5, 0x16, 0x06, + 0x83, 0xFC, 0xD1, 0x01, 0x3B, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x1D, + 0x00, 0x8B, 0xFF, 0x01, 0x01, 0x56, 0xFE, 0x4D, 0x02, 0x45, 0xFD, + 0x8D, 0x02, 0xF0, 0x48, 0xD7, 0x04, 0x47, 0xFC, 0xD1, 0x02, 0x12, + 0xFE, 0x21, 0x01, 0x7E, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x33, 0x00, 0x40, 0xFF, 0xC2, 0x01, 0xA9, 0xFC, 0xBC, 0x05, 0x29, + 0xF6, 0xB3, 0x15, 0xFA, 0x43, 0x31, 0xF7, 0xE6, 0x02, 0x2C, 0xFF, + 0x07, 0x00, 0x2F, 0x00, 0xDC, 0xFF, 0x09, 0x00, 0xFD, 0xFF, 0x31, + 0x00, 0x48, 0xFF, 0xCE, 0x01, 0x42, 0xFC, 0x2A, 0x07, 0xBF, 0xF1, + 0x40, 0x2B, 0x05, 0x35, 0xA6, 0xF1, 0xAB, 0x06, 0xBF, 0xFC, 0x75, + 0x01, 0x77, 0xFF, 0x21, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0x03, 0x00, + 0xC8, 0xFF, 0xD6, 0x00, 0xC4, 0xFD, 0x31, 0x05, 0x73, 0xF3, 0xB0, + 0x3D, 0x49, 0x20, 0x6E, 0xF3, 0xCB, 0x06, 0x40, 0xFC, 0xE6, 0x01, + 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x14, 0x00, 0xAD, 0xFF, 0xAA, + 0x00, 0x0C, 0xFF, 0xF7, 0x00, 0xC1, 0xFF, 0x33, 0xFD, 0xEC, 0x47, + 0x51, 0x0B, 0xAF, 0xF9, 0x1D, 0x04, 0x6B, 0xFD, 0x6E, 0x01, 0x60, + 0xFF, 0x29, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2C, 0x00, 0x54, 0xFF, + 0x8C, 0x01, 0x29, 0xFD, 0xA7, 0x04, 0x8F, 0xF8, 0x64, 0x0E, 0x02, + 0x47, 0x22, 0xFB, 0xC9, 0x00, 0x64, 0x00, 0x5B, 0xFF, 0x84, 0x00, + 0xBC, 0xFF, 0x10, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE5, + 0x01, 0x33, 0xFC, 0xFF, 0x06, 0xC4, 0xF2, 0xB0, 0x23, 0x3B, 0x3B, + 0xAD, 0xF2, 0xBF, 0x05, 0x66, 0xFD, 0x0E, 0x01, 0xAC, 0xFF, 0x0E, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x19, 0x00, 0x8D, 0xFF, 0x4B, 0x01, + 0x01, 0xFD, 0x51, 0x06, 0xFB, 0xF1, 0xDF, 0x37, 0xF0, 0x27, 0x1C, + 0xF2, 0x24, 0x07, 0x34, 0xFC, 0xDC, 0x01, 0x3F, 0xFF, 0x34, 0x00, + 0xFD, 0xFF, 0x0C, 0x00, 0xCE, 0xFF, 0x54, 0x00, 0xBD, 0xFF, 0xB2, + 0xFF, 0x01, 0x02, 0xCF, 0xF8, 0x7D, 0x45, 0x6B, 0x12, 0x30, 0xF7, + 0x48, 0x05, 0xDD, 0xFC, 0xAD, 0x01, 0x48, 0xFF, 0x30, 0x00, 0xFF, + 0xFF, 0x00, 0x00, 0x24, 0x00, 0x70, 0xFF, 0x45, 0x01, 0xC6, 0xFD, + 0x66, 0x03, 0x21, 0xFB, 0x9E, 0x07, 0xAA, 0x48, 0x12, 0x00, 0x64, + 0xFE, 0xB4, 0x01, 0xA6, 0xFE, 0xDB, 0x00, 0x9A, 0xFF, 0x19, 0x00, + 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xDE, 0x01, 0x5F, 0xFC, 0x70, + 0x06, 0x6C, 0xF4, 0xFD, 0x1B, 0x7D, 0x40, 0xB7, 0xF4, 0x5D, 0x04, + 0x49, 0xFE, 0x88, 0x00, 0xEF, 0xFF, 0xF5, 0xFF, 0x04, 0x00, 0xFD, + 0xFF, 0x29, 0x00, 0x61, 0xFF, 0xA1, 0x01, 0x7E, 0xFC, 0xF9, 0x06, + 0x7C, 0xF1, 0x38, 0x31, 0x50, 0x2F, 0x82, 0xF1, 0x12, 0x07, 0x65, + 0xFC, 0xB2, 0x01, 0x57, 0xFF, 0x2C, 0x00, 0xFD, 0xFF, 0x06, 0x00, + 0xED, 0xFF, 0x04, 0x00, 0x60, 0x00, 0x90, 0xFE, 0xEB, 0x03, 0x71, + 0xF5, 0xB7, 0x41, 0xED, 0x19, 0xF5, 0xF4, 0x3B, 0x06, 0x73, 0xFC, + 0xD7, 0x01, 0x39, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x91, + 0xFF, 0xF2, 0x00, 0x76, 0xFE, 0x11, 0x02, 0xB6, 0xFD, 0x8F, 0x01, + 0xDE, 0x48, 0xE9, 0x05, 0xD4, 0xFB, 0x0C, 0x03, 0xF4, 0xFD, 0x2F, + 0x01, 0x79, 0xFF, 0x22, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x32, 0x00, + 0x43, 0xFF, 0xBA, 0x01, 0xBC, 0xFC, 0x90, 0x05, 0x8E, 0xF6, 0x68, + 0x14, 0x99, 0x44, 0xCD, 0xF7, 0x8F, 0x02, 0x60, 0xFF, 0xEA, 0xFF, + 0x3E, 0x00, 0xD7, 0xFF, 0x0A, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x44, + 0xFF, 0xD4, 0x01, 0x3B, 0xFC, 0x2A, 0x07, 0xDF, 0xF1, 0xF6, 0x29, + 0x27, 0x36, 0xC1, 0xF1, 0x8B, 0x06, 0xD8, 0xFC, 0x66, 0x01, 0x80, + 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x07, 0x00, 0xBD, 0xFF, + 0xED, 0x00, 0x9E, 0xFD, 0x6C, 0x05, 0x1F, 0xF3, 0xC0, 0x3C, 0x9E, + 0x21, 0x28, 0xF3, 0xE2, 0x06, 0x3A, 0xFC, 0xE6, 0x01, 0x37, 0xFF, + 0x36, 0x00, 0xFD, 0xFF, 0x12, 0x00, 0xB3, 0xFF, 0x9B, 0x00, 0x2B, + 0xFF, 0xBD, 0x00, 0x2A, 0x00, 0x5E, 0xFC, 0x9A, 0x47, 0x82, 0x0C, + 0x3D, 0xF9, 0x54, 0x04, 0x50, 0xFD, 0x7A, 0x01, 0x5B, 0xFF, 0x2A, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x59, 0xFF, 0x81, 0x01, + 0x42, 0xFD, 0x72, 0x04, 0xFF, 0xF8, 0x2D, 0x0D, 0x69, 0x47, 0xEB, + 0xFB, 0x63, 0x00, 0x9D, 0x00, 0x3C, 0xFF, 0x93, 0x00, 0xB6, 0xFF, + 0x12, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x37, + 0xFC, 0xED, 0x06, 0x03, 0xF3, 0x5B, 0x22, 0x37, 0x3C, 0xF4, 0xF2, + 0x8A, 0x05, 0x89, 0xFD, 0xF9, 0x00, 0xB7, 0xFF, 0x0A, 0x00, 0x01, + 0x00, 0xFE, 0xFF, 0x1C, 0x00, 0x84, 0xFF, 0x5C, 0x01, 0xE6, 0xFC, + 0x77, 0x06, 0xD4, 0xF1, 0xC6, 0x36, 0x3E, 0x29, 0xF3, 0xF1, 0x29, + 0x07, 0x38, 0xFC, 0xD7, 0x01, 0x42, 0xFF, 0x33, 0x00, 0xFD, 0xFF, + 0x0B, 0x00, 0xD4, 0xFF, 0x46, 0x00, 0xDA, 0xFF, 0x7D, 0xFF, 0x5D, + 0x02, 0x26, 0xF8, 0xED, 0x44, 0xB1, 0x13, 0xC7, 0xF6, 0x77, 0x05, + 0xC8, 0xFC, 0xB6, 0x01, 0x45, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0x22, 0x00, 0x76, 0xFF, 0x37, 0x01, 0xE4, 0xFD, 0x2C, 0x03, + 0x94, 0xFB, 0x83, 0x06, 0xCE, 0x48, 0x05, 0x01, 0xF5, 0xFD, 0xF0, + 0x01, 0x87, 0xFE, 0xEA, 0x00, 0x94, 0xFF, 0x1A, 0x00, 0xFE, 0xFF, + 0x35, 0x00, 0x38, 0xFF, 0xD9, 0x01, 0x6C, 0xFC, 0x4F, 0x06, 0xC3, + 0xF4, 0xA9, 0x1A, 0x49, 0x41, 0x2C, 0xF5, 0x15, 0x04, 0x76, 0xFE, + 0x6E, 0x00, 0xFC, 0xFF, 0xF0, 0xFF, 0x05, 0x00, 0xFD, 0xFF, 0x2B, + 0x00, 0x5A, 0xFF, 0xAC, 0x01, 0x6E, 0xFC, 0x0A, 0x07, 0x7E, 0xF1, + 0xFF, 0x2F, 0x8A, 0x30, 0x7D, 0xF1, 0x03, 0x07, 0x75, 0xFC, 0xA7, + 0x01, 0x5D, 0xFF, 0x2A, 0x00, 0xFD, 0xFF, 0x05, 0x00, 0xF2, 0xFF, + 0xF7, 0xFF, 0x7A, 0x00, 0x62, 0xFE, 0x35, 0x04, 0xF7, 0xF4, 0xEF, + 0x40, 0x40, 0x1B, 0x9C, 0xF4, 0x5E, 0x06, 0x66, 0xFC, 0xDB, 0x01, + 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x1A, 0x00, 0x96, 0xFF, 0xE3, + 0x00, 0x95, 0xFE, 0xD5, 0x01, 0x26, 0xFE, 0x98, 0x00, 0xBF, 0x48, + 0x00, 0x07, 0x61, 0xFB, 0x46, 0x03, 0xD6, 0xFD, 0x3D, 0x01, 0x73, + 0xFF, 0x23, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x00, 0x46, 0xFF, + 0xB2, 0x01, 0xD1, 0xFC, 0x62, 0x05, 0xF6, 0xF6, 0x20, 0x13, 0x2E, + 0x45, 0x70, 0xF8, 0x34, 0x02, 0x94, 0xFF, 0xCD, 0xFF, 0x4C, 0x00, + 0xD2, 0xFF, 0x0B, 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x41, 0xFF, 0xDA, + 0x01, 0x36, 0xFC, 0x27, 0x07, 0x05, 0xF2, 0xAA, 0x28, 0x44, 0x37, + 0xE4, 0xF1, 0x67, 0x06, 0xF2, 0xFC, 0x55, 0x01, 0x88, 0xFF, 0x1B, + 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x0B, 0x00, 0xB2, 0xFF, 0x02, 0x01, + 0x7A, 0xFD, 0xA2, 0x05, 0xD4, 0xF2, 0xC7, 0x3B, 0xF2, 0x22, 0xE7, + 0xF2, 0xF5, 0x06, 0x35, 0xFC, 0xE6, 0x01, 0x38, 0xFF, 0x36, 0x00, + 0xFD, 0xFF, 0x11, 0x00, 0xB9, 0xFF, 0x8C, 0x00, 0x4A, 0xFF, 0x83, + 0x00, 0x91, 0x00, 0x91, 0xFB, 0x3D, 0x47, 0xB7, 0x0D, 0xCD, 0xF8, + 0x89, 0x04, 0x36, 0xFD, 0x86, 0x01, 0x57, 0xFF, 0x2B, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5D, 0xFF, 0x75, 0x01, 0x5C, 0xFD, + 0x3C, 0x04, 0x70, 0xF9, 0xFA, 0x0B, 0xC0, 0x47, 0xBC, 0xFC, 0xFC, + 0xFF, 0xD6, 0x00, 0x1D, 0xFF, 0xA2, 0x00, 0xB0, 0xFF, 0x13, 0x00, + 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3C, 0xFC, 0xD8, + 0x06, 0x47, 0xF3, 0x06, 0x21, 0x2A, 0x3D, 0x44, 0xF3, 0x52, 0x05, + 0xAE, 0xFD, 0xE3, 0x00, 0xC2, 0xFF, 0x06, 0x00, 0x01, 0x00, 0xFE, + 0xFF, 0x1F, 0x00, 0x7C, 0xFF, 0x6D, 0x01, 0xCD, 0xFC, 0x99, 0x06, + 0xB4, 0xF1, 0xA6, 0x35, 0x89, 0x2A, 0xD0, 0xF1, 0x2B, 0x07, 0x3E, + 0xFC, 0xD1, 0x01, 0x46, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x0A, 0x00, + 0xD9, 0xFF, 0x37, 0x00, 0xF7, 0xFF, 0x49, 0xFF, 0xB6, 0x02, 0x86, + 0xF7, 0x53, 0x44, 0xFB, 0x14, 0x61, 0xF6, 0xA4, 0x05, 0xB4, 0xFC, + 0xBE, 0x01, 0x42, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x21, + 0x00, 0x7B, 0xFF, 0x29, 0x01, 0x01, 0xFE, 0xF1, 0x02, 0x07, 0xFC, + 0x6E, 0x05, 0xE6, 0x48, 0xFF, 0x01, 0x84, 0xFD, 0x2C, 0x02, 0x68, + 0xFE, 0xF9, 0x00, 0x8E, 0xFF, 0x1C, 0x00, 0xFE, 0xFF, 0x35, 0x00, + 0x3A, 0xFF, 0xD4, 0x01, 0x7A, 0xFC, 0x2B, 0x06, 0x1E, 0xF5, 0x56, + 0x19, 0x0C, 0x42, 0xAA, 0xF5, 0xC9, 0x03, 0xA4, 0xFE, 0x54, 0x00, + 0x09, 0x00, 0xEB, 0xFF, 0x06, 0x00, 0xFD, 0xFF, 0x2D, 0x00, 0x55, + 0xFF, 0xB6, 0x01, 0x5F, 0xFC, 0x17, 0x07, 0x87, 0xF1, 0xC2, 0x2E, + 0xC0, 0x31, 0x7E, 0xF1, 0xF1, 0x06, 0x86, 0xFC, 0x9B, 0x01, 0x63, + 0xFF, 0x28, 0x00, 0xFD, 0xFF, 0x04, 0x00, 0xF7, 0xFF, 0xEA, 0xFF, + 0x93, 0x00, 0x36, 0xFE, 0x7D, 0x04, 0x85, 0xF4, 0x1F, 0x40, 0x94, + 0x1C, 0x47, 0xF4, 0x7E, 0x06, 0x5A, 0xFC, 0xDF, 0x01, 0x37, 0xFF, + 0x36, 0x00, 0xFE, 0xFF, 0x18, 0x00, 0x9C, 0xFF, 0xD4, 0x00, 0xB4, + 0xFE, 0x9A, 0x01, 0x95, 0xFE, 0xA8, 0xFF, 0x98, 0x48, 0x1D, 0x08, + 0xEE, 0xFA, 0x80, 0x03, 0xB9, 0xFD, 0x4B, 0x01, 0x6E, 0xFF, 0x25, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30, 0x00, 0x4A, 0xFF, 0xA9, 0x01, + 0xE7, 0xFC, 0x33, 0x05, 0x60, 0xF7, 0xDA, 0x11, 0xB8, 0x45, 0x1C, + 0xF9, 0xD8, 0x01, 0xCA, 0xFF, 0xAF, 0xFF, 0x5A, 0x00, 0xCC, 0xFF, + 0x0D, 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x3E, 0xFF, 0xDE, 0x01, 0x33, + 0xFC, 0x21, 0x07, 0x30, 0xF2, 0x5C, 0x27, 0x5B, 0x38, 0x0F, 0xF2, + 0x40, 0x06, 0x0E, 0xFD, 0x43, 0x01, 0x91, 0xFF, 0x18, 0x00, 0xFF, + 0xFF, 0x00, 0x00, 0x0F, 0x00, 0xA8, 0xFF, 0x17, 0x01, 0x57, 0xFD, + 0xD6, 0x05, 0x90, 0xF2, 0xC8, 0x3A, 0x46, 0x24, 0xAA, 0xF2, 0x06, + 0x07, 0x32, 0xFC, 0xE5, 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, 0xFF, + 0x10, 0x00, 0xBE, 0xFF, 0x7D, 0x00, 0x69, 0xFF, 0x4B, 0x00, 0xF6, + 0x00, 0xCB, 0xFA, 0xD3, 0x46, 0xF0, 0x0E, 0x5E, 0xF8, 0xBE, 0x04, + 0x1E, 0xFD, 0x91, 0x01, 0x52, 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0x28, 0x00, 0x62, 0xFF, 0x69, 0x01, 0x77, 0xFD, 0x04, 0x04, + 0xE2, 0xF9, 0xCB, 0x0A, 0x0D, 0x48, 0x94, 0xFD, 0x92, 0xFF, 0x10, + 0x01, 0xFE, 0xFE, 0xB1, 0x00, 0xAA, 0xFF, 0x15, 0x00, 0xFD, 0xFF, + 0x36, 0x00, 0x36, 0xFF, 0xE5, 0x01, 0x43, 0xFC, 0xC0, 0x06, 0x8F, + 0xF3, 0xB1, 0x1F, 0x18, 0x3E, 0x9B, 0xF3, 0x16, 0x05, 0xD5, 0xFD, + 0xCC, 0x00, 0xCE, 0xFF, 0x01, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x22, + 0x00, 0x74, 0xFF, 0x7C, 0x01, 0xB5, 0xFC, 0xB8, 0x06, 0x9C, 0xF1, + 0x81, 0x34, 0xD1, 0x2B, 0xB3, 0xF1, 0x29, 0x07, 0x46, 0xFC, 0xCA, + 0x01, 0x4A, 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0x09, 0x00, 0xDF, 0xFF, + 0x29, 0x00, 0x14, 0x00, 0x16, 0xFF, 0x0C, 0x03, 0xEE, 0xF6, 0xB0, + 0x43, 0x47, 0x16, 0xFC, 0xF5, 0xCF, 0x05, 0xA1, 0xFC, 0xC6, 0x01, + 0x3F, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x81, + 0xFF, 0x1B, 0x01, 0x20, 0xFE, 0xB6, 0x02, 0x7A, 0xFC, 0x5F, 0x04, + 0xF4, 0x48, 0xFF, 0x02, 0x13, 0xFD, 0x67, 0x02, 0x49, 0xFE, 0x07, + 0x01, 0x88, 0xFF, 0x1D, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3C, 0xFF, + 0xCF, 0x01, 0x8A, 0xFC, 0x05, 0x06, 0x7B, 0xF5, 0x06, 0x18, 0xC7, + 0x42, 0x2F, 0xF6, 0x7A, 0x03, 0xD4, 0xFE, 0x39, 0x00, 0x17, 0x00, + 0xE6, 0xFF, 0x07, 0x00, 0xFD, 0xFF, 0x2E, 0x00, 0x50, 0xFF, 0xC0, + 0x01, 0x53, 0xFC, 0x21, 0x07, 0x96, 0xF1, 0x82, 0x2D, 0xF2, 0x32, + 0x86, 0xF1, 0xDB, 0x06, 0x99, 0xFC, 0x8E, 0x01, 0x6A, 0xFF, 0x25, + 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFB, 0xFF, 0xDE, 0xFF, 0xAC, 0x00, + 0x0B, 0xFE, 0xC1, 0x04, 0x1B, 0xF4, 0x47, 0x3F, 0xEA, 0x1D, 0xF5, + 0xF3, 0x9C, 0x06, 0x4F, 0xFC, 0xE2, 0x01, 0x36, 0xFF, 0x36, 0x00, + 0xFE, 0xFF, 0x16, 0x00, 0xA2, 0xFF, 0xC5, 0x00, 0xD4, 0xFE, 0x5F, + 0x01, 0x03, 0xFF, 0xBF, 0xFE, 0x63, 0x48, 0x40, 0x09, 0x7B, 0xFA, + 0xB9, 0x03, 0x9D, 0xFD, 0x58, 0x01, 0x69, 0xFF, 0x26, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0x2E, 0x00, 0x4D, 0xFF, 0x9F, 0x01, 0xFE, 0xFC, + 0x02, 0x05, 0xCB, 0xF7, 0x98, 0x10, 0x39, 0x46, 0xD0, 0xF9, 0x78, + 0x01, 0x00, 0x00, 0x91, 0xFF, 0x69, 0x00, 0xC6, 0xFF, 0x0E, 0x00, + 0xFD, 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xE2, 0x01, 0x31, 0xFC, 0x17, + 0x07, 0x61, 0xF2, 0x0A, 0x26, 0x6A, 0x39, 0x41, 0xF2, 0x15, 0x06, + 0x2C, 0xFD, 0x31, 0x01, 0x9B, 0xFF, 0x14, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0x13, 0x00, 0x9E, 0xFF, 0x2B, 0x01, 0x37, 0xFD, 0x05, 0x06, + 0x54, 0xF2, 0xC2, 0x39, 0x99, 0x25, 0x73, 0xF2, 0x14, 0x07, 0x31, + 0xFC, 0xE3, 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0E, 0x00, + 0xC4, 0xFF, 0x6E, 0x00, 0x87, 0xFF, 0x13, 0x00, 0x58, 0x01, 0x0D, + 0xFA, 0x61, 0x46, 0x2D, 0x10, 0xF0, 0xF7, 0xF1, 0x04, 0x05, 0xFD, + 0x9C, 0x01, 0x4E, 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x27, + 0x00, 0x67, 0xFF, 0x5C, 0x01, 0x93, 0xFD, 0xCC, 0x03, 0x54, 0xFA, + 0xA2, 0x09, 0x4F, 0x48, 0x73, 0xFE, 0x27, 0xFF, 0x4B, 0x01, 0xDE, + 0xFE, 0xC0, 0x00, 0xA4, 0xFF, 0x16, 0x00, 0xFE, 0xFF, 0x36, 0x00, + 0x36, 0xFF, 0xE3, 0x01, 0x4C, 0xFC, 0xA6, 0x06, 0xDB, 0xF3, 0x5B, + 0x1E, 0xFC, 0x3E, 0xFA, 0xF3, 0xD7, 0x04, 0xFD, 0xFD, 0xB4, 0x00, + 0xD9, 0xFF, 0xFD, 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0x25, 0x00, 0x6D, + 0xFF, 0x8A, 0x01, 0x9F, 0xFC, 0xD3, 0x06, 0x8A, 0xF1, 0x57, 0x33, + 0x17, 0x2D, 0x9C, 0xF1, 0x24, 0x07, 0x4F, 0xFC, 0xC3, 0x01, 0x4E, + 0xFF, 0x2F, 0x00, 0xFD, 0xFF, 0x08, 0x00, 0xE4, 0xFF, 0x1B, 0x00, + 0x30, 0x00, 0xE4, 0xFE, 0x5F, 0x03, 0x5E, 0xF6, 0x02, 0x43, 0x96, + 0x17, 0x9B, 0xF5, 0xF8, 0x05, 0x8F, 0xFC, 0xCC, 0x01, 0x3D, 0xFF, + 0x34, 0x00, 0xFE, 0xFF, 0x1E, 0x00, 0x86, 0xFF, 0x0C, 0x01, 0x3E, + 0xFE, 0x7B, 0x02, 0xED, 0xFC, 0x56, 0x03, 0xF5, 0x48, 0x06, 0x04, + 0xA1, 0xFC, 0xA3, 0x02, 0x2A, 0xFE, 0x16, 0x01, 0x83, 0xFF, 0x1F, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x3E, 0xFF, 0xC8, 0x01, + 0x9B, 0xFC, 0xDD, 0x05, 0xDC, 0xF5, 0xB6, 0x16, 0x77, 0x43, 0xBD, + 0xF6, 0x28, 0x03, 0x05, 0xFF, 0x1D, 0x00, 0x25, 0x00, 0xE1, 0xFF, + 0x08, 0x00, 0xFD, 0xFF, 0x30, 0x00, 0x4B, 0xFF, 0xC8, 0x01, 0x49, + 0xFC, 0x27, 0x07, 0xAB, 0xF1, 0x3E, 0x2C, 0x1E, 0x34, 0x95, 0xF1, + 0xC1, 0x06, 0xAE, 0xFC, 0x81, 0x01, 0x71, 0xFF, 0x23, 0x00, 0xFE, + 0xFF, 0x02, 0x00, 0x00, 0x00, 0xD2, 0xFF, 0xC4, 0x00, 0xE2, 0xFD, + 0x01, 0x05, 0xBA, 0xF3, 0x64, 0x3E, 0x3F, 0x1F, 0xA8, 0xF3, 0xB8, + 0x06, 0x46, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, + 0x15, 0x00, 0xA8, 0xFF, 0xB6, 0x00, 0xF3, 0xFE, 0x24, 0x01, 0x6E, + 0xFF, 0xDE, 0xFD, 0x25, 0x48, 0x68, 0x0A, 0x08, 0xFA, 0xF2, 0x03, + 0x81, 0xFD, 0x65, 0x01, 0x64, 0xFF, 0x28, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0x2D, 0x00, 0x51, 0xFF, 0x95, 0x01, 0x15, 0xFD, 0xCF, 0x04, + 0x39, 0xF8, 0x59, 0x0F, 0xAF, 0x46, 0x8B, 0xFA, 0x17, 0x01, 0x38, + 0x00, 0x73, 0xFF, 0x78, 0x00, 0xC0, 0xFF, 0x0F, 0x00, 0xFD, 0xFF, + 0x36, 0x00, 0x39, 0xFF, 0xE4, 0x01, 0x32, 0xFC, 0x0B, 0x07, 0x97, + 0xF2, 0xB8, 0x24, 0x71, 0x3A, 0x7B, 0xF2, 0xE6, 0x05, 0x4C, 0xFD, + 0x1D, 0x01, 0xA4, 0xFF, 0x11, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x16, + 0x00, 0x94, 0xFF, 0x3D, 0x01, 0x18, 0xFD, 0x32, 0x06, 0x1F, 0xF2, + 0xB5, 0x38, 0xEB, 0x26, 0x40, 0xF2, 0x1E, 0x07, 0x32, 0xFC, 0xDF, + 0x01, 0x3D, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0D, 0x00, 0xCA, 0xFF, + 0x5F, 0x00, 0xA5, 0xFF, 0xDC, 0xFF, 0xB8, 0x01, 0x57, 0xF9, 0xE5, + 0x45, 0x6E, 0x11, 0x83, 0xF7, 0x23, 0x05, 0xEE, 0xFC, 0xA6, 0x01, + 0x4B, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x25, 0x00, 0x6C, + 0xFF, 0x4F, 0x01, 0xB0, 0xFD, 0x93, 0x03, 0xC7, 0xFA, 0x7D, 0x08, + 0x86, 0x48, 0x5A, 0xFF, 0xBA, 0xFE, 0x86, 0x01, 0xBF, 0xFE, 0xCF, + 0x00, 0x9E, 0xFF, 0x17, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, + 0xE0, 0x01, 0x56, 0xFC, 0x89, 0x06, 0x2B, 0xF4, 0x06, 0x1D, 0xD7, + 0x3F, 0x61, 0xF4, 0x94, 0x04, 0x27, 0xFE, 0x9C, 0x00, 0xE6, 0xFF, + 0xF8, 0xFF, 0x04, 0x00, 0xFD, 0xFF, 0x27, 0x00, 0x66, 0xFF, 0x97, + 0x01, 0x8C, 0xFC, 0xEA, 0x06, 0x80, 0xF1, 0x26, 0x32, 0x58, 0x2E, + 0x8B, 0xF1, 0x1B, 0x07, 0x5B, 0xFC, 0xBA, 0x01, 0x53, 0xFF, 0x2D, + 0x00, 0xFD, 0xFF, 0x07, 0x00, 0xE9, 0xFF, 0x0E, 0x00, 0x4B, 0x00, + 0xB4, 0xFE, 0xAF, 0x03, 0xD5, 0xF5, 0x4D, 0x42, 0xE6, 0x18, 0x3C, + 0xF5, 0x1F, 0x06, 0x7F, 0xFC, 0xD3, 0x01, 0x3B, 0xFF, 0x35, 0x00, + 0xFE, 0xFF, 0x1C, 0x00, 0x8C, 0xFF, 0xFE, 0x00, 0x5D, 0xFE, 0x3F, + 0x02, 0x5E, 0xFD, 0x54, 0x02, 0xEC, 0x48, 0x13, 0x05, 0x2E, 0xFC, + 0xDE, 0x02, 0x0C, 0xFE, 0x24, 0x01, 0x7D, 0xFF, 0x20, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x41, 0xFF, 0xC1, 0x01, 0xAD, 0xFC, + 0xB2, 0x05, 0x3F, 0xF6, 0x69, 0x15, 0x1F, 0x44, 0x53, 0xF7, 0xD3, + 0x02, 0x38, 0xFF, 0x01, 0x00, 0x33, 0x00, 0xDB, 0xFF, 0x09, 0x00, + 0xFD, 0xFF, 0x31, 0x00, 0x47, 0xFF, 0xCF, 0x01, 0x40, 0xFC, 0x2A, + 0x07, 0xC6, 0xF1, 0xF7, 0x2A, 0x46, 0x35, 0xAB, 0xF1, 0xA4, 0x06, + 0xC4, 0xFC, 0x72, 0x01, 0x79, 0xFF, 0x20, 0x00, 0xFE, 0xFF, 0x02, + 0x00, 0x04, 0x00, 0xC6, 0xFF, 0xDB, 0x00, 0xBB, 0xFD, 0x3E, 0x05, + 0x60, 0xF3, 0x7B, 0x3D, 0x94, 0x20, 0x5E, 0xF3, 0xD0, 0x06, 0x3E, + 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x14, 0x00, + 0xAE, 0xFF, 0xA7, 0x00, 0x12, 0xFF, 0xEA, 0x00, 0xD9, 0xFF, 0x03, + 0xFD, 0xDC, 0x47, 0x95, 0x0B, 0x96, 0xF9, 0x29, 0x04, 0x65, 0xFD, + 0x71, 0x01, 0x5F, 0xFF, 0x29, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2C, + 0x00, 0x55, 0xFF, 0x8A, 0x01, 0x2E, 0xFD, 0x9B, 0x04, 0xA8, 0xF8, + 0x1F, 0x0E, 0x1A, 0x47, 0x4E, 0xFB, 0xB3, 0x00, 0x70, 0x00, 0x54, + 0xFF, 0x87, 0x00, 0xBB, 0xFF, 0x11, 0x00, 0xFD, 0xFF, 0x36, 0x00, + 0x38, 0xFF, 0xE6, 0x01, 0x34, 0xFC, 0xFB, 0x06, 0xD2, 0xF2, 0x64, + 0x23, 0x73, 0x3B, 0xBC, 0xF2, 0xB4, 0x05, 0x6E, 0xFD, 0x09, 0x01, + 0xAF, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1A, 0x00, 0x8B, + 0xFF, 0x4F, 0x01, 0xFB, 0xFC, 0x5A, 0x06, 0xF2, 0xF1, 0xA0, 0x37, + 0x3A, 0x28, 0x13, 0xF2, 0x25, 0x07, 0x35, 0xFC, 0xDB, 0x01, 0x40, + 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0C, 0x00, 0xD0, 0xFF, 0x51, 0x00, + 0xC3, 0xFF, 0xA6, 0xFF, 0x16, 0x02, 0xA9, 0xF8, 0x5C, 0x45, 0xB2, + 0x12, 0x19, 0xF7, 0x52, 0x05, 0xD8, 0xFC, 0xAF, 0x01, 0x47, 0xFF, + 0x30, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x24, 0x00, 0x71, 0xFF, 0x42, + 0x01, 0xCD, 0xFD, 0x59, 0x03, 0x3B, 0xFB, 0x5E, 0x07, 0xB3, 0x48, + 0x48, 0x00, 0x4B, 0xFE, 0xC2, 0x01, 0x9F, 0xFE, 0xDE, 0x00, 0x98, + 0xFF, 0x19, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xDD, 0x01, + 0x62, 0xFC, 0x69, 0x06, 0x7F, 0xF4, 0xB2, 0x1B, 0xAB, 0x40, 0xD0, + 0xF4, 0x4E, 0x04, 0x53, 0xFE, 0x83, 0x00, 0xF2, 0xFF, 0xF4, 0xFF, + 0x05, 0x00, 0xFD, 0xFF, 0x29, 0x00, 0x5F, 0xFF, 0xA3, 0x01, 0x7A, + 0xFC, 0xFD, 0x06, 0x7C, 0xF1, 0xF2, 0x30, 0x96, 0x2F, 0x80, 0xF1, + 0x0F, 0x07, 0x69, 0xFC, 0xB0, 0x01, 0x59, 0xFF, 0x2B, 0x00, 0xFD, + 0xFF, 0x06, 0x00, 0xEE, 0xFF, 0x01, 0x00, 0x66, 0x00, 0x85, 0xFE, + 0xFC, 0x03, 0x55, 0xF5, 0x8C, 0x41, 0x38, 0x1A, 0xE1, 0xF4, 0x43, + 0x06, 0x70, 0xFC, 0xD8, 0x01, 0x39, 0xFF, 0x35, 0x00, 0xFE, 0xFF, + 0x1B, 0x00, 0x92, 0xFF, 0xEF, 0x00, 0x7D, 0xFE, 0x04, 0x02, 0xCF, + 0xFD, 0x58, 0x01, 0xD7, 0x48, 0x26, 0x06, 0xBB, 0xFB, 0x19, 0x03, + 0xED, 0xFD, 0x32, 0x01, 0x77, 0xFF, 0x22, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0x32, 0x00, 0x44, 0xFF, 0xB9, 0x01, 0xC1, 0xFC, 0x86, 0x05, + 0xA5, 0xF6, 0x1E, 0x14, 0xBA, 0x44, 0xF0, 0xF7, 0x7B, 0x02, 0x6B, + 0xFF, 0xE4, 0xFF, 0x41, 0x00, 0xD6, 0xFF, 0x0B, 0x00, 0xFD, 0xFF, + 0x33, 0x00, 0x43, 0xFF, 0xD5, 0x01, 0x3A, 0xFC, 0x2A, 0x07, 0xE7, + 0xF1, 0xAC, 0x29, 0x66, 0x36, 0xC9, 0xF1, 0x83, 0x06, 0xDD, 0xFC, + 0x62, 0x01, 0x81, 0xFF, 0x1D, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x08, + 0x00, 0xBB, 0xFF, 0xF1, 0x00, 0x96, 0xFD, 0x78, 0x05, 0x0E, 0xF3, + 0x8A, 0x3C, 0xEA, 0x21, 0x19, 0xF3, 0xE6, 0x06, 0x38, 0xFC, 0xE6, + 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x12, 0x00, 0xB4, 0xFF, + 0x98, 0x00, 0x32, 0xFF, 0xB0, 0x00, 0x41, 0x00, 0x30, 0xFC, 0x86, + 0x47, 0xC6, 0x0C, 0x24, 0xF9, 0x60, 0x04, 0x4B, 0xFD, 0x7D, 0x01, + 0x5A, 0xFF, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x5A, + 0xFF, 0x7E, 0x01, 0x48, 0xFD, 0x66, 0x04, 0x18, 0xF9, 0xE8, 0x0C, + 0x7C, 0x47, 0x19, 0xFC, 0x4D, 0x00, 0xA9, 0x00, 0x35, 0xFF, 0x96, + 0x00, 0xB5, 0xFF, 0x12, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, + 0xE6, 0x01, 0x38, 0xFC, 0xE9, 0x06, 0x12, 0xF3, 0x10, 0x22, 0x6E, + 0x3C, 0x05, 0xF3, 0x7E, 0x05, 0x91, 0xFD, 0xF4, 0x00, 0xBA, 0xFF, + 0x09, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1D, 0x00, 0x82, 0xFF, 0x60, + 0x01, 0xE0, 0xFC, 0x7F, 0x06, 0xCC, 0xF1, 0x85, 0x36, 0x87, 0x29, + 0xEB, 0xF1, 0x2A, 0x07, 0x39, 0xFC, 0xD6, 0x01, 0x43, 0xFF, 0x33, + 0x00, 0xFD, 0xFF, 0x0B, 0x00, 0xD5, 0xFF, 0x42, 0x00, 0xE1, 0xFF, + 0x71, 0xFF, 0x71, 0x02, 0x02, 0xF8, 0xCC, 0x44, 0xFA, 0x13, 0xB0, + 0xF6, 0x81, 0x05, 0xC3, 0xFC, 0xB8, 0x01, 0x44, 0xFF, 0x31, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x22, 0x00, 0x77, 0xFF, 0x34, 0x01, 0xEA, + 0xFD, 0x1F, 0x03, 0xAE, 0xFB, 0x45, 0x06, 0xD5, 0x48, 0x3C, 0x01, + 0xDC, 0xFD, 0xFD, 0x01, 0x80, 0xFE, 0xED, 0x00, 0x93, 0xFF, 0x1B, + 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x39, 0xFF, 0xD8, 0x01, 0x6F, 0xFC, + 0x47, 0x06, 0xD7, 0xF4, 0x5D, 0x1A, 0x74, 0x41, 0x48, 0xF5, 0x04, + 0x04, 0x80, 0xFE, 0x69, 0x00, 0xFF, 0xFF, 0xEF, 0xFF, 0x05, 0x00, + 0xFD, 0xFF, 0x2B, 0x00, 0x59, 0xFF, 0xAE, 0x01, 0x6A, 0xFC, 0x0D, + 0x07, 0x80, 0xF1, 0xB8, 0x2F, 0xCF, 0x30, 0x7D, 0xF1, 0xFF, 0x06, + 0x78, 0xFC, 0xA5, 0x01, 0x5F, 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0x05, + 0x00, 0xF3, 0xFF, 0xF4, 0xFF, 0x80, 0x00, 0x58, 0xFE, 0x46, 0x04, + 0xDD, 0xF4, 0xC3, 0x40, 0x8C, 0x1B, 0x89, 0xF4, 0x66, 0x06, 0x63, + 0xFC, 0xDC, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x19, 0x00, + 0x98, 0xFF, 0xE0, 0x00, 0x9C, 0xFE, 0xC8, 0x01, 0x3F, 0xFE, 0x62, + 0x00, 0xB8, 0x48, 0x3F, 0x07, 0x47, 0xFB, 0x53, 0x03, 0xD0, 0xFD, + 0x40, 0x01, 0x72, 0xFF, 0x23, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30, + 0x00, 0x47, 0xFF, 0xB0, 0x01, 0xD6, 0xFC, 0x58, 0x05, 0x0D, 0xF7, + 0xD7, 0x12, 0x4E, 0x45, 0x96, 0xF8, 0x20, 0x02, 0xA0, 0xFF, 0xC7, + 0xFF, 0x4F, 0x00, 0xD0, 0xFF, 0x0C, 0x00, 0xFD, 0xFF, 0x34, 0x00, + 0x40, 0xFF, 0xDB, 0x01, 0x35, 0xFC, 0x26, 0x07, 0x0E, 0xF2, 0x60, + 0x28, 0x82, 0x37, 0xED, 0xF1, 0x5E, 0x06, 0xF8, 0xFC, 0x51, 0x01, + 0x8A, 0xFF, 0x1A, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0C, 0x00, 0xB0, + 0xFF, 0x07, 0x01, 0x72, 0xFD, 0xAE, 0x05, 0xC4, 0xF2, 0x90, 0x3B, + 0x3F, 0x23, 0xD9, 0xF2, 0xF9, 0x06, 0x34, 0xFC, 0xE6, 0x01, 0x38, + 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x11, 0x00, 0xBA, 0xFF, 0x89, 0x00, + 0x51, 0xFF, 0x77, 0x00, 0xA7, 0x00, 0x64, 0xFB, 0x26, 0x47, 0xFC, + 0x0D, 0xB4, 0xF8, 0x95, 0x04, 0x31, 0xFD, 0x88, 0x01, 0x56, 0xFF, + 0x2C, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x29, 0x00, 0x5E, 0xFF, 0x72, + 0x01, 0x62, 0xFD, 0x2F, 0x04, 0x89, 0xF9, 0xB6, 0x0B, 0xD2, 0x47, + 0xEB, 0xFC, 0xE4, 0xFF, 0xE3, 0x00, 0x16, 0xFF, 0xA5, 0x00, 0xAF, + 0xFF, 0x13, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, + 0x3E, 0xFC, 0xD3, 0x06, 0x56, 0xF3, 0xBA, 0x20, 0x61, 0x3D, 0x56, + 0xF3, 0x45, 0x05, 0xB7, 0xFD, 0xDE, 0x00, 0xC5, 0xFF, 0x05, 0x00, + 0x02, 0x00, 0xFE, 0xFF, 0x20, 0x00, 0x7A, 0xFF, 0x70, 0x01, 0xC7, + 0xFC, 0xA0, 0x06, 0xAE, 0xF1, 0x65, 0x35, 0xD1, 0x2A, 0xCA, 0xF1, + 0x2A, 0x07, 0x40, 0xFC, 0xD0, 0x01, 0x47, 0xFF, 0x32, 0x00, 0xFD, + 0xFF, 0x09, 0x00, 0xDB, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x3D, 0xFF, + 0xC9, 0x02, 0x64, 0xF7, 0x2F, 0x44, 0x44, 0x15, 0x4A, 0xF6, 0xAD, + 0x05, 0xAF, 0xFC, 0xC0, 0x01, 0x41, 0xFF, 0x32, 0x00, 0xFF, 0xFF, + 0x00, 0x00, 0x21, 0x00, 0x7C, 0xFF, 0x26, 0x01, 0x08, 0xFE, 0xE4, + 0x02, 0x21, 0xFC, 0x31, 0x05, 0xEB, 0x48, 0x37, 0x02, 0x6B, 0xFD, + 0x39, 0x02, 0x61, 0xFE, 0xFC, 0x00, 0x8D, 0xFF, 0x1C, 0x00, 0xFE, + 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD3, 0x01, 0x7D, 0xFC, 0x23, 0x06, + 0x32, 0xF5, 0x0C, 0x19, 0x38, 0x42, 0xC7, 0xF5, 0xB8, 0x03, 0xAF, + 0xFE, 0x4E, 0x00, 0x0C, 0x00, 0xEA, 0xFF, 0x06, 0x00, 0xFD, 0xFF, + 0x2D, 0x00, 0x54, 0xFF, 0xB8, 0x01, 0x5D, 0xFC, 0x1A, 0x07, 0x8A, + 0xF1, 0x7B, 0x2E, 0x04, 0x32, 0x7F, 0xF1, 0xEC, 0x06, 0x8A, 0xFC, + 0x98, 0x01, 0x65, 0xFF, 0x27, 0x00, 0xFD, 0xFF, 0x04, 0x00, 0xF8, + 0xFF, 0xE7, 0xFF, 0x99, 0x00, 0x2C, 0xFE, 0x8C, 0x04, 0x6D, 0xF4, + 0xF0, 0x3F, 0xE0, 0x1C, 0x34, 0xF4, 0x85, 0x06, 0x57, 0xFC, 0xE0, + 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x18, 0x00, 0x9E, 0xFF, + 0xD1, 0x00, 0xBB, 0xFE, 0x8D, 0x01, 0xAE, 0xFE, 0x74, 0xFF, 0x8D, + 0x48, 0x5D, 0x08, 0xD4, 0xFA, 0x8D, 0x03, 0xB3, 0xFD, 0x4E, 0x01, + 0x6D, 0xFF, 0x25, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4A, + 0xFF, 0xA7, 0x01, 0xEC, 0xFC, 0x28, 0x05, 0x77, 0xF7, 0x92, 0x11, + 0xD7, 0x45, 0x43, 0xF9, 0xC3, 0x01, 0xD6, 0xFF, 0xA9, 0xFF, 0x5E, + 0x00, 0xCB, 0xFF, 0x0D, 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x3D, 0xFF, + 0xDF, 0x01, 0x32, 0xFC, 0x1F, 0x07, 0x3B, 0xF2, 0x11, 0x27, 0x97, + 0x38, 0x19, 0xF2, 0x36, 0x06, 0x15, 0xFD, 0x3F, 0x01, 0x93, 0xFF, + 0x17, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x10, 0x00, 0xA6, 0xFF, 0x1B, + 0x01, 0x50, 0xFD, 0xE1, 0x05, 0x82, 0xF2, 0x8F, 0x3A, 0x92, 0x24, + 0x9D, 0xF2, 0x09, 0x07, 0x32, 0xFC, 0xE4, 0x01, 0x39, 0xFF, 0x36, + 0x00, 0xFD, 0xFF, 0x0F, 0x00, 0xC0, 0xFF, 0x7A, 0x00, 0x70, 0xFF, + 0x3E, 0x00, 0x0C, 0x01, 0xA1, 0xFA, 0xBB, 0x46, 0x36, 0x0F, 0x45, + 0xF8, 0xC9, 0x04, 0x18, 0xFD, 0x93, 0x01, 0x52, 0xFF, 0x2D, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x28, 0x00, 0x63, 0xFF, 0x66, 0x01, 0x7D, + 0xFD, 0xF8, 0x03, 0xFB, 0xF9, 0x89, 0x0A, 0x1D, 0x48, 0xC5, 0xFD, + 0x7A, 0xFF, 0x1D, 0x01, 0xF7, 0xFE, 0xB4, 0x00, 0xA9, 0xFF, 0x15, + 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE5, 0x01, 0x45, 0xFC, + 0xBB, 0x06, 0xA0, 0xF3, 0x64, 0x1F, 0x4A, 0x3E, 0xB0, 0xF3, 0x08, + 0x05, 0xDE, 0xFD, 0xC7, 0x00, 0xD0, 0xFF, 0x00, 0x00, 0x02, 0x00, + 0xFE, 0xFF, 0x23, 0x00, 0x72, 0xFF, 0x7F, 0x01, 0xB0, 0xFC, 0xBE, + 0x06, 0x97, 0xF1, 0x3F, 0x34, 0x19, 0x2C, 0xAD, 0xF1, 0x28, 0x07, + 0x48, 0xFC, 0xC9, 0x01, 0x4B, 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0x08, + 0x00, 0xE0, 0xFF, 0x26, 0x00, 0x1A, 0x00, 0x0B, 0xFF, 0x1E, 0x03, + 0xCD, 0xF6, 0x89, 0x43, 0x91, 0x16, 0xE7, 0xF5, 0xD8, 0x05, 0x9D, + 0xFC, 0xC7, 0x01, 0x3E, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x00, 0x00, + 0x1F, 0x00, 0x82, 0xFF, 0x18, 0x01, 0x27, 0xFE, 0xA9, 0x02, 0x94, + 0xFC, 0x24, 0x04, 0xF5, 0x48, 0x39, 0x03, 0xF9, 0xFC, 0x74, 0x02, + 0x42, 0xFE, 0x0B, 0x01, 0x87, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x34, + 0x00, 0x3C, 0xFF, 0xCD, 0x01, 0x8E, 0xFC, 0xFC, 0x05, 0x90, 0xF5, + 0xBB, 0x17, 0xEE, 0x42, 0x4E, 0xF6, 0x68, 0x03, 0xDF, 0xFE, 0x33, + 0x00, 0x1A, 0x00, 0xE5, 0xFF, 0x07, 0x00, 0xFD, 0xFF, 0x2F, 0x00, + 0x4F, 0xFF, 0xC2, 0x01, 0x51, 0xFC, 0x23, 0x07, 0x9A, 0xF1, 0x3A, + 0x2D, 0x35, 0x33, 0x89, 0xF1, 0xD5, 0x06, 0x9D, 0xFC, 0x8B, 0x01, + 0x6C, 0xFF, 0x25, 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFC, 0xFF, 0xDB, + 0xFF, 0xB2, 0x00, 0x02, 0xFE, 0xCF, 0x04, 0x05, 0xF4, 0x16, 0x3F, + 0x36, 0x1E, 0xE4, 0xF3, 0xA3, 0x06, 0x4D, 0xFC, 0xE3, 0x01, 0x36, + 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x16, 0x00, 0xA4, 0xFF, 0xC2, 0x00, + 0xDB, 0xFE, 0x52, 0x01, 0x1B, 0xFF, 0x8D, 0xFE, 0x57, 0x48, 0x81, + 0x09, 0x61, 0xFA, 0xC6, 0x03, 0x96, 0xFD, 0x5B, 0x01, 0x68, 0xFF, + 0x26, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2E, 0x00, 0x4E, 0xFF, 0x9D, + 0x01, 0x03, 0xFD, 0xF7, 0x04, 0xE3, 0xF7, 0x51, 0x10, 0x55, 0x46, + 0xF9, 0xF9, 0x63, 0x01, 0x0D, 0x00, 0x8B, 0xFF, 0x6D, 0x00, 0xC5, + 0xFF, 0x0E, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xE2, 0x01, + 0x31, 0xFC, 0x15, 0x07, 0x6D, 0xF2, 0xBF, 0x25, 0xA5, 0x39, 0x4D, + 0xF2, 0x0B, 0x06, 0x33, 0xFD, 0x2D, 0x01, 0x9D, 0xFF, 0x13, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x14, 0x00, 0x9C, 0xFF, 0x2F, 0x01, 0x30, + 0xFD, 0x10, 0x06, 0x47, 0xF2, 0x87, 0x39, 0xE5, 0x25, 0x67, 0xF2, + 0x16, 0x07, 0x31, 0xFC, 0xE2, 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFD, + 0xFF, 0x0E, 0x00, 0xC6, 0xFF, 0x6B, 0x00, 0x8E, 0xFF, 0x06, 0x00, + 0x6E, 0x01, 0xE4, 0xF9, 0x48, 0x46, 0x75, 0x10, 0xD7, 0xF7, 0xFC, + 0x04, 0x00, 0xFD, 0x9E, 0x01, 0x4E, 0xFF, 0x2E, 0x00, 0xFF, 0xFF, + 0x00, 0x00, 0x26, 0x00, 0x68, 0xFF, 0x59, 0x01, 0x99, 0xFD, 0xC0, + 0x03, 0x6E, 0xFA, 0x61, 0x09, 0x5D, 0x48, 0xA6, 0xFE, 0x0F, 0xFF, + 0x58, 0x01, 0xD7, 0xFE, 0xC3, 0x00, 0xA3, 0xFF, 0x16, 0x00, 0xFE, + 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE3, 0x01, 0x4E, 0xFC, 0xA0, 0x06, + 0xED, 0xF3, 0x0F, 0x1E, 0x2D, 0x3F, 0x10, 0xF4, 0xC8, 0x04, 0x07, + 0xFE, 0xAF, 0x00, 0xDC, 0xFF, 0xFC, 0xFF, 0x03, 0x00, 0xFD, 0xFF, + 0x25, 0x00, 0x6B, 0xFF, 0x8D, 0x01, 0x9B, 0xFC, 0xD8, 0x06, 0x87, + 0xF1, 0x13, 0x33, 0x5E, 0x2D, 0x98, 0xF1, 0x22, 0x07, 0x52, 0xFC, + 0xC1, 0x01, 0x4F, 0xFF, 0x2F, 0x00, 0xFD, 0xFF, 0x07, 0x00, 0xE5, + 0xFF, 0x18, 0x00, 0x36, 0x00, 0xD9, 0xFE, 0x71, 0x03, 0x3F, 0xF6, + 0xDB, 0x42, 0xE0, 0x17, 0x86, 0xF5, 0x00, 0x06, 0x8C, 0xFC, 0xCE, + 0x01, 0x3C, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x1D, 0x00, 0x88, 0xFF, + 0x09, 0x01, 0x45, 0xFE, 0x6E, 0x02, 0x06, 0xFD, 0x1C, 0x03, 0xF4, + 0x48, 0x41, 0x04, 0x87, 0xFC, 0xB0, 0x02, 0x23, 0xFE, 0x19, 0x01, + 0x81, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x3F, + 0xFF, 0xC6, 0x01, 0x9F, 0xFC, 0xD3, 0x05, 0xF1, 0xF5, 0x6C, 0x16, + 0x9E, 0x43, 0xDD, 0xF6, 0x15, 0x03, 0x10, 0xFF, 0x17, 0x00, 0x28, + 0x00, 0xDF, 0xFF, 0x09, 0x00, 0xFD, 0xFF, 0x30, 0x00, 0x4A, 0xFF, + 0xCA, 0x01, 0x47, 0xFC, 0x28, 0x07, 0xB0, 0xF1, 0xF5, 0x2B, 0x60, + 0x34, 0x9A, 0xF1, 0xBB, 0x06, 0xB3, 0xFC, 0x7D, 0x01, 0x73, 0xFF, + 0x22, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0x01, 0x00, 0xCF, 0xFF, 0xC9, + 0x00, 0xDA, 0xFD, 0x0F, 0x05, 0xA5, 0xF3, 0x31, 0x3E, 0x8A, 0x1F, + 0x97, 0xF3, 0xBD, 0x06, 0x44, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36, + 0x00, 0xFD, 0xFF, 0x15, 0x00, 0xAA, 0xFF, 0xB3, 0x00, 0xFA, 0xFE, + 0x17, 0x01, 0x86, 0xFF, 0xAC, 0xFD, 0x16, 0x48, 0xAA, 0x0A, 0xEE, + 0xF9, 0xFE, 0x03, 0x7A, 0xFD, 0x67, 0x01, 0x63, 0xFF, 0x28, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0x2D, 0x00, 0x52, 0xFF, 0x92, 0x01, 0x1B, + 0xFD, 0xC4, 0x04, 0x51, 0xF8, 0x13, 0x0F, 0xC8, 0x46, 0xB6, 0xFA, + 0x01, 0x01, 0x44, 0x00, 0x6C, 0xFF, 0x7B, 0x00, 0xBF, 0xFF, 0x10, + 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x39, 0xFF, 0xE5, 0x01, 0x32, 0xFC, + 0x08, 0x07, 0xA4, 0xF2, 0x6D, 0x24, 0xAD, 0x3A, 0x88, 0xF2, 0xDB, + 0x05, 0x53, 0xFD, 0x19, 0x01, 0xA7, 0xFF, 0x10, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x17, 0x00, 0x92, 0xFF, 0x41, 0x01, 0x11, 0xFD, 0x3B, + 0x06, 0x14, 0xF2, 0x78, 0x38, 0x36, 0x27, 0x35, 0xF2, 0x20, 0x07, + 0x33, 0xFC, 0xDF, 0x01, 0x3E, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0D, + 0x00, 0xCB, 0xFF, 0x5C, 0x00, 0xAC, 0xFF, 0xD0, 0xFF, 0xCD, 0x01, + 0x30, 0xF9, 0xC8, 0x45, 0xB6, 0x11, 0x6B, 0xF7, 0x2D, 0x05, 0xE9, + 0xFC, 0xA8, 0x01, 0x4A, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0x00, 0x00, + 0x25, 0x00, 0x6D, 0xFF, 0x4C, 0x01, 0xB6, 0xFD, 0x86, 0x03, 0xE1, + 0xFA, 0x3D, 0x08, 0x92, 0x48, 0x8E, 0xFF, 0xA1, 0xFE, 0x93, 0x01, + 0xB8, 0xFE, 0xD3, 0x00, 0x9D, 0xFF, 0x18, 0x00, 0xFE, 0xFF, 0x36, + 0x00, 0x37, 0xFF, 0xE0, 0x01, 0x58, 0xFC, 0x82, 0x06, 0x3E, 0xF4, + 0xBA, 0x1C, 0x07, 0x40, 0x79, 0xF4, 0x84, 0x04, 0x31, 0xFE, 0x96, + 0x00, 0xE8, 0xFF, 0xF7, 0xFF, 0x04, 0x00, 0xFD, 0xFF, 0x28, 0x00, + 0x64, 0xFF, 0x9A, 0x01, 0x88, 0xFC, 0xEE, 0x06, 0x7E, 0xF1, 0xE3, + 0x31, 0x9F, 0x2E, 0x88, 0xF1, 0x19, 0x07, 0x5E, 0xFC, 0xB7, 0x01, + 0x54, 0xFF, 0x2D, 0x00, 0xFD, 0xFF, 0x06, 0x00, 0xEA, 0xFF, 0x0B, + 0x00, 0x51, 0x00, 0xAA, 0xFE, 0xC0, 0x03, 0xB8, 0xF5, 0x21, 0x42, + 0x31, 0x19, 0x28, 0xF5, 0x27, 0x06, 0x7C, 0xFC, 0xD4, 0x01, 0x3A, + 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1C, 0x00, 0x8D, 0xFF, 0xFA, 0x00, + 0x64, 0xFE, 0x32, 0x02, 0x78, 0xFD, 0x1B, 0x02, 0xEA, 0x48, 0x50, + 0x05, 0x14, 0xFC, 0xEB, 0x02, 0x05, 0xFE, 0x27, 0x01, 0x7C, 0xFF, + 0x21, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x41, 0xFF, 0xBF, + 0x01, 0xB2, 0xFC, 0xA9, 0x05, 0x55, 0xF6, 0x20, 0x15, 0x42, 0x44, + 0x75, 0xF7, 0xBF, 0x02, 0x43, 0xFF, 0xFA, 0xFF, 0x36, 0x00, 0xDA, + 0xFF, 0x0A, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x46, 0xFF, 0xD1, 0x01, + 0x3F, 0xFC, 0x2B, 0x07, 0xCD, 0xF1, 0xAE, 0x2A, 0x86, 0x35, 0xB1, + 0xF1, 0x9D, 0x06, 0xCA, 0xFC, 0x6E, 0x01, 0x7B, 0xFF, 0x20, 0x00, + 0xFE, 0xFF, 0x02, 0x00, 0x05, 0x00, 0xC3, 0xFF, 0xE0, 0x00, 0xB3, + 0xFD, 0x4B, 0x05, 0x4D, 0xF3, 0x45, 0x3D, 0xE0, 0x20, 0x4F, 0xF3, + 0xD5, 0x06, 0x3D, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, + 0xFF, 0x13, 0x00, 0xAF, 0xFF, 0xA4, 0x00, 0x19, 0xFF, 0xDD, 0x00, + 0xF0, 0xFF, 0xD4, 0xFC, 0xC9, 0x47, 0xD8, 0x0B, 0x7C, 0xF9, 0x35, + 0x04, 0x5F, 0xFD, 0x74, 0x01, 0x5E, 0xFF, 0x29, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2C, 0x00, 0x56, 0xFF, 0x87, 0x01, 0x34, 0xFD, 0x8F, + 0x04, 0xC0, 0xF8, 0xD9, 0x0D, 0x31, 0x47, 0x7B, 0xFB, 0x9C, 0x00, + 0x7D, 0x00, 0x4D, 0xFF, 0x8A, 0x00, 0xB9, 0xFF, 0x11, 0x00, 0xFD, + 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE6, 0x01, 0x35, 0xFC, 0xF7, 0x06, + 0xE0, 0xF2, 0x18, 0x23, 0xAB, 0x3B, 0xCC, 0xF2, 0xA8, 0x05, 0x76, + 0xFD, 0x04, 0x01, 0xB1, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0xFE, 0xFF, + 0x1A, 0x00, 0x89, 0xFF, 0x53, 0x01, 0xF5, 0xFC, 0x63, 0x06, 0xE9, + 0xF1, 0x63, 0x37, 0x85, 0x28, 0x09, 0xF2, 0x27, 0x07, 0x35, 0xFC, + 0xDA, 0x01, 0x40, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0C, 0x00, 0xD1, + 0xFF, 0x4E, 0x00, 0xCA, 0xFF, 0x9A, 0xFF, 0x2A, 0x02, 0x83, 0xF8, + 0x3F, 0x45, 0xFB, 0x12, 0x01, 0xF7, 0x5D, 0x05, 0xD3, 0xFC, 0xB1, + 0x01, 0x46, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x23, 0x00, + 0x73, 0xFF, 0x3F, 0x01, 0xD3, 0xFD, 0x4C, 0x03, 0x54, 0xFB, 0x1F, + 0x07, 0xBB, 0x48, 0x7D, 0x00, 0x33, 0xFE, 0xCF, 0x01, 0x98, 0xFE, + 0xE2, 0x00, 0x97, 0xFF, 0x19, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x38, + 0xFF, 0xDC, 0x01, 0x64, 0xFC, 0x62, 0x06, 0x93, 0xF4, 0x66, 0x1B, + 0xD9, 0x40, 0xEA, 0xF4, 0x3E, 0x04, 0x5D, 0xFE, 0x7D, 0x00, 0xF5, + 0xFF, 0xF3, 0xFF, 0x05, 0x00, 0xFD, 0xFF, 0x2A, 0x00, 0x5E, 0xFF, + 0xA6, 0x01, 0x76, 0xFC, 0x01, 0x07, 0x7D, 0xF1, 0xAD, 0x30, 0xDC, + 0x2F, 0x7F, 0xF1, 0x0C, 0x07, 0x6C, 0xFC, 0xAD, 0x01, 0x5A, 0xFF, + 0x2B, 0x00, 0xFD, 0xFF, 0x05, 0x00, 0xEF, 0xFF, 0xFE, 0xFF, 0x6C, + 0x00, 0x7B, 0xFE, 0x0C, 0x04, 0x3A, 0xF5, 0x5F, 0x41, 0x83, 0x1A, + 0xCD, 0xF4, 0x4B, 0x06, 0x6D, 0xFC, 0xD9, 0x01, 0x39, 0xFF, 0x35, + 0x00, 0xFE, 0xFF, 0x1A, 0x00, 0x93, 0xFF, 0xEC, 0x00, 0x83, 0xFE, + 0xF7, 0x01, 0xE8, 0xFD, 0x21, 0x01, 0xD2, 0x48, 0x64, 0x06, 0xA1, + 0xFB, 0x26, 0x03, 0xE7, 0xFD, 0x35, 0x01, 0x76, 0xFF, 0x22, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x00, 0x44, 0xFF, 0xB7, 0x01, 0xC5, + 0xFC, 0x7C, 0x05, 0xBC, 0xF6, 0xD5, 0x13, 0xDC, 0x44, 0x14, 0xF8, + 0x67, 0x02, 0x77, 0xFF, 0xDD, 0xFF, 0x44, 0x00, 0xD5, 0xFF, 0x0B, + 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x42, 0xFF, 0xD7, 0x01, 0x39, 0xFC, + 0x29, 0x07, 0xEF, 0xF1, 0x62, 0x29, 0xA5, 0x36, 0xD0, 0xF1, 0x7B, + 0x06, 0xE3, 0xFC, 0x5E, 0x01, 0x83, 0xFF, 0x1D, 0x00, 0xFE, 0xFF, + 0x01, 0x00, 0x09, 0x00, 0xB8, 0xFF, 0xF6, 0x00, 0x8D, 0xFD, 0x84, + 0x05, 0xFD, 0xF2, 0x52, 0x3C, 0x35, 0x22, 0x0B, 0xF3, 0xEB, 0x06, + 0x37, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x12, + 0x00, 0xB5, 0xFF, 0x94, 0x00, 0x39, 0xFF, 0xA3, 0x00, 0x58, 0x00, + 0x02, 0xFC, 0x73, 0x47, 0x0B, 0x0D, 0x0B, 0xF9, 0x6C, 0x04, 0x45, + 0xFD, 0x80, 0x01, 0x59, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2A, 0x00, 0x5B, 0xFF, 0x7C, 0x01, 0x4E, 0xFD, 0x5A, 0x04, 0x31, + 0xF9, 0xA4, 0x0C, 0x90, 0x47, 0x47, 0xFC, 0x36, 0x00, 0xB6, 0x00, + 0x2E, 0xFF, 0x99, 0x00, 0xB3, 0xFF, 0x12, 0x00, 0xFD, 0xFF, 0x36, + 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x39, 0xFC, 0xE4, 0x06, 0x21, 0xF3, + 0xC4, 0x21, 0xA5, 0x3C, 0x16, 0xF3, 0x72, 0x05, 0x9A, 0xFD, 0xEF, + 0x00, 0xBC, 0xFF, 0x08, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1E, 0x00, + 0x80, 0xFF, 0x64, 0x01, 0xDA, 0xFC, 0x87, 0x06, 0xC5, 0xF1, 0x46, + 0x36, 0xD1, 0x29, 0xE3, 0xF1, 0x2A, 0x07, 0x3A, 0xFC, 0xD5, 0x01, + 0x44, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x0A, 0x00, 0xD6, 0xFF, 0x3F, + 0x00, 0xE7, 0xFF, 0x65, 0xFF, 0x85, 0x02, 0xDE, 0xF7, 0xA9, 0x44, + 0x43, 0x14, 0x99, 0xF6, 0x8B, 0x05, 0xBF, 0xFC, 0xBA, 0x01, 0x43, + 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x22, 0x00, 0x78, 0xFF, + 0x31, 0x01, 0xF1, 0xFD, 0x12, 0x03, 0xC7, 0xFB, 0x07, 0x06, 0xDB, + 0x48, 0x73, 0x01, 0xC3, 0xFD, 0x0A, 0x02, 0x79, 0xFE, 0xF1, 0x00, + 0x91, 0xFF, 0x1B, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x39, 0xFF, 0xD7, + 0x01, 0x72, 0xFC, 0x3F, 0x06, 0xEB, 0xF4, 0x12, 0x1A, 0xA1, 0x41, + 0x63, 0xF5, 0xF3, 0x03, 0x8A, 0xFE, 0x63, 0x00, 0x02, 0x00, 0xEE, + 0xFF, 0x06, 0x00, 0xFD, 0xFF, 0x2C, 0x00, 0x58, 0xFF, 0xB1, 0x01, + 0x67, 0xFC, 0x10, 0x07, 0x81, 0xF1, 0x73, 0x2F, 0x15, 0x31, 0x7C, + 0xF1, 0xFB, 0x06, 0x7C, 0xFC, 0xA2, 0x01, 0x60, 0xFF, 0x29, 0x00, + 0xFD, 0xFF, 0x04, 0x00, 0xF4, 0xFF, 0xF1, 0xFF, 0x85, 0x00, 0x4E, + 0xFE, 0x56, 0x04, 0xC3, 0xF4, 0x95, 0x40, 0xD8, 0x1B, 0x76, 0xF4, + 0x6D, 0x06, 0x60, 0xFC, 0xDD, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, + 0xFF, 0x19, 0x00, 0x99, 0xFF, 0xDD, 0x00, 0xA3, 0xFE, 0xBB, 0x01, + 0x58, 0xFE, 0x2D, 0x00, 0xAF, 0x48, 0x7E, 0x07, 0x2E, 0xFB, 0x60, + 0x03, 0xC9, 0xFD, 0x43, 0x01, 0x71, 0xFF, 0x24, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x30, 0x00, 0x48, 0xFF, 0xAE, 0x01, 0xDB, 0xFC, 0x4D, + 0x05, 0x24, 0xF7, 0x8E, 0x12, 0x6D, 0x45, 0xBC, 0xF8, 0x0C, 0x02, + 0xAC, 0xFF, 0xC0, 0xFF, 0x52, 0x00, 0xCF, 0xFF, 0x0C, 0x00, 0xFD, + 0xFF, 0x34, 0x00, 0x3F, 0xFF, 0xDC, 0x01, 0x34, 0xFC, 0x25, 0x07, + 0x18, 0xF2, 0x15, 0x28, 0xBF, 0x37, 0xF7, 0xF1, 0x56, 0x06, 0xFE, + 0xFC, 0x4D, 0x01, 0x8C, 0xFF, 0x19, 0x00, 0xFF, 0xFF, 0x00, 0x00, + 0x0D, 0x00, 0xAE, 0xFF, 0x0B, 0x01, 0x6A, 0xFD, 0xBA, 0x05, 0xB4, + 0xF2, 0x58, 0x3B, 0x8A, 0x23, 0xCB, 0xF2, 0xFD, 0x06, 0x34, 0xFC, + 0xE6, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x10, 0x00, 0xBB, + 0xFF, 0x85, 0x00, 0x58, 0xFF, 0x6A, 0x00, 0xBE, 0x00, 0x38, 0xFB, + 0x0F, 0x47, 0x42, 0x0E, 0x9B, 0xF8, 0xA1, 0x04, 0x2B, 0xFD, 0x8B, + 0x01, 0x55, 0xFF, 0x2C, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x29, 0x00, + 0x5F, 0xFF, 0x70, 0x01, 0x68, 0xFD, 0x23, 0x04, 0xA2, 0xF9, 0x73, + 0x0B, 0xE4, 0x47, 0x1B, 0xFD, 0xCD, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, + 0xA9, 0x00, 0xAE, 0xFF, 0x14, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, + 0xFF, 0xE6, 0x01, 0x3F, 0xFC, 0xCE, 0x06, 0x66, 0xF3, 0x6F, 0x20, + 0x96, 0x3D, 0x69, 0xF3, 0x38, 0x05, 0xBF, 0xFD, 0xD9, 0x00, 0xC7, + 0xFF, 0x04, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x20, 0x00, 0x78, 0xFF, + 0x74, 0x01, 0xC2, 0xFC, 0xA7, 0x06, 0xA8, 0xF1, 0x25, 0x35, 0x1B, + 0x2B, 0xC2, 0xF1, 0x2A, 0x07, 0x41, 0xFC, 0xCE, 0x01, 0x47, 0xFF, + 0x31, 0x00, 0xFD, 0xFF, 0x09, 0x00, 0xDC, 0xFF, 0x31, 0x00, 0x04, + 0x00, 0x32, 0xFF, 0xDC, 0x02, 0x42, 0xF7, 0x0B, 0x44, 0x8E, 0x15, + 0x34, 0xF6, 0xB7, 0x05, 0xAB, 0xFC, 0xC1, 0x01, 0x40, 0xFF, 0x33, + 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x20, 0x00, 0x7E, 0xFF, 0x23, 0x01, + 0x0F, 0xFE, 0xD7, 0x02, 0x3B, 0xFC, 0xF5, 0x04, 0xED, 0x48, 0x70, + 0x02, 0x52, 0xFD, 0x46, 0x02, 0x5A, 0xFE, 0xFF, 0x00, 0x8B, 0xFF, + 0x1C, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xD2, 0x01, 0x81, + 0xFC, 0x1A, 0x06, 0x47, 0xF5, 0xC1, 0x18, 0x60, 0x42, 0xE4, 0xF5, + 0xA6, 0x03, 0xB9, 0xFE, 0x48, 0x00, 0x0F, 0x00, 0xE9, 0xFF, 0x07, + 0x00, 0xFD, 0xFF, 0x2E, 0x00, 0x53, 0xFF, 0xBB, 0x01, 0x5A, 0xFC, + 0x1C, 0x07, 0x8D, 0xF1, 0x34, 0x2E, 0x48, 0x32, 0x81, 0xF1, 0xE7, + 0x06, 0x8E, 0xFC, 0x96, 0x01, 0x66, 0xFF, 0x27, 0x00, 0xFD, 0xFF, + 0x04, 0x00, 0xF9, 0xFF, 0xE4, 0xFF, 0x9F, 0x00, 0x23, 0xFE, 0x9B, + 0x04, 0x55, 0xF4, 0xC0, 0x3F, 0x2C, 0x1D, 0x22, 0xF4, 0x8C, 0x06, + 0x55, 0xFC, 0xE1, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x17, + 0x00, 0x9F, 0xFF, 0xCE, 0x00, 0xC2, 0xFE, 0x80, 0x01, 0xC6, 0xFE, + 0x40, 0xFF, 0x81, 0x48, 0x9E, 0x08, 0xBA, 0xFA, 0x9A, 0x03, 0xAC, + 0xFD, 0x51, 0x01, 0x6C, 0xFF, 0x25, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x2F, 0x00, 0x4B, 0xFF, 0xA4, 0x01, 0xF1, 0xFC, 0x1D, 0x05, 0x8F, + 0xF7, 0x4A, 0x11, 0xF2, 0x45, 0x6B, 0xF9, 0xAE, 0x01, 0xE2, 0xFF, + 0xA2, 0xFF, 0x61, 0x00, 0xC9, 0xFF, 0x0D, 0x00, 0xFD, 0xFF, 0x35, + 0x00, 0x3D, 0xFF, 0xE0, 0x01, 0x32, 0xFC, 0x1D, 0x07, 0x45, 0xF2, + 0xC6, 0x26, 0xD3, 0x38, 0x24, 0xF2, 0x2D, 0x06, 0x1B, 0xFD, 0x3B, + 0x01, 0x95, 0xFF, 0x16, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x11, 0x00, + 0xA3, 0xFF, 0x20, 0x01, 0x49, 0xFD, 0xEB, 0x05, 0x74, 0xF2, 0x54, + 0x3A, 0xDD, 0x24, 0x91, 0xF2, 0x0C, 0x07, 0x32, 0xFC, 0xE4, 0x01, + 0x3A, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x0F, 0x00, 0xC1, 0xFF, 0x76, + 0x00, 0x76, 0xFF, 0x32, 0x00, 0x22, 0x01, 0x76, 0xFA, 0xA3, 0x46, + 0x7D, 0x0F, 0x2C, 0xF8, 0xD5, 0x04, 0x13, 0xFD, 0x96, 0x01, 0x51, + 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x27, 0x00, 0x64, 0xFF, + 0x63, 0x01, 0x84, 0xFD, 0xEB, 0x03, 0x14, 0xFA, 0x47, 0x0A, 0x2C, + 0x48, 0xF6, 0xFD, 0x63, 0xFF, 0x2B, 0x01, 0xF0, 0xFE, 0xB8, 0x00, + 0xA8, 0xFF, 0x15, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE4, + 0x01, 0x47, 0xFC, 0xB5, 0x06, 0xB0, 0xF3, 0x19, 0x1F, 0x7E, 0x3E, + 0xC4, 0xF3, 0xFA, 0x04, 0xE7, 0xFD, 0xC1, 0x00, 0xD3, 0xFF, 0xFF, + 0xFF, 0x02, 0x00, 0xFE, 0xFF, 0x23, 0x00, 0x71, 0xFF, 0x82, 0x01, + 0xAB, 0xFC, 0xC4, 0x06, 0x93, 0xF1, 0xFD, 0x33, 0x62, 0x2C, 0xA8, + 0xF1, 0x27, 0x07, 0x4A, 0xFC, 0xC7, 0x01, 0x4C, 0xFF, 0x30, 0x00, + 0xFD, 0xFF, 0x08, 0x00, 0xE1, 0xFF, 0x23, 0x00, 0x20, 0x00, 0x00, + 0xFF, 0x31, 0x03, 0xAD, 0xF6, 0x65, 0x43, 0xDC, 0x16, 0xD1, 0xF5, + 0xE1, 0x05, 0x99, 0xFC, 0xC9, 0x01, 0x3E, 0xFF, 0x33, 0x00, 0xFF, + 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x83, 0xFF, 0x14, 0x01, 0x2D, 0xFE, + 0x9C, 0x02, 0xAD, 0xFC, 0xE9, 0x03, 0xF6, 0x48, 0x73, 0x03, 0xE0, + 0xFC, 0x82, 0x02, 0x3B, 0xFE, 0x0E, 0x01, 0x86, 0xFF, 0x1E, 0x00, + 0xFE, 0xFF, 0x34, 0x00, 0x3D, 0xFF, 0xCC, 0x01, 0x91, 0xFC, 0xF3, + 0x05, 0xA6, 0xF5, 0x70, 0x17, 0x17, 0x43, 0x6D, 0xF6, 0x56, 0x03, + 0xEA, 0xFE, 0x2D, 0x00, 0x1D, 0x00, 0xE4, 0xFF, 0x08, 0x00, 0xFD, + 0xFF, 0x2F, 0x00, 0x4E, 0xFF, 0xC3, 0x01, 0x4E, 0xFC, 0x24, 0x07, + 0x9E, 0xF1, 0xF2, 0x2C, 0x78, 0x33, 0x8C, 0xF1, 0xD0, 0x06, 0xA2, + 0xFC, 0x88, 0x01, 0x6D, 0xFF, 0x24, 0x00, 0xFD, 0xFF, 0x03, 0x00, + 0xFD, 0xFF, 0xD8, 0xFF, 0xB7, 0x00, 0xF9, 0xFD, 0xDE, 0x04, 0xEF, + 0xF3, 0xE4, 0x3E, 0x81, 0x1E, 0xD2, 0xF3, 0xA9, 0x06, 0x4B, 0xFC, + 0xE3, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x16, 0x00, 0xA5, + 0xFF, 0xBE, 0x00, 0xE2, 0xFE, 0x45, 0x01, 0x33, 0xFF, 0x5A, 0xFE, + 0x48, 0x48, 0xC3, 0x09, 0x47, 0xFA, 0xD2, 0x03, 0x90, 0xFD, 0x5E, + 0x01, 0x66, 0xFF, 0x27, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2E, 0x00, + 0x4F, 0xFF, 0x9A, 0x01, 0x08, 0xFD, 0xEB, 0x04, 0xFC, 0xF7, 0x0A, + 0x10, 0x70, 0x46, 0x22, 0xFA, 0x4D, 0x01, 0x19, 0x00, 0x84, 0xFF, + 0x70, 0x00, 0xC4, 0xFF, 0x0F, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3B, + 0xFF, 0xE3, 0x01, 0x31, 0xFC, 0x12, 0x07, 0x79, 0xF2, 0x73, 0x25, + 0xDF, 0x39, 0x5A, 0xF2, 0x00, 0x06, 0x3A, 0xFD, 0x28, 0x01, 0x9F, + 0xFF, 0x13, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x15, 0x00, 0x99, 0xFF, + 0x33, 0x01, 0x29, 0xFD, 0x1A, 0x06, 0x3B, 0xF2, 0x4B, 0x39, 0x30, + 0x26, 0x5B, 0xF2, 0x19, 0x07, 0x31, 0xFC, 0xE1, 0x01, 0x3C, 0xFF, + 0x35, 0x00, 0xFD, 0xFF, 0x0E, 0x00, 0xC7, 0xFF, 0x68, 0x00, 0x95, + 0xFF, 0xFA, 0xFF, 0x83, 0x01, 0xBB, 0xF9, 0x2B, 0x46, 0xBB, 0x10, + 0xBF, 0xF7, 0x07, 0x05, 0xFB, 0xFC, 0xA0, 0x01, 0x4D, 0xFF, 0x2F, + 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x26, 0x00, 0x69, 0xFF, 0x56, 0x01, + 0xA0, 0xFD, 0xB3, 0x03, 0x87, 0xFA, 0x1F, 0x09, 0x6A, 0x48, 0xD9, + 0xFE, 0xF6, 0xFE, 0x65, 0x01, 0xD0, 0xFE, 0xC7, 0x00, 0xA2, 0xFF, + 0x17, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE2, 0x01, 0x50, + 0xFC, 0x99, 0x06, 0xFE, 0xF3, 0xC3, 0x1D, 0x5E, 0x3F, 0x27, 0xF4, + 0xB9, 0x04, 0x10, 0xFE, 0xA9, 0x00, 0xDF, 0xFF, 0xFB, 0xFF, 0x03, + 0x00, 0xFD, 0xFF, 0x26, 0x00, 0x69, 0xFF, 0x90, 0x01, 0x96, 0xFC, + 0xDD, 0x06, 0x85, 0xF1, 0xD0, 0x32, 0xA6, 0x2D, 0x94, 0xF1, 0x20, + 0x07, 0x54, 0xFC, 0xBF, 0x01, 0x50, 0xFF, 0x2E, 0x00, 0xFD, 0xFF, + 0x07, 0x00, 0xE6, 0xFF, 0x15, 0x00, 0x3C, 0x00, 0xCF, 0xFE, 0x83, + 0x03, 0x20, 0xF6, 0xB2, 0x42, 0x2B, 0x18, 0x71, 0xF5, 0x09, 0x06, + 0x88, 0xFC, 0xCF, 0x01, 0x3C, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x1D, + 0x00, 0x89, 0xFF, 0x06, 0x01, 0x4C, 0xFE, 0x60, 0x02, 0x1F, 0xFD, + 0xE2, 0x02, 0xF3, 0x48, 0x7D, 0x04, 0x6E, 0xFC, 0xBD, 0x02, 0x1C, + 0xFE, 0x1C, 0x01, 0x80, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x33, 0x00, 0x3F, 0xFF, 0xC5, 0x01, 0xA3, 0xFC, 0xCA, 0x05, 0x07, + 0xF6, 0x22, 0x16, 0xC3, 0x43, 0xFE, 0xF6, 0x02, 0x03, 0x1B, 0xFF, + 0x11, 0x00, 0x2B, 0x00, 0xDE, 0xFF, 0x09, 0x00, 0xFD, 0xFF, 0x31, + 0x00, 0x49, 0xFF, 0xCB, 0x01, 0x45, 0xFC, 0x29, 0x07, 0xB6, 0xF1, + 0xAD, 0x2B, 0xA2, 0x34, 0x9E, 0xF1, 0xB4, 0x06, 0xB8, 0xFC, 0x7A, + 0x01, 0x75, 0xFF, 0x22, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0x02, 0x00, + 0xCC, 0xFF, 0xCE, 0x00, 0xD1, 0xFD, 0x1D, 0x05, 0x91, 0xF3, 0xFE, + 0x3D, 0xD7, 0x1F, 0x87, 0xF3, 0xC3, 0x06, 0x42, 0xFC, 0xE5, 0x01, + 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x14, 0x00, 0xAB, 0xFF, 0xAF, + 0x00, 0x01, 0xFF, 0x0A, 0x01, 0x9E, 0xFF, 0x7C, 0xFD, 0x03, 0x48, + 0xED, 0x0A, 0xD5, 0xF9, 0x0A, 0x04, 0x74, 0xFD, 0x6A, 0x01, 0x62, + 0xFF, 0x28, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2D, 0x00, 0x53, 0xFF, + 0x90, 0x01, 0x20, 0xFD, 0xB8, 0x04, 0x6A, 0xF8, 0xCD, 0x0E, 0xE1, + 0x46, 0xE1, 0xFA, 0xEB, 0x00, 0x51, 0x00, 0x65, 0xFF, 0x7F, 0x00, + 0xBE, 0xFF, 0x10, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x39, 0xFF, 0xE5, + 0x01, 0x33, 0xFC, 0x04, 0x07, 0xB1, 0xF2, 0x21, 0x24, 0xE6, 0x3A, + 0x97, 0xF2, 0xD0, 0x05, 0x5B, 0xFD, 0x15, 0x01, 0xA9, 0xFF, 0x0F, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x18, 0x00, 0x90, 0xFF, 0x45, 0x01, + 0x0B, 0xFD, 0x44, 0x06, 0x0A, 0xF2, 0x3B, 0x38, 0x80, 0x27, 0x2B, + 0xF2, 0x22, 0x07, 0x33, 0xFC, 0xDE, 0x01, 0x3E, 0xFF, 0x34, 0x00, + 0xFD, 0xFF, 0x0D, 0x00, 0xCD, 0xFF, 0x59, 0x00, 0xB3, 0xFF, 0xC4, + 0xFF, 0xE2, 0x01, 0x09, 0xF9, 0xAA, 0x45, 0xFE, 0x11, 0x54, 0xF7, + 0x38, 0x05, 0xE4, 0xFC, 0xAA, 0x01, 0x49, 0xFF, 0x30, 0x00, 0xFF, + 0xFF, 0x00, 0x00, 0x24, 0x00, 0x6E, 0xFF, 0x49, 0x01, 0xBC, 0xFD, + 0x7A, 0x03, 0xFA, 0xFA, 0xFD, 0x07, 0x9C, 0x48, 0xC3, 0xFF, 0x89, + 0xFE, 0xA1, 0x01, 0xB1, 0xFE, 0xD6, 0x00, 0x9C, 0xFF, 0x18, 0x00, + 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xDF, 0x01, 0x5B, 0xFC, 0x7B, + 0x06, 0x50, 0xF4, 0x6E, 0x1C, 0x36, 0x40, 0x92, 0xF4, 0x75, 0x04, + 0x3B, 0xFE, 0x91, 0x00, 0xEB, 0xFF, 0xF6, 0xFF, 0x04, 0x00, 0xFD, + 0xFF, 0x28, 0x00, 0x63, 0xFF, 0x9D, 0x01, 0x84, 0xFC, 0xF3, 0x06, + 0x7D, 0xF1, 0x9E, 0x31, 0xE6, 0x2E, 0x85, 0xF1, 0x16, 0x07, 0x61, + 0xFC, 0xB5, 0x01, 0x55, 0xFF, 0x2D, 0x00, 0xFD, 0xFF, 0x06, 0x00, + 0xEC, 0xFF, 0x08, 0x00, 0x57, 0x00, 0x9F, 0xFE, 0xD1, 0x03, 0x9B, + 0xF5, 0xF7, 0x41, 0x7C, 0x19, 0x13, 0xF5, 0x2F, 0x06, 0x78, 0xFC, + 0xD5, 0x01, 0x3A, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1C, 0x00, 0x8F, + 0xFF, 0xF7, 0x00, 0x6B, 0xFE, 0x25, 0x02, 0x91, 0xFD, 0xE3, 0x01, + 0xE5, 0x48, 0x8D, 0x05, 0xFB, 0xFB, 0xF8, 0x02, 0xFE, 0xFD, 0x2B, + 0x01, 0x7A, 0xFF, 0x21, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x32, 0x00, + 0x42, 0xFF, 0xBD, 0x01, 0xB6, 0xFC, 0x9F, 0x05, 0x6C, 0xF6, 0xD6, + 0x14, 0x65, 0x44, 0x98, 0xF7, 0xAC, 0x02, 0x4E, 0xFF, 0xF4, 0xFF, + 0x39, 0x00, 0xD9, 0xFF, 0x0A, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x45, + 0xFF, 0xD2, 0x01, 0x3D, 0xFC, 0x2B, 0x07, 0xD4, 0xF1, 0x64, 0x2A, + 0xC6, 0x35, 0xB7, 0xF1, 0x96, 0x06, 0xCF, 0xFC, 0x6B, 0x01, 0x7D, + 0xFF, 0x1F, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x06, 0x00, 0xC1, 0xFF, + 0xE5, 0x00, 0xAA, 0xFD, 0x58, 0x05, 0x3A, 0xF3, 0x11, 0x3D, 0x2C, + 0x21, 0x3F, 0xF3, 0xDA, 0x06, 0x3B, 0xFC, 0xE6, 0x01, 0x36, 0xFF, + 0x36, 0x00, 0xFD, 0xFF, 0x13, 0x00, 0xB1, 0xFF, 0xA0, 0x00, 0x20, + 0xFF, 0xD0, 0x00, 0x07, 0x00, 0xA4, 0xFC, 0xB6, 0x47, 0x1C, 0x0C, + 0x63, 0xF9, 0x42, 0x04, 0x59, 0xFD, 0x76, 0x01, 0x5D, 0xFF, 0x2A, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x57, 0xFF, 0x85, 0x01, + 0x39, 0xFD, 0x84, 0x04, 0xD9, 0xF8, 0x95, 0x0D, 0x48, 0x47, 0xA7, + 0xFB, 0x86, 0x00, 0x8A, 0x00, 0x46, 0xFF, 0x8E, 0x00, 0xB8, 0xFF, + 0x11, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x35, + 0xFC, 0xF3, 0x06, 0xEE, 0xF2, 0xCD, 0x22, 0xE4, 0x3B, 0xDC, 0xF2, + 0x9C, 0x05, 0x7E, 0xFD, 0x00, 0x01, 0xB4, 0xFF, 0x0B, 0x00, 0x01, + 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x87, 0xFF, 0x57, 0x01, 0xEF, 0xFC, + 0x6B, 0x06, 0xE0, 0xF1, 0x23, 0x37, 0xCE, 0x28, 0x01, 0xF2, 0x28, + 0x07, 0x36, 0xFC, 0xD9, 0x01, 0x41, 0xFF, 0x33, 0x00, 0xFD, 0xFF, + 0x0B, 0x00, 0xD2, 0xFF, 0x4A, 0x00, 0xD0, 0xFF, 0x8E, 0xFF, 0x3F, + 0x02, 0x5E, 0xF8, 0x1E, 0x45, 0x44, 0x13, 0xEA, 0xF6, 0x67, 0x05, + 0xCF, 0xFC, 0xB3, 0x01, 0x46, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0x23, 0x00, 0x74, 0xFF, 0x3C, 0x01, 0xDA, 0xFD, 0x40, 0x03, + 0x6E, 0xFB, 0xE1, 0x06, 0xC3, 0x48, 0xB3, 0x00, 0x1A, 0xFE, 0xDC, + 0x01, 0x91, 0xFE, 0xE5, 0x00, 0x96, 0xFF, 0x1A, 0x00, 0xFE, 0xFF, + 0x36, 0x00, 0x38, 0xFF, 0xDB, 0x01, 0x67, 0xFC, 0x5A, 0x06, 0xA6, + 0xF4, 0x1B, 0x1B, 0x07, 0x41, 0x04, 0xF5, 0x2D, 0x04, 0x67, 0xFE, + 0x77, 0x00, 0xF8, 0xFF, 0xF2, 0xFF, 0x05, 0x00, 0xFD, 0xFF, 0x2A, + 0x00, 0x5C, 0xFF, 0xA8, 0x01, 0x73, 0xFC, 0x05, 0x07, 0x7D, 0xF1, + 0x67, 0x30, 0x21, 0x30, 0x7E, 0xF1, 0x08, 0x07, 0x6F, 0xFC, 0xAB, + 0x01, 0x5B, 0xFF, 0x2B, 0x00, 0xFD, 0xFF, 0x05, 0x00, 0xF0, 0xFF, + 0xFB, 0xFF, 0x71, 0x00, 0x71, 0xFE, 0x1D, 0x04, 0x1F, 0xF5, 0x32, + 0x41, 0xCE, 0x1A, 0xBA, 0xF4, 0x53, 0x06, 0x6A, 0xFC, 0xDA, 0x01, + 0x38, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1A, 0x00, 0x95, 0xFF, 0xE8, + 0x00, 0x8A, 0xFE, 0xE9, 0x01, 0x01, 0xFE, 0xEA, 0x00, 0xCB, 0x48, + 0xA2, 0x06, 0x87, 0xFB, 0x33, 0x03, 0xE0, 0xFD, 0x39, 0x01, 0x75, + 0xFF, 0x23, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x00, 0x45, 0xFF, + 0xB5, 0x01, 0xCA, 0xFC, 0x72, 0x05, 0xD3, 0xF6, 0x8D, 0x13, 0xFD, + 0x44, 0x39, 0xF8, 0x53, 0x02, 0x82, 0xFF, 0xD7, 0xFF, 0x47, 0x00, + 0xD3, 0xFF, 0x0B, 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x42, 0xFF, 0xD8, + 0x01, 0x37, 0xFC, 0x29, 0x07, 0xF8, 0xF1, 0x19, 0x29, 0xE5, 0x36, + 0xD8, 0xF1, 0x73, 0x06, 0xE9, 0xFC, 0x5B, 0x01, 0x85, 0xFF, 0x1C, + 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x0A, 0x00, 0xB6, 0xFF, 0xFB, 0x00, + 0x85, 0xFD, 0x90, 0x05, 0xEC, 0xF2, 0x1C, 0x3C, 0x81, 0x22, 0xFC, + 0xF2, 0xEF, 0x06, 0x36, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, + 0xFD, 0xFF, 0x12, 0x00, 0xB7, 0xFF, 0x91, 0x00, 0x40, 0xFF, 0x96, + 0x00, 0x6F, 0x00, 0xD5, 0xFB, 0x5E, 0x47, 0x50, 0x0D, 0xF2, 0xF8, + 0x78, 0x04, 0x3F, 0xFD, 0x82, 0x01, 0x58, 0xFF, 0x2B, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5C, 0xFF, 0x79, 0x01, 0x53, 0xFD, + 0x4E, 0x04, 0x4A, 0xF9, 0x60, 0x0C, 0xA3, 0x47, 0x76, 0xFC, 0x1F, + 0x00, 0xC3, 0x00, 0x27, 0xFF, 0x9D, 0x00, 0xB2, 0xFF, 0x13, 0x00, + 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x3A, 0xFC, 0xDF, + 0x06, 0x30, 0xF3, 0x78, 0x21, 0xDB, 0x3C, 0x28, 0xF3, 0x65, 0x05, + 0xA2, 0xFD, 0xEA, 0x00, 0xBE, 0xFF, 0x07, 0x00, 0x01, 0x00, 0xFE, + 0xFF, 0x1E, 0x00, 0x7F, 0xFF, 0x67, 0x01, 0xD5, 0xFC, 0x8E, 0x06, + 0xBE, 0xF1, 0x06, 0x36, 0x1A, 0x2A, 0xDC, 0xF1, 0x2A, 0x07, 0x3C, + 0xFC, 0xD3, 0x01, 0x44, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x0A, 0x00, + 0xD8, 0xFF, 0x3C, 0x00, 0xEE, 0xFF, 0x5A, 0xFF, 0x98, 0x02, 0xBB, + 0xF7, 0x87, 0x44, 0x8C, 0x14, 0x83, 0xF6, 0x95, 0x05, 0xBA, 0xFC, + 0xBB, 0x01, 0x43, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x21, + 0x00, 0x79, 0xFF, 0x2E, 0x01, 0xF7, 0xFD, 0x05, 0x03, 0xE1, 0xFB, + 0xCA, 0x05, 0xDF, 0x48, 0xAB, 0x01, 0xAA, 0xFD, 0x18, 0x02, 0x72, + 0xFE, 0xF4, 0x00, 0x90, 0xFF, 0x1B, 0x00, 0xFE, 0xFF, 0x35, 0x00, + 0x39, 0xFF, 0xD6, 0x01, 0x75, 0xFC, 0x37, 0x06, 0xFF, 0xF4, 0xC7, + 0x19, 0xCC, 0x41, 0x7F, 0xF5, 0xE2, 0x03, 0x95, 0xFE, 0x5D, 0x00, + 0x05, 0x00, 0xED, 0xFF, 0x06, 0x00, 0xFD, 0xFF, 0x2C, 0x00, 0x57, + 0xFF, 0xB3, 0x01, 0x64, 0xFC, 0x13, 0x07, 0x83, 0xF1, 0x2C, 0x2F, + 0x5A, 0x31, 0x7D, 0xF1, 0xF7, 0x06, 0x80, 0xFC, 0x9F, 0x01, 0x61, + 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0x04, 0x00, 0xF5, 0xFF, 0xEE, 0xFF, + 0x8B, 0x00, 0x44, 0xFE, 0x65, 0x04, 0xAA, 0xF4, 0x66, 0x40, 0x23, + 0x1C, 0x63, 0xF4, 0x74, 0x06, 0x5D, 0xFC, 0xDE, 0x01, 0x37, 0xFF, + 0x36, 0x00, 0xFE, 0xFF, 0x19, 0x00, 0x9A, 0xFF, 0xD9, 0x00, 0xAA, + 0xFE, 0xAE, 0x01, 0x70, 0xFE, 0xF8, 0xFF, 0xA6, 0x48, 0xBE, 0x07, + 0x14, 0xFB, 0x6D, 0x03, 0xC3, 0xFD, 0x46, 0x01, 0x70, 0xFF, 0x24, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30, 0x00, 0x48, 0xFF, 0xAC, 0x01, + 0xDF, 0xFC, 0x43, 0x05, 0x3C, 0xF7, 0x46, 0x12, 0x8D, 0x45, 0xE2, + 0xF8, 0xF7, 0x01, 0xB8, 0xFF, 0xB9, 0xFF, 0x56, 0x00, 0xCE, 0xFF, + 0x0C, 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x3F, 0xFF, 0xDD, 0x01, 0x34, + 0xFC, 0x23, 0x07, 0x21, 0xF2, 0xCB, 0x27, 0xFE, 0x37, 0x00, 0xF2, + 0x4D, 0x06, 0x04, 0xFD, 0x49, 0x01, 0x8E, 0xFF, 0x19, 0x00, 0xFF, + 0xFF, 0x00, 0x00, 0x0E, 0x00, 0xAB, 0xFF, 0x10, 0x01, 0x62, 0xFD, + 0xC5, 0x05, 0xA5, 0xF2, 0x1F, 0x3B, 0xD6, 0x23, 0xBE, 0xF2, 0x01, + 0x07, 0x33, 0xFC, 0xE5, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFD, 0xFF, + 0x10, 0x00, 0xBD, 0xFF, 0x82, 0x00, 0x5E, 0xFF, 0x5D, 0x00, 0xD4, + 0x00, 0x0C, 0xFB, 0xF9, 0x46, 0x87, 0x0E, 0x82, 0xF8, 0xAD, 0x04, + 0x26, 0xFD, 0x8D, 0x01, 0x54, 0xFF, 0x2C, 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0x29, 0x00, 0x60, 0xFF, 0x6D, 0x01, 0x6E, 0xFD, 0x17, 0x04, + 0xBC, 0xF9, 0x30, 0x0B, 0xF4, 0x47, 0x4B, 0xFD, 0xB5, 0xFF, 0xFD, + 0x00, 0x08, 0xFF, 0xAC, 0x00, 0xAC, 0xFF, 0x14, 0x00, 0xFD, 0xFF, + 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x41, 0xFC, 0xC8, 0x06, 0x76, + 0xF3, 0x22, 0x20, 0xCA, 0x3D, 0x7D, 0xF3, 0x2A, 0x05, 0xC8, 0xFD, + 0xD4, 0x00, 0xCA, 0xFF, 0x03, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x21, + 0x00, 0x77, 0xFF, 0x77, 0x01, 0xBD, 0xFC, 0xAE, 0x06, 0xA3, 0xF1, + 0xE3, 0x34, 0x64, 0x2B, 0xBC, 0xF1, 0x2A, 0x07, 0x43, 0xFC, 0xCD, + 0x01, 0x48, 0xFF, 0x31, 0x00, 0xFD, 0xFF, 0x09, 0x00, 0xDD, 0xFF, + 0x2E, 0x00, 0x0A, 0x00, 0x27, 0xFF, 0xEF, 0x02, 0x20, 0xF7, 0xE7, + 0x43, 0xD8, 0x15, 0x1E, 0xF6, 0xC0, 0x05, 0xA7, 0xFC, 0xC3, 0x01, + 0x40, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x20, 0x00, 0x7F, + 0xFF, 0x20, 0x01, 0x16, 0xFE, 0xCA, 0x02, 0x54, 0xFC, 0xB9, 0x04, + 0xF2, 0x48, 0xA9, 0x02, 0x39, 0xFD, 0x53, 0x02, 0x53, 0xFE, 0x03, + 0x01, 0x8A, 0xFF, 0x1D, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3B, 0xFF, + 0xD1, 0x01, 0x84, 0xFC, 0x12, 0x06, 0x5C, 0xF5, 0x76, 0x18, 0x89, + 0x42, 0x02, 0xF6, 0x94, 0x03, 0xC4, 0xFE, 0x42, 0x00, 0x12, 0x00, + 0xE8, 0xFF, 0x07, 0x00, 0xFD, 0xFF, 0x2E, 0x00, 0x51, 0xFF, 0xBD, + 0x01, 0x57, 0xFC, 0x1E, 0x07, 0x90, 0xF1, 0xED, 0x2D, 0x8C, 0x32, + 0x83, 0xF1, 0xE2, 0x06, 0x92, 0xFC, 0x93, 0x01, 0x68, 0xFF, 0x26, + 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFA, 0xFF, 0xE2, 0xFF, 0xA4, 0x00, + 0x19, 0xFE, 0xAA, 0x04, 0x3E, 0xF4, 0x90, 0x3F, 0x78, 0x1D, 0x10, + 0xF4, 0x93, 0x06, 0x52, 0xFC, 0xE1, 0x01, 0x36, 0xFF, 0x36, 0x00, + 0xFE, 0xFF, 0x17, 0x00, 0xA0, 0xFF, 0xCA, 0x00, 0xC9, 0xFE, 0x73, + 0x01, 0xDE, 0xFE, 0x0C, 0xFF, 0x76, 0x48, 0xDE, 0x08, 0xA1, 0xFA, + 0xA6, 0x03, 0xA6, 0xFD, 0x53, 0x01, 0x6A, 0xFF, 0x26, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4C, 0xFF, 0xA2, 0x01, 0xF6, 0xFC, + 0x12, 0x05, 0xA7, 0xF7, 0x03, 0x11, 0x10, 0x46, 0x93, 0xF9, 0x98, + 0x01, 0xEE, 0xFF, 0x9B, 0xFF, 0x64, 0x00, 0xC8, 0xFF, 0x0E, 0x00, + 0xFD, 0xFF, 0x35, 0x00, 0x3C, 0xFF, 0xE1, 0x01, 0x32, 0xFC, 0x1B, + 0x07, 0x50, 0xF2, 0x7B, 0x26, 0x11, 0x39, 0x2F, 0xF2, 0x23, 0x06, + 0x22, 0xFD, 0x37, 0x01, 0x97, 0xFF, 0x15, 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0x12, 0x00, 0xA1, 0xFF, 0x24, 0x01, 0x41, 0xFD, 0xF6, 0x05, + 0x67, 0xF2, 0x1A, 0x3A, 0x29, 0x25, 0x84, 0xF2, 0x0F, 0x07, 0x31, + 0xFC, 0xE3, 0x01, 0x3A, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0F, 0x00, + 0xC2, 0xFF, 0x73, 0x00, 0x7D, 0xFF, 0x25, 0x00, 0x38, 0x01, 0x4C, + 0xFA, 0x89, 0x46, 0xC3, 0x0F, 0x14, 0xF8, 0xE0, 0x04, 0x0D, 0xFD, + 0x98, 0x01, 0x50, 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x27, + 0x00, 0x65, 0xFF, 0x60, 0x01, 0x8A, 0xFD, 0xDF, 0x03, 0x2E, 0xFA, + 0x04, 0x0A, 0x3A, 0x48, 0x28, 0xFE, 0x4B, 0xFF, 0x38, 0x01, 0xE9, + 0xFE, 0xBB, 0x00, 0xA6, 0xFF, 0x16, 0x00, 0xFE, 0xFF, 0x36, 0x00, + 0x36, 0xFF, 0xE4, 0x01, 0x49, 0xFC, 0xAF, 0x06, 0xC1, 0xF3, 0xCD, + 0x1E, 0xB1, 0x3E, 0xD9, 0xF3, 0xEC, 0x04, 0xF0, 0xFD, 0xBC, 0x00, + 0xD5, 0xFF, 0xFE, 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0x24, 0x00, 0x6F, + 0xFF, 0x85, 0x01, 0xA6, 0xFC, 0xCA, 0x06, 0x8F, 0xF1, 0xBB, 0x33, + 0xAB, 0x2C, 0xA3, 0xF1, 0x26, 0x07, 0x4C, 0xFC, 0xC5, 0x01, 0x4D, + 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0x08, 0x00, 0xE2, 0xFF, 0x20, 0x00, + 0x26, 0x00, 0xF5, 0xFE, 0x43, 0x03, 0x8D, 0xF6, 0x3C, 0x43, 0x25, + 0x17, 0xBB, 0xF5, 0xEA, 0x05, 0x95, 0xFC, 0xCA, 0x01, 0x3D, 0xFF, + 0x34, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0x1E, 0x00, 0x84, 0xFF, 0x11, + 0x01, 0x34, 0xFE, 0x8F, 0x02, 0xC7, 0xFC, 0xAE, 0x03, 0xF7, 0x48, + 0xAE, 0x03, 0xC7, 0xFC, 0x8F, 0x02, 0x34, 0xFE, 0x11, 0x01, 0x84, + 0xFF, 0x1E, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, + 0x3D, 0xFC, 0xD6, 0x06, 0x4C, 0xF3, 0xED, 0x20, 0x3D, 0x3D, 0x4A, + 0xF3, 0x4E, 0x05, 0xB1, 0xFD, 0xE1, 0x00, 0xC3, 0xFF, 0x05, 0x00, + 0x02, 0x00, 0x02, 0x00, 0x05, 0x00, 0xC3, 0xFF, 0xE1, 0x00, 0xB1, + 0xFD, 0x4E, 0x05, 0x4A, 0xF3, 0x3D, 0x3D, 0xED, 0x20, 0x4C, 0xF3, + 0xD6, 0x06, 0x3D, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, + 0xFF, 0x00, 0x00, 0x1E, 0x00, 0x84, 0xFF, 0x11, 0x01, 0x34, 0xFE, + 0x8F, 0x02, 0xC7, 0xFC, 0xAE, 0x03, 0xF7, 0x48, 0xAE, 0x03, 0xC7, + 0xFC, 0x8F, 0x02, 0x34, 0xFE, 0x11, 0x01, 0x84, 0xFF, 0x1E, 0x00, + 0xFD, 0xFF, 0x30, 0x00, 0x4D, 0xFF, 0xC5, 0x01, 0x4C, 0xFC, 0x26, + 0x07, 0xA3, 0xF1, 0xAB, 0x2C, 0xBB, 0x33, 0x8F, 0xF1, 0xCA, 0x06, + 0xA6, 0xFC, 0x85, 0x01, 0x6F, 0xFF, 0x24, 0x00, 0xFD, 0xFF, 0x16, + 0x00, 0xA6, 0xFF, 0xBB, 0x00, 0xE9, 0xFE, 0x38, 0x01, 0x4B, 0xFF, + 0x28, 0xFE, 0x3A, 0x48, 0x04, 0x0A, 0x2E, 0xFA, 0xDF, 0x03, 0x8A, + 0xFD, 0x60, 0x01, 0x65, 0xFF, 0x27, 0x00, 0x00, 0x00, 0xFD, 0xFF, + 0x35, 0x00, 0x3A, 0xFF, 0xE3, 0x01, 0x31, 0xFC, 0x0F, 0x07, 0x84, + 0xF2, 0x29, 0x25, 0x1A, 0x3A, 0x67, 0xF2, 0xF6, 0x05, 0x41, 0xFD, + 0x24, 0x01, 0xA1, 0xFF, 0x12, 0x00, 0x00, 0x00, 0x0E, 0x00, 0xC8, + 0xFF, 0x64, 0x00, 0x9B, 0xFF, 0xEE, 0xFF, 0x98, 0x01, 0x93, 0xF9, + 0x10, 0x46, 0x03, 0x11, 0xA7, 0xF7, 0x12, 0x05, 0xF6, 0xFC, 0xA2, + 0x01, 0x4C, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, + 0x36, 0xFF, 0xE1, 0x01, 0x52, 0xFC, 0x93, 0x06, 0x10, 0xF4, 0x78, + 0x1D, 0x90, 0x3F, 0x3E, 0xF4, 0xAA, 0x04, 0x19, 0xFE, 0xA4, 0x00, + 0xE2, 0xFF, 0xFA, 0xFF, 0x03, 0x00, 0x07, 0x00, 0xE8, 0xFF, 0x12, + 0x00, 0x42, 0x00, 0xC4, 0xFE, 0x94, 0x03, 0x02, 0xF6, 0x89, 0x42, + 0x76, 0x18, 0x5C, 0xF5, 0x12, 0x06, 0x84, 0xFC, 0xD1, 0x01, 0x3B, + 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x33, 0x00, 0x40, 0xFF, + 0xC3, 0x01, 0xA7, 0xFC, 0xC0, 0x05, 0x1E, 0xF6, 0xD8, 0x15, 0xE7, + 0x43, 0x20, 0xF7, 0xEF, 0x02, 0x27, 0xFF, 0x0A, 0x00, 0x2E, 0x00, + 0xDD, 0xFF, 0x09, 0x00, 0x02, 0x00, 0x03, 0x00, 0xCA, 0xFF, 0xD4, + 0x00, 0xC8, 0xFD, 0x2A, 0x05, 0x7D, 0xF3, 0xCA, 0x3D, 0x22, 0x20, + 0x76, 0xF3, 0xC8, 0x06, 0x41, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, + 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0x2C, 0x00, 0x54, 0xFF, 0x8D, 0x01, + 0x26, 0xFD, 0xAD, 0x04, 0x82, 0xF8, 0x87, 0x0E, 0xF9, 0x46, 0x0C, + 0xFB, 0xD4, 0x00, 0x5D, 0x00, 0x5E, 0xFF, 0x82, 0x00, 0xBD, 0xFF, + 0x10, 0x00, 0xFF, 0xFF, 0x19, 0x00, 0x8E, 0xFF, 0x49, 0x01, 0x04, + 0xFD, 0x4D, 0x06, 0x00, 0xF2, 0xFE, 0x37, 0xCB, 0x27, 0x21, 0xF2, + 0x23, 0x07, 0x34, 0xFC, 0xDD, 0x01, 0x3F, 0xFF, 0x34, 0x00, 0xFD, + 0xFF, 0x00, 0x00, 0x24, 0x00, 0x70, 0xFF, 0x46, 0x01, 0xC3, 0xFD, + 0x6D, 0x03, 0x14, 0xFB, 0xBE, 0x07, 0xA6, 0x48, 0xF8, 0xFF, 0x70, + 0xFE, 0xAE, 0x01, 0xAA, 0xFE, 0xD9, 0x00, 0x9A, 0xFF, 0x19, 0x00, + 0xFD, 0xFF, 0x29, 0x00, 0x61, 0xFF, 0x9F, 0x01, 0x80, 0xFC, 0xF7, + 0x06, 0x7D, 0xF1, 0x5A, 0x31, 0x2C, 0x2F, 0x83, 0xF1, 0x13, 0x07, + 0x64, 0xFC, 0xB3, 0x01, 0x57, 0xFF, 0x2C, 0x00, 0xFD, 0xFF, 0x1B, + 0x00, 0x90, 0xFF, 0xF4, 0x00, 0x72, 0xFE, 0x18, 0x02, 0xAA, 0xFD, + 0xAB, 0x01, 0xDF, 0x48, 0xCA, 0x05, 0xE1, 0xFB, 0x05, 0x03, 0xF7, + 0xFD, 0x2E, 0x01, 0x79, 0xFF, 0x21, 0x00, 0x00, 0x00, 0xFD, 0xFF, + 0x32, 0x00, 0x44, 0xFF, 0xD3, 0x01, 0x3C, 0xFC, 0x2A, 0x07, 0xDC, + 0xF1, 0x1A, 0x2A, 0x06, 0x36, 0xBE, 0xF1, 0x8E, 0x06, 0xD5, 0xFC, + 0x67, 0x01, 0x7F, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x13, 0x00, 0xB2, + 0xFF, 0x9D, 0x00, 0x27, 0xFF, 0xC3, 0x00, 0x1F, 0x00, 0x76, 0xFC, + 0xA3, 0x47, 0x60, 0x0C, 0x4A, 0xF9, 0x4E, 0x04, 0x53, 0xFD, 0x79, + 0x01, 0x5C, 0xFF, 0x2A, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, + 0x37, 0xFF, 0xE6, 0x01, 0x36, 0xFC, 0xEF, 0x06, 0xFC, 0xF2, 0x81, + 0x22, 0x1C, 0x3C, 0xEC, 0xF2, 0x90, 0x05, 0x85, 0xFD, 0xFB, 0x00, + 0xB6, 0xFF, 0x0A, 0x00, 0x01, 0x00, 0x0B, 0x00, 0xD3, 0xFF, 0x47, + 0x00, 0xD7, 0xFF, 0x82, 0xFF, 0x53, 0x02, 0x39, 0xF8, 0xFD, 0x44, + 0x8D, 0x13, 0xD3, 0xF6, 0x72, 0x05, 0xCA, 0xFC, 0xB5, 0x01, 0x45, + 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x35, 0x00, 0x38, 0xFF, + 0xDA, 0x01, 0x6A, 0xFC, 0x53, 0x06, 0xBA, 0xF4, 0xCE, 0x1A, 0x32, + 0x41, 0x1F, 0xF5, 0x1D, 0x04, 0x71, 0xFE, 0x71, 0x00, 0xFB, 0xFF, + 0xF0, 0xFF, 0x05, 0x00, 0x05, 0x00, 0xF2, 0xFF, 0xF8, 0xFF, 0x77, + 0x00, 0x67, 0xFE, 0x2D, 0x04, 0x04, 0xF5, 0x07, 0x41, 0x1B, 0x1B, + 0xA6, 0xF4, 0x5A, 0x06, 0x67, 0xFC, 0xDB, 0x01, 0x38, 0xFF, 0x36, + 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x31, 0x00, 0x46, 0xFF, 0xB3, 0x01, + 0xCF, 0xFC, 0x67, 0x05, 0xEA, 0xF6, 0x44, 0x13, 0x1E, 0x45, 0x5E, + 0xF8, 0x3F, 0x02, 0x8E, 0xFF, 0xD0, 0xFF, 0x4A, 0x00, 0xD2, 0xFF, + 0x0B, 0x00, 0x01, 0x00, 0x0B, 0x00, 0xB4, 0xFF, 0x00, 0x01, 0x7E, + 0xFD, 0x9C, 0x05, 0xDC, 0xF2, 0xE4, 0x3B, 0xCD, 0x22, 0xEE, 0xF2, + 0xF3, 0x06, 0x35, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, + 0xFF, 0x00, 0x00, 0x2A, 0x00, 0x5D, 0xFF, 0x76, 0x01, 0x59, 0xFD, + 0x42, 0x04, 0x63, 0xF9, 0x1C, 0x0C, 0xB6, 0x47, 0xA4, 0xFC, 0x07, + 0x00, 0xD0, 0x00, 0x20, 0xFF, 0xA0, 0x00, 0xB1, 0xFF, 0x13, 0x00, + 0xFE, 0xFF, 0x1F, 0x00, 0x7D, 0xFF, 0x6B, 0x01, 0xCF, 0xFC, 0x96, + 0x06, 0xB7, 0xF1, 0xC6, 0x35, 0x64, 0x2A, 0xD4, 0xF1, 0x2B, 0x07, + 0x3D, 0xFC, 0xD2, 0x01, 0x45, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x00, + 0x00, 0x21, 0x00, 0x7A, 0xFF, 0x2B, 0x01, 0xFE, 0xFD, 0xF8, 0x02, + 0xFB, 0xFB, 0x8D, 0x05, 0xE5, 0x48, 0xE3, 0x01, 0x91, 0xFD, 0x25, + 0x02, 0x6B, 0xFE, 0xF7, 0x00, 0x8F, 0xFF, 0x1C, 0x00, 0xFD, 0xFF, + 0x2D, 0x00, 0x55, 0xFF, 0xB5, 0x01, 0x61, 0xFC, 0x16, 0x07, 0x85, + 0xF1, 0xE6, 0x2E, 0x9E, 0x31, 0x7D, 0xF1, 0xF3, 0x06, 0x84, 0xFC, + 0x9D, 0x01, 0x63, 0xFF, 0x28, 0x00, 0xFD, 0xFF, 0x18, 0x00, 0x9C, + 0xFF, 0xD6, 0x00, 0xB1, 0xFE, 0xA1, 0x01, 0x89, 0xFE, 0xC3, 0xFF, + 0x9C, 0x48, 0xFD, 0x07, 0xFA, 0xFA, 0x7A, 0x03, 0xBC, 0xFD, 0x49, + 0x01, 0x6E, 0xFF, 0x24, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x34, 0x00, + 0x3E, 0xFF, 0xDE, 0x01, 0x33, 0xFC, 0x22, 0x07, 0x2B, 0xF2, 0x80, + 0x27, 0x3B, 0x38, 0x0A, 0xF2, 0x44, 0x06, 0x0B, 0xFD, 0x45, 0x01, + 0x90, 0xFF, 0x18, 0x00, 0xFF, 0xFF, 0x10, 0x00, 0xBE, 0xFF, 0x7F, + 0x00, 0x65, 0xFF, 0x51, 0x00, 0xEB, 0x00, 0xE1, 0xFA, 0xE1, 0x46, + 0xCD, 0x0E, 0x6A, 0xF8, 0xB8, 0x04, 0x20, 0xFD, 0x90, 0x01, 0x53, + 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, + 0xE5, 0x01, 0x42, 0xFC, 0xC3, 0x06, 0x87, 0xF3, 0xD7, 0x1F, 0xFE, + 0x3D, 0x91, 0xF3, 0x1D, 0x05, 0xD1, 0xFD, 0xCE, 0x00, 0xCC, 0xFF, + 0x02, 0x00, 0x02, 0x00, 0x09, 0x00, 0xDE, 0xFF, 0x2B, 0x00, 0x11, + 0x00, 0x1B, 0xFF, 0x02, 0x03, 0xFE, 0xF6, 0xC3, 0x43, 0x22, 0x16, + 0x07, 0xF6, 0xCA, 0x05, 0xA3, 0xFC, 0xC5, 0x01, 0x3F, 0xFF, 0x33, + 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x34, 0x00, 0x3C, 0xFF, 0xCF, 0x01, + 0x88, 0xFC, 0x09, 0x06, 0x71, 0xF5, 0x2B, 0x18, 0xB2, 0x42, 0x20, + 0xF6, 0x83, 0x03, 0xCF, 0xFE, 0x3C, 0x00, 0x15, 0x00, 0xE6, 0xFF, + 0x07, 0x00, 0x03, 0x00, 0xFB, 0xFF, 0xDF, 0xFF, 0xA9, 0x00, 0x10, + 0xFE, 0xB9, 0x04, 0x27, 0xF4, 0x5E, 0x3F, 0xC3, 0x1D, 0xFE, 0xF3, + 0x99, 0x06, 0x50, 0xFC, 0xE2, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, + 0xFF, 0xFF, 0xFF, 0x2F, 0x00, 0x4D, 0xFF, 0xA0, 0x01, 0xFB, 0xFC, + 0x07, 0x05, 0xBF, 0xF7, 0xBB, 0x10, 0x2B, 0x46, 0xBB, 0xF9, 0x83, + 0x01, 0xFA, 0xFF, 0x95, 0xFF, 0x68, 0x00, 0xC7, 0xFF, 0x0E, 0x00, + 0x00, 0x00, 0x13, 0x00, 0x9F, 0xFF, 0x28, 0x01, 0x3A, 0xFD, 0x00, + 0x06, 0x5A, 0xF2, 0xDF, 0x39, 0x73, 0x25, 0x79, 0xF2, 0x12, 0x07, + 0x31, 0xFC, 0xE3, 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x00, + 0x00, 0x27, 0x00, 0x66, 0xFF, 0x5E, 0x01, 0x90, 0xFD, 0xD2, 0x03, + 0x47, 0xFA, 0xC3, 0x09, 0x48, 0x48, 0x5A, 0xFE, 0x33, 0xFF, 0x45, + 0x01, 0xE2, 0xFE, 0xBE, 0x00, 0xA5, 0xFF, 0x16, 0x00, 0xFD, 0xFF, + 0x24, 0x00, 0x6D, 0xFF, 0x88, 0x01, 0xA2, 0xFC, 0xD0, 0x06, 0x8C, + 0xF1, 0x78, 0x33, 0xF2, 0x2C, 0x9E, 0xF1, 0x24, 0x07, 0x4E, 0xFC, + 0xC3, 0x01, 0x4E, 0xFF, 0x2F, 0x00, 0xFD, 0xFF, 0x1E, 0x00, 0x86, + 0xFF, 0x0E, 0x01, 0x3B, 0xFE, 0x82, 0x02, 0xE0, 0xFC, 0x73, 0x03, + 0xF6, 0x48, 0xE9, 0x03, 0xAD, 0xFC, 0x9C, 0x02, 0x2D, 0xFE, 0x14, + 0x01, 0x83, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x30, 0x00, + 0x4C, 0xFF, 0xC7, 0x01, 0x4A, 0xFC, 0x27, 0x07, 0xA8, 0xF1, 0x62, + 0x2C, 0xFD, 0x33, 0x93, 0xF1, 0xC4, 0x06, 0xAB, 0xFC, 0x82, 0x01, + 0x71, 0xFF, 0x23, 0x00, 0xFE, 0xFF, 0x15, 0x00, 0xA8, 0xFF, 0xB8, + 0x00, 0xF0, 0xFE, 0x2B, 0x01, 0x63, 0xFF, 0xF6, 0xFD, 0x2C, 0x48, + 0x47, 0x0A, 0x14, 0xFA, 0xEB, 0x03, 0x84, 0xFD, 0x63, 0x01, 0x64, + 0xFF, 0x27, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x3A, 0xFF, + 0xE4, 0x01, 0x32, 0xFC, 0x0C, 0x07, 0x91, 0xF2, 0xDD, 0x24, 0x54, + 0x3A, 0x74, 0xF2, 0xEB, 0x05, 0x49, 0xFD, 0x20, 0x01, 0xA3, 0xFF, + 0x11, 0x00, 0x00, 0x00, 0x0D, 0x00, 0xC9, 0xFF, 0x61, 0x00, 0xA2, + 0xFF, 0xE2, 0xFF, 0xAE, 0x01, 0x6B, 0xF9, 0xF2, 0x45, 0x4A, 0x11, + 0x8F, 0xF7, 0x1D, 0x05, 0xF1, 0xFC, 0xA4, 0x01, 0x4B, 0xFF, 0x2F, + 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE1, 0x01, + 0x55, 0xFC, 0x8C, 0x06, 0x22, 0xF4, 0x2C, 0x1D, 0xC0, 0x3F, 0x55, + 0xF4, 0x9B, 0x04, 0x23, 0xFE, 0x9F, 0x00, 0xE4, 0xFF, 0xF9, 0xFF, + 0x04, 0x00, 0x07, 0x00, 0xE9, 0xFF, 0x0F, 0x00, 0x48, 0x00, 0xB9, + 0xFE, 0xA6, 0x03, 0xE4, 0xF5, 0x60, 0x42, 0xC1, 0x18, 0x47, 0xF5, + 0x1A, 0x06, 0x81, 0xFC, 0xD2, 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFE, + 0xFF, 0xFF, 0xFF, 0x33, 0x00, 0x40, 0xFF, 0xC1, 0x01, 0xAB, 0xFC, + 0xB7, 0x05, 0x34, 0xF6, 0x8E, 0x15, 0x0B, 0x44, 0x42, 0xF7, 0xDC, + 0x02, 0x32, 0xFF, 0x04, 0x00, 0x31, 0x00, 0xDC, 0xFF, 0x09, 0x00, + 0x02, 0x00, 0x04, 0x00, 0xC7, 0xFF, 0xD9, 0x00, 0xBF, 0xFD, 0x38, + 0x05, 0x69, 0xF3, 0x96, 0x3D, 0x6F, 0x20, 0x66, 0xF3, 0xCE, 0x06, + 0x3F, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFF, + 0xFF, 0x2C, 0x00, 0x55, 0xFF, 0x8B, 0x01, 0x2B, 0xFD, 0xA1, 0x04, + 0x9B, 0xF8, 0x42, 0x0E, 0x0F, 0x47, 0x38, 0xFB, 0xBE, 0x00, 0x6A, + 0x00, 0x58, 0xFF, 0x85, 0x00, 0xBB, 0xFF, 0x10, 0x00, 0xFF, 0xFF, + 0x19, 0x00, 0x8C, 0xFF, 0x4D, 0x01, 0xFE, 0xFC, 0x56, 0x06, 0xF7, + 0xF1, 0xBF, 0x37, 0x15, 0x28, 0x18, 0xF2, 0x25, 0x07, 0x34, 0xFC, + 0xDC, 0x01, 0x3F, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x24, + 0x00, 0x71, 0xFF, 0x43, 0x01, 0xC9, 0xFD, 0x60, 0x03, 0x2E, 0xFB, + 0x7E, 0x07, 0xAF, 0x48, 0x2D, 0x00, 0x58, 0xFE, 0xBB, 0x01, 0xA3, + 0xFE, 0xDD, 0x00, 0x99, 0xFF, 0x19, 0x00, 0xFD, 0xFF, 0x29, 0x00, + 0x60, 0xFF, 0xA2, 0x01, 0x7C, 0xFC, 0xFB, 0x06, 0x7C, 0xF1, 0x15, + 0x31, 0x73, 0x2F, 0x81, 0xF1, 0x10, 0x07, 0x67, 0xFC, 0xB1, 0x01, + 0x58, 0xFF, 0x2C, 0x00, 0xFD, 0xFF, 0x1B, 0x00, 0x91, 0xFF, 0xF1, + 0x00, 0x79, 0xFE, 0x0A, 0x02, 0xC3, 0xFD, 0x73, 0x01, 0xDB, 0x48, + 0x07, 0x06, 0xC7, 0xFB, 0x12, 0x03, 0xF1, 0xFD, 0x31, 0x01, 0x78, + 0xFF, 0x22, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x44, 0xFF, + 0xD5, 0x01, 0x3A, 0xFC, 0x2A, 0x07, 0xE3, 0xF1, 0xD1, 0x29, 0x46, + 0x36, 0xC5, 0xF1, 0x87, 0x06, 0xDA, 0xFC, 0x64, 0x01, 0x80, 0xFF, + 0x1E, 0x00, 0xFE, 0xFF, 0x12, 0x00, 0xB3, 0xFF, 0x99, 0x00, 0x2E, + 0xFF, 0xB6, 0x00, 0x36, 0x00, 0x47, 0xFC, 0x90, 0x47, 0xA4, 0x0C, + 0x31, 0xF9, 0x5A, 0x04, 0x4E, 0xFD, 0x7C, 0x01, 0x5B, 0xFF, 0x2A, + 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, + 0x37, 0xFC, 0xEB, 0x06, 0x0B, 0xF3, 0x35, 0x22, 0x52, 0x3C, 0xFD, + 0xF2, 0x84, 0x05, 0x8D, 0xFD, 0xF6, 0x00, 0xB8, 0xFF, 0x09, 0x00, + 0x01, 0x00, 0x0B, 0x00, 0xD5, 0xFF, 0x44, 0x00, 0xDD, 0xFF, 0x77, + 0xFF, 0x67, 0x02, 0x14, 0xF8, 0xDC, 0x44, 0xD5, 0x13, 0xBC, 0xF6, + 0x7C, 0x05, 0xC5, 0xFC, 0xB7, 0x01, 0x44, 0xFF, 0x31, 0x00, 0xFF, + 0xFF, 0xFE, 0xFF, 0x35, 0x00, 0x39, 0xFF, 0xD9, 0x01, 0x6D, 0xFC, + 0x4B, 0x06, 0xCD, 0xF4, 0x83, 0x1A, 0x5F, 0x41, 0x3A, 0xF5, 0x0C, + 0x04, 0x7B, 0xFE, 0x6C, 0x00, 0xFE, 0xFF, 0xEF, 0xFF, 0x05, 0x00, + 0x05, 0x00, 0xF3, 0xFF, 0xF5, 0xFF, 0x7D, 0x00, 0x5D, 0xFE, 0x3E, + 0x04, 0xEA, 0xF4, 0xD9, 0x40, 0x66, 0x1B, 0x93, 0xF4, 0x62, 0x06, + 0x64, 0xFC, 0xDC, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, + 0xFF, 0x31, 0x00, 0x46, 0xFF, 0xB1, 0x01, 0xD3, 0xFC, 0x5D, 0x05, + 0x01, 0xF7, 0xFB, 0x12, 0x3F, 0x45, 0x83, 0xF8, 0x2A, 0x02, 0x9A, + 0xFF, 0xCA, 0xFF, 0x4E, 0x00, 0xD1, 0xFF, 0x0C, 0x00, 0x00, 0x00, + 0x0C, 0x00, 0xB1, 0xFF, 0x04, 0x01, 0x76, 0xFD, 0xA8, 0x05, 0xCC, + 0xF2, 0xAB, 0x3B, 0x18, 0x23, 0xE0, 0xF2, 0xF7, 0x06, 0x35, 0xFC, + 0xE6, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x29, + 0x00, 0x5E, 0xFF, 0x74, 0x01, 0x5F, 0xFD, 0x35, 0x04, 0x7C, 0xF9, + 0xD8, 0x0B, 0xC9, 0x47, 0xD4, 0xFC, 0xF0, 0xFF, 0xDD, 0x00, 0x19, + 0xFF, 0xA4, 0x00, 0xAF, 0xFF, 0x13, 0x00, 0xFE, 0xFF, 0x20, 0x00, + 0x7B, 0xFF, 0x6E, 0x01, 0xCA, 0xFC, 0x9D, 0x06, 0xB1, 0xF1, 0x86, + 0x35, 0xAE, 0x2A, 0xCD, 0xF1, 0x2B, 0x07, 0x3F, 0xFC, 0xD1, 0x01, + 0x46, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x21, 0x00, 0x7C, + 0xFF, 0x27, 0x01, 0x05, 0xFE, 0xEB, 0x02, 0x14, 0xFC, 0x50, 0x05, + 0xEA, 0x48, 0x1B, 0x02, 0x78, 0xFD, 0x32, 0x02, 0x64, 0xFE, 0xFA, + 0x00, 0x8D, 0xFF, 0x1C, 0x00, 0xFD, 0xFF, 0x2D, 0x00, 0x54, 0xFF, + 0xB7, 0x01, 0x5E, 0xFC, 0x19, 0x07, 0x88, 0xF1, 0x9F, 0x2E, 0xE3, + 0x31, 0x7E, 0xF1, 0xEE, 0x06, 0x88, 0xFC, 0x9A, 0x01, 0x64, 0xFF, + 0x28, 0x00, 0xFD, 0xFF, 0x18, 0x00, 0x9D, 0xFF, 0xD3, 0x00, 0xB8, + 0xFE, 0x93, 0x01, 0xA1, 0xFE, 0x8E, 0xFF, 0x92, 0x48, 0x3D, 0x08, + 0xE1, 0xFA, 0x86, 0x03, 0xB6, 0xFD, 0x4C, 0x01, 0x6D, 0xFF, 0x25, + 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x3E, 0xFF, 0xDF, 0x01, + 0x33, 0xFC, 0x20, 0x07, 0x35, 0xF2, 0x36, 0x27, 0x78, 0x38, 0x14, + 0xF2, 0x3B, 0x06, 0x11, 0xFD, 0x41, 0x01, 0x92, 0xFF, 0x17, 0x00, + 0xFF, 0xFF, 0x10, 0x00, 0xBF, 0xFF, 0x7B, 0x00, 0x6C, 0xFF, 0x44, + 0x00, 0x01, 0x01, 0xB6, 0xFA, 0xC8, 0x46, 0x13, 0x0F, 0x51, 0xF8, + 0xC4, 0x04, 0x1B, 0xFD, 0x92, 0x01, 0x52, 0xFF, 0x2D, 0x00, 0xFF, + 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE5, 0x01, 0x44, 0xFC, + 0xBD, 0x06, 0x97, 0xF3, 0x8A, 0x1F, 0x31, 0x3E, 0xA5, 0xF3, 0x0F, + 0x05, 0xDA, 0xFD, 0xC9, 0x00, 0xCF, 0xFF, 0x01, 0x00, 0x02, 0x00, + 0x09, 0x00, 0xDF, 0xFF, 0x28, 0x00, 0x17, 0x00, 0x10, 0xFF, 0x15, + 0x03, 0xDD, 0xF6, 0x9E, 0x43, 0x6C, 0x16, 0xF1, 0xF5, 0xD3, 0x05, + 0x9F, 0xFC, 0xC6, 0x01, 0x3F, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0xFE, + 0xFF, 0x34, 0x00, 0x3C, 0xFF, 0xCE, 0x01, 0x8C, 0xFC, 0x00, 0x06, + 0x86, 0xF5, 0xE0, 0x17, 0xDB, 0x42, 0x3F, 0xF6, 0x71, 0x03, 0xD9, + 0xFE, 0x36, 0x00, 0x18, 0x00, 0xE5, 0xFF, 0x07, 0x00, 0x03, 0x00, + 0xFC, 0xFF, 0xDC, 0xFF, 0xAF, 0x00, 0x07, 0xFE, 0xC8, 0x04, 0x10, + 0xF4, 0x2D, 0x3F, 0x0F, 0x1E, 0xED, 0xF3, 0xA0, 0x06, 0x4E, 0xFC, + 0xE3, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x2E, + 0x00, 0x4E, 0xFF, 0x9E, 0x01, 0x00, 0xFD, 0xFC, 0x04, 0xD7, 0xF7, + 0x75, 0x10, 0x48, 0x46, 0xE4, 0xF9, 0x6E, 0x01, 0x06, 0x00, 0x8E, + 0xFF, 0x6B, 0x00, 0xC6, 0xFF, 0x0E, 0x00, 0xFF, 0xFF, 0x13, 0x00, + 0x9D, 0xFF, 0x2D, 0x01, 0x33, 0xFD, 0x0B, 0x06, 0x4D, 0xF2, 0xA5, + 0x39, 0xBF, 0x25, 0x6D, 0xF2, 0x15, 0x07, 0x31, 0xFC, 0xE2, 0x01, + 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x26, 0x00, 0x68, + 0xFF, 0x5B, 0x01, 0x96, 0xFD, 0xC6, 0x03, 0x61, 0xFA, 0x81, 0x09, + 0x57, 0x48, 0x8D, 0xFE, 0x1B, 0xFF, 0x52, 0x01, 0xDB, 0xFE, 0xC2, + 0x00, 0xA4, 0xFF, 0x16, 0x00, 0xFD, 0xFF, 0x25, 0x00, 0x6C, 0xFF, + 0x8B, 0x01, 0x9D, 0xFC, 0xD5, 0x06, 0x89, 0xF1, 0x35, 0x33, 0x3A, + 0x2D, 0x9A, 0xF1, 0x23, 0x07, 0x51, 0xFC, 0xC2, 0x01, 0x4F, 0xFF, + 0x2F, 0x00, 0xFD, 0xFF, 0x1E, 0x00, 0x87, 0xFF, 0x0B, 0x01, 0x42, + 0xFE, 0x74, 0x02, 0xF9, 0xFC, 0x39, 0x03, 0xF5, 0x48, 0x24, 0x04, + 0x94, 0xFC, 0xA9, 0x02, 0x27, 0xFE, 0x18, 0x01, 0x82, 0xFF, 0x1F, + 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x30, 0x00, 0x4B, 0xFF, 0xC9, 0x01, + 0x48, 0xFC, 0x28, 0x07, 0xAD, 0xF1, 0x19, 0x2C, 0x3F, 0x34, 0x97, + 0xF1, 0xBE, 0x06, 0xB0, 0xFC, 0x7F, 0x01, 0x72, 0xFF, 0x23, 0x00, + 0xFE, 0xFF, 0x15, 0x00, 0xA9, 0xFF, 0xB4, 0x00, 0xF7, 0xFE, 0x1D, + 0x01, 0x7A, 0xFF, 0xC5, 0xFD, 0x1D, 0x48, 0x89, 0x0A, 0xFB, 0xF9, + 0xF8, 0x03, 0x7D, 0xFD, 0x66, 0x01, 0x63, 0xFF, 0x28, 0x00, 0x00, + 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x39, 0xFF, 0xE4, 0x01, 0x32, 0xFC, + 0x09, 0x07, 0x9D, 0xF2, 0x92, 0x24, 0x8F, 0x3A, 0x82, 0xF2, 0xE1, + 0x05, 0x50, 0xFD, 0x1B, 0x01, 0xA6, 0xFF, 0x10, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0xCB, 0xFF, 0x5E, 0x00, 0xA9, 0xFF, 0xD6, 0xFF, 0xC3, + 0x01, 0x43, 0xF9, 0xD7, 0x45, 0x92, 0x11, 0x77, 0xF7, 0x28, 0x05, + 0xEC, 0xFC, 0xA7, 0x01, 0x4A, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0xFE, + 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE0, 0x01, 0x57, 0xFC, 0x85, 0x06, + 0x34, 0xF4, 0xE0, 0x1C, 0xF0, 0x3F, 0x6D, 0xF4, 0x8C, 0x04, 0x2C, + 0xFE, 0x99, 0x00, 0xE7, 0xFF, 0xF8, 0xFF, 0x04, 0x00, 0x06, 0x00, + 0xEA, 0xFF, 0x0C, 0x00, 0x4E, 0x00, 0xAF, 0xFE, 0xB8, 0x03, 0xC7, + 0xF5, 0x38, 0x42, 0x0C, 0x19, 0x32, 0xF5, 0x23, 0x06, 0x7D, 0xFC, + 0xD3, 0x01, 0x3A, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x32, + 0x00, 0x41, 0xFF, 0xC0, 0x01, 0xAF, 0xFC, 0xAD, 0x05, 0x4A, 0xF6, + 0x44, 0x15, 0x2F, 0x44, 0x64, 0xF7, 0xC9, 0x02, 0x3D, 0xFF, 0xFE, + 0xFF, 0x34, 0x00, 0xDB, 0xFF, 0x09, 0x00, 0x02, 0x00, 0x05, 0x00, + 0xC5, 0xFF, 0xDE, 0x00, 0xB7, 0xFD, 0x45, 0x05, 0x56, 0xF3, 0x61, + 0x3D, 0xBA, 0x20, 0x56, 0xF3, 0xD3, 0x06, 0x3E, 0xFC, 0xE6, 0x01, + 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0x2C, 0x00, 0x56, + 0xFF, 0x88, 0x01, 0x31, 0xFD, 0x95, 0x04, 0xB4, 0xF8, 0xFC, 0x0D, + 0x26, 0x47, 0x64, 0xFB, 0xA7, 0x00, 0x77, 0x00, 0x51, 0xFF, 0x89, + 0x00, 0xBA, 0xFF, 0x11, 0x00, 0xFF, 0xFF, 0x1A, 0x00, 0x8A, 0xFF, + 0x51, 0x01, 0xF8, 0xFC, 0x5E, 0x06, 0xED, 0xF1, 0x82, 0x37, 0x60, + 0x28, 0x0E, 0xF2, 0x26, 0x07, 0x35, 0xFC, 0xDB, 0x01, 0x40, 0xFF, + 0x34, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x23, 0x00, 0x72, 0xFF, 0x40, + 0x01, 0xD0, 0xFD, 0x53, 0x03, 0x47, 0xFB, 0x3F, 0x07, 0xB8, 0x48, + 0x62, 0x00, 0x3F, 0xFE, 0xC8, 0x01, 0x9C, 0xFE, 0xE0, 0x00, 0x98, + 0xFF, 0x19, 0x00, 0xFD, 0xFF, 0x29, 0x00, 0x5F, 0xFF, 0xA5, 0x01, + 0x78, 0xFC, 0xFF, 0x06, 0x7D, 0xF1, 0xCF, 0x30, 0xB8, 0x2F, 0x80, + 0xF1, 0x0D, 0x07, 0x6A, 0xFC, 0xAE, 0x01, 0x59, 0xFF, 0x2B, 0x00, + 0xFD, 0xFF, 0x1B, 0x00, 0x93, 0xFF, 0xED, 0x00, 0x80, 0xFE, 0xFD, + 0x01, 0xDC, 0xFD, 0x3C, 0x01, 0xD5, 0x48, 0x45, 0x06, 0xAE, 0xFB, + 0x1F, 0x03, 0xEA, 0xFD, 0x34, 0x01, 0x77, 0xFF, 0x22, 0x00, 0x00, + 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x43, 0xFF, 0xD6, 0x01, 0x39, 0xFC, + 0x2A, 0x07, 0xEB, 0xF1, 0x87, 0x29, 0x85, 0x36, 0xCC, 0xF1, 0x7F, + 0x06, 0xE0, 0xFC, 0x60, 0x01, 0x82, 0xFF, 0x1D, 0x00, 0xFE, 0xFF, + 0x12, 0x00, 0xB5, 0xFF, 0x96, 0x00, 0x35, 0xFF, 0xA9, 0x00, 0x4D, + 0x00, 0x19, 0xFC, 0x7C, 0x47, 0xE8, 0x0C, 0x18, 0xF9, 0x66, 0x04, + 0x48, 0xFD, 0x7E, 0x01, 0x5A, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0xFD, + 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x38, 0xFC, 0xE6, 0x06, + 0x19, 0xF3, 0xEA, 0x21, 0x8A, 0x3C, 0x0E, 0xF3, 0x78, 0x05, 0x96, + 0xFD, 0xF1, 0x00, 0xBB, 0xFF, 0x08, 0x00, 0x01, 0x00, 0x0B, 0x00, + 0xD6, 0xFF, 0x41, 0x00, 0xE4, 0xFF, 0x6B, 0xFF, 0x7B, 0x02, 0xF0, + 0xF7, 0xBA, 0x44, 0x1E, 0x14, 0xA5, 0xF6, 0x86, 0x05, 0xC1, 0xFC, + 0xB9, 0x01, 0x44, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x35, + 0x00, 0x39, 0xFF, 0xD8, 0x01, 0x70, 0xFC, 0x43, 0x06, 0xE1, 0xF4, + 0x38, 0x1A, 0x8C, 0x41, 0x55, 0xF5, 0xFC, 0x03, 0x85, 0xFE, 0x66, + 0x00, 0x01, 0x00, 0xEE, 0xFF, 0x06, 0x00, 0x05, 0x00, 0xF4, 0xFF, + 0xF2, 0xFF, 0x83, 0x00, 0x53, 0xFE, 0x4E, 0x04, 0xD0, 0xF4, 0xAB, + 0x40, 0xB2, 0x1B, 0x7F, 0xF4, 0x69, 0x06, 0x62, 0xFC, 0xDD, 0x01, + 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x30, 0x00, 0x47, + 0xFF, 0xAF, 0x01, 0xD8, 0xFC, 0x52, 0x05, 0x19, 0xF7, 0xB2, 0x12, + 0x5C, 0x45, 0xA9, 0xF8, 0x16, 0x02, 0xA6, 0xFF, 0xC3, 0xFF, 0x51, + 0x00, 0xD0, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0xAF, 0xFF, + 0x09, 0x01, 0x6E, 0xFD, 0xB4, 0x05, 0xBC, 0xF2, 0x73, 0x3B, 0x64, + 0x23, 0xD2, 0xF2, 0xFB, 0x06, 0x34, 0xFC, 0xE6, 0x01, 0x38, 0xFF, + 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x29, 0x00, 0x5F, 0xFF, 0x71, + 0x01, 0x65, 0xFD, 0x29, 0x04, 0x96, 0xF9, 0x95, 0x0B, 0xDC, 0x47, + 0x03, 0xFD, 0xD9, 0xFF, 0xEA, 0x00, 0x12, 0xFF, 0xA7, 0x00, 0xAE, + 0xFF, 0x14, 0x00, 0xFE, 0xFF, 0x20, 0x00, 0x79, 0xFF, 0x72, 0x01, + 0xC4, 0xFC, 0xA4, 0x06, 0xAB, 0xF1, 0x46, 0x35, 0xF7, 0x2A, 0xC6, + 0xF1, 0x2A, 0x07, 0x40, 0xFC, 0xCF, 0x01, 0x47, 0xFF, 0x31, 0x00, + 0xFD, 0xFF, 0x00, 0x00, 0x20, 0x00, 0x7D, 0xFF, 0x24, 0x01, 0x0C, + 0xFE, 0xDE, 0x02, 0x2E, 0xFC, 0x13, 0x05, 0xEC, 0x48, 0x54, 0x02, + 0x5E, 0xFD, 0x3F, 0x02, 0x5D, 0xFE, 0xFE, 0x00, 0x8C, 0xFF, 0x1C, + 0x00, 0xFD, 0xFF, 0x2D, 0x00, 0x53, 0xFF, 0xBA, 0x01, 0x5B, 0xFC, + 0x1B, 0x07, 0x8B, 0xF1, 0x58, 0x2E, 0x26, 0x32, 0x80, 0xF1, 0xEA, + 0x06, 0x8C, 0xFC, 0x97, 0x01, 0x66, 0xFF, 0x27, 0x00, 0xFD, 0xFF, + 0x17, 0x00, 0x9E, 0xFF, 0xCF, 0x00, 0xBF, 0xFE, 0x86, 0x01, 0xBA, + 0xFE, 0x5A, 0xFF, 0x86, 0x48, 0x7D, 0x08, 0xC7, 0xFA, 0x93, 0x03, + 0xB0, 0xFD, 0x4F, 0x01, 0x6C, 0xFF, 0x25, 0x00, 0x00, 0x00, 0xFD, + 0xFF, 0x35, 0x00, 0x3D, 0xFF, 0xDF, 0x01, 0x32, 0xFC, 0x1E, 0x07, + 0x40, 0xF2, 0xEB, 0x26, 0xB5, 0x38, 0x1F, 0xF2, 0x32, 0x06, 0x18, + 0xFD, 0x3D, 0x01, 0x94, 0xFF, 0x16, 0x00, 0xFF, 0xFF, 0x0F, 0x00, + 0xC0, 0xFF, 0x78, 0x00, 0x73, 0xFF, 0x38, 0x00, 0x17, 0x01, 0x8B, + 0xFA, 0xAF, 0x46, 0x59, 0x0F, 0x39, 0xF8, 0xCF, 0x04, 0x15, 0xFD, + 0x95, 0x01, 0x51, 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36, + 0x00, 0x36, 0xFF, 0xE5, 0x01, 0x46, 0xFC, 0xB8, 0x06, 0xA8, 0xF3, + 0x3F, 0x1F, 0x64, 0x3E, 0xBA, 0xF3, 0x01, 0x05, 0xE2, 0xFD, 0xC4, + 0x00, 0xD2, 0xFF, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0xE1, 0xFF, + 0x25, 0x00, 0x1D, 0x00, 0x05, 0xFF, 0x28, 0x03, 0xBD, 0xF6, 0x77, + 0x43, 0xB6, 0x16, 0xDC, 0xF5, 0xDD, 0x05, 0x9B, 0xFC, 0xC8, 0x01, + 0x3E, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x34, 0x00, 0x3D, + 0xFF, 0xCC, 0x01, 0x8F, 0xFC, 0xF8, 0x05, 0x9B, 0xF5, 0x96, 0x17, + 0x02, 0x43, 0x5E, 0xF6, 0x5F, 0x03, 0xE4, 0xFE, 0x30, 0x00, 0x1B, + 0x00, 0xE4, 0xFF, 0x08, 0x00, 0x03, 0x00, 0xFD, 0xFF, 0xD9, 0xFF, + 0xB4, 0x00, 0xFD, 0xFD, 0xD7, 0x04, 0xFA, 0xF3, 0xFC, 0x3E, 0x5B, + 0x1E, 0xDB, 0xF3, 0xA6, 0x06, 0x4C, 0xFC, 0xE3, 0x01, 0x36, 0xFF, + 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x2E, 0x00, 0x4E, 0xFF, 0x9C, + 0x01, 0x05, 0xFD, 0xF1, 0x04, 0xF0, 0xF7, 0x2D, 0x10, 0x61, 0x46, + 0x0D, 0xFA, 0x58, 0x01, 0x13, 0x00, 0x87, 0xFF, 0x6E, 0x00, 0xC4, + 0xFF, 0x0E, 0x00, 0xFF, 0xFF, 0x14, 0x00, 0x9B, 0xFF, 0x31, 0x01, + 0x2C, 0xFD, 0x15, 0x06, 0x41, 0xF2, 0x6A, 0x39, 0x0A, 0x26, 0x61, + 0xF2, 0x17, 0x07, 0x31, 0xFC, 0xE2, 0x01, 0x3B, 0xFF, 0x35, 0x00, + 0xFD, 0xFF, 0x00, 0x00, 0x26, 0x00, 0x69, 0xFF, 0x58, 0x01, 0x9D, + 0xFD, 0xB9, 0x03, 0x7B, 0xFA, 0x40, 0x09, 0x63, 0x48, 0xBF, 0xFE, + 0x03, 0xFF, 0x5F, 0x01, 0xD4, 0xFE, 0xC5, 0x00, 0xA2, 0xFF, 0x16, + 0x00, 0xFD, 0xFF, 0x25, 0x00, 0x6A, 0xFF, 0x8E, 0x01, 0x99, 0xFC, + 0xDB, 0x06, 0x86, 0xF1, 0xF2, 0x32, 0x82, 0x2D, 0x96, 0xF1, 0x21, + 0x07, 0x53, 0xFC, 0xC0, 0x01, 0x50, 0xFF, 0x2E, 0x00, 0xFD, 0xFF, + 0x1D, 0x00, 0x88, 0xFF, 0x07, 0x01, 0x49, 0xFE, 0x67, 0x02, 0x13, + 0xFD, 0xFF, 0x02, 0xF4, 0x48, 0x5F, 0x04, 0x7A, 0xFC, 0xB6, 0x02, + 0x20, 0xFE, 0x1B, 0x01, 0x81, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFD, + 0xFF, 0x30, 0x00, 0x4A, 0xFF, 0xCA, 0x01, 0x46, 0xFC, 0x29, 0x07, + 0xB3, 0xF1, 0xD1, 0x2B, 0x81, 0x34, 0x9C, 0xF1, 0xB8, 0x06, 0xB5, + 0xFC, 0x7C, 0x01, 0x74, 0xFF, 0x22, 0x00, 0xFE, 0xFF, 0x15, 0x00, + 0xAA, 0xFF, 0xB1, 0x00, 0xFE, 0xFE, 0x10, 0x01, 0x92, 0xFF, 0x94, + 0xFD, 0x0D, 0x48, 0xCB, 0x0A, 0xE2, 0xF9, 0x04, 0x04, 0x77, 0xFD, + 0x69, 0x01, 0x62, 0xFF, 0x28, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, + 0x00, 0x39, 0xFF, 0xE5, 0x01, 0x32, 0xFC, 0x06, 0x07, 0xAA, 0xF2, + 0x46, 0x24, 0xC8, 0x3A, 0x90, 0xF2, 0xD6, 0x05, 0x57, 0xFD, 0x17, + 0x01, 0xA8, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x0D, 0x00, 0xCC, 0xFF, + 0x5A, 0x00, 0xAF, 0xFF, 0xCA, 0xFF, 0xD8, 0x01, 0x1C, 0xF9, 0xB8, + 0x45, 0xDA, 0x11, 0x60, 0xF7, 0x33, 0x05, 0xE7, 0xFC, 0xA9, 0x01, + 0x4A, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x37, + 0xFF, 0xDF, 0x01, 0x5A, 0xFC, 0x7E, 0x06, 0x47, 0xF4, 0x94, 0x1C, + 0x1F, 0x40, 0x85, 0xF4, 0x7D, 0x04, 0x36, 0xFE, 0x93, 0x00, 0xEA, + 0xFF, 0xF7, 0xFF, 0x04, 0x00, 0x06, 0x00, 0xEB, 0xFF, 0x09, 0x00, + 0x54, 0x00, 0xA4, 0xFE, 0xC9, 0x03, 0xAA, 0xF5, 0x0C, 0x42, 0x56, + 0x19, 0x1E, 0xF5, 0x2B, 0x06, 0x7A, 0xFC, 0xD4, 0x01, 0x3A, 0xFF, + 0x35, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x32, 0x00, 0x42, 0xFF, 0xBE, + 0x01, 0xB4, 0xFC, 0xA4, 0x05, 0x61, 0xF6, 0xFB, 0x14, 0x53, 0x44, + 0x86, 0xF7, 0xB6, 0x02, 0x49, 0xFF, 0xF7, 0xFF, 0x37, 0x00, 0xD9, + 0xFF, 0x0A, 0x00, 0x01, 0x00, 0x06, 0x00, 0xC2, 0xFF, 0xE3, 0x00, + 0xAE, 0xFD, 0x52, 0x05, 0x44, 0xF3, 0x2A, 0x3D, 0x06, 0x21, 0x47, + 0xF3, 0xD8, 0x06, 0x3C, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, + 0xFD, 0xFF, 0x00, 0x00, 0x2B, 0x00, 0x57, 0xFF, 0x86, 0x01, 0x36, + 0xFD, 0x89, 0x04, 0xCD, 0xF8, 0xB7, 0x0D, 0x3D, 0x47, 0x91, 0xFB, + 0x91, 0x00, 0x83, 0x00, 0x4A, 0xFF, 0x8C, 0x00, 0xB9, 0xFF, 0x11, + 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x88, 0xFF, 0x55, 0x01, 0xF2, 0xFC, + 0x67, 0x06, 0xE4, 0xF1, 0x44, 0x37, 0xAA, 0x28, 0x05, 0xF2, 0x27, + 0x07, 0x36, 0xFC, 0xDA, 0x01, 0x41, 0xFF, 0x33, 0x00, 0xFD, 0xFF, + 0x00, 0x00, 0x23, 0x00, 0x73, 0xFF, 0x3D, 0x01, 0xD6, 0xFD, 0x46, + 0x03, 0x61, 0xFB, 0x00, 0x07, 0xBF, 0x48, 0x98, 0x00, 0x26, 0xFE, + 0xD5, 0x01, 0x95, 0xFE, 0xE3, 0x00, 0x96, 0xFF, 0x1A, 0x00, 0xFD, + 0xFF, 0x2A, 0x00, 0x5D, 0xFF, 0xA7, 0x01, 0x75, 0xFC, 0x03, 0x07, + 0x7D, 0xF1, 0x8A, 0x30, 0xFF, 0x2F, 0x7E, 0xF1, 0x0A, 0x07, 0x6E, + 0xFC, 0xAC, 0x01, 0x5A, 0xFF, 0x2B, 0x00, 0xFD, 0xFF, 0x1A, 0x00, + 0x94, 0xFF, 0xEA, 0x00, 0x87, 0xFE, 0xF0, 0x01, 0xF5, 0xFD, 0x05, + 0x01, 0xCE, 0x48, 0x83, 0x06, 0x94, 0xFB, 0x2C, 0x03, 0xE4, 0xFD, + 0x37, 0x01, 0x76, 0xFF, 0x22, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x33, + 0x00, 0x42, 0xFF, 0xD7, 0x01, 0x38, 0xFC, 0x29, 0x07, 0xF3, 0xF1, + 0x3E, 0x29, 0xC6, 0x36, 0xD4, 0xF1, 0x77, 0x06, 0xE6, 0xFC, 0x5C, + 0x01, 0x84, 0xFF, 0x1C, 0x00, 0xFE, 0xFF, 0x12, 0x00, 0xB6, 0xFF, + 0x93, 0x00, 0x3C, 0xFF, 0x9D, 0x00, 0x63, 0x00, 0xEB, 0xFB, 0x69, + 0x47, 0x2D, 0x0D, 0xFF, 0xF8, 0x72, 0x04, 0x42, 0xFD, 0x81, 0x01, + 0x59, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, + 0xFF, 0xE6, 0x01, 0x3A, 0xFC, 0xE2, 0x06, 0x28, 0xF3, 0x9E, 0x21, + 0xC0, 0x3C, 0x1F, 0xF3, 0x6C, 0x05, 0x9E, 0xFD, 0xED, 0x00, 0xBD, + 0xFF, 0x07, 0x00, 0x01, 0x00, 0x0A, 0x00, 0xD7, 0xFF, 0x3E, 0x00, + 0xEA, 0xFF, 0x60, 0xFF, 0x8F, 0x02, 0xCD, 0xF7, 0x99, 0x44, 0x68, + 0x14, 0x8E, 0xF6, 0x90, 0x05, 0xBC, 0xFC, 0xBA, 0x01, 0x43, 0xFF, + 0x32, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x35, 0x00, 0x39, 0xFF, 0xD7, + 0x01, 0x73, 0xFC, 0x3B, 0x06, 0xF5, 0xF4, 0xED, 0x19, 0xB7, 0x41, + 0x71, 0xF5, 0xEB, 0x03, 0x90, 0xFE, 0x60, 0x00, 0x04, 0x00, 0xED, + 0xFF, 0x06, 0x00, 0x04, 0x00, 0xF5, 0xFF, 0xEF, 0xFF, 0x88, 0x00, + 0x49, 0xFE, 0x5D, 0x04, 0xB7, 0xF4, 0x7D, 0x40, 0xFD, 0x1B, 0x6C, + 0xF4, 0x70, 0x06, 0x5F, 0xFC, 0xDE, 0x01, 0x37, 0xFF, 0x36, 0x00, + 0xFE, 0xFF, 0xFF, 0xFF, 0x30, 0x00, 0x48, 0xFF, 0xAD, 0x01, 0xDD, + 0xFC, 0x48, 0x05, 0x30, 0xF7, 0x6B, 0x12, 0x7D, 0x45, 0xCF, 0xF8, + 0x01, 0x02, 0xB2, 0xFF, 0xBD, 0xFF, 0x54, 0x00, 0xCE, 0xFF, 0x0C, + 0x00, 0x00, 0x00, 0x0E, 0x00, 0xAC, 0xFF, 0x0E, 0x01, 0x66, 0xFD, + 0xBF, 0x05, 0xAD, 0xF2, 0x3B, 0x3B, 0xB0, 0x23, 0xC4, 0xF2, 0xFF, + 0x06, 0x33, 0xFC, 0xE5, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFD, 0xFF, + 0x00, 0x00, 0x29, 0x00, 0x60, 0xFF, 0x6E, 0x01, 0x6B, 0xFD, 0x1D, + 0x04, 0xAF, 0xF9, 0x51, 0x0B, 0xEC, 0x47, 0x33, 0xFD, 0xC1, 0xFF, + 0xF7, 0x00, 0x0C, 0xFF, 0xAA, 0x00, 0xAD, 0xFF, 0x14, 0x00, 0xFE, + 0xFF, 0x21, 0x00, 0x77, 0xFF, 0x75, 0x01, 0xBF, 0xFC, 0xAB, 0x06, + 0xA6, 0xF1, 0x05, 0x35, 0x40, 0x2B, 0xBF, 0xF1, 0x2A, 0x07, 0x42, + 0xFC, 0xCE, 0x01, 0x48, 0xFF, 0x31, 0x00, 0xFD, 0xFF, 0x00, 0x00, + 0x20, 0x00, 0x7E, 0xFF, 0x21, 0x01, 0x12, 0xFE, 0xD1, 0x02, 0x47, + 0xFC, 0xD7, 0x04, 0xF0, 0x48, 0x8D, 0x02, 0x45, 0xFD, 0x4D, 0x02, + 0x56, 0xFE, 0x01, 0x01, 0x8B, 0xFF, 0x1D, 0x00, 0xFD, 0xFF, 0x2E, + 0x00, 0x52, 0xFF, 0xBC, 0x01, 0x58, 0xFC, 0x1D, 0x07, 0x8E, 0xF1, + 0x11, 0x2E, 0x6B, 0x32, 0x81, 0xF1, 0xE5, 0x06, 0x90, 0xFC, 0x94, + 0x01, 0x67, 0xFF, 0x26, 0x00, 0xFD, 0xFF, 0x17, 0x00, 0xA0, 0xFF, + 0xCC, 0x00, 0xC6, 0xFE, 0x79, 0x01, 0xD2, 0xFE, 0x26, 0xFF, 0x7C, + 0x48, 0xBE, 0x08, 0xAE, 0xFA, 0xA0, 0x03, 0xA9, 0xFD, 0x52, 0x01, + 0x6B, 0xFF, 0x25, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3C, + 0xFF, 0xE0, 0x01, 0x32, 0xFC, 0x1C, 0x07, 0x4B, 0xF2, 0xA0, 0x26, + 0xF2, 0x38, 0x2A, 0xF2, 0x28, 0x06, 0x1F, 0xFD, 0x39, 0x01, 0x96, + 0xFF, 0x16, 0x00, 0xFF, 0xFF, 0x0F, 0x00, 0xC2, 0xFF, 0x75, 0x00, + 0x7A, 0xFF, 0x2B, 0x00, 0x2D, 0x01, 0x61, 0xFA, 0x97, 0x46, 0xA0, + 0x0F, 0x20, 0xF8, 0xDA, 0x04, 0x10, 0xFD, 0x97, 0x01, 0x50, 0xFF, + 0x2E, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE4, + 0x01, 0x48, 0xFC, 0xB2, 0x06, 0xB9, 0xF3, 0xF3, 0x1E, 0x98, 0x3E, + 0xCF, 0xF3, 0xF3, 0x04, 0xEB, 0xFD, 0xBF, 0x00, 0xD4, 0xFF, 0xFF, + 0xFF, 0x03, 0x00, 0x08, 0x00, 0xE2, 0xFF, 0x21, 0x00, 0x23, 0x00, + 0xFA, 0xFE, 0x3A, 0x03, 0x9D, 0xF6, 0x50, 0x43, 0x00, 0x17, 0xC6, + 0xF5, 0xE6, 0x05, 0x97, 0xFC, 0xC9, 0x01, 0x3E, 0xFF, 0x34, 0x00, + 0xFE, 0xFF, 0xFE, 0xFF, 0x34, 0x00, 0x3D, 0xFF, 0xCB, 0x01, 0x93, + 0xFC, 0xEF, 0x05, 0xB0, 0xF5, 0x4B, 0x17, 0x2A, 0x43, 0x7D, 0xF6, + 0x4D, 0x03, 0xEF, 0xFE, 0x2A, 0x00, 0x1E, 0x00, 0xE3, 0xFF, 0x08, + 0x00, 0x03, 0x00, 0xFE, 0xFF, 0xD7, 0xFF, 0xBA, 0x00, 0xF4, 0xFD, + 0xE5, 0x04, 0xE4, 0xF3, 0xCA, 0x3E, 0xA7, 0x1E, 0xCA, 0xF3, 0xAC, + 0x06, 0x4A, 0xFC, 0xE4, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, + 0xFF, 0xFF, 0x2E, 0x00, 0x4F, 0xFF, 0x99, 0x01, 0x0B, 0xFD, 0xE6, + 0x04, 0x08, 0xF8, 0xE7, 0x0F, 0x7C, 0x46, 0x37, 0xFA, 0x42, 0x01, + 0x1F, 0x00, 0x81, 0xFF, 0x71, 0x00, 0xC3, 0xFF, 0x0F, 0x00, 0xFF, + 0xFF, 0x15, 0x00, 0x98, 0xFF, 0x35, 0x01, 0x25, 0xFD, 0x1E, 0x06, + 0x35, 0xF2, 0x2E, 0x39, 0x55, 0x26, 0x56, 0xF2, 0x1A, 0x07, 0x31, + 0xFC, 0xE1, 0x01, 0x3C, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x00, 0x00, + 0x26, 0x00, 0x6A, 0xFF, 0x55, 0x01, 0xA3, 0xFD, 0xAD, 0x03, 0x94, + 0xFA, 0xFF, 0x08, 0x70, 0x48, 0xF3, 0xFE, 0xEA, 0xFE, 0x6C, 0x01, + 0xCD, 0xFE, 0xC9, 0x00, 0xA1, 0xFF, 0x17, 0x00, 0xFD, 0xFF, 0x26, + 0x00, 0x69, 0xFF, 0x91, 0x01, 0x94, 0xFC, 0xE0, 0x06, 0x84, 0xF1, + 0xAF, 0x32, 0xCA, 0x2D, 0x92, 0xF1, 0x1F, 0x07, 0x56, 0xFC, 0xBE, + 0x01, 0x51, 0xFF, 0x2E, 0x00, 0xFD, 0xFF, 0x1D, 0x00, 0x8A, 0xFF, + 0x04, 0x01, 0x50, 0xFE, 0x5A, 0x02, 0x2C, 0xFD, 0xC6, 0x02, 0xF2, + 0x48, 0x9B, 0x04, 0x61, 0xFC, 0xC3, 0x02, 0x19, 0xFE, 0x1E, 0x01, + 0x7F, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x31, 0x00, 0x49, + 0xFF, 0xCC, 0x01, 0x44, 0xFC, 0x29, 0x07, 0xB9, 0xF1, 0x89, 0x2B, + 0xC3, 0x34, 0xA0, 0xF1, 0xB1, 0x06, 0xBA, 0xFC, 0x79, 0x01, 0x76, + 0xFF, 0x21, 0x00, 0xFE, 0xFF, 0x14, 0x00, 0xAC, 0xFF, 0xAE, 0x00, + 0x05, 0xFF, 0x03, 0x01, 0xAA, 0xFF, 0x63, 0xFD, 0xFD, 0x47, 0x0E, + 0x0B, 0xC8, 0xF9, 0x11, 0x04, 0x71, 0xFD, 0x6C, 0x01, 0x61, 0xFF, + 0x28, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x39, 0xFF, 0xE5, + 0x01, 0x33, 0xFC, 0x03, 0x07, 0xB7, 0xF2, 0xFC, 0x23, 0x03, 0x3B, + 0x9E, 0xF2, 0xCB, 0x05, 0x5F, 0xFD, 0x12, 0x01, 0xAA, 0xFF, 0x0E, + 0x00, 0x00, 0x00, 0x0C, 0x00, 0xCD, 0xFF, 0x57, 0x00, 0xB6, 0xFF, + 0xBE, 0xFF, 0xED, 0x01, 0xF5, 0xF8, 0x9B, 0x45, 0x22, 0x12, 0x48, + 0xF7, 0x3D, 0x05, 0xE2, 0xFC, 0xAB, 0x01, 0x49, 0xFF, 0x30, 0x00, + 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xDF, 0x01, 0x5C, + 0xFC, 0x78, 0x06, 0x5A, 0xF4, 0x49, 0x1C, 0x4E, 0x40, 0x9E, 0xF4, + 0x6D, 0x04, 0x3F, 0xFE, 0x8E, 0x00, 0xED, 0xFF, 0xF6, 0xFF, 0x04, + 0x00, 0x06, 0x00, 0xEC, 0xFF, 0x06, 0x00, 0x5A, 0x00, 0x9A, 0xFE, + 0xDA, 0x03, 0x8D, 0xF5, 0xE1, 0x41, 0xA1, 0x19, 0x09, 0xF5, 0x33, + 0x06, 0x77, 0xFC, 0xD6, 0x01, 0x3A, 0xFF, 0x35, 0x00, 0xFE, 0xFF, + 0xFF, 0xFF, 0x32, 0x00, 0x42, 0xFF, 0xBC, 0x01, 0xB8, 0xFC, 0x9A, + 0x05, 0x77, 0xF6, 0xB1, 0x14, 0x77, 0x44, 0xA9, 0xF7, 0xA2, 0x02, + 0x54, 0xFF, 0xF1, 0xFF, 0x3A, 0x00, 0xD8, 0xFF, 0x0A, 0x00, 0x01, + 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xE8, 0x00, 0xA6, 0xFD, 0x5F, 0x05, + 0x31, 0xF3, 0xF6, 0x3C, 0x52, 0x21, 0x37, 0xF3, 0xDD, 0x06, 0x3B, + 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, + 0x2B, 0x00, 0x58, 0xFF, 0x83, 0x01, 0x3C, 0xFD, 0x7E, 0x04, 0xE6, + 0xF8, 0x72, 0x0D, 0x52, 0x47, 0xBE, 0xFB, 0x7A, 0x00, 0x90, 0x00, + 0x43, 0xFF, 0x8F, 0x00, 0xB7, 0xFF, 0x11, 0x00, 0xFE, 0xFF, 0x1C, + 0x00, 0x86, 0xFF, 0x59, 0x01, 0xEC, 0xFC, 0x6F, 0x06, 0xDC, 0xF1, + 0x04, 0x37, 0xF3, 0x28, 0xFC, 0xF1, 0x28, 0x07, 0x37, 0xFC, 0xD8, + 0x01, 0x41, 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x23, 0x00, + 0x74, 0xFF, 0x3A, 0x01, 0xDD, 0xFD, 0x39, 0x03, 0x7B, 0xFB, 0xC1, + 0x06, 0xC7, 0x48, 0xCF, 0x00, 0x0D, 0xFE, 0xE3, 0x01, 0x8E, 0xFE, + 0xE7, 0x00, 0x95, 0xFF, 0x1A, 0x00, 0xFD, 0xFF, 0x2A, 0x00, 0x5C, + 0xFF, 0xAA, 0x01, 0x71, 0xFC, 0x07, 0x07, 0x7E, 0xF1, 0x44, 0x30, + 0x44, 0x30, 0x7E, 0xF1, 0x07, 0x07, 0x71, 0xFC, 0xAA, 0x01, 0x5C, + 0xFF, 0x2A, 0x00, 0xFD, 0xFF, 0x1A, 0x00, 0x95, 0xFF, 0xE7, 0x00, + 0x8E, 0xFE, 0xE3, 0x01, 0x0D, 0xFE, 0xCF, 0x00, 0xC7, 0x48, 0xC1, + 0x06, 0x7B, 0xFB, 0x39, 0x03, 0xDD, 0xFD, 0x3A, 0x01, 0x74, 0xFF, + 0x23, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x41, 0xFF, 0xD8, + 0x01, 0x37, 0xFC, 0x28, 0x07, 0xFC, 0xF1, 0xF3, 0x28, 0x04, 0x37, + 0xDC, 0xF1, 0x6F, 0x06, 0xEC, 0xFC, 0x59, 0x01, 0x86, 0xFF, 0x1C, + 0x00, 0xFE, 0xFF, 0x11, 0x00, 0xB7, 0xFF, 0x8F, 0x00, 0x43, 0xFF, + 0x90, 0x00, 0x7A, 0x00, 0xBE, 0xFB, 0x52, 0x47, 0x72, 0x0D, 0xE6, + 0xF8, 0x7E, 0x04, 0x3C, 0xFD, 0x83, 0x01, 0x58, 0xFF, 0x2B, 0x00, + 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3B, + 0xFC, 0xDD, 0x06, 0x37, 0xF3, 0x52, 0x21, 0xF6, 0x3C, 0x31, 0xF3, + 0x5F, 0x05, 0xA6, 0xFD, 0xE8, 0x00, 0xC0, 0xFF, 0x07, 0x00, 0x01, + 0x00, 0x0A, 0x00, 0xD8, 0xFF, 0x3A, 0x00, 0xF1, 0xFF, 0x54, 0xFF, + 0xA2, 0x02, 0xA9, 0xF7, 0x77, 0x44, 0xB1, 0x14, 0x77, 0xF6, 0x9A, + 0x05, 0xB8, 0xFC, 0xBC, 0x01, 0x42, 0xFF, 0x32, 0x00, 0xFF, 0xFF, + 0xFE, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD6, 0x01, 0x77, 0xFC, 0x33, + 0x06, 0x09, 0xF5, 0xA1, 0x19, 0xE1, 0x41, 0x8D, 0xF5, 0xDA, 0x03, + 0x9A, 0xFE, 0x5A, 0x00, 0x06, 0x00, 0xEC, 0xFF, 0x06, 0x00, 0x04, + 0x00, 0xF6, 0xFF, 0xED, 0xFF, 0x8E, 0x00, 0x3F, 0xFE, 0x6D, 0x04, + 0x9E, 0xF4, 0x4E, 0x40, 0x49, 0x1C, 0x5A, 0xF4, 0x78, 0x06, 0x5C, + 0xFC, 0xDF, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, + 0x30, 0x00, 0x49, 0xFF, 0xAB, 0x01, 0xE2, 0xFC, 0x3D, 0x05, 0x48, + 0xF7, 0x22, 0x12, 0x9B, 0x45, 0xF5, 0xF8, 0xED, 0x01, 0xBE, 0xFF, + 0xB6, 0xFF, 0x57, 0x00, 0xCD, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x0E, + 0x00, 0xAA, 0xFF, 0x12, 0x01, 0x5F, 0xFD, 0xCB, 0x05, 0x9E, 0xF2, + 0x03, 0x3B, 0xFC, 0x23, 0xB7, 0xF2, 0x03, 0x07, 0x33, 0xFC, 0xE5, + 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x28, 0x00, + 0x61, 0xFF, 0x6C, 0x01, 0x71, 0xFD, 0x11, 0x04, 0xC8, 0xF9, 0x0E, + 0x0B, 0xFD, 0x47, 0x63, 0xFD, 0xAA, 0xFF, 0x03, 0x01, 0x05, 0xFF, + 0xAE, 0x00, 0xAC, 0xFF, 0x14, 0x00, 0xFE, 0xFF, 0x21, 0x00, 0x76, + 0xFF, 0x79, 0x01, 0xBA, 0xFC, 0xB1, 0x06, 0xA0, 0xF1, 0xC3, 0x34, + 0x89, 0x2B, 0xB9, 0xF1, 0x29, 0x07, 0x44, 0xFC, 0xCC, 0x01, 0x49, + 0xFF, 0x31, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x20, 0x00, 0x7F, 0xFF, + 0x1E, 0x01, 0x19, 0xFE, 0xC3, 0x02, 0x61, 0xFC, 0x9B, 0x04, 0xF2, + 0x48, 0xC6, 0x02, 0x2C, 0xFD, 0x5A, 0x02, 0x50, 0xFE, 0x04, 0x01, + 0x8A, 0xFF, 0x1D, 0x00, 0xFD, 0xFF, 0x2E, 0x00, 0x51, 0xFF, 0xBE, + 0x01, 0x56, 0xFC, 0x1F, 0x07, 0x92, 0xF1, 0xCA, 0x2D, 0xAF, 0x32, + 0x84, 0xF1, 0xE0, 0x06, 0x94, 0xFC, 0x91, 0x01, 0x69, 0xFF, 0x26, + 0x00, 0xFD, 0xFF, 0x17, 0x00, 0xA1, 0xFF, 0xC9, 0x00, 0xCD, 0xFE, + 0x6C, 0x01, 0xEA, 0xFE, 0xF3, 0xFE, 0x70, 0x48, 0xFF, 0x08, 0x94, + 0xFA, 0xAD, 0x03, 0xA3, 0xFD, 0x55, 0x01, 0x6A, 0xFF, 0x26, 0x00, + 0x00, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3C, 0xFF, 0xE1, 0x01, 0x31, + 0xFC, 0x1A, 0x07, 0x56, 0xF2, 0x55, 0x26, 0x2E, 0x39, 0x35, 0xF2, + 0x1E, 0x06, 0x25, 0xFD, 0x35, 0x01, 0x98, 0xFF, 0x15, 0x00, 0xFF, + 0xFF, 0x0F, 0x00, 0xC3, 0xFF, 0x71, 0x00, 0x81, 0xFF, 0x1F, 0x00, + 0x42, 0x01, 0x37, 0xFA, 0x7C, 0x46, 0xE7, 0x0F, 0x08, 0xF8, 0xE6, + 0x04, 0x0B, 0xFD, 0x99, 0x01, 0x4F, 0xFF, 0x2E, 0x00, 0xFF, 0xFF, + 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE4, 0x01, 0x4A, 0xFC, 0xAC, + 0x06, 0xCA, 0xF3, 0xA7, 0x1E, 0xCA, 0x3E, 0xE4, 0xF3, 0xE5, 0x04, + 0xF4, 0xFD, 0xBA, 0x00, 0xD7, 0xFF, 0xFE, 0xFF, 0x03, 0x00, 0x08, + 0x00, 0xE3, 0xFF, 0x1E, 0x00, 0x2A, 0x00, 0xEF, 0xFE, 0x4D, 0x03, + 0x7D, 0xF6, 0x2A, 0x43, 0x4B, 0x17, 0xB0, 0xF5, 0xEF, 0x05, 0x93, + 0xFC, 0xCB, 0x01, 0x3D, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0xFE, 0xFF, + 0x34, 0x00, 0x3E, 0xFF, 0xC9, 0x01, 0x97, 0xFC, 0xE6, 0x05, 0xC6, + 0xF5, 0x00, 0x17, 0x50, 0x43, 0x9D, 0xF6, 0x3A, 0x03, 0xFA, 0xFE, + 0x23, 0x00, 0x21, 0x00, 0xE2, 0xFF, 0x08, 0x00, 0x03, 0x00, 0xFF, + 0xFF, 0xD4, 0xFF, 0xBF, 0x00, 0xEB, 0xFD, 0xF3, 0x04, 0xCF, 0xF3, + 0x98, 0x3E, 0xF3, 0x1E, 0xB9, 0xF3, 0xB2, 0x06, 0x48, 0xFC, 0xE4, + 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x2E, 0x00, + 0x50, 0xFF, 0x97, 0x01, 0x10, 0xFD, 0xDA, 0x04, 0x20, 0xF8, 0xA0, + 0x0F, 0x97, 0x46, 0x61, 0xFA, 0x2D, 0x01, 0x2B, 0x00, 0x7A, 0xFF, + 0x75, 0x00, 0xC2, 0xFF, 0x0F, 0x00, 0xFF, 0xFF, 0x16, 0x00, 0x96, + 0xFF, 0x39, 0x01, 0x1F, 0xFD, 0x28, 0x06, 0x2A, 0xF2, 0xF2, 0x38, + 0xA0, 0x26, 0x4B, 0xF2, 0x1C, 0x07, 0x32, 0xFC, 0xE0, 0x01, 0x3C, + 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x25, 0x00, 0x6B, 0xFF, + 0x52, 0x01, 0xA9, 0xFD, 0xA0, 0x03, 0xAE, 0xFA, 0xBE, 0x08, 0x7C, + 0x48, 0x26, 0xFF, 0xD2, 0xFE, 0x79, 0x01, 0xC6, 0xFE, 0xCC, 0x00, + 0xA0, 0xFF, 0x17, 0x00, 0xFD, 0xFF, 0x26, 0x00, 0x67, 0xFF, 0x94, + 0x01, 0x90, 0xFC, 0xE5, 0x06, 0x81, 0xF1, 0x6B, 0x32, 0x11, 0x2E, + 0x8E, 0xF1, 0x1D, 0x07, 0x58, 0xFC, 0xBC, 0x01, 0x52, 0xFF, 0x2E, + 0x00, 0xFD, 0xFF, 0x1D, 0x00, 0x8B, 0xFF, 0x01, 0x01, 0x56, 0xFE, + 0x4D, 0x02, 0x45, 0xFD, 0x8D, 0x02, 0xF0, 0x48, 0xD7, 0x04, 0x47, + 0xFC, 0xD1, 0x02, 0x12, 0xFE, 0x21, 0x01, 0x7E, 0xFF, 0x20, 0x00, + 0x00, 0x00, 0xFD, 0xFF, 0x31, 0x00, 0x48, 0xFF, 0xCE, 0x01, 0x42, + 0xFC, 0x2A, 0x07, 0xBF, 0xF1, 0x40, 0x2B, 0x05, 0x35, 0xA6, 0xF1, + 0xAB, 0x06, 0xBF, 0xFC, 0x75, 0x01, 0x77, 0xFF, 0x21, 0x00, 0xFE, + 0xFF, 0x14, 0x00, 0xAD, 0xFF, 0xAA, 0x00, 0x0C, 0xFF, 0xF7, 0x00, + 0xC1, 0xFF, 0x33, 0xFD, 0xEC, 0x47, 0x51, 0x0B, 0xAF, 0xF9, 0x1D, + 0x04, 0x6B, 0xFD, 0x6E, 0x01, 0x60, 0xFF, 0x29, 0x00, 0x00, 0x00, + 0xFD, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE5, 0x01, 0x33, 0xFC, 0xFF, + 0x06, 0xC4, 0xF2, 0xB0, 0x23, 0x3B, 0x3B, 0xAD, 0xF2, 0xBF, 0x05, + 0x66, 0xFD, 0x0E, 0x01, 0xAC, 0xFF, 0x0E, 0x00, 0x00, 0x00, 0x0C, + 0x00, 0xCE, 0xFF, 0x54, 0x00, 0xBD, 0xFF, 0xB2, 0xFF, 0x01, 0x02, + 0xCF, 0xF8, 0x7D, 0x45, 0x6B, 0x12, 0x30, 0xF7, 0x48, 0x05, 0xDD, + 0xFC, 0xAD, 0x01, 0x48, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, + 0x36, 0x00, 0x37, 0xFF, 0xDE, 0x01, 0x5F, 0xFC, 0x70, 0x06, 0x6C, + 0xF4, 0xFD, 0x1B, 0x7D, 0x40, 0xB7, 0xF4, 0x5D, 0x04, 0x49, 0xFE, + 0x88, 0x00, 0xEF, 0xFF, 0xF5, 0xFF, 0x04, 0x00, 0x06, 0x00, 0xED, + 0xFF, 0x04, 0x00, 0x60, 0x00, 0x90, 0xFE, 0xEB, 0x03, 0x71, 0xF5, + 0xB7, 0x41, 0xED, 0x19, 0xF5, 0xF4, 0x3B, 0x06, 0x73, 0xFC, 0xD7, + 0x01, 0x39, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x32, 0x00, + 0x43, 0xFF, 0xBA, 0x01, 0xBC, 0xFC, 0x90, 0x05, 0x8E, 0xF6, 0x68, + 0x14, 0x99, 0x44, 0xCD, 0xF7, 0x8F, 0x02, 0x60, 0xFF, 0xEA, 0xFF, + 0x3E, 0x00, 0xD7, 0xFF, 0x0A, 0x00, 0x01, 0x00, 0x07, 0x00, 0xBD, + 0xFF, 0xED, 0x00, 0x9E, 0xFD, 0x6C, 0x05, 0x1F, 0xF3, 0xC0, 0x3C, + 0x9E, 0x21, 0x28, 0xF3, 0xE2, 0x06, 0x3A, 0xFC, 0xE6, 0x01, 0x37, + 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x2B, 0x00, 0x59, 0xFF, + 0x81, 0x01, 0x42, 0xFD, 0x72, 0x04, 0xFF, 0xF8, 0x2D, 0x0D, 0x69, + 0x47, 0xEB, 0xFB, 0x63, 0x00, 0x9D, 0x00, 0x3C, 0xFF, 0x93, 0x00, + 0xB6, 0xFF, 0x12, 0x00, 0xFE, 0xFF, 0x1C, 0x00, 0x84, 0xFF, 0x5C, + 0x01, 0xE6, 0xFC, 0x77, 0x06, 0xD4, 0xF1, 0xC6, 0x36, 0x3E, 0x29, + 0xF3, 0xF1, 0x29, 0x07, 0x38, 0xFC, 0xD7, 0x01, 0x42, 0xFF, 0x33, + 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x22, 0x00, 0x76, 0xFF, 0x37, 0x01, + 0xE4, 0xFD, 0x2C, 0x03, 0x94, 0xFB, 0x83, 0x06, 0xCE, 0x48, 0x05, + 0x01, 0xF5, 0xFD, 0xF0, 0x01, 0x87, 0xFE, 0xEA, 0x00, 0x94, 0xFF, + 0x1A, 0x00, 0xFD, 0xFF, 0x2B, 0x00, 0x5A, 0xFF, 0xAC, 0x01, 0x6E, + 0xFC, 0x0A, 0x07, 0x7E, 0xF1, 0xFF, 0x2F, 0x8A, 0x30, 0x7D, 0xF1, + 0x03, 0x07, 0x75, 0xFC, 0xA7, 0x01, 0x5D, 0xFF, 0x2A, 0x00, 0xFD, + 0xFF, 0x1A, 0x00, 0x96, 0xFF, 0xE3, 0x00, 0x95, 0xFE, 0xD5, 0x01, + 0x26, 0xFE, 0x98, 0x00, 0xBF, 0x48, 0x00, 0x07, 0x61, 0xFB, 0x46, + 0x03, 0xD6, 0xFD, 0x3D, 0x01, 0x73, 0xFF, 0x23, 0x00, 0x00, 0x00, + 0xFD, 0xFF, 0x33, 0x00, 0x41, 0xFF, 0xDA, 0x01, 0x36, 0xFC, 0x27, + 0x07, 0x05, 0xF2, 0xAA, 0x28, 0x44, 0x37, 0xE4, 0xF1, 0x67, 0x06, + 0xF2, 0xFC, 0x55, 0x01, 0x88, 0xFF, 0x1B, 0x00, 0xFE, 0xFF, 0x11, + 0x00, 0xB9, 0xFF, 0x8C, 0x00, 0x4A, 0xFF, 0x83, 0x00, 0x91, 0x00, + 0x91, 0xFB, 0x3D, 0x47, 0xB7, 0x0D, 0xCD, 0xF8, 0x89, 0x04, 0x36, + 0xFD, 0x86, 0x01, 0x57, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0xFD, 0xFF, + 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3C, 0xFC, 0xD8, 0x06, 0x47, + 0xF3, 0x06, 0x21, 0x2A, 0x3D, 0x44, 0xF3, 0x52, 0x05, 0xAE, 0xFD, + 0xE3, 0x00, 0xC2, 0xFF, 0x06, 0x00, 0x01, 0x00, 0x0A, 0x00, 0xD9, + 0xFF, 0x37, 0x00, 0xF7, 0xFF, 0x49, 0xFF, 0xB6, 0x02, 0x86, 0xF7, + 0x53, 0x44, 0xFB, 0x14, 0x61, 0xF6, 0xA4, 0x05, 0xB4, 0xFC, 0xBE, + 0x01, 0x42, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x35, 0x00, + 0x3A, 0xFF, 0xD4, 0x01, 0x7A, 0xFC, 0x2B, 0x06, 0x1E, 0xF5, 0x56, + 0x19, 0x0C, 0x42, 0xAA, 0xF5, 0xC9, 0x03, 0xA4, 0xFE, 0x54, 0x00, + 0x09, 0x00, 0xEB, 0xFF, 0x06, 0x00, 0x04, 0x00, 0xF7, 0xFF, 0xEA, + 0xFF, 0x93, 0x00, 0x36, 0xFE, 0x7D, 0x04, 0x85, 0xF4, 0x1F, 0x40, + 0x94, 0x1C, 0x47, 0xF4, 0x7E, 0x06, 0x5A, 0xFC, 0xDF, 0x01, 0x37, + 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x30, 0x00, 0x4A, 0xFF, + 0xA9, 0x01, 0xE7, 0xFC, 0x33, 0x05, 0x60, 0xF7, 0xDA, 0x11, 0xB8, + 0x45, 0x1C, 0xF9, 0xD8, 0x01, 0xCA, 0xFF, 0xAF, 0xFF, 0x5A, 0x00, + 0xCC, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x0F, 0x00, 0xA8, 0xFF, 0x17, + 0x01, 0x57, 0xFD, 0xD6, 0x05, 0x90, 0xF2, 0xC8, 0x3A, 0x46, 0x24, + 0xAA, 0xF2, 0x06, 0x07, 0x32, 0xFC, 0xE5, 0x01, 0x39, 0xFF, 0x36, + 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x28, 0x00, 0x62, 0xFF, 0x69, 0x01, + 0x77, 0xFD, 0x04, 0x04, 0xE2, 0xF9, 0xCB, 0x0A, 0x0D, 0x48, 0x94, + 0xFD, 0x92, 0xFF, 0x10, 0x01, 0xFE, 0xFE, 0xB1, 0x00, 0xAA, 0xFF, + 0x15, 0x00, 0xFE, 0xFF, 0x22, 0x00, 0x74, 0xFF, 0x7C, 0x01, 0xB5, + 0xFC, 0xB8, 0x06, 0x9C, 0xF1, 0x81, 0x34, 0xD1, 0x2B, 0xB3, 0xF1, + 0x29, 0x07, 0x46, 0xFC, 0xCA, 0x01, 0x4A, 0xFF, 0x30, 0x00, 0xFD, + 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x81, 0xFF, 0x1B, 0x01, 0x20, 0xFE, + 0xB6, 0x02, 0x7A, 0xFC, 0x5F, 0x04, 0xF4, 0x48, 0xFF, 0x02, 0x13, + 0xFD, 0x67, 0x02, 0x49, 0xFE, 0x07, 0x01, 0x88, 0xFF, 0x1D, 0x00, + 0xFD, 0xFF, 0x2E, 0x00, 0x50, 0xFF, 0xC0, 0x01, 0x53, 0xFC, 0x21, + 0x07, 0x96, 0xF1, 0x82, 0x2D, 0xF2, 0x32, 0x86, 0xF1, 0xDB, 0x06, + 0x99, 0xFC, 0x8E, 0x01, 0x6A, 0xFF, 0x25, 0x00, 0xFD, 0xFF, 0x16, + 0x00, 0xA2, 0xFF, 0xC5, 0x00, 0xD4, 0xFE, 0x5F, 0x01, 0x03, 0xFF, + 0xBF, 0xFE, 0x63, 0x48, 0x40, 0x09, 0x7B, 0xFA, 0xB9, 0x03, 0x9D, + 0xFD, 0x58, 0x01, 0x69, 0xFF, 0x26, 0x00, 0x00, 0x00, 0xFD, 0xFF, + 0x35, 0x00, 0x3B, 0xFF, 0xE2, 0x01, 0x31, 0xFC, 0x17, 0x07, 0x61, + 0xF2, 0x0A, 0x26, 0x6A, 0x39, 0x41, 0xF2, 0x15, 0x06, 0x2C, 0xFD, + 0x31, 0x01, 0x9B, 0xFF, 0x14, 0x00, 0xFF, 0xFF, 0x0E, 0x00, 0xC4, + 0xFF, 0x6E, 0x00, 0x87, 0xFF, 0x13, 0x00, 0x58, 0x01, 0x0D, 0xFA, + 0x61, 0x46, 0x2D, 0x10, 0xF0, 0xF7, 0xF1, 0x04, 0x05, 0xFD, 0x9C, + 0x01, 0x4E, 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, + 0x36, 0xFF, 0xE3, 0x01, 0x4C, 0xFC, 0xA6, 0x06, 0xDB, 0xF3, 0x5B, + 0x1E, 0xFC, 0x3E, 0xFA, 0xF3, 0xD7, 0x04, 0xFD, 0xFD, 0xB4, 0x00, + 0xD9, 0xFF, 0xFD, 0xFF, 0x03, 0x00, 0x08, 0x00, 0xE4, 0xFF, 0x1B, + 0x00, 0x30, 0x00, 0xE4, 0xFE, 0x5F, 0x03, 0x5E, 0xF6, 0x02, 0x43, + 0x96, 0x17, 0x9B, 0xF5, 0xF8, 0x05, 0x8F, 0xFC, 0xCC, 0x01, 0x3D, + 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x33, 0x00, 0x3E, 0xFF, + 0xC8, 0x01, 0x9B, 0xFC, 0xDD, 0x05, 0xDC, 0xF5, 0xB6, 0x16, 0x77, + 0x43, 0xBD, 0xF6, 0x28, 0x03, 0x05, 0xFF, 0x1D, 0x00, 0x25, 0x00, + 0xE1, 0xFF, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0xD2, 0xFF, 0xC4, + 0x00, 0xE2, 0xFD, 0x01, 0x05, 0xBA, 0xF3, 0x64, 0x3E, 0x3F, 0x1F, + 0xA8, 0xF3, 0xB8, 0x06, 0x46, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36, + 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0x2D, 0x00, 0x51, 0xFF, 0x95, 0x01, + 0x15, 0xFD, 0xCF, 0x04, 0x39, 0xF8, 0x59, 0x0F, 0xAF, 0x46, 0x8B, + 0xFA, 0x17, 0x01, 0x38, 0x00, 0x73, 0xFF, 0x78, 0x00, 0xC0, 0xFF, + 0x0F, 0x00, 0xFF, 0xFF, 0x16, 0x00, 0x94, 0xFF, 0x3D, 0x01, 0x18, + 0xFD, 0x32, 0x06, 0x1F, 0xF2, 0xB5, 0x38, 0xEB, 0x26, 0x40, 0xF2, + 0x1E, 0x07, 0x32, 0xFC, 0xDF, 0x01, 0x3D, 0xFF, 0x35, 0x00, 0xFD, + 0xFF, 0x00, 0x00, 0x25, 0x00, 0x6C, 0xFF, 0x4F, 0x01, 0xB0, 0xFD, + 0x93, 0x03, 0xC7, 0xFA, 0x7D, 0x08, 0x86, 0x48, 0x5A, 0xFF, 0xBA, + 0xFE, 0x86, 0x01, 0xBF, 0xFE, 0xCF, 0x00, 0x9E, 0xFF, 0x17, 0x00, + 0xFD, 0xFF, 0x27, 0x00, 0x66, 0xFF, 0x97, 0x01, 0x8C, 0xFC, 0xEA, + 0x06, 0x80, 0xF1, 0x26, 0x32, 0x58, 0x2E, 0x8B, 0xF1, 0x1B, 0x07, + 0x5B, 0xFC, 0xBA, 0x01, 0x53, 0xFF, 0x2D, 0x00, 0xFD, 0xFF, 0x1C, + 0x00, 0x8C, 0xFF, 0xFE, 0x00, 0x5D, 0xFE, 0x3F, 0x02, 0x5E, 0xFD, + 0x54, 0x02, 0xEC, 0x48, 0x13, 0x05, 0x2E, 0xFC, 0xDE, 0x02, 0x0C, + 0xFE, 0x24, 0x01, 0x7D, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xFD, 0xFF, + 0x31, 0x00, 0x47, 0xFF, 0xCF, 0x01, 0x40, 0xFC, 0x2A, 0x07, 0xC6, + 0xF1, 0xF7, 0x2A, 0x46, 0x35, 0xAB, 0xF1, 0xA4, 0x06, 0xC4, 0xFC, + 0x72, 0x01, 0x79, 0xFF, 0x20, 0x00, 0xFE, 0xFF, 0x14, 0x00, 0xAE, + 0xFF, 0xA7, 0x00, 0x12, 0xFF, 0xEA, 0x00, 0xD9, 0xFF, 0x03, 0xFD, + 0xDC, 0x47, 0x95, 0x0B, 0x96, 0xF9, 0x29, 0x04, 0x65, 0xFD, 0x71, + 0x01, 0x5F, 0xFF, 0x29, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, + 0x38, 0xFF, 0xE6, 0x01, 0x34, 0xFC, 0xFB, 0x06, 0xD2, 0xF2, 0x64, + 0x23, 0x73, 0x3B, 0xBC, 0xF2, 0xB4, 0x05, 0x6E, 0xFD, 0x09, 0x01, + 0xAF, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x0C, 0x00, 0xD0, 0xFF, 0x51, + 0x00, 0xC3, 0xFF, 0xA6, 0xFF, 0x16, 0x02, 0xA9, 0xF8, 0x5C, 0x45, + 0xB2, 0x12, 0x19, 0xF7, 0x52, 0x05, 0xD8, 0xFC, 0xAF, 0x01, 0x47, + 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x38, 0xFF, + 0xDD, 0x01, 0x62, 0xFC, 0x69, 0x06, 0x7F, 0xF4, 0xB2, 0x1B, 0xAB, + 0x40, 0xD0, 0xF4, 0x4E, 0x04, 0x53, 0xFE, 0x83, 0x00, 0xF2, 0xFF, + 0xF4, 0xFF, 0x05, 0x00, 0x06, 0x00, 0xEE, 0xFF, 0x01, 0x00, 0x66, + 0x00, 0x85, 0xFE, 0xFC, 0x03, 0x55, 0xF5, 0x8C, 0x41, 0x38, 0x1A, + 0xE1, 0xF4, 0x43, 0x06, 0x70, 0xFC, 0xD8, 0x01, 0x39, 0xFF, 0x35, + 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x32, 0x00, 0x44, 0xFF, 0xB9, 0x01, + 0xC1, 0xFC, 0x86, 0x05, 0xA5, 0xF6, 0x1E, 0x14, 0xBA, 0x44, 0xF0, + 0xF7, 0x7B, 0x02, 0x6B, 0xFF, 0xE4, 0xFF, 0x41, 0x00, 0xD6, 0xFF, + 0x0B, 0x00, 0x01, 0x00, 0x08, 0x00, 0xBB, 0xFF, 0xF1, 0x00, 0x96, + 0xFD, 0x78, 0x05, 0x0E, 0xF3, 0x8A, 0x3C, 0xEA, 0x21, 0x19, 0xF3, + 0xE6, 0x06, 0x38, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, + 0xFF, 0x00, 0x00, 0x2B, 0x00, 0x5A, 0xFF, 0x7E, 0x01, 0x48, 0xFD, + 0x66, 0x04, 0x18, 0xF9, 0xE8, 0x0C, 0x7C, 0x47, 0x19, 0xFC, 0x4D, + 0x00, 0xA9, 0x00, 0x35, 0xFF, 0x96, 0x00, 0xB5, 0xFF, 0x12, 0x00, + 0xFE, 0xFF, 0x1D, 0x00, 0x82, 0xFF, 0x60, 0x01, 0xE0, 0xFC, 0x7F, + 0x06, 0xCC, 0xF1, 0x85, 0x36, 0x87, 0x29, 0xEB, 0xF1, 0x2A, 0x07, + 0x39, 0xFC, 0xD6, 0x01, 0x43, 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0x00, + 0x00, 0x22, 0x00, 0x77, 0xFF, 0x34, 0x01, 0xEA, 0xFD, 0x1F, 0x03, + 0xAE, 0xFB, 0x45, 0x06, 0xD5, 0x48, 0x3C, 0x01, 0xDC, 0xFD, 0xFD, + 0x01, 0x80, 0xFE, 0xED, 0x00, 0x93, 0xFF, 0x1B, 0x00, 0xFD, 0xFF, + 0x2B, 0x00, 0x59, 0xFF, 0xAE, 0x01, 0x6A, 0xFC, 0x0D, 0x07, 0x80, + 0xF1, 0xB8, 0x2F, 0xCF, 0x30, 0x7D, 0xF1, 0xFF, 0x06, 0x78, 0xFC, + 0xA5, 0x01, 0x5F, 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0x19, 0x00, 0x98, + 0xFF, 0xE0, 0x00, 0x9C, 0xFE, 0xC8, 0x01, 0x3F, 0xFE, 0x62, 0x00, + 0xB8, 0x48, 0x3F, 0x07, 0x47, 0xFB, 0x53, 0x03, 0xD0, 0xFD, 0x40, + 0x01, 0x72, 0xFF, 0x23, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x34, 0x00, + 0x40, 0xFF, 0xDB, 0x01, 0x35, 0xFC, 0x26, 0x07, 0x0E, 0xF2, 0x60, + 0x28, 0x82, 0x37, 0xED, 0xF1, 0x5E, 0x06, 0xF8, 0xFC, 0x51, 0x01, + 0x8A, 0xFF, 0x1A, 0x00, 0xFF, 0xFF, 0x11, 0x00, 0xBA, 0xFF, 0x89, + 0x00, 0x51, 0xFF, 0x77, 0x00, 0xA7, 0x00, 0x64, 0xFB, 0x26, 0x47, + 0xFC, 0x0D, 0xB4, 0xF8, 0x95, 0x04, 0x31, 0xFD, 0x88, 0x01, 0x56, + 0xFF, 0x2C, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, + 0xE6, 0x01, 0x3E, 0xFC, 0xD3, 0x06, 0x56, 0xF3, 0xBA, 0x20, 0x61, + 0x3D, 0x56, 0xF3, 0x45, 0x05, 0xB7, 0xFD, 0xDE, 0x00, 0xC5, 0xFF, + 0x05, 0x00, 0x02, 0x00, 0x09, 0x00, 0xDB, 0xFF, 0x34, 0x00, 0xFE, + 0xFF, 0x3D, 0xFF, 0xC9, 0x02, 0x64, 0xF7, 0x2F, 0x44, 0x44, 0x15, + 0x4A, 0xF6, 0xAD, 0x05, 0xAF, 0xFC, 0xC0, 0x01, 0x41, 0xFF, 0x32, + 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD3, 0x01, + 0x7D, 0xFC, 0x23, 0x06, 0x32, 0xF5, 0x0C, 0x19, 0x38, 0x42, 0xC7, + 0xF5, 0xB8, 0x03, 0xAF, 0xFE, 0x4E, 0x00, 0x0C, 0x00, 0xEA, 0xFF, + 0x06, 0x00, 0x04, 0x00, 0xF8, 0xFF, 0xE7, 0xFF, 0x99, 0x00, 0x2C, + 0xFE, 0x8C, 0x04, 0x6D, 0xF4, 0xF0, 0x3F, 0xE0, 0x1C, 0x34, 0xF4, + 0x85, 0x06, 0x57, 0xFC, 0xE0, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, + 0xFF, 0xFF, 0xFF, 0x2F, 0x00, 0x4A, 0xFF, 0xA7, 0x01, 0xEC, 0xFC, + 0x28, 0x05, 0x77, 0xF7, 0x92, 0x11, 0xD7, 0x45, 0x43, 0xF9, 0xC3, + 0x01, 0xD6, 0xFF, 0xA9, 0xFF, 0x5E, 0x00, 0xCB, 0xFF, 0x0D, 0x00, + 0x00, 0x00, 0x10, 0x00, 0xA6, 0xFF, 0x1B, 0x01, 0x50, 0xFD, 0xE1, + 0x05, 0x82, 0xF2, 0x8F, 0x3A, 0x92, 0x24, 0x9D, 0xF2, 0x09, 0x07, + 0x32, 0xFC, 0xE4, 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, + 0x00, 0x28, 0x00, 0x63, 0xFF, 0x66, 0x01, 0x7D, 0xFD, 0xF8, 0x03, + 0xFB, 0xF9, 0x89, 0x0A, 0x1D, 0x48, 0xC5, 0xFD, 0x7A, 0xFF, 0x1D, + 0x01, 0xF7, 0xFE, 0xB4, 0x00, 0xA9, 0xFF, 0x15, 0x00, 0xFE, 0xFF, + 0x23, 0x00, 0x72, 0xFF, 0x7F, 0x01, 0xB0, 0xFC, 0xBE, 0x06, 0x97, + 0xF1, 0x3F, 0x34, 0x19, 0x2C, 0xAD, 0xF1, 0x28, 0x07, 0x48, 0xFC, + 0xC9, 0x01, 0x4B, 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x1F, + 0x00, 0x82, 0xFF, 0x18, 0x01, 0x27, 0xFE, 0xA9, 0x02, 0x94, 0xFC, + 0x24, 0x04, 0xF5, 0x48, 0x39, 0x03, 0xF9, 0xFC, 0x74, 0x02, 0x42, + 0xFE, 0x0B, 0x01, 0x87, 0xFF, 0x1E, 0x00, 0xFD, 0xFF, 0x2F, 0x00, + 0x4F, 0xFF, 0xC2, 0x01, 0x51, 0xFC, 0x23, 0x07, 0x9A, 0xF1, 0x3A, + 0x2D, 0x35, 0x33, 0x89, 0xF1, 0xD5, 0x06, 0x9D, 0xFC, 0x8B, 0x01, + 0x6C, 0xFF, 0x25, 0x00, 0xFD, 0xFF, 0x16, 0x00, 0xA4, 0xFF, 0xC2, + 0x00, 0xDB, 0xFE, 0x52, 0x01, 0x1B, 0xFF, 0x8D, 0xFE, 0x57, 0x48, + 0x81, 0x09, 0x61, 0xFA, 0xC6, 0x03, 0x96, 0xFD, 0x5B, 0x01, 0x68, + 0xFF, 0x26, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3B, 0xFF, + 0xE2, 0x01, 0x31, 0xFC, 0x15, 0x07, 0x6D, 0xF2, 0xBF, 0x25, 0xA5, + 0x39, 0x4D, 0xF2, 0x0B, 0x06, 0x33, 0xFD, 0x2D, 0x01, 0x9D, 0xFF, + 0x13, 0x00, 0xFF, 0xFF, 0x0E, 0x00, 0xC6, 0xFF, 0x6B, 0x00, 0x8E, + 0xFF, 0x06, 0x00, 0x6E, 0x01, 0xE4, 0xF9, 0x48, 0x46, 0x75, 0x10, + 0xD7, 0xF7, 0xFC, 0x04, 0x00, 0xFD, 0x9E, 0x01, 0x4E, 0xFF, 0x2E, + 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE3, 0x01, + 0x4E, 0xFC, 0xA0, 0x06, 0xED, 0xF3, 0x0F, 0x1E, 0x2D, 0x3F, 0x10, + 0xF4, 0xC8, 0x04, 0x07, 0xFE, 0xAF, 0x00, 0xDC, 0xFF, 0xFC, 0xFF, + 0x03, 0x00, 0x07, 0x00, 0xE5, 0xFF, 0x18, 0x00, 0x36, 0x00, 0xD9, + 0xFE, 0x71, 0x03, 0x3F, 0xF6, 0xDB, 0x42, 0xE0, 0x17, 0x86, 0xF5, + 0x00, 0x06, 0x8C, 0xFC, 0xCE, 0x01, 0x3C, 0xFF, 0x34, 0x00, 0xFE, + 0xFF, 0xFF, 0xFF, 0x33, 0x00, 0x3F, 0xFF, 0xC6, 0x01, 0x9F, 0xFC, + 0xD3, 0x05, 0xF1, 0xF5, 0x6C, 0x16, 0x9E, 0x43, 0xDD, 0xF6, 0x15, + 0x03, 0x10, 0xFF, 0x17, 0x00, 0x28, 0x00, 0xDF, 0xFF, 0x09, 0x00, + 0x02, 0x00, 0x01, 0x00, 0xCF, 0xFF, 0xC9, 0x00, 0xDA, 0xFD, 0x0F, + 0x05, 0xA5, 0xF3, 0x31, 0x3E, 0x8A, 0x1F, 0x97, 0xF3, 0xBD, 0x06, + 0x44, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFF, + 0xFF, 0x2D, 0x00, 0x52, 0xFF, 0x92, 0x01, 0x1B, 0xFD, 0xC4, 0x04, + 0x51, 0xF8, 0x13, 0x0F, 0xC8, 0x46, 0xB6, 0xFA, 0x01, 0x01, 0x44, + 0x00, 0x6C, 0xFF, 0x7B, 0x00, 0xBF, 0xFF, 0x10, 0x00, 0xFF, 0xFF, + 0x17, 0x00, 0x92, 0xFF, 0x41, 0x01, 0x11, 0xFD, 0x3B, 0x06, 0x14, + 0xF2, 0x78, 0x38, 0x36, 0x27, 0x35, 0xF2, 0x20, 0x07, 0x33, 0xFC, + 0xDF, 0x01, 0x3E, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x25, + 0x00, 0x6D, 0xFF, 0x4C, 0x01, 0xB6, 0xFD, 0x86, 0x03, 0xE1, 0xFA, + 0x3D, 0x08, 0x92, 0x48, 0x8E, 0xFF, 0xA1, 0xFE, 0x93, 0x01, 0xB8, + 0xFE, 0xD3, 0x00, 0x9D, 0xFF, 0x18, 0x00, 0xFD, 0xFF, 0x28, 0x00, + 0x64, 0xFF, 0x9A, 0x01, 0x88, 0xFC, 0xEE, 0x06, 0x7E, 0xF1, 0xE3, + 0x31, 0x9F, 0x2E, 0x88, 0xF1, 0x19, 0x07, 0x5E, 0xFC, 0xB7, 0x01, + 0x54, 0xFF, 0x2D, 0x00, 0xFD, 0xFF, 0x1C, 0x00, 0x8D, 0xFF, 0xFA, + 0x00, 0x64, 0xFE, 0x32, 0x02, 0x78, 0xFD, 0x1B, 0x02, 0xEA, 0x48, + 0x50, 0x05, 0x14, 0xFC, 0xEB, 0x02, 0x05, 0xFE, 0x27, 0x01, 0x7C, + 0xFF, 0x21, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x46, 0xFF, + 0xD1, 0x01, 0x3F, 0xFC, 0x2B, 0x07, 0xCD, 0xF1, 0xAE, 0x2A, 0x86, + 0x35, 0xB1, 0xF1, 0x9D, 0x06, 0xCA, 0xFC, 0x6E, 0x01, 0x7B, 0xFF, + 0x20, 0x00, 0xFE, 0xFF, 0x13, 0x00, 0xAF, 0xFF, 0xA4, 0x00, 0x19, + 0xFF, 0xDD, 0x00, 0xF0, 0xFF, 0xD4, 0xFC, 0xC9, 0x47, 0xD8, 0x0B, + 0x7C, 0xF9, 0x35, 0x04, 0x5F, 0xFD, 0x74, 0x01, 0x5E, 0xFF, 0x29, + 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE6, 0x01, + 0x35, 0xFC, 0xF7, 0x06, 0xE0, 0xF2, 0x18, 0x23, 0xAB, 0x3B, 0xCC, + 0xF2, 0xA8, 0x05, 0x76, 0xFD, 0x04, 0x01, 0xB1, 0xFF, 0x0C, 0x00, + 0x00, 0x00, 0x0C, 0x00, 0xD1, 0xFF, 0x4E, 0x00, 0xCA, 0xFF, 0x9A, + 0xFF, 0x2A, 0x02, 0x83, 0xF8, 0x3F, 0x45, 0xFB, 0x12, 0x01, 0xF7, + 0x5D, 0x05, 0xD3, 0xFC, 0xB1, 0x01, 0x46, 0xFF, 0x31, 0x00, 0xFF, + 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xDC, 0x01, 0x64, 0xFC, + 0x62, 0x06, 0x93, 0xF4, 0x66, 0x1B, 0xD9, 0x40, 0xEA, 0xF4, 0x3E, + 0x04, 0x5D, 0xFE, 0x7D, 0x00, 0xF5, 0xFF, 0xF3, 0xFF, 0x05, 0x00, + 0x05, 0x00, 0xEF, 0xFF, 0xFE, 0xFF, 0x6C, 0x00, 0x7B, 0xFE, 0x0C, + 0x04, 0x3A, 0xF5, 0x5F, 0x41, 0x83, 0x1A, 0xCD, 0xF4, 0x4B, 0x06, + 0x6D, 0xFC, 0xD9, 0x01, 0x39, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0xFF, + 0xFF, 0x31, 0x00, 0x44, 0xFF, 0xB7, 0x01, 0xC5, 0xFC, 0x7C, 0x05, + 0xBC, 0xF6, 0xD5, 0x13, 0xDC, 0x44, 0x14, 0xF8, 0x67, 0x02, 0x77, + 0xFF, 0xDD, 0xFF, 0x44, 0x00, 0xD5, 0xFF, 0x0B, 0x00, 0x01, 0x00, + 0x09, 0x00, 0xB8, 0xFF, 0xF6, 0x00, 0x8D, 0xFD, 0x84, 0x05, 0xFD, + 0xF2, 0x52, 0x3C, 0x35, 0x22, 0x0B, 0xF3, 0xEB, 0x06, 0x37, 0xFC, + 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x2A, + 0x00, 0x5B, 0xFF, 0x7C, 0x01, 0x4E, 0xFD, 0x5A, 0x04, 0x31, 0xF9, + 0xA4, 0x0C, 0x90, 0x47, 0x47, 0xFC, 0x36, 0x00, 0xB6, 0x00, 0x2E, + 0xFF, 0x99, 0x00, 0xB3, 0xFF, 0x12, 0x00, 0xFE, 0xFF, 0x1E, 0x00, + 0x80, 0xFF, 0x64, 0x01, 0xDA, 0xFC, 0x87, 0x06, 0xC5, 0xF1, 0x46, + 0x36, 0xD1, 0x29, 0xE3, 0xF1, 0x2A, 0x07, 0x3A, 0xFC, 0xD5, 0x01, + 0x44, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x22, 0x00, 0x78, + 0xFF, 0x31, 0x01, 0xF1, 0xFD, 0x12, 0x03, 0xC7, 0xFB, 0x07, 0x06, + 0xDB, 0x48, 0x73, 0x01, 0xC3, 0xFD, 0x0A, 0x02, 0x79, 0xFE, 0xF1, + 0x00, 0x91, 0xFF, 0x1B, 0x00, 0xFD, 0xFF, 0x2C, 0x00, 0x58, 0xFF, + 0xB1, 0x01, 0x67, 0xFC, 0x10, 0x07, 0x81, 0xF1, 0x73, 0x2F, 0x15, + 0x31, 0x7C, 0xF1, 0xFB, 0x06, 0x7C, 0xFC, 0xA2, 0x01, 0x60, 0xFF, + 0x29, 0x00, 0xFD, 0xFF, 0x19, 0x00, 0x99, 0xFF, 0xDD, 0x00, 0xA3, + 0xFE, 0xBB, 0x01, 0x58, 0xFE, 0x2D, 0x00, 0xAF, 0x48, 0x7E, 0x07, + 0x2E, 0xFB, 0x60, 0x03, 0xC9, 0xFD, 0x43, 0x01, 0x71, 0xFF, 0x24, + 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x3F, 0xFF, 0xDC, 0x01, + 0x34, 0xFC, 0x25, 0x07, 0x18, 0xF2, 0x15, 0x28, 0xBF, 0x37, 0xF7, + 0xF1, 0x56, 0x06, 0xFE, 0xFC, 0x4D, 0x01, 0x8C, 0xFF, 0x19, 0x00, + 0xFF, 0xFF, 0x10, 0x00, 0xBB, 0xFF, 0x85, 0x00, 0x58, 0xFF, 0x6A, + 0x00, 0xBE, 0x00, 0x38, 0xFB, 0x0F, 0x47, 0x42, 0x0E, 0x9B, 0xF8, + 0xA1, 0x04, 0x2B, 0xFD, 0x8B, 0x01, 0x55, 0xFF, 0x2C, 0x00, 0xFF, + 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3F, 0xFC, + 0xCE, 0x06, 0x66, 0xF3, 0x6F, 0x20, 0x96, 0x3D, 0x69, 0xF3, 0x38, + 0x05, 0xBF, 0xFD, 0xD9, 0x00, 0xC7, 0xFF, 0x04, 0x00, 0x02, 0x00, + 0x09, 0x00, 0xDC, 0xFF, 0x31, 0x00, 0x04, 0x00, 0x32, 0xFF, 0xDC, + 0x02, 0x42, 0xF7, 0x0B, 0x44, 0x8E, 0x15, 0x34, 0xF6, 0xB7, 0x05, + 0xAB, 0xFC, 0xC1, 0x01, 0x40, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0xFE, + 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xD2, 0x01, 0x81, 0xFC, 0x1A, 0x06, + 0x47, 0xF5, 0xC1, 0x18, 0x60, 0x42, 0xE4, 0xF5, 0xA6, 0x03, 0xB9, + 0xFE, 0x48, 0x00, 0x0F, 0x00, 0xE9, 0xFF, 0x07, 0x00, 0x04, 0x00, + 0xF9, 0xFF, 0xE4, 0xFF, 0x9F, 0x00, 0x23, 0xFE, 0x9B, 0x04, 0x55, + 0xF4, 0xC0, 0x3F, 0x2C, 0x1D, 0x22, 0xF4, 0x8C, 0x06, 0x55, 0xFC, + 0xE1, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x2F, + 0x00, 0x4B, 0xFF, 0xA4, 0x01, 0xF1, 0xFC, 0x1D, 0x05, 0x8F, 0xF7, + 0x4A, 0x11, 0xF2, 0x45, 0x6B, 0xF9, 0xAE, 0x01, 0xE2, 0xFF, 0xA2, + 0xFF, 0x61, 0x00, 0xC9, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x11, 0x00, + 0xA3, 0xFF, 0x20, 0x01, 0x49, 0xFD, 0xEB, 0x05, 0x74, 0xF2, 0x54, + 0x3A, 0xDD, 0x24, 0x91, 0xF2, 0x0C, 0x07, 0x32, 0xFC, 0xE4, 0x01, + 0x3A, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x27, 0x00, 0x64, + 0xFF, 0x63, 0x01, 0x84, 0xFD, 0xEB, 0x03, 0x14, 0xFA, 0x47, 0x0A, + 0x2C, 0x48, 0xF6, 0xFD, 0x63, 0xFF, 0x2B, 0x01, 0xF0, 0xFE, 0xB8, + 0x00, 0xA8, 0xFF, 0x15, 0x00, 0xFE, 0xFF, 0x23, 0x00, 0x71, 0xFF, + 0x82, 0x01, 0xAB, 0xFC, 0xC4, 0x06, 0x93, 0xF1, 0xFD, 0x33, 0x62, + 0x2C, 0xA8, 0xF1, 0x27, 0x07, 0x4A, 0xFC, 0xC7, 0x01, 0x4C, 0xFF, + 0x30, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x83, 0xFF, 0x14, + 0x01, 0x2D, 0xFE, 0x9C, 0x02, 0xAD, 0xFC, 0xE9, 0x03, 0xF6, 0x48, + 0x73, 0x03, 0xE0, 0xFC, 0x82, 0x02, 0x3B, 0xFE, 0x0E, 0x01, 0x86, + 0xFF, 0x1E, 0x00, 0xFD, 0xFF, 0x2F, 0x00, 0x4E, 0xFF, 0xC3, 0x01, + 0x4E, 0xFC, 0x24, 0x07, 0x9E, 0xF1, 0xF2, 0x2C, 0x78, 0x33, 0x8C, + 0xF1, 0xD0, 0x06, 0xA2, 0xFC, 0x88, 0x01, 0x6D, 0xFF, 0x24, 0x00, + 0xFD, 0xFF, 0x16, 0x00, 0xA5, 0xFF, 0xBE, 0x00, 0xE2, 0xFE, 0x45, + 0x01, 0x33, 0xFF, 0x5A, 0xFE, 0x48, 0x48, 0xC3, 0x09, 0x47, 0xFA, + 0xD2, 0x03, 0x90, 0xFD, 0x5E, 0x01, 0x66, 0xFF, 0x27, 0x00, 0x00, + 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xE3, 0x01, 0x31, 0xFC, + 0x12, 0x07, 0x79, 0xF2, 0x73, 0x25, 0xDF, 0x39, 0x5A, 0xF2, 0x00, + 0x06, 0x3A, 0xFD, 0x28, 0x01, 0x9F, 0xFF, 0x13, 0x00, 0x00, 0x00, + 0x0E, 0x00, 0xC7, 0xFF, 0x68, 0x00, 0x95, 0xFF, 0xFA, 0xFF, 0x83, + 0x01, 0xBB, 0xF9, 0x2B, 0x46, 0xBB, 0x10, 0xBF, 0xF7, 0x07, 0x05, + 0xFB, 0xFC, 0xA0, 0x01, 0x4D, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0xFE, + 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE2, 0x01, 0x50, 0xFC, 0x99, 0x06, + 0xFE, 0xF3, 0xC3, 0x1D, 0x5E, 0x3F, 0x27, 0xF4, 0xB9, 0x04, 0x10, + 0xFE, 0xA9, 0x00, 0xDF, 0xFF, 0xFB, 0xFF, 0x03, 0x00, 0x07, 0x00, + 0xE6, 0xFF, 0x15, 0x00, 0x3C, 0x00, 0xCF, 0xFE, 0x83, 0x03, 0x20, + 0xF6, 0xB2, 0x42, 0x2B, 0x18, 0x71, 0xF5, 0x09, 0x06, 0x88, 0xFC, + 0xCF, 0x01, 0x3C, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x33, + 0x00, 0x3F, 0xFF, 0xC5, 0x01, 0xA3, 0xFC, 0xCA, 0x05, 0x07, 0xF6, + 0x22, 0x16, 0xC3, 0x43, 0xFE, 0xF6, 0x02, 0x03, 0x1B, 0xFF, 0x11, + 0x00, 0x2B, 0x00, 0xDE, 0xFF, 0x09, 0x00, 0x02, 0x00, 0x02, 0x00, + 0xCC, 0xFF, 0xCE, 0x00, 0xD1, 0xFD, 0x1D, 0x05, 0x91, 0xF3, 0xFE, + 0x3D, 0xD7, 0x1F, 0x87, 0xF3, 0xC3, 0x06, 0x42, 0xFC, 0xE5, 0x01, + 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0x2D, 0x00, 0x53, + 0xFF, 0x90, 0x01, 0x20, 0xFD, 0xB8, 0x04, 0x6A, 0xF8, 0xCD, 0x0E, + 0xE1, 0x46, 0xE1, 0xFA, 0xEB, 0x00, 0x51, 0x00, 0x65, 0xFF, 0x7F, + 0x00, 0xBE, 0xFF, 0x10, 0x00, 0xFF, 0xFF, 0x18, 0x00, 0x90, 0xFF, + 0x45, 0x01, 0x0B, 0xFD, 0x44, 0x06, 0x0A, 0xF2, 0x3B, 0x38, 0x80, + 0x27, 0x2B, 0xF2, 0x22, 0x07, 0x33, 0xFC, 0xDE, 0x01, 0x3E, 0xFF, + 0x34, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x24, 0x00, 0x6E, 0xFF, 0x49, + 0x01, 0xBC, 0xFD, 0x7A, 0x03, 0xFA, 0xFA, 0xFD, 0x07, 0x9C, 0x48, + 0xC3, 0xFF, 0x89, 0xFE, 0xA1, 0x01, 0xB1, 0xFE, 0xD6, 0x00, 0x9C, + 0xFF, 0x18, 0x00, 0xFD, 0xFF, 0x28, 0x00, 0x63, 0xFF, 0x9D, 0x01, + 0x84, 0xFC, 0xF3, 0x06, 0x7D, 0xF1, 0x9E, 0x31, 0xE6, 0x2E, 0x85, + 0xF1, 0x16, 0x07, 0x61, 0xFC, 0xB5, 0x01, 0x55, 0xFF, 0x2D, 0x00, + 0xFD, 0xFF, 0x1C, 0x00, 0x8F, 0xFF, 0xF7, 0x00, 0x6B, 0xFE, 0x25, + 0x02, 0x91, 0xFD, 0xE3, 0x01, 0xE5, 0x48, 0x8D, 0x05, 0xFB, 0xFB, + 0xF8, 0x02, 0xFE, 0xFD, 0x2B, 0x01, 0x7A, 0xFF, 0x21, 0x00, 0x00, + 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x45, 0xFF, 0xD2, 0x01, 0x3D, 0xFC, + 0x2B, 0x07, 0xD4, 0xF1, 0x64, 0x2A, 0xC6, 0x35, 0xB7, 0xF1, 0x96, + 0x06, 0xCF, 0xFC, 0x6B, 0x01, 0x7D, 0xFF, 0x1F, 0x00, 0xFE, 0xFF, + 0x13, 0x00, 0xB1, 0xFF, 0xA0, 0x00, 0x20, 0xFF, 0xD0, 0x00, 0x07, + 0x00, 0xA4, 0xFC, 0xB6, 0x47, 0x1C, 0x0C, 0x63, 0xF9, 0x42, 0x04, + 0x59, 0xFD, 0x76, 0x01, 0x5D, 0xFF, 0x2A, 0x00, 0x00, 0x00, 0xFD, + 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x35, 0xFC, 0xF3, 0x06, + 0xEE, 0xF2, 0xCD, 0x22, 0xE4, 0x3B, 0xDC, 0xF2, 0x9C, 0x05, 0x7E, + 0xFD, 0x00, 0x01, 0xB4, 0xFF, 0x0B, 0x00, 0x01, 0x00, 0x0B, 0x00, + 0xD2, 0xFF, 0x4A, 0x00, 0xD0, 0xFF, 0x8E, 0xFF, 0x3F, 0x02, 0x5E, + 0xF8, 0x1E, 0x45, 0x44, 0x13, 0xEA, 0xF6, 0x67, 0x05, 0xCF, 0xFC, + 0xB3, 0x01, 0x46, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, + 0x00, 0x38, 0xFF, 0xDB, 0x01, 0x67, 0xFC, 0x5A, 0x06, 0xA6, 0xF4, + 0x1B, 0x1B, 0x07, 0x41, 0x04, 0xF5, 0x2D, 0x04, 0x67, 0xFE, 0x77, + 0x00, 0xF8, 0xFF, 0xF2, 0xFF, 0x05, 0x00, 0x05, 0x00, 0xF0, 0xFF, + 0xFB, 0xFF, 0x71, 0x00, 0x71, 0xFE, 0x1D, 0x04, 0x1F, 0xF5, 0x32, + 0x41, 0xCE, 0x1A, 0xBA, 0xF4, 0x53, 0x06, 0x6A, 0xFC, 0xDA, 0x01, + 0x38, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x31, 0x00, 0x45, + 0xFF, 0xB5, 0x01, 0xCA, 0xFC, 0x72, 0x05, 0xD3, 0xF6, 0x8D, 0x13, + 0xFD, 0x44, 0x39, 0xF8, 0x53, 0x02, 0x82, 0xFF, 0xD7, 0xFF, 0x47, + 0x00, 0xD3, 0xFF, 0x0B, 0x00, 0x01, 0x00, 0x0A, 0x00, 0xB6, 0xFF, + 0xFB, 0x00, 0x85, 0xFD, 0x90, 0x05, 0xEC, 0xF2, 0x1C, 0x3C, 0x81, + 0x22, 0xFC, 0xF2, 0xEF, 0x06, 0x36, 0xFC, 0xE6, 0x01, 0x37, 0xFF, + 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x2A, 0x00, 0x5C, 0xFF, 0x79, + 0x01, 0x53, 0xFD, 0x4E, 0x04, 0x4A, 0xF9, 0x60, 0x0C, 0xA3, 0x47, + 0x76, 0xFC, 0x1F, 0x00, 0xC3, 0x00, 0x27, 0xFF, 0x9D, 0x00, 0xB2, + 0xFF, 0x13, 0x00, 0xFE, 0xFF, 0x1E, 0x00, 0x7F, 0xFF, 0x67, 0x01, + 0xD5, 0xFC, 0x8E, 0x06, 0xBE, 0xF1, 0x06, 0x36, 0x1A, 0x2A, 0xDC, + 0xF1, 0x2A, 0x07, 0x3C, 0xFC, 0xD3, 0x01, 0x44, 0xFF, 0x32, 0x00, + 0xFD, 0xFF, 0x00, 0x00, 0x21, 0x00, 0x79, 0xFF, 0x2E, 0x01, 0xF7, + 0xFD, 0x05, 0x03, 0xE1, 0xFB, 0xCA, 0x05, 0xDF, 0x48, 0xAB, 0x01, + 0xAA, 0xFD, 0x18, 0x02, 0x72, 0xFE, 0xF4, 0x00, 0x90, 0xFF, 0x1B, + 0x00, 0xFD, 0xFF, 0x2C, 0x00, 0x57, 0xFF, 0xB3, 0x01, 0x64, 0xFC, + 0x13, 0x07, 0x83, 0xF1, 0x2C, 0x2F, 0x5A, 0x31, 0x7D, 0xF1, 0xF7, + 0x06, 0x80, 0xFC, 0x9F, 0x01, 0x61, 0xFF, 0x29, 0x00, 0xFD, 0xFF, + 0x19, 0x00, 0x9A, 0xFF, 0xD9, 0x00, 0xAA, 0xFE, 0xAE, 0x01, 0x70, + 0xFE, 0xF8, 0xFF, 0xA6, 0x48, 0xBE, 0x07, 0x14, 0xFB, 0x6D, 0x03, + 0xC3, 0xFD, 0x46, 0x01, 0x70, 0xFF, 0x24, 0x00, 0x00, 0x00, 0xFD, + 0xFF, 0x34, 0x00, 0x3F, 0xFF, 0xDD, 0x01, 0x34, 0xFC, 0x23, 0x07, + 0x21, 0xF2, 0xCB, 0x27, 0xFE, 0x37, 0x00, 0xF2, 0x4D, 0x06, 0x04, + 0xFD, 0x49, 0x01, 0x8E, 0xFF, 0x19, 0x00, 0xFF, 0xFF, 0x10, 0x00, + 0xBD, 0xFF, 0x82, 0x00, 0x5E, 0xFF, 0x5D, 0x00, 0xD4, 0x00, 0x0C, + 0xFB, 0xF9, 0x46, 0x87, 0x0E, 0x82, 0xF8, 0xAD, 0x04, 0x26, 0xFD, + 0x8D, 0x01, 0x54, 0xFF, 0x2C, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36, + 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x41, 0xFC, 0xC8, 0x06, 0x76, 0xF3, + 0x22, 0x20, 0xCA, 0x3D, 0x7D, 0xF3, 0x2A, 0x05, 0xC8, 0xFD, 0xD4, + 0x00, 0xCA, 0xFF, 0x03, 0x00, 0x02, 0x00, 0x09, 0x00, 0xDD, 0xFF, + 0x2E, 0x00, 0x0A, 0x00, 0x27, 0xFF, 0xEF, 0x02, 0x20, 0xF7, 0xE7, + 0x43, 0xD8, 0x15, 0x1E, 0xF6, 0xC0, 0x05, 0xA7, 0xFC, 0xC3, 0x01, + 0x40, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x34, 0x00, 0x3B, + 0xFF, 0xD1, 0x01, 0x84, 0xFC, 0x12, 0x06, 0x5C, 0xF5, 0x76, 0x18, + 0x89, 0x42, 0x02, 0xF6, 0x94, 0x03, 0xC4, 0xFE, 0x42, 0x00, 0x12, + 0x00, 0xE8, 0xFF, 0x07, 0x00, 0x03, 0x00, 0xFA, 0xFF, 0xE2, 0xFF, + 0xA4, 0x00, 0x19, 0xFE, 0xAA, 0x04, 0x3E, 0xF4, 0x90, 0x3F, 0x78, + 0x1D, 0x10, 0xF4, 0x93, 0x06, 0x52, 0xFC, 0xE1, 0x01, 0x36, 0xFF, + 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x2F, 0x00, 0x4C, 0xFF, 0xA2, + 0x01, 0xF6, 0xFC, 0x12, 0x05, 0xA7, 0xF7, 0x03, 0x11, 0x10, 0x46, + 0x93, 0xF9, 0x98, 0x01, 0xEE, 0xFF, 0x9B, 0xFF, 0x64, 0x00, 0xC8, + 0xFF, 0x0E, 0x00, 0x00, 0x00, 0x12, 0x00, 0xA1, 0xFF, 0x24, 0x01, + 0x41, 0xFD, 0xF6, 0x05, 0x67, 0xF2, 0x1A, 0x3A, 0x29, 0x25, 0x84, + 0xF2, 0x0F, 0x07, 0x31, 0xFC, 0xE3, 0x01, 0x3A, 0xFF, 0x35, 0x00, + 0xFD, 0xFF, 0x00, 0x00, 0x27, 0x00, 0x65, 0xFF, 0x60, 0x01, 0x8A, + 0xFD, 0xDF, 0x03, 0x2E, 0xFA, 0x04, 0x0A, 0x3A, 0x48, 0x28, 0xFE, + 0x4B, 0xFF, 0x38, 0x01, 0xE9, 0xFE, 0xBB, 0x00, 0xA6, 0xFF, 0x16, + 0x00, 0xFD, 0xFF, 0x24, 0x00, 0x6F, 0xFF, 0x85, 0x01, 0xA6, 0xFC, + 0xCA, 0x06, 0x8F, 0xF1, 0xBB, 0x33, 0xAB, 0x2C, 0xA3, 0xF1, 0x26, + 0x07, 0x4C, 0xFC, 0xC5, 0x01, 0x4D, 0xFF, 0x30, 0x00, 0xFD, 0xFF, + 0x00, 0x00, 0x1E, 0x00, 0x84, 0xFF, 0x11, 0x01, 0x34, 0xFE, 0x8F, + 0x02, 0xC7, 0xFC, 0xAE, 0x03, 0xF7, 0x48, 0xAE, 0x03, 0xC7, 0xFC, + 0x8F, 0x02, 0x34, 0xFE, 0x11, 0x01, 0x84, 0xFF, 0x1E, 0x00, 0xFD, + 0xFF, 0x2A, 0x00, 0x5C, 0xFF, 0xAA, 0x01, 0x71, 0xFC, 0x07, 0x07, + 0x7E, 0xF1, 0x44, 0x30, 0x44, 0x30, 0x7E, 0xF1, 0x07, 0x07, 0x71, + 0xFC, 0xAA, 0x01, 0x5C, 0xFF, 0x2A, 0x00, 0xFD, 0xFF, 0x00, 0x00, + 0x1E, 0x00, 0x84, 0xFF, 0x11, 0x01, 0x34, 0xFE, 0x8F, 0x02, 0xC7, + 0xFC, 0xAE, 0x03, 0xF7, 0x48, 0xAE, 0x03, 0xC7, 0xFC, 0x8F, 0x02, + 0x34, 0xFE, 0x11, 0x01, 0x84, 0xFF, 0x1E, 0x00, 0x02, 0x00, 0x05, + 0x00, 0xC3, 0xFF, 0xE1, 0x00, 0xB1, 0xFD, 0x4E, 0x05, 0x4A, 0xF3, + 0x3D, 0x3D, 0xED, 0x20, 0x4C, 0xF3, 0xD6, 0x06, 0x3D, 0xFC, 0xE6, + 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x36, 0x00, + 0x36, 0xFF, 0xE6, 0x01, 0x3D, 0xFC, 0xD6, 0x06, 0x4C, 0xF3, 0xED, + 0x20, 0x3D, 0x3D, 0x4A, 0xF3, 0x4E, 0x05, 0xB1, 0xFD, 0xE1, 0x00, + 0xC3, 0xFF, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x84, + 0xFF, 0x11, 0x01, 0x34, 0xFE, 0x8F, 0x02, 0xC7, 0xFC, 0xAE, 0x03, + 0xF7, 0x48, 0xAE, 0x03, 0xC7, 0xFC, 0x8F, 0x02, 0x34, 0xFE, 0x11, + 0x01, 0x84, 0xFF, 0x1E, 0x00, 0x16, 0x00, 0xA6, 0xFF, 0xBB, 0x00, + 0xE9, 0xFE, 0x38, 0x01, 0x4B, 0xFF, 0x28, 0xFE, 0x3A, 0x48, 0x04, + 0x0A, 0x2E, 0xFA, 0xDF, 0x03, 0x8A, 0xFD, 0x60, 0x01, 0x65, 0xFF, + 0x27, 0x00, 0x00, 0x00, 0x0E, 0x00, 0xC8, 0xFF, 0x64, 0x00, 0x9B, + 0xFF, 0xEE, 0xFF, 0x98, 0x01, 0x93, 0xF9, 0x10, 0x46, 0x03, 0x11, + 0xA7, 0xF7, 0x12, 0x05, 0xF6, 0xFC, 0xA2, 0x01, 0x4C, 0xFF, 0x2F, + 0x00, 0xFF, 0xFF, 0x07, 0x00, 0xE8, 0xFF, 0x12, 0x00, 0x42, 0x00, + 0xC4, 0xFE, 0x94, 0x03, 0x02, 0xF6, 0x89, 0x42, 0x76, 0x18, 0x5C, + 0xF5, 0x12, 0x06, 0x84, 0xFC, 0xD1, 0x01, 0x3B, 0xFF, 0x34, 0x00, + 0xFE, 0xFF, 0x02, 0x00, 0x03, 0x00, 0xCA, 0xFF, 0xD4, 0x00, 0xC8, + 0xFD, 0x2A, 0x05, 0x7D, 0xF3, 0xCA, 0x3D, 0x22, 0x20, 0x76, 0xF3, + 0xC8, 0x06, 0x41, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, + 0xFF, 0xFF, 0xFF, 0x19, 0x00, 0x8E, 0xFF, 0x49, 0x01, 0x04, 0xFD, + 0x4D, 0x06, 0x00, 0xF2, 0xFE, 0x37, 0xCB, 0x27, 0x21, 0xF2, 0x23, + 0x07, 0x34, 0xFC, 0xDD, 0x01, 0x3F, 0xFF, 0x34, 0x00, 0xFD, 0xFF, + 0xFD, 0xFF, 0x29, 0x00, 0x61, 0xFF, 0x9F, 0x01, 0x80, 0xFC, 0xF7, + 0x06, 0x7D, 0xF1, 0x5A, 0x31, 0x2C, 0x2F, 0x83, 0xF1, 0x13, 0x07, + 0x64, 0xFC, 0xB3, 0x01, 0x57, 0xFF, 0x2C, 0x00, 0xFD, 0xFF, 0xFD, + 0xFF, 0x32, 0x00, 0x44, 0xFF, 0xD3, 0x01, 0x3C, 0xFC, 0x2A, 0x07, + 0xDC, 0xF1, 0x1A, 0x2A, 0x06, 0x36, 0xBE, 0xF1, 0x8E, 0x06, 0xD5, + 0xFC, 0x67, 0x01, 0x7F, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0xFD, 0xFF, + 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x36, 0xFC, 0xEF, 0x06, 0xFC, + 0xF2, 0x81, 0x22, 0x1C, 0x3C, 0xEC, 0xF2, 0x90, 0x05, 0x85, 0xFD, + 0xFB, 0x00, 0xB6, 0xFF, 0x0A, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x35, + 0x00, 0x38, 0xFF, 0xDA, 0x01, 0x6A, 0xFC, 0x53, 0x06, 0xBA, 0xF4, + 0xCE, 0x1A, 0x32, 0x41, 0x1F, 0xF5, 0x1D, 0x04, 0x71, 0xFE, 0x71, + 0x00, 0xFB, 0xFF, 0xF0, 0xFF, 0x05, 0x00, 0xFF, 0xFF, 0x31, 0x00, + 0x46, 0xFF, 0xB3, 0x01, 0xCF, 0xFC, 0x67, 0x05, 0xEA, 0xF6, 0x44, + 0x13, 0x1E, 0x45, 0x5E, 0xF8, 0x3F, 0x02, 0x8E, 0xFF, 0xD0, 0xFF, + 0x4A, 0x00, 0xD2, 0xFF, 0x0B, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5D, + 0xFF, 0x76, 0x01, 0x59, 0xFD, 0x42, 0x04, 0x63, 0xF9, 0x1C, 0x0C, + 0xB6, 0x47, 0xA4, 0xFC, 0x07, 0x00, 0xD0, 0x00, 0x20, 0xFF, 0xA0, + 0x00, 0xB1, 0xFF, 0x13, 0x00, 0x00, 0x00, 0x21, 0x00, 0x7A, 0xFF, + 0x2B, 0x01, 0xFE, 0xFD, 0xF8, 0x02, 0xFB, 0xFB, 0x8D, 0x05, 0xE5, + 0x48, 0xE3, 0x01, 0x91, 0xFD, 0x25, 0x02, 0x6B, 0xFE, 0xF7, 0x00, + 0x8F, 0xFF, 0x1C, 0x00, 0x18, 0x00, 0x9C, 0xFF, 0xD6, 0x00, 0xB1, + 0xFE, 0xA1, 0x01, 0x89, 0xFE, 0xC3, 0xFF, 0x9C, 0x48, 0xFD, 0x07, + 0xFA, 0xFA, 0x7A, 0x03, 0xBC, 0xFD, 0x49, 0x01, 0x6E, 0xFF, 0x24, + 0x00, 0x00, 0x00, 0x10, 0x00, 0xBE, 0xFF, 0x7F, 0x00, 0x65, 0xFF, + 0x51, 0x00, 0xEB, 0x00, 0xE1, 0xFA, 0xE1, 0x46, 0xCD, 0x0E, 0x6A, + 0xF8, 0xB8, 0x04, 0x20, 0xFD, 0x90, 0x01, 0x53, 0xFF, 0x2D, 0x00, + 0xFF, 0xFF, 0x09, 0x00, 0xDE, 0xFF, 0x2B, 0x00, 0x11, 0x00, 0x1B, + 0xFF, 0x02, 0x03, 0xFE, 0xF6, 0xC3, 0x43, 0x22, 0x16, 0x07, 0xF6, + 0xCA, 0x05, 0xA3, 0xFC, 0xC5, 0x01, 0x3F, 0xFF, 0x33, 0x00, 0xFF, + 0xFF, 0x03, 0x00, 0xFB, 0xFF, 0xDF, 0xFF, 0xA9, 0x00, 0x10, 0xFE, + 0xB9, 0x04, 0x27, 0xF4, 0x5E, 0x3F, 0xC3, 0x1D, 0xFE, 0xF3, 0x99, + 0x06, 0x50, 0xFC, 0xE2, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, + 0x00, 0x00, 0x13, 0x00, 0x9F, 0xFF, 0x28, 0x01, 0x3A, 0xFD, 0x00, + 0x06, 0x5A, 0xF2, 0xDF, 0x39, 0x73, 0x25, 0x79, 0xF2, 0x12, 0x07, + 0x31, 0xFC, 0xE3, 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0xFD, + 0xFF, 0x24, 0x00, 0x6D, 0xFF, 0x88, 0x01, 0xA2, 0xFC, 0xD0, 0x06, + 0x8C, 0xF1, 0x78, 0x33, 0xF2, 0x2C, 0x9E, 0xF1, 0x24, 0x07, 0x4E, + 0xFC, 0xC3, 0x01, 0x4E, 0xFF, 0x2F, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, + 0x30, 0x00, 0x4C, 0xFF, 0xC7, 0x01, 0x4A, 0xFC, 0x27, 0x07, 0xA8, + 0xF1, 0x62, 0x2C, 0xFD, 0x33, 0x93, 0xF1, 0xC4, 0x06, 0xAB, 0xFC, + 0x82, 0x01, 0x71, 0xFF, 0x23, 0x00, 0xFE, 0xFF, 0xFD, 0xFF, 0x36, + 0x00, 0x3A, 0xFF, 0xE4, 0x01, 0x32, 0xFC, 0x0C, 0x07, 0x91, 0xF2, + 0xDD, 0x24, 0x54, 0x3A, 0x74, 0xF2, 0xEB, 0x05, 0x49, 0xFD, 0x20, + 0x01, 0xA3, 0xFF, 0x11, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x36, 0x00, + 0x37, 0xFF, 0xE1, 0x01, 0x55, 0xFC, 0x8C, 0x06, 0x22, 0xF4, 0x2C, + 0x1D, 0xC0, 0x3F, 0x55, 0xF4, 0x9B, 0x04, 0x23, 0xFE, 0x9F, 0x00, + 0xE4, 0xFF, 0xF9, 0xFF, 0x04, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x40, + 0xFF, 0xC1, 0x01, 0xAB, 0xFC, 0xB7, 0x05, 0x34, 0xF6, 0x8E, 0x15, + 0x0B, 0x44, 0x42, 0xF7, 0xDC, 0x02, 0x32, 0xFF, 0x04, 0x00, 0x31, + 0x00, 0xDC, 0xFF, 0x09, 0x00, 0xFF, 0xFF, 0x2C, 0x00, 0x55, 0xFF, + 0x8B, 0x01, 0x2B, 0xFD, 0xA1, 0x04, 0x9B, 0xF8, 0x42, 0x0E, 0x0F, + 0x47, 0x38, 0xFB, 0xBE, 0x00, 0x6A, 0x00, 0x58, 0xFF, 0x85, 0x00, + 0xBB, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x24, 0x00, 0x71, 0xFF, 0x43, + 0x01, 0xC9, 0xFD, 0x60, 0x03, 0x2E, 0xFB, 0x7E, 0x07, 0xAF, 0x48, + 0x2D, 0x00, 0x58, 0xFE, 0xBB, 0x01, 0xA3, 0xFE, 0xDD, 0x00, 0x99, + 0xFF, 0x19, 0x00, 0x1B, 0x00, 0x91, 0xFF, 0xF1, 0x00, 0x79, 0xFE, + 0x0A, 0x02, 0xC3, 0xFD, 0x73, 0x01, 0xDB, 0x48, 0x07, 0x06, 0xC7, + 0xFB, 0x12, 0x03, 0xF1, 0xFD, 0x31, 0x01, 0x78, 0xFF, 0x22, 0x00, + 0x00, 0x00, 0x12, 0x00, 0xB3, 0xFF, 0x99, 0x00, 0x2E, 0xFF, 0xB6, + 0x00, 0x36, 0x00, 0x47, 0xFC, 0x90, 0x47, 0xA4, 0x0C, 0x31, 0xF9, + 0x5A, 0x04, 0x4E, 0xFD, 0x7C, 0x01, 0x5B, 0xFF, 0x2A, 0x00, 0x00, + 0x00, 0x0B, 0x00, 0xD5, 0xFF, 0x44, 0x00, 0xDD, 0xFF, 0x77, 0xFF, + 0x67, 0x02, 0x14, 0xF8, 0xDC, 0x44, 0xD5, 0x13, 0xBC, 0xF6, 0x7C, + 0x05, 0xC5, 0xFC, 0xB7, 0x01, 0x44, 0xFF, 0x31, 0x00, 0xFF, 0xFF, + 0x05, 0x00, 0xF3, 0xFF, 0xF5, 0xFF, 0x7D, 0x00, 0x5D, 0xFE, 0x3E, + 0x04, 0xEA, 0xF4, 0xD9, 0x40, 0x66, 0x1B, 0x93, 0xF4, 0x62, 0x06, + 0x64, 0xFC, 0xDC, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x00, + 0x00, 0x0C, 0x00, 0xB1, 0xFF, 0x04, 0x01, 0x76, 0xFD, 0xA8, 0x05, + 0xCC, 0xF2, 0xAB, 0x3B, 0x18, 0x23, 0xE0, 0xF2, 0xF7, 0x06, 0x35, + 0xFC, 0xE6, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFE, 0xFF, + 0x20, 0x00, 0x7B, 0xFF, 0x6E, 0x01, 0xCA, 0xFC, 0x9D, 0x06, 0xB1, + 0xF1, 0x86, 0x35, 0xAE, 0x2A, 0xCD, 0xF1, 0x2B, 0x07, 0x3F, 0xFC, + 0xD1, 0x01, 0x46, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x2D, + 0x00, 0x54, 0xFF, 0xB7, 0x01, 0x5E, 0xFC, 0x19, 0x07, 0x88, 0xF1, + 0x9F, 0x2E, 0xE3, 0x31, 0x7E, 0xF1, 0xEE, 0x06, 0x88, 0xFC, 0x9A, + 0x01, 0x64, 0xFF, 0x28, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x34, 0x00, + 0x3E, 0xFF, 0xDF, 0x01, 0x33, 0xFC, 0x20, 0x07, 0x35, 0xF2, 0x36, + 0x27, 0x78, 0x38, 0x14, 0xF2, 0x3B, 0x06, 0x11, 0xFD, 0x41, 0x01, + 0x92, 0xFF, 0x17, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, + 0xFF, 0xE5, 0x01, 0x44, 0xFC, 0xBD, 0x06, 0x97, 0xF3, 0x8A, 0x1F, + 0x31, 0x3E, 0xA5, 0xF3, 0x0F, 0x05, 0xDA, 0xFD, 0xC9, 0x00, 0xCF, + 0xFF, 0x01, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3C, 0xFF, + 0xCE, 0x01, 0x8C, 0xFC, 0x00, 0x06, 0x86, 0xF5, 0xE0, 0x17, 0xDB, + 0x42, 0x3F, 0xF6, 0x71, 0x03, 0xD9, 0xFE, 0x36, 0x00, 0x18, 0x00, + 0xE5, 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0x2E, 0x00, 0x4E, 0xFF, 0x9E, + 0x01, 0x00, 0xFD, 0xFC, 0x04, 0xD7, 0xF7, 0x75, 0x10, 0x48, 0x46, + 0xE4, 0xF9, 0x6E, 0x01, 0x06, 0x00, 0x8E, 0xFF, 0x6B, 0x00, 0xC6, + 0xFF, 0x0E, 0x00, 0x00, 0x00, 0x26, 0x00, 0x68, 0xFF, 0x5B, 0x01, + 0x96, 0xFD, 0xC6, 0x03, 0x61, 0xFA, 0x81, 0x09, 0x57, 0x48, 0x8D, + 0xFE, 0x1B, 0xFF, 0x52, 0x01, 0xDB, 0xFE, 0xC2, 0x00, 0xA4, 0xFF, + 0x16, 0x00, 0x1E, 0x00, 0x87, 0xFF, 0x0B, 0x01, 0x42, 0xFE, 0x74, + 0x02, 0xF9, 0xFC, 0x39, 0x03, 0xF5, 0x48, 0x24, 0x04, 0x94, 0xFC, + 0xA9, 0x02, 0x27, 0xFE, 0x18, 0x01, 0x82, 0xFF, 0x1F, 0x00, 0x00, + 0x00, 0x15, 0x00, 0xA9, 0xFF, 0xB4, 0x00, 0xF7, 0xFE, 0x1D, 0x01, + 0x7A, 0xFF, 0xC5, 0xFD, 0x1D, 0x48, 0x89, 0x0A, 0xFB, 0xF9, 0xF8, + 0x03, 0x7D, 0xFD, 0x66, 0x01, 0x63, 0xFF, 0x28, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0xCB, 0xFF, 0x5E, 0x00, 0xA9, 0xFF, 0xD6, 0xFF, 0xC3, + 0x01, 0x43, 0xF9, 0xD7, 0x45, 0x92, 0x11, 0x77, 0xF7, 0x28, 0x05, + 0xEC, 0xFC, 0xA7, 0x01, 0x4A, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0x06, + 0x00, 0xEA, 0xFF, 0x0C, 0x00, 0x4E, 0x00, 0xAF, 0xFE, 0xB8, 0x03, + 0xC7, 0xF5, 0x38, 0x42, 0x0C, 0x19, 0x32, 0xF5, 0x23, 0x06, 0x7D, + 0xFC, 0xD3, 0x01, 0x3A, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x02, 0x00, + 0x05, 0x00, 0xC5, 0xFF, 0xDE, 0x00, 0xB7, 0xFD, 0x45, 0x05, 0x56, + 0xF3, 0x61, 0x3D, 0xBA, 0x20, 0x56, 0xF3, 0xD3, 0x06, 0x3E, 0xFC, + 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0x1A, + 0x00, 0x8A, 0xFF, 0x51, 0x01, 0xF8, 0xFC, 0x5E, 0x06, 0xED, 0xF1, + 0x82, 0x37, 0x60, 0x28, 0x0E, 0xF2, 0x26, 0x07, 0x35, 0xFC, 0xDB, + 0x01, 0x40, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x29, 0x00, + 0x5F, 0xFF, 0xA5, 0x01, 0x78, 0xFC, 0xFF, 0x06, 0x7D, 0xF1, 0xCF, + 0x30, 0xB8, 0x2F, 0x80, 0xF1, 0x0D, 0x07, 0x6A, 0xFC, 0xAE, 0x01, + 0x59, 0xFF, 0x2B, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x33, 0x00, 0x43, + 0xFF, 0xD6, 0x01, 0x39, 0xFC, 0x2A, 0x07, 0xEB, 0xF1, 0x87, 0x29, + 0x85, 0x36, 0xCC, 0xF1, 0x7F, 0x06, 0xE0, 0xFC, 0x60, 0x01, 0x82, + 0xFF, 0x1D, 0x00, 0xFE, 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, + 0xE6, 0x01, 0x38, 0xFC, 0xE6, 0x06, 0x19, 0xF3, 0xEA, 0x21, 0x8A, + 0x3C, 0x0E, 0xF3, 0x78, 0x05, 0x96, 0xFD, 0xF1, 0x00, 0xBB, 0xFF, + 0x08, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x39, 0xFF, 0xD8, + 0x01, 0x70, 0xFC, 0x43, 0x06, 0xE1, 0xF4, 0x38, 0x1A, 0x8C, 0x41, + 0x55, 0xF5, 0xFC, 0x03, 0x85, 0xFE, 0x66, 0x00, 0x01, 0x00, 0xEE, + 0xFF, 0x06, 0x00, 0xFF, 0xFF, 0x30, 0x00, 0x47, 0xFF, 0xAF, 0x01, + 0xD8, 0xFC, 0x52, 0x05, 0x19, 0xF7, 0xB2, 0x12, 0x5C, 0x45, 0xA9, + 0xF8, 0x16, 0x02, 0xA6, 0xFF, 0xC3, 0xFF, 0x51, 0x00, 0xD0, 0xFF, + 0x0C, 0x00, 0x00, 0x00, 0x29, 0x00, 0x5F, 0xFF, 0x71, 0x01, 0x65, + 0xFD, 0x29, 0x04, 0x96, 0xF9, 0x95, 0x0B, 0xDC, 0x47, 0x03, 0xFD, + 0xD9, 0xFF, 0xEA, 0x00, 0x12, 0xFF, 0xA7, 0x00, 0xAE, 0xFF, 0x14, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x7D, 0xFF, 0x24, 0x01, 0x0C, 0xFE, + 0xDE, 0x02, 0x2E, 0xFC, 0x13, 0x05, 0xEC, 0x48, 0x54, 0x02, 0x5E, + 0xFD, 0x3F, 0x02, 0x5D, 0xFE, 0xFE, 0x00, 0x8C, 0xFF, 0x1C, 0x00, + 0x17, 0x00, 0x9E, 0xFF, 0xCF, 0x00, 0xBF, 0xFE, 0x86, 0x01, 0xBA, + 0xFE, 0x5A, 0xFF, 0x86, 0x48, 0x7D, 0x08, 0xC7, 0xFA, 0x93, 0x03, + 0xB0, 0xFD, 0x4F, 0x01, 0x6C, 0xFF, 0x25, 0x00, 0x00, 0x00, 0x0F, + 0x00, 0xC0, 0xFF, 0x78, 0x00, 0x73, 0xFF, 0x38, 0x00, 0x17, 0x01, + 0x8B, 0xFA, 0xAF, 0x46, 0x59, 0x0F, 0x39, 0xF8, 0xCF, 0x04, 0x15, + 0xFD, 0x95, 0x01, 0x51, 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0x08, 0x00, + 0xE1, 0xFF, 0x25, 0x00, 0x1D, 0x00, 0x05, 0xFF, 0x28, 0x03, 0xBD, + 0xF6, 0x77, 0x43, 0xB6, 0x16, 0xDC, 0xF5, 0xDD, 0x05, 0x9B, 0xFC, + 0xC8, 0x01, 0x3E, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0xFD, + 0xFF, 0xD9, 0xFF, 0xB4, 0x00, 0xFD, 0xFD, 0xD7, 0x04, 0xFA, 0xF3, + 0xFC, 0x3E, 0x5B, 0x1E, 0xDB, 0xF3, 0xA6, 0x06, 0x4C, 0xFC, 0xE3, + 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x14, 0x00, + 0x9B, 0xFF, 0x31, 0x01, 0x2C, 0xFD, 0x15, 0x06, 0x41, 0xF2, 0x6A, + 0x39, 0x0A, 0x26, 0x61, 0xF2, 0x17, 0x07, 0x31, 0xFC, 0xE2, 0x01, + 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x25, 0x00, 0x6A, + 0xFF, 0x8E, 0x01, 0x99, 0xFC, 0xDB, 0x06, 0x86, 0xF1, 0xF2, 0x32, + 0x82, 0x2D, 0x96, 0xF1, 0x21, 0x07, 0x53, 0xFC, 0xC0, 0x01, 0x50, + 0xFF, 0x2E, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x30, 0x00, 0x4A, 0xFF, + 0xCA, 0x01, 0x46, 0xFC, 0x29, 0x07, 0xB3, 0xF1, 0xD1, 0x2B, 0x81, + 0x34, 0x9C, 0xF1, 0xB8, 0x06, 0xB5, 0xFC, 0x7C, 0x01, 0x74, 0xFF, + 0x22, 0x00, 0xFE, 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x39, 0xFF, 0xE5, + 0x01, 0x32, 0xFC, 0x06, 0x07, 0xAA, 0xF2, 0x46, 0x24, 0xC8, 0x3A, + 0x90, 0xF2, 0xD6, 0x05, 0x57, 0xFD, 0x17, 0x01, 0xA8, 0xFF, 0x0F, + 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xDF, 0x01, + 0x5A, 0xFC, 0x7E, 0x06, 0x47, 0xF4, 0x94, 0x1C, 0x1F, 0x40, 0x85, + 0xF4, 0x7D, 0x04, 0x36, 0xFE, 0x93, 0x00, 0xEA, 0xFF, 0xF7, 0xFF, + 0x04, 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x42, 0xFF, 0xBE, 0x01, 0xB4, + 0xFC, 0xA4, 0x05, 0x61, 0xF6, 0xFB, 0x14, 0x53, 0x44, 0x86, 0xF7, + 0xB6, 0x02, 0x49, 0xFF, 0xF7, 0xFF, 0x37, 0x00, 0xD9, 0xFF, 0x0A, + 0x00, 0x00, 0x00, 0x2B, 0x00, 0x57, 0xFF, 0x86, 0x01, 0x36, 0xFD, + 0x89, 0x04, 0xCD, 0xF8, 0xB7, 0x0D, 0x3D, 0x47, 0x91, 0xFB, 0x91, + 0x00, 0x83, 0x00, 0x4A, 0xFF, 0x8C, 0x00, 0xB9, 0xFF, 0x11, 0x00, + 0x00, 0x00, 0x23, 0x00, 0x73, 0xFF, 0x3D, 0x01, 0xD6, 0xFD, 0x46, + 0x03, 0x61, 0xFB, 0x00, 0x07, 0xBF, 0x48, 0x98, 0x00, 0x26, 0xFE, + 0xD5, 0x01, 0x95, 0xFE, 0xE3, 0x00, 0x96, 0xFF, 0x1A, 0x00, 0x1A, + 0x00, 0x94, 0xFF, 0xEA, 0x00, 0x87, 0xFE, 0xF0, 0x01, 0xF5, 0xFD, + 0x05, 0x01, 0xCE, 0x48, 0x83, 0x06, 0x94, 0xFB, 0x2C, 0x03, 0xE4, + 0xFD, 0x37, 0x01, 0x76, 0xFF, 0x22, 0x00, 0x00, 0x00, 0x12, 0x00, + 0xB6, 0xFF, 0x93, 0x00, 0x3C, 0xFF, 0x9D, 0x00, 0x63, 0x00, 0xEB, + 0xFB, 0x69, 0x47, 0x2D, 0x0D, 0xFF, 0xF8, 0x72, 0x04, 0x42, 0xFD, + 0x81, 0x01, 0x59, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xD7, + 0xFF, 0x3E, 0x00, 0xEA, 0xFF, 0x60, 0xFF, 0x8F, 0x02, 0xCD, 0xF7, + 0x99, 0x44, 0x68, 0x14, 0x8E, 0xF6, 0x90, 0x05, 0xBC, 0xFC, 0xBA, + 0x01, 0x43, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x04, 0x00, 0xF5, 0xFF, + 0xEF, 0xFF, 0x88, 0x00, 0x49, 0xFE, 0x5D, 0x04, 0xB7, 0xF4, 0x7D, + 0x40, 0xFD, 0x1B, 0x6C, 0xF4, 0x70, 0x06, 0x5F, 0xFC, 0xDE, 0x01, + 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0x0E, 0x00, 0xAC, + 0xFF, 0x0E, 0x01, 0x66, 0xFD, 0xBF, 0x05, 0xAD, 0xF2, 0x3B, 0x3B, + 0xB0, 0x23, 0xC4, 0xF2, 0xFF, 0x06, 0x33, 0xFC, 0xE5, 0x01, 0x38, + 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFE, 0xFF, 0x21, 0x00, 0x77, 0xFF, + 0x75, 0x01, 0xBF, 0xFC, 0xAB, 0x06, 0xA6, 0xF1, 0x05, 0x35, 0x40, + 0x2B, 0xBF, 0xF1, 0x2A, 0x07, 0x42, 0xFC, 0xCE, 0x01, 0x48, 0xFF, + 0x31, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x2E, 0x00, 0x52, 0xFF, 0xBC, + 0x01, 0x58, 0xFC, 0x1D, 0x07, 0x8E, 0xF1, 0x11, 0x2E, 0x6B, 0x32, + 0x81, 0xF1, 0xE5, 0x06, 0x90, 0xFC, 0x94, 0x01, 0x67, 0xFF, 0x26, + 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x35, 0x00, 0x3C, 0xFF, 0xE0, 0x01, + 0x32, 0xFC, 0x1C, 0x07, 0x4B, 0xF2, 0xA0, 0x26, 0xF2, 0x38, 0x2A, + 0xF2, 0x28, 0x06, 0x1F, 0xFD, 0x39, 0x01, 0x96, 0xFF, 0x16, 0x00, + 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE4, 0x01, 0x48, + 0xFC, 0xB2, 0x06, 0xB9, 0xF3, 0xF3, 0x1E, 0x98, 0x3E, 0xCF, 0xF3, + 0xF3, 0x04, 0xEB, 0xFD, 0xBF, 0x00, 0xD4, 0xFF, 0xFF, 0xFF, 0x03, + 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3D, 0xFF, 0xCB, 0x01, 0x93, 0xFC, + 0xEF, 0x05, 0xB0, 0xF5, 0x4B, 0x17, 0x2A, 0x43, 0x7D, 0xF6, 0x4D, + 0x03, 0xEF, 0xFE, 0x2A, 0x00, 0x1E, 0x00, 0xE3, 0xFF, 0x08, 0x00, + 0xFF, 0xFF, 0x2E, 0x00, 0x4F, 0xFF, 0x99, 0x01, 0x0B, 0xFD, 0xE6, + 0x04, 0x08, 0xF8, 0xE7, 0x0F, 0x7C, 0x46, 0x37, 0xFA, 0x42, 0x01, + 0x1F, 0x00, 0x81, 0xFF, 0x71, 0x00, 0xC3, 0xFF, 0x0F, 0x00, 0x00, + 0x00, 0x26, 0x00, 0x6A, 0xFF, 0x55, 0x01, 0xA3, 0xFD, 0xAD, 0x03, + 0x94, 0xFA, 0xFF, 0x08, 0x70, 0x48, 0xF3, 0xFE, 0xEA, 0xFE, 0x6C, + 0x01, 0xCD, 0xFE, 0xC9, 0x00, 0xA1, 0xFF, 0x17, 0x00, 0x1D, 0x00, + 0x8A, 0xFF, 0x04, 0x01, 0x50, 0xFE, 0x5A, 0x02, 0x2C, 0xFD, 0xC6, + 0x02, 0xF2, 0x48, 0x9B, 0x04, 0x61, 0xFC, 0xC3, 0x02, 0x19, 0xFE, + 0x1E, 0x01, 0x7F, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x14, 0x00, 0xAC, + 0xFF, 0xAE, 0x00, 0x05, 0xFF, 0x03, 0x01, 0xAA, 0xFF, 0x63, 0xFD, + 0xFD, 0x47, 0x0E, 0x0B, 0xC8, 0xF9, 0x11, 0x04, 0x71, 0xFD, 0x6C, + 0x01, 0x61, 0xFF, 0x28, 0x00, 0x00, 0x00, 0x0C, 0x00, 0xCD, 0xFF, + 0x57, 0x00, 0xB6, 0xFF, 0xBE, 0xFF, 0xED, 0x01, 0xF5, 0xF8, 0x9B, + 0x45, 0x22, 0x12, 0x48, 0xF7, 0x3D, 0x05, 0xE2, 0xFC, 0xAB, 0x01, + 0x49, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0x06, 0x00, 0xEC, 0xFF, 0x06, + 0x00, 0x5A, 0x00, 0x9A, 0xFE, 0xDA, 0x03, 0x8D, 0xF5, 0xE1, 0x41, + 0xA1, 0x19, 0x09, 0xF5, 0x33, 0x06, 0x77, 0xFC, 0xD6, 0x01, 0x3A, + 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF, + 0xE8, 0x00, 0xA6, 0xFD, 0x5F, 0x05, 0x31, 0xF3, 0xF6, 0x3C, 0x52, + 0x21, 0x37, 0xF3, 0xDD, 0x06, 0x3B, 0xFC, 0xE6, 0x01, 0x36, 0xFF, + 0x36, 0x00, 0xFD, 0xFF, 0xFE, 0xFF, 0x1C, 0x00, 0x86, 0xFF, 0x59, + 0x01, 0xEC, 0xFC, 0x6F, 0x06, 0xDC, 0xF1, 0x04, 0x37, 0xF3, 0x28, + 0xFC, 0xF1, 0x28, 0x07, 0x37, 0xFC, 0xD8, 0x01, 0x41, 0xFF, 0x33, + 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x2A, 0x00, 0x5C, 0xFF, 0xAA, 0x01, + 0x71, 0xFC, 0x07, 0x07, 0x7E, 0xF1, 0x44, 0x30, 0x44, 0x30, 0x7E, + 0xF1, 0x07, 0x07, 0x71, 0xFC, 0xAA, 0x01, 0x5C, 0xFF, 0x2A, 0x00, + 0xFD, 0xFF, 0xFD, 0xFF, 0x33, 0x00, 0x41, 0xFF, 0xD8, 0x01, 0x37, + 0xFC, 0x28, 0x07, 0xFC, 0xF1, 0xF3, 0x28, 0x04, 0x37, 0xDC, 0xF1, + 0x6F, 0x06, 0xEC, 0xFC, 0x59, 0x01, 0x86, 0xFF, 0x1C, 0x00, 0xFE, + 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3B, 0xFC, + 0xDD, 0x06, 0x37, 0xF3, 0x52, 0x21, 0xF6, 0x3C, 0x31, 0xF3, 0x5F, + 0x05, 0xA6, 0xFD, 0xE8, 0x00, 0xC0, 0xFF, 0x07, 0x00, 0x01, 0x00, + 0xFE, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD6, 0x01, 0x77, 0xFC, 0x33, + 0x06, 0x09, 0xF5, 0xA1, 0x19, 0xE1, 0x41, 0x8D, 0xF5, 0xDA, 0x03, + 0x9A, 0xFE, 0x5A, 0x00, 0x06, 0x00, 0xEC, 0xFF, 0x06, 0x00, 0xFF, + 0xFF, 0x30, 0x00, 0x49, 0xFF, 0xAB, 0x01, 0xE2, 0xFC, 0x3D, 0x05, + 0x48, 0xF7, 0x22, 0x12, 0x9B, 0x45, 0xF5, 0xF8, 0xED, 0x01, 0xBE, + 0xFF, 0xB6, 0xFF, 0x57, 0x00, 0xCD, 0xFF, 0x0C, 0x00, 0x00, 0x00, + 0x28, 0x00, 0x61, 0xFF, 0x6C, 0x01, 0x71, 0xFD, 0x11, 0x04, 0xC8, + 0xF9, 0x0E, 0x0B, 0xFD, 0x47, 0x63, 0xFD, 0xAA, 0xFF, 0x03, 0x01, + 0x05, 0xFF, 0xAE, 0x00, 0xAC, 0xFF, 0x14, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x7F, 0xFF, 0x1E, 0x01, 0x19, 0xFE, 0xC3, 0x02, 0x61, 0xFC, + 0x9B, 0x04, 0xF2, 0x48, 0xC6, 0x02, 0x2C, 0xFD, 0x5A, 0x02, 0x50, + 0xFE, 0x04, 0x01, 0x8A, 0xFF, 0x1D, 0x00, 0x17, 0x00, 0xA1, 0xFF, + 0xC9, 0x00, 0xCD, 0xFE, 0x6C, 0x01, 0xEA, 0xFE, 0xF3, 0xFE, 0x70, + 0x48, 0xFF, 0x08, 0x94, 0xFA, 0xAD, 0x03, 0xA3, 0xFD, 0x55, 0x01, + 0x6A, 0xFF, 0x26, 0x00, 0x00, 0x00, 0x0F, 0x00, 0xC3, 0xFF, 0x71, + 0x00, 0x81, 0xFF, 0x1F, 0x00, 0x42, 0x01, 0x37, 0xFA, 0x7C, 0x46, + 0xE7, 0x0F, 0x08, 0xF8, 0xE6, 0x04, 0x0B, 0xFD, 0x99, 0x01, 0x4F, + 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0x08, 0x00, 0xE3, 0xFF, 0x1E, 0x00, + 0x2A, 0x00, 0xEF, 0xFE, 0x4D, 0x03, 0x7D, 0xF6, 0x2A, 0x43, 0x4B, + 0x17, 0xB0, 0xF5, 0xEF, 0x05, 0x93, 0xFC, 0xCB, 0x01, 0x3D, 0xFF, + 0x34, 0x00, 0xFE, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0xD4, 0xFF, 0xBF, + 0x00, 0xEB, 0xFD, 0xF3, 0x04, 0xCF, 0xF3, 0x98, 0x3E, 0xF3, 0x1E, + 0xB9, 0xF3, 0xB2, 0x06, 0x48, 0xFC, 0xE4, 0x01, 0x36, 0xFF, 0x36, + 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x16, 0x00, 0x96, 0xFF, 0x39, 0x01, + 0x1F, 0xFD, 0x28, 0x06, 0x2A, 0xF2, 0xF2, 0x38, 0xA0, 0x26, 0x4B, + 0xF2, 0x1C, 0x07, 0x32, 0xFC, 0xE0, 0x01, 0x3C, 0xFF, 0x35, 0x00, + 0xFD, 0xFF, 0xFD, 0xFF, 0x26, 0x00, 0x67, 0xFF, 0x94, 0x01, 0x90, + 0xFC, 0xE5, 0x06, 0x81, 0xF1, 0x6B, 0x32, 0x11, 0x2E, 0x8E, 0xF1, + 0x1D, 0x07, 0x58, 0xFC, 0xBC, 0x01, 0x52, 0xFF, 0x2E, 0x00, 0xFD, + 0xFF, 0xFD, 0xFF, 0x31, 0x00, 0x48, 0xFF, 0xCE, 0x01, 0x42, 0xFC, + 0x2A, 0x07, 0xBF, 0xF1, 0x40, 0x2B, 0x05, 0x35, 0xA6, 0xF1, 0xAB, + 0x06, 0xBF, 0xFC, 0x75, 0x01, 0x77, 0xFF, 0x21, 0x00, 0xFE, 0xFF, + 0xFD, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE5, 0x01, 0x33, 0xFC, 0xFF, + 0x06, 0xC4, 0xF2, 0xB0, 0x23, 0x3B, 0x3B, 0xAD, 0xF2, 0xBF, 0x05, + 0x66, 0xFD, 0x0E, 0x01, 0xAC, 0xFF, 0x0E, 0x00, 0x00, 0x00, 0xFE, + 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xDE, 0x01, 0x5F, 0xFC, 0x70, 0x06, + 0x6C, 0xF4, 0xFD, 0x1B, 0x7D, 0x40, 0xB7, 0xF4, 0x5D, 0x04, 0x49, + 0xFE, 0x88, 0x00, 0xEF, 0xFF, 0xF5, 0xFF, 0x04, 0x00, 0xFF, 0xFF, + 0x32, 0x00, 0x43, 0xFF, 0xBA, 0x01, 0xBC, 0xFC, 0x90, 0x05, 0x8E, + 0xF6, 0x68, 0x14, 0x99, 0x44, 0xCD, 0xF7, 0x8F, 0x02, 0x60, 0xFF, + 0xEA, 0xFF, 0x3E, 0x00, 0xD7, 0xFF, 0x0A, 0x00, 0x00, 0x00, 0x2B, + 0x00, 0x59, 0xFF, 0x81, 0x01, 0x42, 0xFD, 0x72, 0x04, 0xFF, 0xF8, + 0x2D, 0x0D, 0x69, 0x47, 0xEB, 0xFB, 0x63, 0x00, 0x9D, 0x00, 0x3C, + 0xFF, 0x93, 0x00, 0xB6, 0xFF, 0x12, 0x00, 0x00, 0x00, 0x22, 0x00, + 0x76, 0xFF, 0x37, 0x01, 0xE4, 0xFD, 0x2C, 0x03, 0x94, 0xFB, 0x83, + 0x06, 0xCE, 0x48, 0x05, 0x01, 0xF5, 0xFD, 0xF0, 0x01, 0x87, 0xFE, + 0xEA, 0x00, 0x94, 0xFF, 0x1A, 0x00, 0x1A, 0x00, 0x96, 0xFF, 0xE3, + 0x00, 0x95, 0xFE, 0xD5, 0x01, 0x26, 0xFE, 0x98, 0x00, 0xBF, 0x48, + 0x00, 0x07, 0x61, 0xFB, 0x46, 0x03, 0xD6, 0xFD, 0x3D, 0x01, 0x73, + 0xFF, 0x23, 0x00, 0x00, 0x00, 0x11, 0x00, 0xB9, 0xFF, 0x8C, 0x00, + 0x4A, 0xFF, 0x83, 0x00, 0x91, 0x00, 0x91, 0xFB, 0x3D, 0x47, 0xB7, + 0x0D, 0xCD, 0xF8, 0x89, 0x04, 0x36, 0xFD, 0x86, 0x01, 0x57, 0xFF, + 0x2B, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xD9, 0xFF, 0x37, 0x00, 0xF7, + 0xFF, 0x49, 0xFF, 0xB6, 0x02, 0x86, 0xF7, 0x53, 0x44, 0xFB, 0x14, + 0x61, 0xF6, 0xA4, 0x05, 0xB4, 0xFC, 0xBE, 0x01, 0x42, 0xFF, 0x32, + 0x00, 0xFF, 0xFF, 0x04, 0x00, 0xF7, 0xFF, 0xEA, 0xFF, 0x93, 0x00, + 0x36, 0xFE, 0x7D, 0x04, 0x85, 0xF4, 0x1F, 0x40, 0x94, 0x1C, 0x47, + 0xF4, 0x7E, 0x06, 0x5A, 0xFC, 0xDF, 0x01, 0x37, 0xFF, 0x36, 0x00, + 0xFE, 0xFF, 0x00, 0x00, 0x0F, 0x00, 0xA8, 0xFF, 0x17, 0x01, 0x57, + 0xFD, 0xD6, 0x05, 0x90, 0xF2, 0xC8, 0x3A, 0x46, 0x24, 0xAA, 0xF2, + 0x06, 0x07, 0x32, 0xFC, 0xE5, 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, + 0xFF, 0xFE, 0xFF, 0x22, 0x00, 0x74, 0xFF, 0x7C, 0x01, 0xB5, 0xFC, + 0xB8, 0x06, 0x9C, 0xF1, 0x81, 0x34, 0xD1, 0x2B, 0xB3, 0xF1, 0x29, + 0x07, 0x46, 0xFC, 0xCA, 0x01, 0x4A, 0xFF, 0x30, 0x00, 0xFD, 0xFF, + 0xFD, 0xFF, 0x2E, 0x00, 0x50, 0xFF, 0xC0, 0x01, 0x53, 0xFC, 0x21, + 0x07, 0x96, 0xF1, 0x82, 0x2D, 0xF2, 0x32, 0x86, 0xF1, 0xDB, 0x06, + 0x99, 0xFC, 0x8E, 0x01, 0x6A, 0xFF, 0x25, 0x00, 0xFD, 0xFF, 0xFD, + 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xE2, 0x01, 0x31, 0xFC, 0x17, 0x07, + 0x61, 0xF2, 0x0A, 0x26, 0x6A, 0x39, 0x41, 0xF2, 0x15, 0x06, 0x2C, + 0xFD, 0x31, 0x01, 0x9B, 0xFF, 0x14, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, + 0x36, 0x00, 0x36, 0xFF, 0xE3, 0x01, 0x4C, 0xFC, 0xA6, 0x06, 0xDB, + 0xF3, 0x5B, 0x1E, 0xFC, 0x3E, 0xFA, 0xF3, 0xD7, 0x04, 0xFD, 0xFD, + 0xB4, 0x00, 0xD9, 0xFF, 0xFD, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0x33, + 0x00, 0x3E, 0xFF, 0xC8, 0x01, 0x9B, 0xFC, 0xDD, 0x05, 0xDC, 0xF5, + 0xB6, 0x16, 0x77, 0x43, 0xBD, 0xF6, 0x28, 0x03, 0x05, 0xFF, 0x1D, + 0x00, 0x25, 0x00, 0xE1, 0xFF, 0x08, 0x00, 0xFF, 0xFF, 0x2D, 0x00, + 0x51, 0xFF, 0x95, 0x01, 0x15, 0xFD, 0xCF, 0x04, 0x39, 0xF8, 0x59, + 0x0F, 0xAF, 0x46, 0x8B, 0xFA, 0x17, 0x01, 0x38, 0x00, 0x73, 0xFF, + 0x78, 0x00, 0xC0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x25, 0x00, 0x6C, + 0xFF, 0x4F, 0x01, 0xB0, 0xFD, 0x93, 0x03, 0xC7, 0xFA, 0x7D, 0x08, + 0x86, 0x48, 0x5A, 0xFF, 0xBA, 0xFE, 0x86, 0x01, 0xBF, 0xFE, 0xCF, + 0x00, 0x9E, 0xFF, 0x17, 0x00, 0x1C, 0x00, 0x8C, 0xFF, 0xFE, 0x00, + 0x5D, 0xFE, 0x3F, 0x02, 0x5E, 0xFD, 0x54, 0x02, 0xEC, 0x48, 0x13, + 0x05, 0x2E, 0xFC, 0xDE, 0x02, 0x0C, 0xFE, 0x24, 0x01, 0x7D, 0xFF, + 0x20, 0x00, 0x00, 0x00, 0x14, 0x00, 0xAE, 0xFF, 0xA7, 0x00, 0x12, + 0xFF, 0xEA, 0x00, 0xD9, 0xFF, 0x03, 0xFD, 0xDC, 0x47, 0x95, 0x0B, + 0x96, 0xF9, 0x29, 0x04, 0x65, 0xFD, 0x71, 0x01, 0x5F, 0xFF, 0x29, + 0x00, 0x00, 0x00, 0x0C, 0x00, 0xD0, 0xFF, 0x51, 0x00, 0xC3, 0xFF, + 0xA6, 0xFF, 0x16, 0x02, 0xA9, 0xF8, 0x5C, 0x45, 0xB2, 0x12, 0x19, + 0xF7, 0x52, 0x05, 0xD8, 0xFC, 0xAF, 0x01, 0x47, 0xFF, 0x30, 0x00, + 0xFF, 0xFF, 0x06, 0x00, 0xEE, 0xFF, 0x01, 0x00, 0x66, 0x00, 0x85, + 0xFE, 0xFC, 0x03, 0x55, 0xF5, 0x8C, 0x41, 0x38, 0x1A, 0xE1, 0xF4, + 0x43, 0x06, 0x70, 0xFC, 0xD8, 0x01, 0x39, 0xFF, 0x35, 0x00, 0xFE, + 0xFF, 0x01, 0x00, 0x08, 0x00, 0xBB, 0xFF, 0xF1, 0x00, 0x96, 0xFD, + 0x78, 0x05, 0x0E, 0xF3, 0x8A, 0x3C, 0xEA, 0x21, 0x19, 0xF3, 0xE6, + 0x06, 0x38, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, + 0xFE, 0xFF, 0x1D, 0x00, 0x82, 0xFF, 0x60, 0x01, 0xE0, 0xFC, 0x7F, + 0x06, 0xCC, 0xF1, 0x85, 0x36, 0x87, 0x29, 0xEB, 0xF1, 0x2A, 0x07, + 0x39, 0xFC, 0xD6, 0x01, 0x43, 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0xFD, + 0xFF, 0x2B, 0x00, 0x59, 0xFF, 0xAE, 0x01, 0x6A, 0xFC, 0x0D, 0x07, + 0x80, 0xF1, 0xB8, 0x2F, 0xCF, 0x30, 0x7D, 0xF1, 0xFF, 0x06, 0x78, + 0xFC, 0xA5, 0x01, 0x5F, 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, + 0x34, 0x00, 0x40, 0xFF, 0xDB, 0x01, 0x35, 0xFC, 0x26, 0x07, 0x0E, + 0xF2, 0x60, 0x28, 0x82, 0x37, 0xED, 0xF1, 0x5E, 0x06, 0xF8, 0xFC, + 0x51, 0x01, 0x8A, 0xFF, 0x1A, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36, + 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3E, 0xFC, 0xD3, 0x06, 0x56, 0xF3, + 0xBA, 0x20, 0x61, 0x3D, 0x56, 0xF3, 0x45, 0x05, 0xB7, 0xFD, 0xDE, + 0x00, 0xC5, 0xFF, 0x05, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x35, 0x00, + 0x3A, 0xFF, 0xD3, 0x01, 0x7D, 0xFC, 0x23, 0x06, 0x32, 0xF5, 0x0C, + 0x19, 0x38, 0x42, 0xC7, 0xF5, 0xB8, 0x03, 0xAF, 0xFE, 0x4E, 0x00, + 0x0C, 0x00, 0xEA, 0xFF, 0x06, 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4A, + 0xFF, 0xA7, 0x01, 0xEC, 0xFC, 0x28, 0x05, 0x77, 0xF7, 0x92, 0x11, + 0xD7, 0x45, 0x43, 0xF9, 0xC3, 0x01, 0xD6, 0xFF, 0xA9, 0xFF, 0x5E, + 0x00, 0xCB, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x28, 0x00, 0x63, 0xFF, + 0x66, 0x01, 0x7D, 0xFD, 0xF8, 0x03, 0xFB, 0xF9, 0x89, 0x0A, 0x1D, + 0x48, 0xC5, 0xFD, 0x7A, 0xFF, 0x1D, 0x01, 0xF7, 0xFE, 0xB4, 0x00, + 0xA9, 0xFF, 0x15, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x82, 0xFF, 0x18, + 0x01, 0x27, 0xFE, 0xA9, 0x02, 0x94, 0xFC, 0x24, 0x04, 0xF5, 0x48, + 0x39, 0x03, 0xF9, 0xFC, 0x74, 0x02, 0x42, 0xFE, 0x0B, 0x01, 0x87, + 0xFF, 0x1E, 0x00, 0x16, 0x00, 0xA4, 0xFF, 0xC2, 0x00, 0xDB, 0xFE, + 0x52, 0x01, 0x1B, 0xFF, 0x8D, 0xFE, 0x57, 0x48, 0x81, 0x09, 0x61, + 0xFA, 0xC6, 0x03, 0x96, 0xFD, 0x5B, 0x01, 0x68, 0xFF, 0x26, 0x00, + 0x00, 0x00, 0x0E, 0x00, 0xC6, 0xFF, 0x6B, 0x00, 0x8E, 0xFF, 0x06, + 0x00, 0x6E, 0x01, 0xE4, 0xF9, 0x48, 0x46, 0x75, 0x10, 0xD7, 0xF7, + 0xFC, 0x04, 0x00, 0xFD, 0x9E, 0x01, 0x4E, 0xFF, 0x2E, 0x00, 0xFF, + 0xFF, 0x07, 0x00, 0xE5, 0xFF, 0x18, 0x00, 0x36, 0x00, 0xD9, 0xFE, + 0x71, 0x03, 0x3F, 0xF6, 0xDB, 0x42, 0xE0, 0x17, 0x86, 0xF5, 0x00, + 0x06, 0x8C, 0xFC, 0xCE, 0x01, 0x3C, 0xFF, 0x34, 0x00, 0xFE, 0xFF, + 0x02, 0x00, 0x01, 0x00, 0xCF, 0xFF, 0xC9, 0x00, 0xDA, 0xFD, 0x0F, + 0x05, 0xA5, 0xF3, 0x31, 0x3E, 0x8A, 0x1F, 0x97, 0xF3, 0xBD, 0x06, + 0x44, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFF, + 0xFF, 0x17, 0x00, 0x92, 0xFF, 0x41, 0x01, 0x11, 0xFD, 0x3B, 0x06, + 0x14, 0xF2, 0x78, 0x38, 0x36, 0x27, 0x35, 0xF2, 0x20, 0x07, 0x33, + 0xFC, 0xDF, 0x01, 0x3E, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, + 0x28, 0x00, 0x64, 0xFF, 0x9A, 0x01, 0x88, 0xFC, 0xEE, 0x06, 0x7E, + 0xF1, 0xE3, 0x31, 0x9F, 0x2E, 0x88, 0xF1, 0x19, 0x07, 0x5E, 0xFC, + 0xB7, 0x01, 0x54, 0xFF, 0x2D, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x32, + 0x00, 0x46, 0xFF, 0xD1, 0x01, 0x3F, 0xFC, 0x2B, 0x07, 0xCD, 0xF1, + 0xAE, 0x2A, 0x86, 0x35, 0xB1, 0xF1, 0x9D, 0x06, 0xCA, 0xFC, 0x6E, + 0x01, 0x7B, 0xFF, 0x20, 0x00, 0xFE, 0xFF, 0xFD, 0xFF, 0x36, 0x00, + 0x38, 0xFF, 0xE6, 0x01, 0x35, 0xFC, 0xF7, 0x06, 0xE0, 0xF2, 0x18, + 0x23, 0xAB, 0x3B, 0xCC, 0xF2, 0xA8, 0x05, 0x76, 0xFD, 0x04, 0x01, + 0xB1, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x38, + 0xFF, 0xDC, 0x01, 0x64, 0xFC, 0x62, 0x06, 0x93, 0xF4, 0x66, 0x1B, + 0xD9, 0x40, 0xEA, 0xF4, 0x3E, 0x04, 0x5D, 0xFE, 0x7D, 0x00, 0xF5, + 0xFF, 0xF3, 0xFF, 0x05, 0x00, 0xFF, 0xFF, 0x31, 0x00, 0x44, 0xFF, + 0xB7, 0x01, 0xC5, 0xFC, 0x7C, 0x05, 0xBC, 0xF6, 0xD5, 0x13, 0xDC, + 0x44, 0x14, 0xF8, 0x67, 0x02, 0x77, 0xFF, 0xDD, 0xFF, 0x44, 0x00, + 0xD5, 0xFF, 0x0B, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5B, 0xFF, 0x7C, + 0x01, 0x4E, 0xFD, 0x5A, 0x04, 0x31, 0xF9, 0xA4, 0x0C, 0x90, 0x47, + 0x47, 0xFC, 0x36, 0x00, 0xB6, 0x00, 0x2E, 0xFF, 0x99, 0x00, 0xB3, + 0xFF, 0x12, 0x00, 0x00, 0x00, 0x22, 0x00, 0x78, 0xFF, 0x31, 0x01, + 0xF1, 0xFD, 0x12, 0x03, 0xC7, 0xFB, 0x07, 0x06, 0xDB, 0x48, 0x73, + 0x01, 0xC3, 0xFD, 0x0A, 0x02, 0x79, 0xFE, 0xF1, 0x00, 0x91, 0xFF, + 0x1B, 0x00, 0x19, 0x00, 0x99, 0xFF, 0xDD, 0x00, 0xA3, 0xFE, 0xBB, + 0x01, 0x58, 0xFE, 0x2D, 0x00, 0xAF, 0x48, 0x7E, 0x07, 0x2E, 0xFB, + 0x60, 0x03, 0xC9, 0xFD, 0x43, 0x01, 0x71, 0xFF, 0x24, 0x00, 0x00, + 0x00, 0x10, 0x00, 0xBB, 0xFF, 0x85, 0x00, 0x58, 0xFF, 0x6A, 0x00, + 0xBE, 0x00, 0x38, 0xFB, 0x0F, 0x47, 0x42, 0x0E, 0x9B, 0xF8, 0xA1, + 0x04, 0x2B, 0xFD, 0x8B, 0x01, 0x55, 0xFF, 0x2C, 0x00, 0xFF, 0xFF, + 0x09, 0x00, 0xDC, 0xFF, 0x31, 0x00, 0x04, 0x00, 0x32, 0xFF, 0xDC, + 0x02, 0x42, 0xF7, 0x0B, 0x44, 0x8E, 0x15, 0x34, 0xF6, 0xB7, 0x05, + 0xAB, 0xFC, 0xC1, 0x01, 0x40, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x04, + 0x00, 0xF9, 0xFF, 0xE4, 0xFF, 0x9F, 0x00, 0x23, 0xFE, 0x9B, 0x04, + 0x55, 0xF4, 0xC0, 0x3F, 0x2C, 0x1D, 0x22, 0xF4, 0x8C, 0x06, 0x55, + 0xFC, 0xE1, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x00, 0x00, + 0x11, 0x00, 0xA3, 0xFF, 0x20, 0x01, 0x49, 0xFD, 0xEB, 0x05, 0x74, + 0xF2, 0x54, 0x3A, 0xDD, 0x24, 0x91, 0xF2, 0x0C, 0x07, 0x32, 0xFC, + 0xE4, 0x01, 0x3A, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFE, 0xFF, 0x23, + 0x00, 0x71, 0xFF, 0x82, 0x01, 0xAB, 0xFC, 0xC4, 0x06, 0x93, 0xF1, + 0xFD, 0x33, 0x62, 0x2C, 0xA8, 0xF1, 0x27, 0x07, 0x4A, 0xFC, 0xC7, + 0x01, 0x4C, 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x2F, 0x00, + 0x4E, 0xFF, 0xC3, 0x01, 0x4E, 0xFC, 0x24, 0x07, 0x9E, 0xF1, 0xF2, + 0x2C, 0x78, 0x33, 0x8C, 0xF1, 0xD0, 0x06, 0xA2, 0xFC, 0x88, 0x01, + 0x6D, 0xFF, 0x24, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x35, 0x00, 0x3B, + 0xFF, 0xE3, 0x01, 0x31, 0xFC, 0x12, 0x07, 0x79, 0xF2, 0x73, 0x25, + 0xDF, 0x39, 0x5A, 0xF2, 0x00, 0x06, 0x3A, 0xFD, 0x28, 0x01, 0x9F, + 0xFF, 0x13, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, + 0xE2, 0x01, 0x50, 0xFC, 0x99, 0x06, 0xFE, 0xF3, 0xC3, 0x1D, 0x5E, + 0x3F, 0x27, 0xF4, 0xB9, 0x04, 0x10, 0xFE, 0xA9, 0x00, 0xDF, 0xFF, + 0xFB, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x3F, 0xFF, 0xC5, + 0x01, 0xA3, 0xFC, 0xCA, 0x05, 0x07, 0xF6, 0x22, 0x16, 0xC3, 0x43, + 0xFE, 0xF6, 0x02, 0x03, 0x1B, 0xFF, 0x11, 0x00, 0x2B, 0x00, 0xDE, + 0xFF, 0x09, 0x00, 0xFF, 0xFF, 0x2D, 0x00, 0x53, 0xFF, 0x90, 0x01, + 0x20, 0xFD, 0xB8, 0x04, 0x6A, 0xF8, 0xCD, 0x0E, 0xE1, 0x46, 0xE1, + 0xFA, 0xEB, 0x00, 0x51, 0x00, 0x65, 0xFF, 0x7F, 0x00, 0xBE, 0xFF, + 0x10, 0x00, 0x00, 0x00, 0x24, 0x00, 0x6E, 0xFF, 0x49, 0x01, 0xBC, + 0xFD, 0x7A, 0x03, 0xFA, 0xFA, 0xFD, 0x07, 0x9C, 0x48, 0xC3, 0xFF, + 0x89, 0xFE, 0xA1, 0x01, 0xB1, 0xFE, 0xD6, 0x00, 0x9C, 0xFF, 0x18, + 0x00, 0x1C, 0x00, 0x8F, 0xFF, 0xF7, 0x00, 0x6B, 0xFE, 0x25, 0x02, + 0x91, 0xFD, 0xE3, 0x01, 0xE5, 0x48, 0x8D, 0x05, 0xFB, 0xFB, 0xF8, + 0x02, 0xFE, 0xFD, 0x2B, 0x01, 0x7A, 0xFF, 0x21, 0x00, 0x00, 0x00, + 0x13, 0x00, 0xB1, 0xFF, 0xA0, 0x00, 0x20, 0xFF, 0xD0, 0x00, 0x07, + 0x00, 0xA4, 0xFC, 0xB6, 0x47, 0x1C, 0x0C, 0x63, 0xF9, 0x42, 0x04, + 0x59, 0xFD, 0x76, 0x01, 0x5D, 0xFF, 0x2A, 0x00, 0x00, 0x00, 0x0B, + 0x00, 0xD2, 0xFF, 0x4A, 0x00, 0xD0, 0xFF, 0x8E, 0xFF, 0x3F, 0x02, + 0x5E, 0xF8, 0x1E, 0x45, 0x44, 0x13, 0xEA, 0xF6, 0x67, 0x05, 0xCF, + 0xFC, 0xB3, 0x01, 0x46, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0x05, 0x00, + 0xF0, 0xFF, 0xFB, 0xFF, 0x71, 0x00, 0x71, 0xFE, 0x1D, 0x04, 0x1F, + 0xF5, 0x32, 0x41, 0xCE, 0x1A, 0xBA, 0xF4, 0x53, 0x06, 0x6A, 0xFC, + 0xDA, 0x01, 0x38, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x0A, + 0x00, 0xB6, 0xFF, 0xFB, 0x00, 0x85, 0xFD, 0x90, 0x05, 0xEC, 0xF2, + 0x1C, 0x3C, 0x81, 0x22, 0xFC, 0xF2, 0xEF, 0x06, 0x36, 0xFC, 0xE6, + 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFE, 0xFF, 0x1E, 0x00, + 0x7F, 0xFF, 0x67, 0x01, 0xD5, 0xFC, 0x8E, 0x06, 0xBE, 0xF1, 0x06, + 0x36, 0x1A, 0x2A, 0xDC, 0xF1, 0x2A, 0x07, 0x3C, 0xFC, 0xD3, 0x01, + 0x44, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x2C, 0x00, 0x57, + 0xFF, 0xB3, 0x01, 0x64, 0xFC, 0x13, 0x07, 0x83, 0xF1, 0x2C, 0x2F, + 0x5A, 0x31, 0x7D, 0xF1, 0xF7, 0x06, 0x80, 0xFC, 0x9F, 0x01, 0x61, + 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x34, 0x00, 0x3F, 0xFF, + 0xDD, 0x01, 0x34, 0xFC, 0x23, 0x07, 0x21, 0xF2, 0xCB, 0x27, 0xFE, + 0x37, 0x00, 0xF2, 0x4D, 0x06, 0x04, 0xFD, 0x49, 0x01, 0x8E, 0xFF, + 0x19, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, + 0x01, 0x41, 0xFC, 0xC8, 0x06, 0x76, 0xF3, 0x22, 0x20, 0xCA, 0x3D, + 0x7D, 0xF3, 0x2A, 0x05, 0xC8, 0xFD, 0xD4, 0x00, 0xCA, 0xFF, 0x03, + 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3B, 0xFF, 0xD1, 0x01, + 0x84, 0xFC, 0x12, 0x06, 0x5C, 0xF5, 0x76, 0x18, 0x89, 0x42, 0x02, + 0xF6, 0x94, 0x03, 0xC4, 0xFE, 0x42, 0x00, 0x12, 0x00, 0xE8, 0xFF, + 0x07, 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4C, 0xFF, 0xA2, 0x01, 0xF6, + 0xFC, 0x12, 0x05, 0xA7, 0xF7, 0x03, 0x11, 0x10, 0x46, 0x93, 0xF9, + 0x98, 0x01, 0xEE, 0xFF, 0x9B, 0xFF, 0x64, 0x00, 0xC8, 0xFF, 0x0E, + 0x00, 0x00, 0x00, 0x27, 0x00, 0x65, 0xFF, 0x60, 0x01, 0x8A, 0xFD, + 0xDF, 0x03, 0x2E, 0xFA, 0x04, 0x0A, 0x3A, 0x48, 0x28, 0xFE, 0x4B, + 0xFF, 0x38, 0x01, 0xE9, 0xFE, 0xBB, 0x00, 0xA6, 0xFF, 0x16, 0x00, + 0x00, 0x00, 0x1E, 0x00, 0x84, 0xFF, 0x11, 0x01, 0x34, 0xFE, 0x8F, + 0x02, 0xC7, 0xFC, 0xAE, 0x03, 0xF7, 0x48, 0xAE, 0x03, 0xC7, 0xFC, + 0x8F, 0x02, 0x34, 0xFE, 0x11, 0x01, 0x84, 0xFF, 0x1E, 0x00, 0x00, + 0x00, 0xF4, 0xFF, 0x1A, 0x00, 0xFF, 0x00, 0x07, 0x03, 0x16, 0x06, + 0x7C, 0x09, 0x2A, 0x0C, 0x2E, 0x0D, 0x2A, 0x0C, 0x7C, 0x09, 0x16, + 0x06, 0x07, 0x03, 0xFF, 0x00, 0x1A, 0x00, 0xF4, 0xFF, 0xF2, 0xFF, + 0xA0, 0xFF, 0x71, 0xFF, 0x71, 0x00, 0x86, 0x03, 0x73, 0x08, 0x88, + 0x0D, 0x78, 0x10, 0xC9, 0x0F, 0xD5, 0x0B, 0x8B, 0x06, 0x28, 0x02, + 0xDF, 0xFF, 0x6F, 0xFF, 0xC3, 0xFF, 0xFD, 0xFF, 0x00, 0x00, 0xDC, + 0xFF, 0x80, 0xFF, 0x9A, 0xFF, 0x46, 0x01, 0x1E, 0x05, 0x5A, 0x0A, + 0xED, 0x0E, 0xAA, 0x10, 0xAF, 0x0E, 0xFD, 0x09, 0xCB, 0x04, 0x18, + 0x01, 0x8E, 0xFF, 0x85, 0xFF, 0xE1, 0xFF, 0xFC, 0xFF, 0xBD, 0xFF, + 0x6D, 0xFF, 0xF6, 0xFF, 0x65, 0x02, 0xE5, 0x06, 0x2B, 0x0C, 0xF3, + 0x0F, 0x60, 0x10, 0x3B, 0x0D, 0x16, 0x08, 0x3F, 0x03, 0x50, 0x00, + 0x6E, 0xFF, 0xA7, 0xFF, 0xF5, 0xFF, 0xEF, 0xFF, 0x9A, 0xFF, 0x75, + 0xFF, 0x91, 0x00, 0xC9, 0x03, 0xC8, 0x08, 0xCC, 0x0D, 0x89, 0x10, + 0x9F, 0x0F, 0x85, 0x0B, 0x3B, 0x06, 0xF4, 0x01, 0xCD, 0xFF, 0x72, + 0xFF, 0xC9, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0xD7, 0xFF, 0x7B, 0xFF, + 0xA5, 0xFF, 0x73, 0x01, 0x6A, 0x05, 0xAD, 0x0A, 0x21, 0x0F, 0xA6, + 0x10, 0x74, 0x0E, 0xA9, 0x09, 0x83, 0x04, 0xF0, 0x00, 0x85, 0xFF, + 0x8B, 0xFF, 0xE5, 0xFF, 0xFA, 0xFF, 0xB7, 0xFF, 0x6C, 0xFF, 0x0C, + 0x00, 0x9D, 0x02, 0x37, 0x07, 0x78, 0x0C, 0x15, 0x10, 0x47, 0x10, + 0xF3, 0x0C, 0xC2, 0x07, 0x01, 0x03, 0x35, 0x00, 0x6D, 0xFF, 0xAD, + 0xFF, 0xF7, 0xFF, 0xEB, 0xFF, 0x94, 0xFF, 0x7A, 0xFF, 0xB3, 0x00, + 0x0D, 0x04, 0x1C, 0x09, 0x0D, 0x0E, 0x97, 0x10, 0x73, 0x0F, 0x35, + 0x0B, 0xEB, 0x05, 0xC1, 0x01, 0xBD, 0xFF, 0x75, 0xFF, 0xCE, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0xFF, 0x77, 0xFF, 0xB3, 0xFF, 0xA1, + 0x01, 0xB7, 0x05, 0xFF, 0x0A, 0x53, 0x0F, 0x9E, 0x10, 0x37, 0x0E, + 0x55, 0x09, 0x3B, 0x04, 0xCB, 0x00, 0x7E, 0xFF, 0x90, 0xFF, 0xE9, + 0xFF, 0xF8, 0xFF, 0xB1, 0xFF, 0x6C, 0xFF, 0x24, 0x00, 0xD8, 0x02, + 0x8A, 0x07, 0xC2, 0x0C, 0x34, 0x10, 0x2A, 0x10, 0xAA, 0x0C, 0x6F, + 0x07, 0xC4, 0x02, 0x1C, 0x00, 0x6C, 0xFF, 0xB3, 0xFF, 0xF9, 0xFF, + 0xE8, 0xFF, 0x8E, 0xFF, 0x80, 0xFF, 0xD7, 0x00, 0x53, 0x04, 0x71, + 0x09, 0x4C, 0x0E, 0xA1, 0x10, 0x43, 0x0F, 0xE3, 0x0A, 0x9D, 0x05, + 0x91, 0x01, 0xAE, 0xFF, 0x79, 0xFF, 0xD4, 0xFF, 0x00, 0x00, 0xFF, + 0xFF, 0xCD, 0xFF, 0x74, 0xFF, 0xC2, 0xFF, 0xD2, 0x01, 0x06, 0x06, + 0x50, 0x0B, 0x82, 0x0F, 0x93, 0x10, 0xF8, 0x0D, 0x00, 0x09, 0xF6, + 0x03, 0xA7, 0x00, 0x78, 0xFF, 0x96, 0xFF, 0xEC, 0xFF, 0xF6, 0xFF, + 0xAB, 0xFF, 0x6D, 0xFF, 0x3E, 0x00, 0x15, 0x03, 0xDE, 0x07, 0x0B, + 0x0D, 0x50, 0x10, 0x0A, 0x10, 0x5E, 0x0C, 0x1C, 0x07, 0x8A, 0x02, + 0x04, 0x00, 0x6C, 0xFF, 0xB9, 0xFF, 0xFB, 0xFF, 0xE4, 0xFF, 0x89, + 0xFF, 0x88, 0xFF, 0xFD, 0x00, 0x9B, 0x04, 0xC5, 0x09, 0x88, 0x0E, + 0xA8, 0x10, 0x10, 0x0F, 0x91, 0x0A, 0x50, 0x05, 0x64, 0x01, 0xA1, + 0xFF, 0x7D, 0xFF, 0xD9, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0xC7, 0xFF, + 0x71, 0xFF, 0xD3, 0xFF, 0x05, 0x02, 0x55, 0x06, 0xA0, 0x0B, 0xAD, + 0x0F, 0x84, 0x10, 0xB6, 0x0D, 0xAC, 0x08, 0xB3, 0x03, 0x86, 0x00, + 0x74, 0xFF, 0x9C, 0xFF, 0xF0, 0xFF, 0xF4, 0xFF, 0xA5, 0xFF, 0x6F, + 0xFF, 0x5A, 0x00, 0x54, 0x03, 0x32, 0x08, 0x52, 0x0D, 0x68, 0x10, + 0xE6, 0x0F, 0x11, 0x0C, 0xCA, 0x06, 0x52, 0x02, 0xEF, 0xFF, 0x6E, + 0xFF, 0xBF, 0xFF, 0xFC, 0xFF, 0xDF, 0xFF, 0x84, 0xFF, 0x91, 0xFF, + 0x25, 0x01, 0xE4, 0x04, 0x19, 0x0A, 0xC2, 0x0E, 0xAA, 0x10, 0xDA, + 0x0E, 0x3E, 0x0A, 0x05, 0x05, 0x38, 0x01, 0x96, 0xFF, 0x81, 0xFF, + 0xDD, 0xFF, 0x00, 0x00, 0xFD, 0xFF, 0xC1, 0xFF, 0x6E, 0xFF, 0xE6, + 0xFF, 0x3A, 0x02, 0xA6, 0x06, 0xEF, 0x0B, 0xD6, 0x0F, 0x71, 0x10, + 0x71, 0x0D, 0x57, 0x08, 0x71, 0x03, 0x67, 0x00, 0x70, 0xFF, 0xA2, + 0xFF, 0xF3, 0xFF, 0xF1, 0xFF, 0x9F, 0xFF, 0x72, 0xFF, 0x78, 0x00, + 0x95, 0x03, 0x86, 0x08, 0x98, 0x0D, 0x7C, 0x10, 0xC0, 0x0F, 0xC3, + 0x0B, 0x79, 0x06, 0x1C, 0x02, 0xDB, 0xFF, 0x70, 0xFF, 0xC5, 0xFF, + 0xFE, 0xFF, 0x00, 0x00, 0xDB, 0xFF, 0x7F, 0xFF, 0x9C, 0xFF, 0x50, + 0x01, 0x2F, 0x05, 0x6C, 0x0A, 0xF9, 0x0E, 0xA9, 0x10, 0xA2, 0x0E, + 0xEA, 0x09, 0xBB, 0x04, 0x0F, 0x01, 0x8C, 0xFF, 0x87, 0xFF, 0xE2, + 0xFF, 0xFC, 0xFF, 0xBC, 0xFF, 0x6D, 0xFF, 0xFA, 0xFF, 0x71, 0x02, + 0xF7, 0x06, 0x3C, 0x0C, 0xFB, 0x0F, 0x5B, 0x10, 0x2B, 0x0D, 0x03, + 0x08, 0x31, 0x03, 0x4A, 0x00, 0x6E, 0xFF, 0xA8, 0xFF, 0xF5, 0xFF, + 0xEE, 0xFF, 0x99, 0xFF, 0x76, 0xFF, 0x98, 0x00, 0xD8, 0x03, 0xDB, + 0x08, 0xDB, 0x0D, 0x8D, 0x10, 0x96, 0x0F, 0x73, 0x0B, 0x29, 0x06, + 0xE8, 0x01, 0xC9, 0xFF, 0x72, 0xFF, 0xCA, 0xFF, 0xFE, 0xFF, 0x00, + 0x00, 0xD6, 0xFF, 0x7A, 0xFF, 0xA8, 0xFF, 0x7D, 0x01, 0x7B, 0x05, + 0xBF, 0x0A, 0x2D, 0x0F, 0xA5, 0x10, 0x67, 0x0E, 0x96, 0x09, 0x73, + 0x04, 0xE7, 0x00, 0x84, 0xFF, 0x8C, 0xFF, 0xE6, 0xFF, 0xFA, 0xFF, + 0xB6, 0xFF, 0x6C, 0xFF, 0x11, 0x00, 0xAA, 0x02, 0x4A, 0x07, 0x88, + 0x0C, 0x1C, 0x10, 0x41, 0x10, 0xE3, 0x0C, 0xAF, 0x07, 0xF3, 0x02, + 0x2F, 0x00, 0x6C, 0xFF, 0xAE, 0xFF, 0xF7, 0xFF, 0xEA, 0xFF, 0x93, + 0xFF, 0x7B, 0xFF, 0xBB, 0x00, 0x1C, 0x04, 0x2F, 0x09, 0x1B, 0x0E, + 0x9A, 0x10, 0x68, 0x0F, 0x23, 0x0B, 0xDA, 0x05, 0xB7, 0x01, 0xB9, + 0xFF, 0x76, 0xFF, 0xD0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD1, 0xFF, + 0x76, 0xFF, 0xB6, 0xFF, 0xAC, 0x01, 0xC8, 0x05, 0x11, 0x0B, 0x5E, + 0x0F, 0x9C, 0x10, 0x29, 0x0E, 0x42, 0x09, 0x2C, 0x04, 0xC2, 0x00, + 0x7D, 0xFF, 0x92, 0xFF, 0xEA, 0xFF, 0xF8, 0xFF, 0xB0, 0xFF, 0x6C, + 0xFF, 0x29, 0x00, 0xE6, 0x02, 0x9D, 0x07, 0xD3, 0x0C, 0x3B, 0x10, + 0x23, 0x10, 0x99, 0x0C, 0x5C, 0x07, 0xB7, 0x02, 0x16, 0x00, 0x6C, + 0xFF, 0xB4, 0xFF, 0xF9, 0xFF, 0xE7, 0xFF, 0x8D, 0xFF, 0x82, 0xFF, + 0xDF, 0x00, 0x63, 0x04, 0x84, 0x09, 0x59, 0x0E, 0xA3, 0x10, 0x38, + 0x0F, 0xD1, 0x0A, 0x8C, 0x05, 0x87, 0x01, 0xAB, 0xFF, 0x79, 0xFF, + 0xD5, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xCB, 0xFF, 0x73, 0xFF, 0xC6, + 0xFF, 0xDD, 0x01, 0x17, 0x06, 0x62, 0x0B, 0x8C, 0x0F, 0x90, 0x10, + 0xE9, 0x0D, 0xED, 0x08, 0xE7, 0x03, 0xA0, 0x00, 0x77, 0xFF, 0x97, + 0xFF, 0xED, 0xFF, 0xF6, 0xFF, 0xA9, 0xFF, 0x6D, 0xFF, 0x44, 0x00, + 0x23, 0x03, 0xF1, 0x07, 0x1B, 0x0D, 0x55, 0x10, 0x02, 0x10, 0x4D, + 0x0C, 0x0A, 0x07, 0x7E, 0x02, 0xFF, 0xFF, 0x6D, 0xFF, 0xBA, 0xFF, + 0xFB, 0xFF, 0xE3, 0xFF, 0x88, 0xFF, 0x8A, 0xFF, 0x06, 0x01, 0xAB, + 0x04, 0xD8, 0x09, 0x95, 0x0E, 0xA9, 0x10, 0x05, 0x0F, 0x7F, 0x0A, + 0x40, 0x05, 0x5A, 0x01, 0x9F, 0xFF, 0x7E, 0xFF, 0xDA, 0xFF, 0x00, + 0x00, 0xFE, 0xFF, 0xC6, 0xFF, 0x70, 0xFF, 0xD7, 0xFF, 0x10, 0x02, + 0x67, 0x06, 0xB1, 0x0B, 0xB7, 0x0F, 0x80, 0x10, 0xA7, 0x0D, 0x99, + 0x08, 0xA4, 0x03, 0x7F, 0x00, 0x73, 0xFF, 0x9D, 0xFF, 0xF0, 0xFF, + 0xF3, 0xFF, 0xA3, 0xFF, 0x70, 0xFF, 0x60, 0x00, 0x62, 0x03, 0x45, + 0x08, 0x62, 0x0D, 0x6C, 0x10, 0xDE, 0x0F, 0x00, 0x0C, 0xB8, 0x06, + 0x46, 0x02, 0xEA, 0xFF, 0x6E, 0xFF, 0xC0, 0xFF, 0xFD, 0xFF, 0x00, + 0x00, 0xDE, 0xFF, 0x83, 0xFF, 0x94, 0xFF, 0x2F, 0x01, 0xF4, 0x04, + 0x2B, 0x0A, 0xCE, 0x0E, 0xAA, 0x10, 0xCE, 0x0E, 0x2B, 0x0A, 0xF4, + 0x04, 0x2F, 0x01, 0x94, 0xFF, 0x83, 0xFF, 0xDE, 0xFF, 0xFD, 0xFF, + 0xC0, 0xFF, 0x6E, 0xFF, 0xEA, 0xFF, 0x46, 0x02, 0xB8, 0x06, 0x00, + 0x0C, 0xDE, 0x0F, 0x6C, 0x10, 0x62, 0x0D, 0x45, 0x08, 0x62, 0x03, + 0x60, 0x00, 0x70, 0xFF, 0xA3, 0xFF, 0xF3, 0xFF, 0xF0, 0xFF, 0x9D, + 0xFF, 0x73, 0xFF, 0x7F, 0x00, 0xA4, 0x03, 0x99, 0x08, 0xA7, 0x0D, + 0x80, 0x10, 0xB7, 0x0F, 0xB1, 0x0B, 0x67, 0x06, 0x10, 0x02, 0xD7, + 0xFF, 0x70, 0xFF, 0xC6, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0xDA, 0xFF, + 0x7E, 0xFF, 0x9F, 0xFF, 0x5A, 0x01, 0x40, 0x05, 0x7F, 0x0A, 0x05, + 0x0F, 0xA9, 0x10, 0x95, 0x0E, 0xD8, 0x09, 0xAB, 0x04, 0x06, 0x01, + 0x8A, 0xFF, 0x88, 0xFF, 0xE3, 0xFF, 0xFB, 0xFF, 0xBA, 0xFF, 0x6D, + 0xFF, 0xFF, 0xFF, 0x7E, 0x02, 0x0A, 0x07, 0x4D, 0x0C, 0x02, 0x10, + 0x55, 0x10, 0x1B, 0x0D, 0xF1, 0x07, 0x23, 0x03, 0x44, 0x00, 0x6D, + 0xFF, 0xA9, 0xFF, 0xF6, 0xFF, 0xED, 0xFF, 0x97, 0xFF, 0x77, 0xFF, + 0xA0, 0x00, 0xE7, 0x03, 0xED, 0x08, 0xE9, 0x0D, 0x90, 0x10, 0x8C, + 0x0F, 0x62, 0x0B, 0x17, 0x06, 0xDD, 0x01, 0xC6, 0xFF, 0x73, 0xFF, + 0xCB, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xD5, 0xFF, 0x79, 0xFF, 0xAB, + 0xFF, 0x87, 0x01, 0x8C, 0x05, 0xD1, 0x0A, 0x38, 0x0F, 0xA3, 0x10, + 0x59, 0x0E, 0x84, 0x09, 0x63, 0x04, 0xDF, 0x00, 0x82, 0xFF, 0x8D, + 0xFF, 0xE7, 0xFF, 0xF9, 0xFF, 0xB4, 0xFF, 0x6C, 0xFF, 0x16, 0x00, + 0xB7, 0x02, 0x5C, 0x07, 0x99, 0x0C, 0x23, 0x10, 0x3B, 0x10, 0xD3, + 0x0C, 0x9D, 0x07, 0xE6, 0x02, 0x29, 0x00, 0x6C, 0xFF, 0xB0, 0xFF, + 0xF8, 0xFF, 0xEA, 0xFF, 0x92, 0xFF, 0x7D, 0xFF, 0xC2, 0x00, 0x2C, + 0x04, 0x42, 0x09, 0x29, 0x0E, 0x9C, 0x10, 0x5E, 0x0F, 0x11, 0x0B, + 0xC8, 0x05, 0xAC, 0x01, 0xB6, 0xFF, 0x76, 0xFF, 0xD1, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xD0, 0xFF, 0x76, 0xFF, 0xB9, 0xFF, 0xB7, 0x01, + 0xDA, 0x05, 0x23, 0x0B, 0x68, 0x0F, 0x9A, 0x10, 0x1B, 0x0E, 0x2F, + 0x09, 0x1C, 0x04, 0xBB, 0x00, 0x7B, 0xFF, 0x93, 0xFF, 0xEA, 0xFF, + 0xF7, 0xFF, 0xAE, 0xFF, 0x6C, 0xFF, 0x2F, 0x00, 0xF3, 0x02, 0xAF, + 0x07, 0xE3, 0x0C, 0x41, 0x10, 0x1C, 0x10, 0x88, 0x0C, 0x4A, 0x07, + 0xAA, 0x02, 0x11, 0x00, 0x6C, 0xFF, 0xB6, 0xFF, 0xFA, 0xFF, 0xE6, + 0xFF, 0x8C, 0xFF, 0x84, 0xFF, 0xE7, 0x00, 0x73, 0x04, 0x96, 0x09, + 0x67, 0x0E, 0xA5, 0x10, 0x2D, 0x0F, 0xBF, 0x0A, 0x7B, 0x05, 0x7D, + 0x01, 0xA8, 0xFF, 0x7A, 0xFF, 0xD6, 0xFF, 0x00, 0x00, 0xFE, 0xFF, + 0xCA, 0xFF, 0x72, 0xFF, 0xC9, 0xFF, 0xE8, 0x01, 0x29, 0x06, 0x73, + 0x0B, 0x96, 0x0F, 0x8D, 0x10, 0xDB, 0x0D, 0xDB, 0x08, 0xD8, 0x03, + 0x98, 0x00, 0x76, 0xFF, 0x99, 0xFF, 0xEE, 0xFF, 0xF5, 0xFF, 0xA8, + 0xFF, 0x6E, 0xFF, 0x4A, 0x00, 0x31, 0x03, 0x03, 0x08, 0x2B, 0x0D, + 0x5B, 0x10, 0xFB, 0x0F, 0x3C, 0x0C, 0xF7, 0x06, 0x71, 0x02, 0xFA, + 0xFF, 0x6D, 0xFF, 0xBC, 0xFF, 0xFC, 0xFF, 0xE2, 0xFF, 0x87, 0xFF, + 0x8C, 0xFF, 0x0F, 0x01, 0xBB, 0x04, 0xEA, 0x09, 0xA2, 0x0E, 0xA9, + 0x10, 0xF9, 0x0E, 0x6C, 0x0A, 0x2F, 0x05, 0x50, 0x01, 0x9C, 0xFF, + 0x7F, 0xFF, 0xDB, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0xC5, 0xFF, 0x70, + 0xFF, 0xDB, 0xFF, 0x1C, 0x02, 0x79, 0x06, 0xC3, 0x0B, 0xC0, 0x0F, + 0x7C, 0x10, 0x98, 0x0D, 0x86, 0x08, 0x95, 0x03, 0x78, 0x00, 0x72, + 0xFF, 0x9F, 0xFF, 0xF1, 0xFF, 0xF3, 0xFF, 0xA2, 0xFF, 0x70, 0xFF, + 0x67, 0x00, 0x71, 0x03, 0x57, 0x08, 0x71, 0x0D, 0x71, 0x10, 0xD6, + 0x0F, 0xEF, 0x0B, 0xA6, 0x06, 0x3A, 0x02, 0xE6, 0xFF, 0x6E, 0xFF, + 0xC1, 0xFF, 0xFD, 0xFF, 0x00, 0x00, 0xDD, 0xFF, 0x81, 0xFF, 0x96, + 0xFF, 0x38, 0x01, 0x05, 0x05, 0x3E, 0x0A, 0xDA, 0x0E, 0xAA, 0x10, + 0xC2, 0x0E, 0x19, 0x0A, 0xE4, 0x04, 0x25, 0x01, 0x91, 0xFF, 0x84, + 0xFF, 0xDF, 0xFF, 0xFC, 0xFF, 0xBF, 0xFF, 0x6E, 0xFF, 0xEF, 0xFF, + 0x52, 0x02, 0xCA, 0x06, 0x11, 0x0C, 0xE6, 0x0F, 0x68, 0x10, 0x52, + 0x0D, 0x32, 0x08, 0x54, 0x03, 0x5A, 0x00, 0x6F, 0xFF, 0xA5, 0xFF, + 0xF4, 0xFF, 0xF0, 0xFF, 0x9C, 0xFF, 0x74, 0xFF, 0x86, 0x00, 0xB3, + 0x03, 0xAC, 0x08, 0xB6, 0x0D, 0x84, 0x10, 0xAD, 0x0F, 0xA0, 0x0B, + 0x55, 0x06, 0x05, 0x02, 0xD3, 0xFF, 0x71, 0xFF, 0xC7, 0xFF, 0xFE, + 0xFF, 0x00, 0x00, 0xD9, 0xFF, 0x7D, 0xFF, 0xA1, 0xFF, 0x64, 0x01, + 0x50, 0x05, 0x91, 0x0A, 0x10, 0x0F, 0xA8, 0x10, 0x88, 0x0E, 0xC5, + 0x09, 0x9B, 0x04, 0xFD, 0x00, 0x88, 0xFF, 0x89, 0xFF, 0xE4, 0xFF, + 0xFB, 0xFF, 0xB9, 0xFF, 0x6C, 0xFF, 0x04, 0x00, 0x8A, 0x02, 0x1C, + 0x07, 0x5E, 0x0C, 0x0A, 0x10, 0x50, 0x10, 0x0B, 0x0D, 0xDE, 0x07, + 0x15, 0x03, 0x3E, 0x00, 0x6D, 0xFF, 0xAB, 0xFF, 0xF6, 0xFF, 0xEC, + 0xFF, 0x96, 0xFF, 0x78, 0xFF, 0xA7, 0x00, 0xF6, 0x03, 0x00, 0x09, + 0xF8, 0x0D, 0x93, 0x10, 0x82, 0x0F, 0x50, 0x0B, 0x06, 0x06, 0xD2, + 0x01, 0xC2, 0xFF, 0x74, 0xFF, 0xCD, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0xD4, 0xFF, 0x79, 0xFF, 0xAE, 0xFF, 0x91, 0x01, 0x9D, 0x05, 0xE3, + 0x0A, 0x43, 0x0F, 0xA1, 0x10, 0x4C, 0x0E, 0x71, 0x09, 0x53, 0x04, + 0xD7, 0x00, 0x80, 0xFF, 0x8E, 0xFF, 0xE8, 0xFF, 0xF9, 0xFF, 0xB3, + 0xFF, 0x6C, 0xFF, 0x1C, 0x00, 0xC4, 0x02, 0x6F, 0x07, 0xAA, 0x0C, + 0x2A, 0x10, 0x34, 0x10, 0xC2, 0x0C, 0x8A, 0x07, 0xD8, 0x02, 0x24, + 0x00, 0x6C, 0xFF, 0xB1, 0xFF, 0xF8, 0xFF, 0xE9, 0xFF, 0x90, 0xFF, + 0x7E, 0xFF, 0xCB, 0x00, 0x3B, 0x04, 0x55, 0x09, 0x37, 0x0E, 0x9E, + 0x10, 0x53, 0x0F, 0xFF, 0x0A, 0xB7, 0x05, 0xA1, 0x01, 0xB3, 0xFF, + 0x77, 0xFF, 0xD2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCE, 0xFF, 0x75, + 0xFF, 0xBD, 0xFF, 0xC1, 0x01, 0xEB, 0x05, 0x35, 0x0B, 0x73, 0x0F, + 0x97, 0x10, 0x0D, 0x0E, 0x1C, 0x09, 0x0D, 0x04, 0xB3, 0x00, 0x7A, + 0xFF, 0x94, 0xFF, 0xEB, 0xFF, 0xF7, 0xFF, 0xAD, 0xFF, 0x6D, 0xFF, + 0x35, 0x00, 0x01, 0x03, 0xC2, 0x07, 0xF3, 0x0C, 0x47, 0x10, 0x15, + 0x10, 0x78, 0x0C, 0x37, 0x07, 0x9D, 0x02, 0x0C, 0x00, 0x6C, 0xFF, + 0xB7, 0xFF, 0xFA, 0xFF, 0xE5, 0xFF, 0x8B, 0xFF, 0x85, 0xFF, 0xF0, + 0x00, 0x83, 0x04, 0xA9, 0x09, 0x74, 0x0E, 0xA6, 0x10, 0x21, 0x0F, + 0xAD, 0x0A, 0x6A, 0x05, 0x73, 0x01, 0xA5, 0xFF, 0x7B, 0xFF, 0xD7, + 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0xC9, 0xFF, 0x72, 0xFF, 0xCD, 0xFF, + 0xF4, 0x01, 0x3B, 0x06, 0x85, 0x0B, 0x9F, 0x0F, 0x89, 0x10, 0xCC, + 0x0D, 0xC8, 0x08, 0xC9, 0x03, 0x91, 0x00, 0x75, 0xFF, 0x9A, 0xFF, + 0xEF, 0xFF, 0xF5, 0xFF, 0xA7, 0xFF, 0x6E, 0xFF, 0x50, 0x00, 0x3F, + 0x03, 0x16, 0x08, 0x3B, 0x0D, 0x60, 0x10, 0xF3, 0x0F, 0x2B, 0x0C, + 0xE5, 0x06, 0x65, 0x02, 0xF6, 0xFF, 0x6D, 0xFF, 0xBD, 0xFF, 0xFC, + 0xFF, 0xE1, 0xFF, 0x85, 0xFF, 0x8E, 0xFF, 0x18, 0x01, 0xCB, 0x04, + 0xFD, 0x09, 0xAF, 0x0E, 0xAA, 0x10, 0xED, 0x0E, 0x5A, 0x0A, 0x1E, + 0x05, 0x46, 0x01, 0x9A, 0xFF, 0x80, 0xFF, 0xDC, 0xFF, 0x00, 0x00, + 0xFD, 0xFF, 0xC3, 0xFF, 0x6F, 0xFF, 0xDF, 0xFF, 0x28, 0x02, 0x8B, + 0x06, 0xD5, 0x0B, 0xC9, 0x0F, 0x78, 0x10, 0x88, 0x0D, 0x73, 0x08, + 0x86, 0x03, 0x71, 0x00, 0x71, 0xFF, 0xA0, 0xFF, 0xF2, 0xFF, 0xF2, + 0xFF, 0xA1, 0xFF, 0x71, 0xFF, 0x6E, 0x00, 0x7F, 0x03, 0x6A, 0x08, + 0x81, 0x0D, 0x76, 0x10, 0xCD, 0x0F, 0xDD, 0x0B, 0x94, 0x06, 0x2E, + 0x02, 0xE1, 0xFF, 0x6F, 0xFF, 0xC3, 0xFF, 0xFD, 0xFF, 0x00, 0x00, + 0xDC, 0xFF, 0x80, 0xFF, 0x98, 0xFF, 0x42, 0x01, 0x16, 0x05, 0x50, + 0x0A, 0xE7, 0x0E, 0xAA, 0x10, 0xB5, 0x0E, 0x06, 0x0A, 0xD3, 0x04, + 0x1C, 0x01, 0x8F, 0xFF, 0x85, 0xFF, 0xE0, 0xFF, 0xFC, 0xFF, 0xBE, + 0xFF, 0x6D, 0xFF, 0xF3, 0xFF, 0x5E, 0x02, 0xDC, 0x06, 0x23, 0x0C, + 0xEF, 0x0F, 0x63, 0x10, 0x43, 0x0D, 0x1F, 0x08, 0x46, 0x03, 0x53, + 0x00, 0x6E, 0xFF, 0xA6, 0xFF, 0xF4, 0xFF, 0xEF, 0xFF, 0x9B, 0xFF, + 0x75, 0xFF, 0x8D, 0x00, 0xC1, 0x03, 0xBE, 0x08, 0xC4, 0x0D, 0x88, + 0x10, 0xA4, 0x0F, 0x8E, 0x0B, 0x43, 0x06, 0xF9, 0x01, 0xCF, 0xFF, + 0x71, 0xFF, 0xC8, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0xD8, 0xFF, 0x7C, + 0xFF, 0xA4, 0xFF, 0x6E, 0x01, 0x61, 0x05, 0xA3, 0x0A, 0x1C, 0x0F, + 0xA7, 0x10, 0x7B, 0x0E, 0xB2, 0x09, 0x8B, 0x04, 0xF4, 0x00, 0x86, + 0xFF, 0x8A, 0xFF, 0xE4, 0xFF, 0xFA, 0xFF, 0xB8, 0xFF, 0x6C, 0xFF, + 0x09, 0x00, 0x97, 0x02, 0x2E, 0x07, 0x6F, 0x0C, 0x11, 0x10, 0x4A, + 0x10, 0xFB, 0x0C, 0xCB, 0x07, 0x07, 0x03, 0x38, 0x00, 0x6D, 0xFF, + 0xAC, 0xFF, 0xF7, 0xFF, 0xEC, 0xFF, 0x95, 0xFF, 0x79, 0xFF, 0xAF, + 0x00, 0x05, 0x04, 0x13, 0x09, 0x06, 0x0E, 0x96, 0x10, 0x78, 0x0F, + 0x3E, 0x0B, 0xF4, 0x05, 0xC7, 0x01, 0xBF, 0xFF, 0x74, 0xFF, 0xCE, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0xFF, 0x78, 0xFF, 0xB1, 0xFF, + 0x9C, 0x01, 0xAE, 0x05, 0xF6, 0x0A, 0x4E, 0x0F, 0x9F, 0x10, 0x3E, + 0x0E, 0x5E, 0x09, 0x43, 0x04, 0xCF, 0x00, 0x7F, 0xFF, 0x90, 0xFF, + 0xE8, 0xFF, 0xF9, 0xFF, 0xB2, 0xFF, 0x6C, 0xFF, 0x21, 0x00, 0xD2, + 0x02, 0x81, 0x07, 0xBA, 0x0C, 0x31, 0x10, 0x2E, 0x10, 0xB2, 0x0C, + 0x78, 0x07, 0xCB, 0x02, 0x1E, 0x00, 0x6C, 0xFF, 0xB2, 0xFF, 0xF9, + 0xFF, 0xE8, 0xFF, 0x8F, 0xFF, 0x80, 0xFF, 0xD3, 0x00, 0x4B, 0x04, + 0x67, 0x09, 0x45, 0x0E, 0xA0, 0x10, 0x48, 0x0F, 0xEC, 0x0A, 0xA6, + 0x05, 0x97, 0x01, 0xB0, 0xFF, 0x78, 0xFF, 0xD3, 0xFF, 0x00, 0x00, + 0xFF, 0xFF, 0xCD, 0xFF, 0x74, 0xFF, 0xC0, 0xFF, 0xCC, 0x01, 0xFD, + 0x05, 0x47, 0x0B, 0x7D, 0x0F, 0x94, 0x10, 0xFF, 0x0D, 0x0A, 0x09, + 0xFE, 0x03, 0xAB, 0x00, 0x79, 0xFF, 0x95, 0xFF, 0xEC, 0xFF, 0xF7, + 0xFF, 0xAC, 0xFF, 0x6D, 0xFF, 0x3B, 0x00, 0x0E, 0x03, 0xD5, 0x07, + 0x03, 0x0D, 0x4D, 0x10, 0x0E, 0x10, 0x67, 0x0C, 0x25, 0x07, 0x91, + 0x02, 0x07, 0x00, 0x6C, 0xFF, 0xB8, 0xFF, 0xFB, 0xFF, 0xE4, 0xFF, + 0x89, 0xFF, 0x87, 0xFF, 0xF9, 0x00, 0x93, 0x04, 0xBC, 0x09, 0x82, + 0x0E, 0xA7, 0x10, 0x16, 0x0F, 0x9A, 0x0A, 0x59, 0x05, 0x69, 0x01, + 0xA3, 0xFF, 0x7C, 0xFF, 0xD8, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0xC8, + 0xFF, 0x71, 0xFF, 0xD1, 0xFF, 0xFF, 0x01, 0x4C, 0x06, 0x97, 0x0B, + 0xA9, 0x0F, 0x86, 0x10, 0xBD, 0x0D, 0xB5, 0x08, 0xBA, 0x03, 0x8A, + 0x00, 0x74, 0xFF, 0x9B, 0xFF, 0xEF, 0xFF, 0xF4, 0xFF, 0xA5, 0xFF, + 0x6F, 0xFF, 0x57, 0x00, 0x4D, 0x03, 0x29, 0x08, 0x4B, 0x0D, 0x65, + 0x10, 0xEB, 0x0F, 0x1A, 0x0C, 0xD3, 0x06, 0x58, 0x02, 0xF1, 0xFF, + 0x6D, 0xFF, 0xBE, 0xFF, 0xFC, 0xFF, 0xE0, 0xFF, 0x84, 0xFF, 0x90, + 0xFF, 0x21, 0x01, 0xDC, 0x04, 0x10, 0x0A, 0xBB, 0x0E, 0xAA, 0x10, + 0xE1, 0x0E, 0x47, 0x0A, 0x0D, 0x05, 0x3D, 0x01, 0x97, 0xFF, 0x81, + 0xFF, 0xDD, 0xFF, 0x00, 0x00, 0xFD, 0xFF, 0xC2, 0xFF, 0x6F, 0xFF, + 0xE4, 0xFF, 0x34, 0x02, 0x9D, 0x06, 0xE6, 0x0B, 0xD1, 0x0F, 0x73, + 0x10, 0x79, 0x0D, 0x61, 0x08, 0x78, 0x03, 0x6A, 0x00, 0x70, 0xFF, + 0xA1, 0xFF, 0xF2, 0xFF, 0xF1, 0xFF, 0x9F, 0xFF, 0x72, 0xFF, 0x74, + 0x00, 0x8E, 0x03, 0x7D, 0x08, 0x90, 0x0D, 0x7A, 0x10, 0xC4, 0x0F, + 0xCC, 0x0B, 0x82, 0x06, 0x22, 0x02, 0xDD, 0xFF, 0x6F, 0xFF, 0xC4, + 0xFF, 0xFD, 0xFF, 0x00, 0x00, 0xDB, 0xFF, 0x7F, 0xFF, 0x9B, 0xFF, + 0x4B, 0x01, 0x26, 0x05, 0x63, 0x0A, 0xF3, 0x0E, 0xAA, 0x10, 0xA8, + 0x0E, 0xF4, 0x09, 0xC3, 0x04, 0x13, 0x01, 0x8D, 0xFF, 0x86, 0xFF, + 0xE1, 0xFF, 0xFC, 0xFF, 0xBC, 0xFF, 0x6D, 0xFF, 0xF8, 0xFF, 0x6B, + 0x02, 0xEE, 0x06, 0x34, 0x0C, 0xF7, 0x0F, 0x5D, 0x10, 0x33, 0x0D, + 0x0D, 0x08, 0x38, 0x03, 0x4D, 0x00, 0x6E, 0xFF, 0xA7, 0xFF, 0xF5, + 0xFF, 0xEE, 0xFF, 0x99, 0xFF, 0x76, 0xFF, 0x94, 0x00, 0xD0, 0x03, + 0xD1, 0x08, 0xD3, 0x0D, 0x8B, 0x10, 0x9A, 0x0F, 0x7C, 0x0B, 0x32, + 0x06, 0xEE, 0x01, 0xCB, 0xFF, 0x72, 0xFF, 0xCA, 0xFF, 0xFE, 0xFF, + 0x00, 0x00, 0xD6, 0xFF, 0x7B, 0xFF, 0xA7, 0xFF, 0x78, 0x01, 0x72, + 0x05, 0xB6, 0x0A, 0x27, 0x0F, 0xA5, 0x10, 0x6E, 0x0E, 0xA0, 0x09, + 0x7B, 0x04, 0xEC, 0x00, 0x85, 0xFF, 0x8B, 0xFF, 0xE5, 0xFF, 0xFA, + 0xFF, 0xB6, 0xFF, 0x6C, 0xFF, 0x0E, 0x00, 0xA4, 0x02, 0x41, 0x07, + 0x80, 0x0C, 0x19, 0x10, 0x44, 0x10, 0xEB, 0x0C, 0xB9, 0x07, 0xFA, + 0x02, 0x32, 0x00, 0x6D, 0xFF, 0xAE, 0xFF, 0xF7, 0xFF, 0xEB, 0xFF, + 0x93, 0xFF, 0x7B, 0xFF, 0xB7, 0x00, 0x15, 0x04, 0x26, 0x09, 0x14, + 0x0E, 0x98, 0x10, 0x6D, 0x0F, 0x2C, 0x0B, 0xE3, 0x05, 0xBC, 0x01, + 0xBB, 0xFF, 0x75, 0xFF, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD1, + 0xFF, 0x77, 0xFF, 0xB5, 0xFF, 0xA6, 0x01, 0xC0, 0x05, 0x08, 0x0B, + 0x58, 0x0F, 0x9D, 0x10, 0x30, 0x0E, 0x4B, 0x09, 0x34, 0x04, 0xC6, + 0x00, 0x7D, 0xFF, 0x91, 0xFF, 0xE9, 0xFF, 0xF8, 0xFF, 0xB0, 0xFF, + 0x6C, 0xFF, 0x27, 0x00, 0xDF, 0x02, 0x94, 0x07, 0xCA, 0x0C, 0x37, + 0x10, 0x27, 0x10, 0xA1, 0x0C, 0x65, 0x07, 0xBE, 0x02, 0x19, 0x00, + 0x6C, 0xFF, 0xB4, 0xFF, 0xF9, 0xFF, 0xE7, 0xFF, 0x8E, 0xFF, 0x81, + 0xFF, 0xDB, 0x00, 0x5B, 0x04, 0x7A, 0x09, 0x53, 0x0E, 0xA2, 0x10, + 0x3D, 0x0F, 0xDA, 0x0A, 0x95, 0x05, 0x8C, 0x01, 0xAD, 0xFF, 0x79, + 0xFF, 0xD4, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xCC, 0xFF, 0x73, 0xFF, + 0xC4, 0xFF, 0xD7, 0x01, 0x0E, 0x06, 0x59, 0x0B, 0x87, 0x0F, 0x91, + 0x10, 0xF0, 0x0D, 0xF7, 0x08, 0xEF, 0x03, 0xA3, 0x00, 0x78, 0xFF, + 0x97, 0xFF, 0xED, 0xFF, 0xF6, 0xFF, 0xAA, 0xFF, 0x6D, 0xFF, 0x41, + 0x00, 0x1C, 0x03, 0xE7, 0x07, 0x13, 0x0D, 0x52, 0x10, 0x06, 0x10, + 0x56, 0x0C, 0x13, 0x07, 0x84, 0x02, 0x02, 0x00, 0x6D, 0xFF, 0xBA, + 0xFF, 0xFB, 0xFF, 0xE3, 0xFF, 0x88, 0xFF, 0x89, 0xFF, 0x01, 0x01, + 0xA3, 0x04, 0xCE, 0x09, 0x8F, 0x0E, 0xA8, 0x10, 0x0A, 0x0F, 0x88, + 0x0A, 0x48, 0x05, 0x5F, 0x01, 0xA0, 0xFF, 0x7D, 0xFF, 0xD9, 0xFF, + 0x00, 0x00, 0xFE, 0xFF, 0xC7, 0xFF, 0x70, 0xFF, 0xD5, 0xFF, 0x0B, + 0x02, 0x5E, 0x06, 0xA9, 0x0B, 0xB2, 0x0F, 0x82, 0x10, 0xAE, 0x0D, + 0xA2, 0x08, 0xAB, 0x03, 0x82, 0x00, 0x73, 0xFF, 0x9D, 0xFF, 0xF0, + 0xFF, 0xF3, 0xFF, 0xA4, 0xFF, 0x6F, 0xFF, 0x5D, 0x00, 0x5B, 0x03, + 0x3B, 0x08, 0x5A, 0x0D, 0x6A, 0x10, 0xE2, 0x0F, 0x09, 0x0C, 0xC1, + 0x06, 0x4C, 0x02, 0xEC, 0xFF, 0x6E, 0xFF, 0xC0, 0xFF, 0xFC, 0xFF, + 0xDF, 0xFF, 0x83, 0xFF, 0x93, 0xFF, 0x2A, 0x01, 0xEC, 0x04, 0x22, + 0x0A, 0xC8, 0x0E, 0xAB, 0x10, 0xD4, 0x0E, 0x35, 0x0A, 0xFD, 0x04, + 0x33, 0x01, 0x95, 0xFF, 0x82, 0xFF, 0xDE, 0xFF, 0x00, 0x00, 0xFD, + 0xFF, 0xC1, 0xFF, 0x6E, 0xFF, 0xE8, 0xFF, 0x40, 0x02, 0xAF, 0x06, + 0xF7, 0x0B, 0xDA, 0x0F, 0x6F, 0x10, 0x6A, 0x0D, 0x4E, 0x08, 0x6A, + 0x03, 0x64, 0x00, 0x70, 0xFF, 0xA3, 0xFF, 0xF3, 0xFF, 0xF1, 0xFF, + 0x9E, 0xFF, 0x72, 0xFF, 0x7B, 0x00, 0x9C, 0x03, 0x90, 0x08, 0x9F, + 0x0D, 0x7E, 0x10, 0xBB, 0x0F, 0xBA, 0x0B, 0x70, 0x06, 0x16, 0x02, + 0xD9, 0xFF, 0x70, 0xFF, 0xC5, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0xDA, + 0xFF, 0x7E, 0xFF, 0x9D, 0xFF, 0x55, 0x01, 0x37, 0x05, 0x75, 0x0A, + 0xFF, 0x0E, 0xA9, 0x10, 0x9C, 0x0E, 0xE1, 0x09, 0xB3, 0x04, 0x0A, + 0x01, 0x8B, 0xFF, 0x87, 0xFF, 0xE2, 0xFF, 0xFB, 0xFF, 0xBB, 0xFF, + 0x6D, 0xFF, 0xFD, 0xFF, 0x77, 0x02, 0x01, 0x07, 0x45, 0x0C, 0xFF, + 0x0F, 0x58, 0x10, 0x23, 0x0D, 0xFA, 0x07, 0x2A, 0x03, 0x47, 0x00, + 0x6E, 0xFF, 0xA9, 0xFF, 0xF5, 0xFF, 0xED, 0xFF, 0x98, 0xFF, 0x77, + 0xFF, 0x9C, 0x00, 0xDF, 0x03, 0xE4, 0x08, 0xE2, 0x0D, 0x8E, 0x10, + 0x91, 0x0F, 0x6B, 0x0B, 0x20, 0x06, 0xE3, 0x01, 0xC8, 0xFF, 0x73, + 0xFF, 0xCB, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xD5, 0xFF, 0x7A, 0xFF, + 0xAA, 0xFF, 0x82, 0x01, 0x83, 0x05, 0xC8, 0x0A, 0x32, 0x0F, 0xA4, + 0x10, 0x60, 0x0E, 0x8D, 0x09, 0x6B, 0x04, 0xE3, 0x00, 0x83, 0xFF, + 0x8D, 0xFF, 0xE6, 0xFF, 0xFA, 0xFF, 0xB5, 0xFF, 0x6C, 0xFF, 0x14, + 0x00, 0xB1, 0x02, 0x53, 0x07, 0x91, 0x0C, 0x20, 0x10, 0x3E, 0x10, + 0xDB, 0x0C, 0xA6, 0x07, 0xEC, 0x02, 0x2C, 0x00, 0x6C, 0xFF, 0xAF, + 0xFF, 0xF8, 0xFF, 0xEA, 0xFF, 0x92, 0xFF, 0x7C, 0xFF, 0xBE, 0x00, + 0x24, 0x04, 0x38, 0x09, 0x22, 0x0E, 0x9B, 0x10, 0x63, 0x0F, 0x1A, + 0x0B, 0xD1, 0x05, 0xB1, 0x01, 0xB8, 0xFF, 0x76, 0xFF, 0xD0, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0xFF, 0x76, 0xFF, 0xB8, 0xFF, 0xB1, + 0x01, 0xD1, 0x05, 0x1A, 0x0B, 0x63, 0x0F, 0x9B, 0x10, 0x22, 0x0E, + 0x38, 0x09, 0x24, 0x04, 0xBE, 0x00, 0x7C, 0xFF, 0x92, 0xFF, 0xEA, + 0xFF, 0xF8, 0xFF, 0xAF, 0xFF, 0x6C, 0xFF, 0x2C, 0x00, 0xEC, 0x02, + 0xA6, 0x07, 0xDB, 0x0C, 0x3E, 0x10, 0x20, 0x10, 0x91, 0x0C, 0x53, + 0x07, 0xB1, 0x02, 0x14, 0x00, 0x6C, 0xFF, 0xB5, 0xFF, 0xFA, 0xFF, + 0xE6, 0xFF, 0x8D, 0xFF, 0x83, 0xFF, 0xE3, 0x00, 0x6B, 0x04, 0x8D, + 0x09, 0x60, 0x0E, 0xA4, 0x10, 0x32, 0x0F, 0xC8, 0x0A, 0x83, 0x05, + 0x82, 0x01, 0xAA, 0xFF, 0x7A, 0xFF, 0xD5, 0xFF, 0x00, 0x00, 0xFF, + 0xFF, 0xCB, 0xFF, 0x73, 0xFF, 0xC8, 0xFF, 0xE3, 0x01, 0x20, 0x06, + 0x6B, 0x0B, 0x91, 0x0F, 0x8E, 0x10, 0xE2, 0x0D, 0xE4, 0x08, 0xDF, + 0x03, 0x9C, 0x00, 0x77, 0xFF, 0x98, 0xFF, 0xED, 0xFF, 0xF5, 0xFF, + 0xA9, 0xFF, 0x6E, 0xFF, 0x47, 0x00, 0x2A, 0x03, 0xFA, 0x07, 0x23, + 0x0D, 0x58, 0x10, 0xFF, 0x0F, 0x45, 0x0C, 0x01, 0x07, 0x77, 0x02, + 0xFD, 0xFF, 0x6D, 0xFF, 0xBB, 0xFF, 0xFB, 0xFF, 0xE2, 0xFF, 0x87, + 0xFF, 0x8B, 0xFF, 0x0A, 0x01, 0xB3, 0x04, 0xE1, 0x09, 0x9C, 0x0E, + 0xA9, 0x10, 0xFF, 0x0E, 0x75, 0x0A, 0x37, 0x05, 0x55, 0x01, 0x9D, + 0xFF, 0x7E, 0xFF, 0xDA, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0xC5, 0xFF, + 0x70, 0xFF, 0xD9, 0xFF, 0x16, 0x02, 0x70, 0x06, 0xBA, 0x0B, 0xBB, + 0x0F, 0x7E, 0x10, 0x9F, 0x0D, 0x90, 0x08, 0x9C, 0x03, 0x7B, 0x00, + 0x72, 0xFF, 0x9E, 0xFF, 0xF1, 0xFF, 0xF3, 0xFF, 0xA3, 0xFF, 0x70, + 0xFF, 0x64, 0x00, 0x6A, 0x03, 0x4E, 0x08, 0x6A, 0x0D, 0x6F, 0x10, + 0xDA, 0x0F, 0xF7, 0x0B, 0xAF, 0x06, 0x40, 0x02, 0xE8, 0xFF, 0x6E, + 0xFF, 0xC1, 0xFF, 0xFD, 0xFF, 0x00, 0x00, 0xDE, 0xFF, 0x82, 0xFF, + 0x95, 0xFF, 0x33, 0x01, 0xFD, 0x04, 0x35, 0x0A, 0xD4, 0x0E, 0xAB, + 0x10, 0xC8, 0x0E, 0x22, 0x0A, 0xEC, 0x04, 0x2A, 0x01, 0x93, 0xFF, + 0x83, 0xFF, 0xDF, 0xFF, 0xFC, 0xFF, 0xC0, 0xFF, 0x6E, 0xFF, 0xEC, + 0xFF, 0x4C, 0x02, 0xC1, 0x06, 0x09, 0x0C, 0xE2, 0x0F, 0x6A, 0x10, + 0x5A, 0x0D, 0x3B, 0x08, 0x5B, 0x03, 0x5D, 0x00, 0x6F, 0xFF, 0xA4, + 0xFF, 0xF3, 0xFF, 0xF0, 0xFF, 0x9D, 0xFF, 0x73, 0xFF, 0x82, 0x00, + 0xAB, 0x03, 0xA2, 0x08, 0xAE, 0x0D, 0x82, 0x10, 0xB2, 0x0F, 0xA9, + 0x0B, 0x5E, 0x06, 0x0B, 0x02, 0xD5, 0xFF, 0x70, 0xFF, 0xC7, 0xFF, + 0xFE, 0xFF, 0x00, 0x00, 0xD9, 0xFF, 0x7D, 0xFF, 0xA0, 0xFF, 0x5F, + 0x01, 0x48, 0x05, 0x88, 0x0A, 0x0A, 0x0F, 0xA8, 0x10, 0x8F, 0x0E, + 0xCE, 0x09, 0xA3, 0x04, 0x01, 0x01, 0x89, 0xFF, 0x88, 0xFF, 0xE3, + 0xFF, 0xFB, 0xFF, 0xBA, 0xFF, 0x6D, 0xFF, 0x02, 0x00, 0x84, 0x02, + 0x13, 0x07, 0x56, 0x0C, 0x06, 0x10, 0x52, 0x10, 0x13, 0x0D, 0xE7, + 0x07, 0x1C, 0x03, 0x41, 0x00, 0x6D, 0xFF, 0xAA, 0xFF, 0xF6, 0xFF, + 0xED, 0xFF, 0x97, 0xFF, 0x78, 0xFF, 0xA3, 0x00, 0xEF, 0x03, 0xF7, + 0x08, 0xF0, 0x0D, 0x91, 0x10, 0x87, 0x0F, 0x59, 0x0B, 0x0E, 0x06, + 0xD7, 0x01, 0xC4, 0xFF, 0x73, 0xFF, 0xCC, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0xD4, 0xFF, 0x79, 0xFF, 0xAD, 0xFF, 0x8C, 0x01, 0x95, 0x05, + 0xDA, 0x0A, 0x3D, 0x0F, 0xA2, 0x10, 0x53, 0x0E, 0x7A, 0x09, 0x5B, + 0x04, 0xDB, 0x00, 0x81, 0xFF, 0x8E, 0xFF, 0xE7, 0xFF, 0xF9, 0xFF, + 0xB4, 0xFF, 0x6C, 0xFF, 0x19, 0x00, 0xBE, 0x02, 0x65, 0x07, 0xA1, + 0x0C, 0x27, 0x10, 0x37, 0x10, 0xCA, 0x0C, 0x94, 0x07, 0xDF, 0x02, + 0x27, 0x00, 0x6C, 0xFF, 0xB0, 0xFF, 0xF8, 0xFF, 0xE9, 0xFF, 0x91, + 0xFF, 0x7D, 0xFF, 0xC6, 0x00, 0x34, 0x04, 0x4B, 0x09, 0x30, 0x0E, + 0x9D, 0x10, 0x58, 0x0F, 0x08, 0x0B, 0xC0, 0x05, 0xA6, 0x01, 0xB5, + 0xFF, 0x77, 0xFF, 0xD1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, + 0x75, 0xFF, 0xBB, 0xFF, 0xBC, 0x01, 0xE3, 0x05, 0x2C, 0x0B, 0x6D, + 0x0F, 0x98, 0x10, 0x14, 0x0E, 0x26, 0x09, 0x15, 0x04, 0xB7, 0x00, + 0x7B, 0xFF, 0x93, 0xFF, 0xEB, 0xFF, 0xF7, 0xFF, 0xAE, 0xFF, 0x6D, + 0xFF, 0x32, 0x00, 0xFA, 0x02, 0xB9, 0x07, 0xEB, 0x0C, 0x44, 0x10, + 0x19, 0x10, 0x80, 0x0C, 0x41, 0x07, 0xA4, 0x02, 0x0E, 0x00, 0x6C, + 0xFF, 0xB6, 0xFF, 0xFA, 0xFF, 0xE5, 0xFF, 0x8B, 0xFF, 0x85, 0xFF, + 0xEC, 0x00, 0x7B, 0x04, 0xA0, 0x09, 0x6E, 0x0E, 0xA5, 0x10, 0x27, + 0x0F, 0xB6, 0x0A, 0x72, 0x05, 0x78, 0x01, 0xA7, 0xFF, 0x7B, 0xFF, + 0xD6, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0xCA, 0xFF, 0x72, 0xFF, 0xCB, + 0xFF, 0xEE, 0x01, 0x32, 0x06, 0x7C, 0x0B, 0x9A, 0x0F, 0x8B, 0x10, + 0xD3, 0x0D, 0xD1, 0x08, 0xD0, 0x03, 0x94, 0x00, 0x76, 0xFF, 0x99, + 0xFF, 0xEE, 0xFF, 0xF5, 0xFF, 0xA7, 0xFF, 0x6E, 0xFF, 0x4D, 0x00, + 0x38, 0x03, 0x0D, 0x08, 0x33, 0x0D, 0x5D, 0x10, 0xF7, 0x0F, 0x34, + 0x0C, 0xEE, 0x06, 0x6B, 0x02, 0xF8, 0xFF, 0x6D, 0xFF, 0xBC, 0xFF, + 0xFC, 0xFF, 0xE1, 0xFF, 0x86, 0xFF, 0x8D, 0xFF, 0x13, 0x01, 0xC3, + 0x04, 0xF4, 0x09, 0xA8, 0x0E, 0xAA, 0x10, 0xF3, 0x0E, 0x63, 0x0A, + 0x26, 0x05, 0x4B, 0x01, 0x9B, 0xFF, 0x7F, 0xFF, 0xDB, 0xFF, 0x00, + 0x00, 0xFD, 0xFF, 0xC4, 0xFF, 0x6F, 0xFF, 0xDD, 0xFF, 0x22, 0x02, + 0x82, 0x06, 0xCC, 0x0B, 0xC4, 0x0F, 0x7A, 0x10, 0x90, 0x0D, 0x7D, + 0x08, 0x8E, 0x03, 0x74, 0x00, 0x72, 0xFF, 0x9F, 0xFF, 0xF1, 0xFF, + 0xF2, 0xFF, 0xA1, 0xFF, 0x70, 0xFF, 0x6A, 0x00, 0x78, 0x03, 0x61, + 0x08, 0x79, 0x0D, 0x73, 0x10, 0xD1, 0x0F, 0xE6, 0x0B, 0x9D, 0x06, + 0x34, 0x02, 0xE4, 0xFF, 0x6F, 0xFF, 0xC2, 0xFF, 0xFD, 0xFF, 0x00, + 0x00, 0xDD, 0xFF, 0x81, 0xFF, 0x97, 0xFF, 0x3D, 0x01, 0x0D, 0x05, + 0x47, 0x0A, 0xE1, 0x0E, 0xAA, 0x10, 0xBB, 0x0E, 0x10, 0x0A, 0xDC, + 0x04, 0x21, 0x01, 0x90, 0xFF, 0x84, 0xFF, 0xE0, 0xFF, 0xFC, 0xFF, + 0xBE, 0xFF, 0x6D, 0xFF, 0xF1, 0xFF, 0x58, 0x02, 0xD3, 0x06, 0x1A, + 0x0C, 0xEB, 0x0F, 0x65, 0x10, 0x4B, 0x0D, 0x29, 0x08, 0x4D, 0x03, + 0x57, 0x00, 0x6F, 0xFF, 0xA5, 0xFF, 0xF4, 0xFF, 0xEF, 0xFF, 0x9B, + 0xFF, 0x74, 0xFF, 0x8A, 0x00, 0xBA, 0x03, 0xB5, 0x08, 0xBD, 0x0D, + 0x86, 0x10, 0xA9, 0x0F, 0x97, 0x0B, 0x4C, 0x06, 0xFF, 0x01, 0xD1, + 0xFF, 0x71, 0xFF, 0xC8, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0xD8, 0xFF, + 0x7C, 0xFF, 0xA3, 0xFF, 0x69, 0x01, 0x59, 0x05, 0x9A, 0x0A, 0x16, + 0x0F, 0xA7, 0x10, 0x82, 0x0E, 0xBC, 0x09, 0x93, 0x04, 0xF9, 0x00, + 0x87, 0xFF, 0x89, 0xFF, 0xE4, 0xFF, 0xFB, 0xFF, 0xB8, 0xFF, 0x6C, + 0xFF, 0x07, 0x00, 0x91, 0x02, 0x25, 0x07, 0x67, 0x0C, 0x0E, 0x10, + 0x4D, 0x10, 0x03, 0x0D, 0xD5, 0x07, 0x0E, 0x03, 0x3B, 0x00, 0x6D, + 0xFF, 0xAC, 0xFF, 0xF7, 0xFF, 0xEC, 0xFF, 0x95, 0xFF, 0x79, 0xFF, + 0xAB, 0x00, 0xFE, 0x03, 0x0A, 0x09, 0xFF, 0x0D, 0x94, 0x10, 0x7D, + 0x0F, 0x47, 0x0B, 0xFD, 0x05, 0xCC, 0x01, 0xC0, 0xFF, 0x74, 0xFF, + 0xCD, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xD3, 0xFF, 0x78, 0xFF, 0xB0, + 0xFF, 0x97, 0x01, 0xA6, 0x05, 0xEC, 0x0A, 0x48, 0x0F, 0xA0, 0x10, + 0x45, 0x0E, 0x67, 0x09, 0x4B, 0x04, 0xD3, 0x00, 0x80, 0xFF, 0x8F, + 0xFF, 0xE8, 0xFF, 0xF9, 0xFF, 0xB2, 0xFF, 0x6C, 0xFF, 0x1E, 0x00, + 0xCB, 0x02, 0x78, 0x07, 0xB2, 0x0C, 0x2E, 0x10, 0x31, 0x10, 0xBA, + 0x0C, 0x81, 0x07, 0xD2, 0x02, 0x21, 0x00, 0x6C, 0xFF, 0xB2, 0xFF, + 0xF9, 0xFF, 0xE8, 0xFF, 0x90, 0xFF, 0x7F, 0xFF, 0xCF, 0x00, 0x43, + 0x04, 0x5E, 0x09, 0x3E, 0x0E, 0x9F, 0x10, 0x4E, 0x0F, 0xF6, 0x0A, + 0xAE, 0x05, 0x9C, 0x01, 0xB1, 0xFF, 0x78, 0xFF, 0xD2, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xCE, 0xFF, 0x74, 0xFF, 0xBF, 0xFF, 0xC7, 0x01, + 0xF4, 0x05, 0x3E, 0x0B, 0x78, 0x0F, 0x96, 0x10, 0x06, 0x0E, 0x13, + 0x09, 0x05, 0x04, 0xAF, 0x00, 0x79, 0xFF, 0x95, 0xFF, 0xEC, 0xFF, + 0xF7, 0xFF, 0xAC, 0xFF, 0x6D, 0xFF, 0x38, 0x00, 0x07, 0x03, 0xCB, + 0x07, 0xFB, 0x0C, 0x4A, 0x10, 0x11, 0x10, 0x6F, 0x0C, 0x2E, 0x07, + 0x97, 0x02, 0x09, 0x00, 0x6C, 0xFF, 0xB8, 0xFF, 0xFA, 0xFF, 0xE4, + 0xFF, 0x8A, 0xFF, 0x86, 0xFF, 0xF4, 0x00, 0x8B, 0x04, 0xB2, 0x09, + 0x7B, 0x0E, 0xA7, 0x10, 0x1C, 0x0F, 0xA3, 0x0A, 0x61, 0x05, 0x6E, + 0x01, 0xA4, 0xFF, 0x7C, 0xFF, 0xD8, 0xFF, 0x00, 0x00, 0xFE, 0xFF, + 0xC8, 0xFF, 0x71, 0xFF, 0xCF, 0xFF, 0xF9, 0x01, 0x43, 0x06, 0x8E, + 0x0B, 0xA4, 0x0F, 0x88, 0x10, 0xC4, 0x0D, 0xBE, 0x08, 0xC1, 0x03, + 0x8D, 0x00, 0x75, 0xFF, 0x9B, 0xFF, 0xEF, 0xFF, 0xF4, 0xFF, 0xA6, + 0xFF, 0x6E, 0xFF, 0x53, 0x00, 0x46, 0x03, 0x1F, 0x08, 0x43, 0x0D, + 0x63, 0x10, 0xEF, 0x0F, 0x23, 0x0C, 0xDC, 0x06, 0x5E, 0x02, 0xF3, + 0xFF, 0x6D, 0xFF, 0xBE, 0xFF, 0xFC, 0xFF, 0xE0, 0xFF, 0x85, 0xFF, + 0x8F, 0xFF, 0x1C, 0x01, 0xD3, 0x04, 0x06, 0x0A, 0xB5, 0x0E, 0xAA, + 0x10, 0xE7, 0x0E, 0x50, 0x0A, 0x16, 0x05, 0x42, 0x01, 0x98, 0xFF, + 0x80, 0xFF, 0xDC, 0xFF, 0x00, 0x00, 0xFD, 0xFF, 0xC3, 0xFF, 0x6F, + 0xFF, 0xE1, 0xFF, 0x2E, 0x02, 0x94, 0x06, 0xDD, 0x0B, 0xCD, 0x0F, + 0x76, 0x10, 0x81, 0x0D, 0x6A, 0x08, 0x7F, 0x03, 0x6E, 0x00, 0x71, + 0xFF, 0xA1, 0xFF, 0xF2, 0xFF, 0x00, 0x00, 0x15, 0x00, 0xD1, 0xFF, + 0x8B, 0xFE, 0xBC, 0xFD, 0xE1, 0x00, 0x84, 0x09, 0xB0, 0x13, 0x47, + 0x18, 0xB0, 0x13, 0x84, 0x09, 0xE1, 0x00, 0xBC, 0xFD, 0x8B, 0xFE, + 0xD1, 0xFF, 0x15, 0x00, 0xFD, 0xFF, 0x13, 0x00, 0xDA, 0x00, 0x30, + 0x00, 0x5D, 0xFC, 0xB3, 0xFC, 0x35, 0x0A, 0xC2, 0x1C, 0x24, 0x20, + 0x48, 0x10, 0x5D, 0xFF, 0x74, 0xFB, 0x3A, 0xFF, 0xFB, 0x00, 0x42, + 0x00, 0xF8, 0xFF, 0xFA, 0xFF, 0x2C, 0x00, 0xF3, 0x00, 0xAD, 0xFF, + 0xC5, 0xFB, 0x11, 0xFE, 0xAF, 0x0D, 0xEF, 0x1E, 0x68, 0x1E, 0xBC, + 0x0C, 0xA7, 0xFD, 0xEA, 0xFB, 0xD3, 0xFF, 0xEE, 0x00, 0x24, 0x00, + 0xFA, 0xFF, 0xF7, 0xFF, 0x4C, 0x00, 0xFB, 0x00, 0x0C, 0xFF, 0x5F, + 0xFB, 0xE8, 0xFF, 0x3D, 0x11, 0x7E, 0x20, 0x13, 0x1C, 0x4C, 0x09, + 0x6A, 0xFC, 0x8C, 0xFC, 0x4E, 0x00, 0xD1, 0x00, 0x0E, 0x00, 0xFD, + 0xFF, 0xF7, 0xFF, 0x72, 0x00, 0xEC, 0x00, 0x55, 0xFE, 0x3D, 0xFB, + 0x37, 0x02, 0xBE, 0x14, 0x5D, 0x21, 0x40, 0x19, 0x18, 0x06, 0xA2, + 0xFB, 0x47, 0xFD, 0xA7, 0x00, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFC, 0xFF, 0x9B, 0x00, 0xC0, 0x00, 0x92, 0xFD, 0x73, + 0xFB, 0xF2, 0x04, 0x0E, 0x18, 0x81, 0x21, 0x0C, 0x16, 0x37, 0x03, + 0x47, 0xFB, 0x0B, 0xFE, 0xDF, 0x00, 0x82, 0x00, 0xF9, 0xFF, 0xFE, + 0xFF, 0x08, 0x00, 0xC3, 0x00, 0x74, 0x00, 0xD2, 0xFC, 0x10, 0xFC, + 0x08, 0x08, 0x0A, 0x1B, 0xE9, 0x20, 0x9A, 0x12, 0xBE, 0x00, 0x49, + 0xFB, 0xC8, 0xFE, 0xF9, 0x00, 0x5A, 0x00, 0xF7, 0xFF, 0xFC, 0xFF, + 0x1B, 0x00, 0xE4, 0x00, 0x06, 0x00, 0x24, 0xFC, 0x1E, 0xFD, 0x65, + 0x0B, 0x94, 0x1D, 0x9D, 0x1F, 0x0D, 0x0F, 0xB8, 0xFE, 0x96, 0xFB, + 0x72, 0xFF, 0xF9, 0x00, 0x37, 0x00, 0xF8, 0xFF, 0xF9, 0xFF, 0x36, + 0x00, 0xF8, 0x00, 0x78, 0xFF, 0x9B, 0xFB, 0xA6, 0xFE, 0xE9, 0x0E, + 0x8D, 0x1F, 0xAA, 0x1D, 0x87, 0x0B, 0x2B, 0xFD, 0x1E, 0xFC, 0x02, + 0x00, 0xE5, 0x00, 0x1C, 0x00, 0xFB, 0xFF, 0xF7, 0xFF, 0x58, 0x00, + 0xF9, 0x00, 0xCF, 0xFE, 0x4A, 0xFB, 0xA7, 0x00, 0x77, 0x12, 0xE0, + 0x20, 0x26, 0x1B, 0x28, 0x08, 0x18, 0xFC, 0xCB, 0xFC, 0x71, 0x00, + 0xC5, 0x00, 0x08, 0x00, 0xFE, 0xFF, 0xF8, 0xFF, 0x80, 0x00, 0xE1, + 0x00, 0x13, 0xFE, 0x45, 0xFB, 0x1D, 0x03, 0xEB, 0x15, 0x7F, 0x21, + 0x2D, 0x18, 0x0E, 0x05, 0x77, 0xFB, 0x8B, 0xFD, 0xBE, 0x00, 0x9D, + 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xA9, 0x00, + 0xAA, 0x00, 0x4F, 0xFD, 0x9D, 0xFB, 0xFA, 0x05, 0x22, 0x19, 0x62, + 0x21, 0xE0, 0x14, 0x50, 0x02, 0x3E, 0xFB, 0x4E, 0xFE, 0xEB, 0x00, + 0x73, 0x00, 0xF7, 0xFF, 0xFE, 0xFF, 0x0D, 0x00, 0xD0, 0x00, 0x52, + 0x00, 0x93, 0xFC, 0x60, 0xFC, 0x2C, 0x09, 0xFA, 0x1B, 0x8A, 0x20, + 0x60, 0x11, 0xFD, 0xFF, 0x5C, 0xFB, 0x06, 0xFF, 0xFB, 0x00, 0x4D, + 0x00, 0xF7, 0xFF, 0xFA, 0xFF, 0x23, 0x00, 0xED, 0x00, 0xD9, 0xFF, + 0xEF, 0xFB, 0x98, 0xFD, 0x99, 0x0C, 0x54, 0x1E, 0x02, 0x1F, 0xD2, + 0x0D, 0x20, 0xFE, 0xC0, 0xFB, 0xA7, 0xFF, 0xF4, 0x00, 0x2D, 0x00, + 0xF9, 0xFF, 0xF8, 0xFF, 0x41, 0x00, 0xFB, 0x00, 0x41, 0xFF, 0x78, + 0xFB, 0x4A, 0xFF, 0x25, 0x10, 0x16, 0x20, 0xDA, 0x1C, 0x56, 0x0A, + 0xBE, 0xFC, 0x56, 0xFC, 0x2C, 0x00, 0xDB, 0x00, 0x14, 0x00, 0xFD, + 0xFF, 0xF7, 0xFF, 0x66, 0x00, 0xF4, 0x00, 0x8F, 0xFE, 0x3F, 0xFB, + 0x75, 0x01, 0xAE, 0x13, 0x2C, 0x21, 0x2A, 0x1A, 0x0D, 0x07, 0xD4, + 0xFB, 0x0C, 0xFD, 0x8F, 0x00, 0xB7, 0x00, 0x03, 0x00, 0xFF, 0xFF, + 0x00, 0x00, 0xFA, 0xFF, 0x8E, 0x00, 0xD1, 0x00, 0xCF, 0xFD, 0x58, + 0xFB, 0x10, 0x04, 0x10, 0x17, 0x8A, 0x21, 0x10, 0x17, 0x10, 0x04, + 0x58, 0xFB, 0xCF, 0xFD, 0xD1, 0x00, 0x8E, 0x00, 0xFA, 0xFF, 0xFF, + 0xFF, 0x03, 0x00, 0xB7, 0x00, 0x8F, 0x00, 0x0C, 0xFD, 0xD4, 0xFB, + 0x0D, 0x07, 0x2A, 0x1A, 0x2C, 0x21, 0xAE, 0x13, 0x75, 0x01, 0x3F, + 0xFB, 0x8F, 0xFE, 0xF4, 0x00, 0x66, 0x00, 0xF7, 0xFF, 0xFD, 0xFF, + 0x14, 0x00, 0xDB, 0x00, 0x2C, 0x00, 0x56, 0xFC, 0xBE, 0xFC, 0x56, + 0x0A, 0xDA, 0x1C, 0x16, 0x20, 0x25, 0x10, 0x4A, 0xFF, 0x78, 0xFB, + 0x41, 0xFF, 0xFB, 0x00, 0x41, 0x00, 0xF8, 0xFF, 0xF9, 0xFF, 0x2D, + 0x00, 0xF4, 0x00, 0xA7, 0xFF, 0xC0, 0xFB, 0x20, 0xFE, 0xD2, 0x0D, + 0x02, 0x1F, 0x54, 0x1E, 0x99, 0x0C, 0x98, 0xFD, 0xEF, 0xFB, 0xD9, + 0xFF, 0xED, 0x00, 0x23, 0x00, 0xFA, 0xFF, 0xF7, 0xFF, 0x4D, 0x00, + 0xFB, 0x00, 0x06, 0xFF, 0x5C, 0xFB, 0xFD, 0xFF, 0x60, 0x11, 0x8A, + 0x20, 0xFA, 0x1B, 0x2C, 0x09, 0x60, 0xFC, 0x93, 0xFC, 0x52, 0x00, + 0xD0, 0x00, 0x0D, 0x00, 0xFE, 0xFF, 0xF7, 0xFF, 0x73, 0x00, 0xEB, + 0x00, 0x4E, 0xFE, 0x3E, 0xFB, 0x50, 0x02, 0xE0, 0x14, 0x62, 0x21, + 0x22, 0x19, 0xFA, 0x05, 0x9D, 0xFB, 0x4F, 0xFD, 0xAA, 0x00, 0xA9, + 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x9D, 0x00, + 0xBE, 0x00, 0x8B, 0xFD, 0x77, 0xFB, 0x0E, 0x05, 0x2D, 0x18, 0x7F, + 0x21, 0xEB, 0x15, 0x1D, 0x03, 0x45, 0xFB, 0x13, 0xFE, 0xE1, 0x00, + 0x80, 0x00, 0xF8, 0xFF, 0xFE, 0xFF, 0x08, 0x00, 0xC5, 0x00, 0x71, + 0x00, 0xCB, 0xFC, 0x18, 0xFC, 0x28, 0x08, 0x26, 0x1B, 0xE0, 0x20, + 0x77, 0x12, 0xA7, 0x00, 0x4A, 0xFB, 0xCF, 0xFE, 0xF9, 0x00, 0x58, + 0x00, 0xF7, 0xFF, 0xFB, 0xFF, 0x1C, 0x00, 0xE5, 0x00, 0x02, 0x00, + 0x1E, 0xFC, 0x2B, 0xFD, 0x87, 0x0B, 0xAA, 0x1D, 0x8D, 0x1F, 0xE9, + 0x0E, 0xA6, 0xFE, 0x9B, 0xFB, 0x78, 0xFF, 0xF8, 0x00, 0x36, 0x00, + 0xF9, 0xFF, 0xF8, 0xFF, 0x37, 0x00, 0xF9, 0x00, 0x72, 0xFF, 0x96, + 0xFB, 0xB8, 0xFE, 0x0D, 0x0F, 0x9D, 0x1F, 0x94, 0x1D, 0x65, 0x0B, + 0x1E, 0xFD, 0x24, 0xFC, 0x06, 0x00, 0xE4, 0x00, 0x1B, 0x00, 0xFC, + 0xFF, 0xF7, 0xFF, 0x5A, 0x00, 0xF9, 0x00, 0xC8, 0xFE, 0x49, 0xFB, + 0xBE, 0x00, 0x9A, 0x12, 0xE9, 0x20, 0x0A, 0x1B, 0x08, 0x08, 0x10, + 0xFC, 0xD2, 0xFC, 0x74, 0x00, 0xC3, 0x00, 0x08, 0x00, 0xFE, 0xFF, + 0xF9, 0xFF, 0x82, 0x00, 0xDF, 0x00, 0x0B, 0xFE, 0x47, 0xFB, 0x37, + 0x03, 0x0C, 0x16, 0x81, 0x21, 0x0E, 0x18, 0xF2, 0x04, 0x73, 0xFB, + 0x92, 0xFD, 0xC0, 0x00, 0x9B, 0x00, 0xFC, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xAB, 0x00, 0xA7, 0x00, 0x47, 0xFD, 0xA2, 0xFB, + 0x18, 0x06, 0x40, 0x19, 0x5D, 0x21, 0xBE, 0x14, 0x37, 0x02, 0x3D, + 0xFB, 0x55, 0xFE, 0xEC, 0x00, 0x72, 0x00, 0xF7, 0xFF, 0xFD, 0xFF, + 0x0E, 0x00, 0xD1, 0x00, 0x4E, 0x00, 0x8C, 0xFC, 0x6A, 0xFC, 0x4C, + 0x09, 0x13, 0x1C, 0x7E, 0x20, 0x3D, 0x11, 0xE8, 0xFF, 0x5F, 0xFB, + 0x0C, 0xFF, 0xFB, 0x00, 0x4C, 0x00, 0xF7, 0xFF, 0xFA, 0xFF, 0x24, + 0x00, 0xEE, 0x00, 0xD3, 0xFF, 0xEA, 0xFB, 0xA7, 0xFD, 0xBC, 0x0C, + 0x68, 0x1E, 0xEF, 0x1E, 0xAF, 0x0D, 0x11, 0xFE, 0xC5, 0xFB, 0xAD, + 0xFF, 0xF3, 0x00, 0x2C, 0x00, 0xFA, 0xFF, 0xF8, 0xFF, 0x42, 0x00, + 0xFB, 0x00, 0x3A, 0xFF, 0x74, 0xFB, 0x5D, 0xFF, 0x48, 0x10, 0x24, + 0x20, 0xC2, 0x1C, 0x35, 0x0A, 0xB3, 0xFC, 0x5D, 0xFC, 0x30, 0x00, + 0xDA, 0x00, 0x13, 0x00, 0xFD, 0xFF, 0xF7, 0xFF, 0x67, 0x00, 0xF3, + 0x00, 0x88, 0xFE, 0x3E, 0xFB, 0x8C, 0x01, 0xD0, 0x13, 0x33, 0x21, + 0x0D, 0x1A, 0xEE, 0x06, 0xCD, 0xFB, 0x13, 0xFD, 0x92, 0x00, 0xB6, + 0x00, 0x03, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFA, 0xFF, 0x90, 0x00, + 0xCF, 0x00, 0xC7, 0xFD, 0x5B, 0xFB, 0x2B, 0x04, 0x31, 0x17, 0x8A, + 0x21, 0xF0, 0x16, 0xF4, 0x03, 0x56, 0xFB, 0xD6, 0xFD, 0xD3, 0x00, + 0x8D, 0x00, 0xFA, 0xFF, 0xFF, 0xFF, 0x04, 0x00, 0xB9, 0x00, 0x8C, + 0x00, 0x05, 0xFD, 0xDB, 0xFB, 0x2C, 0x07, 0x47, 0x1A, 0x25, 0x21, + 0x8B, 0x13, 0x5D, 0x01, 0x40, 0xFB, 0x97, 0xFE, 0xF5, 0x00, 0x64, + 0x00, 0xF7, 0xFF, 0xFC, 0xFF, 0x15, 0x00, 0xDC, 0x00, 0x27, 0x00, + 0x50, 0xFC, 0xCA, 0xFC, 0x78, 0x0A, 0xF2, 0x1C, 0x07, 0x20, 0x02, + 0x10, 0x37, 0xFF, 0x7B, 0xFB, 0x47, 0xFF, 0xFB, 0x00, 0x40, 0x00, + 0xF8, 0xFF, 0xF9, 0xFF, 0x2E, 0x00, 0xF5, 0x00, 0xA2, 0xFF, 0xBB, + 0xFB, 0x31, 0xFE, 0xF5, 0x0D, 0x14, 0x1F, 0x3F, 0x1E, 0x77, 0x0C, + 0x8A, 0xFD, 0xF5, 0xFB, 0xDE, 0xFF, 0xEC, 0x00, 0x22, 0x00, 0xFB, + 0xFF, 0xF7, 0xFF, 0x4E, 0x00, 0xFB, 0x00, 0xFF, 0xFE, 0x59, 0xFB, + 0x11, 0x00, 0x83, 0x11, 0x96, 0x20, 0xE0, 0x1B, 0x0B, 0x09, 0x56, + 0xFC, 0x99, 0xFC, 0x56, 0x00, 0xCE, 0x00, 0x0D, 0x00, 0xFE, 0xFF, + 0xF8, 0xFF, 0x75, 0x00, 0xEA, 0x00, 0x47, 0xFE, 0x3E, 0xFB, 0x69, + 0x02, 0x02, 0x15, 0x66, 0x21, 0x04, 0x19, 0xDC, 0x05, 0x98, 0xFB, + 0x56, 0xFD, 0xAD, 0x00, 0xA8, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0xFD, 0xFF, 0x9E, 0x00, 0xBC, 0x00, 0x83, 0xFD, 0x7B, 0xFB, + 0x2B, 0x05, 0x4C, 0x18, 0x7C, 0x21, 0xCA, 0x15, 0x03, 0x03, 0x44, + 0xFB, 0x1A, 0xFE, 0xE2, 0x00, 0x7E, 0x00, 0xF8, 0xFF, 0xFE, 0xFF, + 0x09, 0x00, 0xC6, 0x00, 0x6D, 0x00, 0xC3, 0xFC, 0x20, 0xFC, 0x49, + 0x08, 0x41, 0x1B, 0xD6, 0x20, 0x54, 0x12, 0x92, 0x00, 0x4C, 0xFB, + 0xD6, 0xFE, 0xFA, 0x00, 0x57, 0x00, 0xF7, 0xFF, 0xFB, 0xFF, 0x1D, + 0x00, 0xE6, 0x00, 0xFD, 0xFF, 0x18, 0xFC, 0x38, 0xFD, 0xA9, 0x0B, + 0xC0, 0x1D, 0x7C, 0x1F, 0xC6, 0x0E, 0x95, 0xFE, 0x9F, 0xFB, 0x7E, + 0xFF, 0xF8, 0x00, 0x35, 0x00, 0xF9, 0xFF, 0xF8, 0xFF, 0x38, 0x00, + 0xF9, 0x00, 0x6C, 0xFF, 0x92, 0xFB, 0xC9, 0xFE, 0x2F, 0x0F, 0xAD, + 0x1F, 0x7D, 0x1D, 0x42, 0x0B, 0x12, 0xFD, 0x2A, 0xFC, 0x0B, 0x00, + 0xE3, 0x00, 0x1A, 0x00, 0xFC, 0xFF, 0xF7, 0xFF, 0x5B, 0x00, 0xF8, + 0x00, 0xC1, 0xFE, 0x47, 0xFB, 0xD4, 0x00, 0xBC, 0x12, 0xF3, 0x20, + 0xEF, 0x1A, 0xE9, 0x07, 0x08, 0xFC, 0xD9, 0xFC, 0x78, 0x00, 0xC2, + 0x00, 0x07, 0x00, 0xFF, 0xFF, 0xF9, 0xFF, 0x83, 0x00, 0xDD, 0x00, + 0x04, 0xFE, 0x49, 0xFB, 0x52, 0x03, 0x2D, 0x16, 0x83, 0x21, 0xEF, + 0x17, 0xD5, 0x04, 0x6F, 0xFB, 0x9A, 0xFD, 0xC3, 0x00, 0x9A, 0x00, + 0xFC, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xAD, 0x00, 0xA4, + 0x00, 0x40, 0xFD, 0xA8, 0xFB, 0x36, 0x06, 0x5E, 0x19, 0x58, 0x21, + 0x9C, 0x14, 0x1E, 0x02, 0x3D, 0xFB, 0x5D, 0xFE, 0xED, 0x00, 0x70, + 0x00, 0xF7, 0xFF, 0xFD, 0xFF, 0x0F, 0x00, 0xD2, 0x00, 0x4A, 0x00, + 0x85, 0xFC, 0x74, 0xFC, 0x6D, 0x09, 0x2D, 0x1C, 0x72, 0x20, 0x1A, + 0x11, 0xD4, 0xFF, 0x61, 0xFB, 0x13, 0xFF, 0xFC, 0x00, 0x4A, 0x00, + 0xF7, 0xFF, 0xFA, 0xFF, 0x25, 0x00, 0xEF, 0x00, 0xCE, 0xFF, 0xE4, + 0xFB, 0xB5, 0xFD, 0xDE, 0x0C, 0x7C, 0x1E, 0xDD, 0x1E, 0x8C, 0x0D, + 0x01, 0xFE, 0xCA, 0xFB, 0xB3, 0xFF, 0xF3, 0x00, 0x2B, 0x00, 0xFA, + 0xFF, 0xF8, 0xFF, 0x44, 0x00, 0xFB, 0x00, 0x34, 0xFF, 0x71, 0xFB, + 0x71, 0xFF, 0x6B, 0x10, 0x32, 0x20, 0xA9, 0x1C, 0x13, 0x0A, 0xA8, + 0xFC, 0x63, 0xFC, 0x35, 0x00, 0xD9, 0x00, 0x12, 0x00, 0xFD, 0xFF, + 0xF7, 0xFF, 0x69, 0x00, 0xF2, 0x00, 0x81, 0xFE, 0x3E, 0xFB, 0xA4, + 0x01, 0xF2, 0x13, 0x3A, 0x21, 0xF0, 0x19, 0xCF, 0x06, 0xC7, 0xFB, + 0x1B, 0xFD, 0x96, 0x00, 0xB4, 0x00, 0x02, 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0xFB, 0xFF, 0x92, 0x00, 0xCD, 0x00, 0xC0, 0xFD, 0x5E, 0xFB, + 0x47, 0x04, 0x51, 0x17, 0x8A, 0x21, 0xD0, 0x16, 0xD9, 0x03, 0x53, + 0xFB, 0xDE, 0xFD, 0xD5, 0x00, 0x8B, 0x00, 0xFA, 0xFF, 0xFF, 0xFF, + 0x04, 0x00, 0xBA, 0x00, 0x89, 0x00, 0xFD, 0xFC, 0xE2, 0xFB, 0x4B, + 0x07, 0x63, 0x1A, 0x1D, 0x21, 0x69, 0x13, 0x46, 0x01, 0x41, 0xFB, + 0x9E, 0xFE, 0xF5, 0x00, 0x63, 0x00, 0xF7, 0xFF, 0xFC, 0xFF, 0x16, + 0x00, 0xDD, 0x00, 0x23, 0x00, 0x49, 0xFC, 0xD5, 0xFC, 0x99, 0x0A, + 0x09, 0x1D, 0xF9, 0x1F, 0xDF, 0x0F, 0x24, 0xFF, 0x7F, 0xFB, 0x4D, + 0xFF, 0xFB, 0x00, 0x3F, 0x00, 0xF8, 0xFF, 0xF9, 0xFF, 0x2F, 0x00, + 0xF5, 0x00, 0x9C, 0xFF, 0xB6, 0xFB, 0x41, 0xFE, 0x17, 0x0E, 0x26, + 0x1F, 0x2B, 0x1E, 0x54, 0x0C, 0x7C, 0xFD, 0xFA, 0xFB, 0xE3, 0xFF, + 0xEB, 0x00, 0x21, 0x00, 0xFB, 0xFF, 0xF7, 0xFF, 0x50, 0x00, 0xFB, + 0x00, 0xF8, 0xFE, 0x57, 0xFB, 0x26, 0x00, 0xA6, 0x11, 0xA1, 0x20, + 0xC6, 0x1B, 0xEA, 0x08, 0x4D, 0xFC, 0xA0, 0xFC, 0x5A, 0x00, 0xCD, + 0x00, 0x0C, 0x00, 0xFE, 0xFF, 0xF8, 0xFF, 0x77, 0x00, 0xE9, 0x00, + 0x3F, 0xFE, 0x3F, 0xFB, 0x82, 0x02, 0x23, 0x15, 0x6B, 0x21, 0xE5, + 0x18, 0xBE, 0x05, 0x93, 0xFB, 0x5E, 0xFD, 0xAF, 0x00, 0xA6, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0xA0, 0x00, 0xB9, + 0x00, 0x7C, 0xFD, 0x80, 0xFB, 0x48, 0x05, 0x6B, 0x18, 0x79, 0x21, + 0xA9, 0x15, 0xE9, 0x02, 0x43, 0xFB, 0x21, 0xFE, 0xE3, 0x00, 0x7D, + 0x00, 0xF8, 0xFF, 0xFE, 0xFF, 0x09, 0x00, 0xC7, 0x00, 0x69, 0x00, + 0xBC, 0xFC, 0x29, 0xFC, 0x69, 0x08, 0x5C, 0x1B, 0xCC, 0x20, 0x32, + 0x12, 0x7C, 0x00, 0x4E, 0xFB, 0xDD, 0xFE, 0xFA, 0x00, 0x56, 0x00, + 0xF7, 0xFF, 0xFB, 0xFF, 0x1D, 0x00, 0xE7, 0x00, 0xF8, 0xFF, 0x12, + 0xFC, 0x45, 0xFD, 0xCB, 0x0B, 0xD6, 0x1D, 0x6C, 0x1F, 0xA3, 0x0E, + 0x84, 0xFE, 0xA4, 0xFB, 0x84, 0xFF, 0xF7, 0x00, 0x34, 0x00, 0xF9, + 0xFF, 0xF8, 0xFF, 0x3A, 0x00, 0xFA, 0x00, 0x66, 0xFF, 0x8E, 0xFB, + 0xDB, 0xFE, 0x53, 0x0F, 0xBD, 0x1F, 0x66, 0x1D, 0x21, 0x0B, 0x05, + 0xFD, 0x30, 0xFC, 0x10, 0x00, 0xE2, 0x00, 0x19, 0x00, 0xFC, 0xFF, + 0xF7, 0xFF, 0x5D, 0x00, 0xF8, 0x00, 0xBA, 0xFE, 0x46, 0xFB, 0xEA, + 0x00, 0xDF, 0x12, 0xFC, 0x20, 0xD3, 0x1A, 0xC9, 0x07, 0x00, 0xFC, + 0xE0, 0xFC, 0x7B, 0x00, 0xC0, 0x00, 0x07, 0x00, 0xFF, 0xFF, 0xF9, + 0xFF, 0x85, 0x00, 0xDC, 0x00, 0xFC, 0xFD, 0x4A, 0xFB, 0x6C, 0x03, + 0x4E, 0x16, 0x85, 0x21, 0xCF, 0x17, 0xB8, 0x04, 0x6C, 0xFB, 0xA2, + 0xFD, 0xC5, 0x00, 0x98, 0x00, 0xFC, 0xFF, 0x00, 0x00, 0xFF, 0xFF, + 0x01, 0x00, 0xAE, 0x00, 0xA1, 0x00, 0x38, 0xFD, 0xAE, 0xFB, 0x54, + 0x06, 0x7C, 0x19, 0x53, 0x21, 0x7B, 0x14, 0x05, 0x02, 0x3D, 0xFB, + 0x64, 0xFE, 0xEE, 0x00, 0x6F, 0x00, 0xF7, 0xFF, 0xFD, 0xFF, 0x0F, + 0x00, 0xD4, 0x00, 0x46, 0x00, 0x7E, 0xFC, 0x7E, 0xFC, 0x8E, 0x09, + 0x46, 0x1C, 0x66, 0x20, 0xF7, 0x10, 0xC0, 0xFF, 0x64, 0xFB, 0x1A, + 0xFF, 0xFC, 0x00, 0x49, 0x00, 0xF7, 0xFF, 0xFA, 0xFF, 0x26, 0x00, + 0xF0, 0x00, 0xC9, 0xFF, 0xDF, 0xFB, 0xC4, 0xFD, 0x01, 0x0D, 0x90, + 0x1E, 0xCA, 0x1E, 0x69, 0x0D, 0xF1, 0xFD, 0xCF, 0xFB, 0xB8, 0xFF, + 0xF2, 0x00, 0x29, 0x00, 0xFA, 0xFF, 0xF7, 0xFF, 0x45, 0x00, 0xFC, + 0x00, 0x2D, 0xFF, 0x6D, 0xFB, 0x84, 0xFF, 0x8E, 0x10, 0x3F, 0x20, + 0x91, 0x1C, 0xF2, 0x09, 0x9D, 0xFC, 0x6A, 0xFC, 0x39, 0x00, 0xD7, + 0x00, 0x12, 0x00, 0xFD, 0xFF, 0xF7, 0xFF, 0x6A, 0x00, 0xF1, 0x00, + 0x7A, 0xFE, 0x3D, 0xFB, 0xBC, 0x01, 0x14, 0x14, 0x41, 0x21, 0xD4, + 0x19, 0xB0, 0x06, 0xC0, 0xFB, 0x22, 0xFD, 0x99, 0x00, 0xB3, 0x00, + 0x02, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFB, 0xFF, 0x93, 0x00, 0xCB, + 0x00, 0xB8, 0xFD, 0x61, 0xFB, 0x63, 0x04, 0x71, 0x17, 0x89, 0x21, + 0xB0, 0x16, 0xBD, 0x03, 0x51, 0xFB, 0xE6, 0xFD, 0xD7, 0x00, 0x8A, + 0x00, 0xFA, 0xFF, 0xFF, 0xFF, 0x05, 0x00, 0xBC, 0x00, 0x86, 0x00, + 0xF6, 0xFC, 0xE9, 0xFB, 0x6A, 0x07, 0x80, 0x1A, 0x15, 0x21, 0x47, + 0x13, 0x2F, 0x01, 0x42, 0xFB, 0xA5, 0xFE, 0xF6, 0x00, 0x61, 0x00, + 0xF7, 0xFF, 0xFC, 0xFF, 0x16, 0x00, 0xDF, 0x00, 0x1E, 0x00, 0x43, + 0xFC, 0xE1, 0xFC, 0xBB, 0x0A, 0x21, 0x1D, 0xEA, 0x1F, 0xBC, 0x0F, + 0x12, 0xFF, 0x82, 0xFB, 0x54, 0xFF, 0xFA, 0x00, 0x3D, 0x00, 0xF8, + 0xFF, 0xF9, 0xFF, 0x30, 0x00, 0xF6, 0x00, 0x96, 0xFF, 0xB1, 0xFB, + 0x51, 0xFE, 0x3A, 0x0E, 0x38, 0x1F, 0x16, 0x1E, 0x32, 0x0C, 0x6E, + 0xFD, 0x00, 0xFC, 0xE8, 0xFF, 0xEA, 0x00, 0x20, 0x00, 0xFB, 0xFF, + 0xF7, 0xFF, 0x51, 0x00, 0xFB, 0x00, 0xF1, 0xFE, 0x54, 0xFB, 0x3B, + 0x00, 0xC9, 0x11, 0xAD, 0x20, 0xAC, 0x1B, 0xCA, 0x08, 0x44, 0xFC, + 0xA7, 0xFC, 0x5E, 0x00, 0xCC, 0x00, 0x0B, 0x00, 0xFE, 0xFF, 0xF8, + 0xFF, 0x78, 0x00, 0xE7, 0x00, 0x38, 0xFE, 0x40, 0xFB, 0x9B, 0x02, + 0x45, 0x15, 0x6F, 0x21, 0xC7, 0x18, 0xA1, 0x05, 0x8E, 0xFB, 0x65, + 0xFD, 0xB2, 0x00, 0xA5, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFE, 0xFF, 0xA2, 0x00, 0xB7, 0x00, 0x74, 0xFD, 0x84, 0xFB, 0x66, + 0x05, 0x8A, 0x18, 0x76, 0x21, 0x87, 0x15, 0xCF, 0x02, 0x41, 0xFB, + 0x29, 0xFE, 0xE5, 0x00, 0x7B, 0x00, 0xF8, 0xFF, 0xFE, 0xFF, 0x0A, + 0x00, 0xC9, 0x00, 0x66, 0x00, 0xB5, 0xFC, 0x32, 0xFC, 0x89, 0x08, + 0x77, 0x1B, 0xC2, 0x20, 0x0F, 0x12, 0x66, 0x00, 0x50, 0xFB, 0xE4, + 0xFE, 0xFA, 0x00, 0x54, 0x00, 0xF7, 0xFF, 0xFB, 0xFF, 0x1E, 0x00, + 0xE8, 0x00, 0xF3, 0xFF, 0x0C, 0xFC, 0x53, 0xFD, 0xED, 0x0B, 0xEB, + 0x1D, 0x5A, 0x1F, 0x80, 0x0E, 0x73, 0xFE, 0xA8, 0xFB, 0x8A, 0xFF, + 0xF7, 0x00, 0x32, 0x00, 0xF9, 0xFF, 0xF8, 0xFF, 0x3B, 0x00, 0xFA, + 0x00, 0x60, 0xFF, 0x8A, 0xFB, 0xED, 0xFE, 0x76, 0x0F, 0xCC, 0x1F, + 0x4F, 0x1D, 0xFF, 0x0A, 0xF9, 0xFC, 0x36, 0xFC, 0x15, 0x00, 0xE1, + 0x00, 0x18, 0x00, 0xFC, 0xFF, 0xF7, 0xFF, 0x5E, 0x00, 0xF7, 0x00, + 0xB3, 0xFE, 0x44, 0xFB, 0x01, 0x01, 0x02, 0x13, 0x04, 0x21, 0xB8, + 0x1A, 0xA9, 0x07, 0xF8, 0xFB, 0xE7, 0xFC, 0x7F, 0x00, 0xBF, 0x00, + 0x06, 0x00, 0xFF, 0xFF, 0xF9, 0xFF, 0x86, 0x00, 0xDA, 0x00, 0xF5, + 0xFD, 0x4C, 0xFB, 0x87, 0x03, 0x6E, 0x16, 0x86, 0x21, 0xB0, 0x17, + 0x9C, 0x04, 0x68, 0xFB, 0xA9, 0xFD, 0xC7, 0x00, 0x96, 0x00, 0xFB, + 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x01, 0x00, 0xB0, 0x00, 0x9F, 0x00, + 0x31, 0xFD, 0xB4, 0xFB, 0x73, 0x06, 0x99, 0x19, 0x4D, 0x21, 0x59, + 0x14, 0xED, 0x01, 0x3D, 0xFB, 0x6B, 0xFE, 0xEF, 0x00, 0x6D, 0x00, + 0xF7, 0xFF, 0xFD, 0xFF, 0x10, 0x00, 0xD5, 0x00, 0x42, 0x00, 0x77, + 0xFC, 0x88, 0xFC, 0xAF, 0x09, 0x5F, 0x1C, 0x59, 0x20, 0xD4, 0x10, + 0xAC, 0xFF, 0x67, 0xFB, 0x20, 0xFF, 0xFC, 0x00, 0x48, 0x00, 0xF7, + 0xFF, 0xFA, 0xFF, 0x27, 0x00, 0xF0, 0x00, 0xC3, 0xFF, 0xD9, 0xFB, + 0xD3, 0xFD, 0x24, 0x0D, 0xA3, 0x1E, 0xB7, 0x1E, 0x46, 0x0D, 0xE2, + 0xFD, 0xD4, 0xFB, 0xBE, 0xFF, 0xF1, 0x00, 0x28, 0x00, 0xFA, 0xFF, + 0xF7, 0xFF, 0x46, 0x00, 0xFC, 0x00, 0x27, 0xFF, 0x6A, 0xFB, 0x98, + 0xFF, 0xB1, 0x10, 0x4C, 0x20, 0x78, 0x1C, 0xD1, 0x09, 0x93, 0xFC, + 0x71, 0xFC, 0x3D, 0x00, 0xD6, 0x00, 0x11, 0x00, 0xFD, 0xFF, 0xF7, + 0xFF, 0x6C, 0x00, 0xF0, 0x00, 0x72, 0xFE, 0x3D, 0xFB, 0xD4, 0x01, + 0x36, 0x14, 0x47, 0x21, 0xB6, 0x19, 0x91, 0x06, 0xBA, 0xFB, 0x29, + 0xFD, 0x9C, 0x00, 0xB1, 0x00, 0x02, 0x00, 0xFF, 0xFF, 0x00, 0x00, + 0xFB, 0xFF, 0x95, 0x00, 0xC9, 0x00, 0xB1, 0xFD, 0x65, 0xFB, 0x80, + 0x04, 0x90, 0x17, 0x88, 0x21, 0x8F, 0x16, 0xA2, 0x03, 0x4E, 0xFB, + 0xED, 0xFD, 0xD9, 0x00, 0x88, 0x00, 0xF9, 0xFF, 0xFF, 0xFF, 0x05, + 0x00, 0xBD, 0x00, 0x82, 0x00, 0xEF, 0xFC, 0xF0, 0xFB, 0x8A, 0x07, + 0x9C, 0x1A, 0x0D, 0x21, 0x24, 0x13, 0x18, 0x01, 0x43, 0xFB, 0xAC, + 0xFE, 0xF7, 0x00, 0x60, 0x00, 0xF7, 0xFF, 0xFC, 0xFF, 0x17, 0x00, + 0xE0, 0x00, 0x1A, 0x00, 0x3D, 0xFC, 0xED, 0xFC, 0xDD, 0x0A, 0x38, + 0x1D, 0xDB, 0x1F, 0x99, 0x0F, 0xFF, 0xFE, 0x86, 0xFB, 0x5A, 0xFF, + 0xFA, 0x00, 0x3C, 0x00, 0xF8, 0xFF, 0xF9, 0xFF, 0x31, 0x00, 0xF6, + 0x00, 0x90, 0xFF, 0xAD, 0xFB, 0x62, 0xFE, 0x5D, 0x0E, 0x49, 0x1F, + 0x01, 0x1E, 0x10, 0x0C, 0x60, 0xFD, 0x06, 0xFC, 0xEE, 0xFF, 0xE9, + 0x00, 0x1F, 0x00, 0xFB, 0xFF, 0xF7, 0xFF, 0x53, 0x00, 0xFB, 0x00, + 0xEB, 0xFE, 0x52, 0xFB, 0x51, 0x00, 0xEC, 0x11, 0xB7, 0x20, 0x91, + 0x1B, 0xA9, 0x08, 0x3B, 0xFC, 0xAE, 0xFC, 0x62, 0x00, 0xCA, 0x00, + 0x0B, 0x00, 0xFE, 0xFF, 0xF8, 0xFF, 0x7A, 0x00, 0xE6, 0x00, 0x30, + 0xFE, 0x40, 0xFB, 0xB5, 0x02, 0x66, 0x15, 0x73, 0x21, 0xA9, 0x18, + 0x83, 0x05, 0x89, 0xFB, 0x6D, 0xFD, 0xB4, 0x00, 0xA3, 0x00, 0xFE, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xA3, 0x00, 0xB4, 0x00, + 0x6D, 0xFD, 0x89, 0xFB, 0x83, 0x05, 0xA9, 0x18, 0x73, 0x21, 0x66, + 0x15, 0xB5, 0x02, 0x40, 0xFB, 0x30, 0xFE, 0xE6, 0x00, 0x7A, 0x00, + 0xF8, 0xFF, 0xFE, 0xFF, 0x0B, 0x00, 0xCA, 0x00, 0x62, 0x00, 0xAE, + 0xFC, 0x3B, 0xFC, 0xA9, 0x08, 0x91, 0x1B, 0xB7, 0x20, 0xEC, 0x11, + 0x51, 0x00, 0x52, 0xFB, 0xEB, 0xFE, 0xFB, 0x00, 0x53, 0x00, 0xF7, + 0xFF, 0xFB, 0xFF, 0x1F, 0x00, 0xE9, 0x00, 0xEE, 0xFF, 0x06, 0xFC, + 0x60, 0xFD, 0x10, 0x0C, 0x01, 0x1E, 0x49, 0x1F, 0x5D, 0x0E, 0x62, + 0xFE, 0xAD, 0xFB, 0x90, 0xFF, 0xF6, 0x00, 0x31, 0x00, 0xF9, 0xFF, + 0xF8, 0xFF, 0x3C, 0x00, 0xFA, 0x00, 0x5A, 0xFF, 0x86, 0xFB, 0xFF, + 0xFE, 0x99, 0x0F, 0xDB, 0x1F, 0x38, 0x1D, 0xDD, 0x0A, 0xED, 0xFC, + 0x3D, 0xFC, 0x1A, 0x00, 0xE0, 0x00, 0x17, 0x00, 0xFC, 0xFF, 0xF7, + 0xFF, 0x60, 0x00, 0xF7, 0x00, 0xAC, 0xFE, 0x43, 0xFB, 0x18, 0x01, + 0x24, 0x13, 0x0D, 0x21, 0x9C, 0x1A, 0x8A, 0x07, 0xF0, 0xFB, 0xEF, + 0xFC, 0x82, 0x00, 0xBD, 0x00, 0x05, 0x00, 0xFF, 0xFF, 0xF9, 0xFF, + 0x88, 0x00, 0xD9, 0x00, 0xED, 0xFD, 0x4E, 0xFB, 0xA2, 0x03, 0x8F, + 0x16, 0x88, 0x21, 0x90, 0x17, 0x80, 0x04, 0x65, 0xFB, 0xB1, 0xFD, + 0xC9, 0x00, 0x95, 0x00, 0xFB, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x02, + 0x00, 0xB1, 0x00, 0x9C, 0x00, 0x29, 0xFD, 0xBA, 0xFB, 0x91, 0x06, + 0xB6, 0x19, 0x47, 0x21, 0x36, 0x14, 0xD4, 0x01, 0x3D, 0xFB, 0x72, + 0xFE, 0xF0, 0x00, 0x6C, 0x00, 0xF7, 0xFF, 0xFD, 0xFF, 0x11, 0x00, + 0xD6, 0x00, 0x3D, 0x00, 0x71, 0xFC, 0x93, 0xFC, 0xD1, 0x09, 0x78, + 0x1C, 0x4C, 0x20, 0xB1, 0x10, 0x98, 0xFF, 0x6A, 0xFB, 0x27, 0xFF, + 0xFC, 0x00, 0x46, 0x00, 0xF7, 0xFF, 0xFA, 0xFF, 0x28, 0x00, 0xF1, + 0x00, 0xBE, 0xFF, 0xD4, 0xFB, 0xE2, 0xFD, 0x46, 0x0D, 0xB7, 0x1E, + 0xA3, 0x1E, 0x24, 0x0D, 0xD3, 0xFD, 0xD9, 0xFB, 0xC3, 0xFF, 0xF0, + 0x00, 0x27, 0x00, 0xFA, 0xFF, 0xF7, 0xFF, 0x48, 0x00, 0xFC, 0x00, + 0x20, 0xFF, 0x67, 0xFB, 0xAC, 0xFF, 0xD4, 0x10, 0x59, 0x20, 0x5F, + 0x1C, 0xAF, 0x09, 0x88, 0xFC, 0x77, 0xFC, 0x42, 0x00, 0xD5, 0x00, + 0x10, 0x00, 0xFD, 0xFF, 0xF7, 0xFF, 0x6D, 0x00, 0xEF, 0x00, 0x6B, + 0xFE, 0x3D, 0xFB, 0xED, 0x01, 0x59, 0x14, 0x4D, 0x21, 0x99, 0x19, + 0x73, 0x06, 0xB4, 0xFB, 0x31, 0xFD, 0x9F, 0x00, 0xB0, 0x00, 0x01, + 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFB, 0xFF, 0x96, 0x00, 0xC7, 0x00, + 0xA9, 0xFD, 0x68, 0xFB, 0x9C, 0x04, 0xB0, 0x17, 0x86, 0x21, 0x6E, + 0x16, 0x87, 0x03, 0x4C, 0xFB, 0xF5, 0xFD, 0xDA, 0x00, 0x86, 0x00, + 0xF9, 0xFF, 0xFF, 0xFF, 0x06, 0x00, 0xBF, 0x00, 0x7F, 0x00, 0xE7, + 0xFC, 0xF8, 0xFB, 0xA9, 0x07, 0xB8, 0x1A, 0x04, 0x21, 0x02, 0x13, + 0x01, 0x01, 0x44, 0xFB, 0xB3, 0xFE, 0xF7, 0x00, 0x5E, 0x00, 0xF7, + 0xFF, 0xFC, 0xFF, 0x18, 0x00, 0xE1, 0x00, 0x15, 0x00, 0x36, 0xFC, + 0xF9, 0xFC, 0xFF, 0x0A, 0x4F, 0x1D, 0xCC, 0x1F, 0x76, 0x0F, 0xED, + 0xFE, 0x8A, 0xFB, 0x60, 0xFF, 0xFA, 0x00, 0x3B, 0x00, 0xF8, 0xFF, + 0xF9, 0xFF, 0x32, 0x00, 0xF7, 0x00, 0x8A, 0xFF, 0xA8, 0xFB, 0x73, + 0xFE, 0x80, 0x0E, 0x5A, 0x1F, 0xEB, 0x1D, 0xED, 0x0B, 0x53, 0xFD, + 0x0C, 0xFC, 0xF3, 0xFF, 0xE8, 0x00, 0x1E, 0x00, 0xFB, 0xFF, 0xF7, + 0xFF, 0x54, 0x00, 0xFA, 0x00, 0xE4, 0xFE, 0x50, 0xFB, 0x66, 0x00, + 0x0F, 0x12, 0xC2, 0x20, 0x77, 0x1B, 0x89, 0x08, 0x32, 0xFC, 0xB5, + 0xFC, 0x66, 0x00, 0xC9, 0x00, 0x0A, 0x00, 0xFE, 0xFF, 0xF8, 0xFF, + 0x7B, 0x00, 0xE5, 0x00, 0x29, 0xFE, 0x41, 0xFB, 0xCF, 0x02, 0x87, + 0x15, 0x76, 0x21, 0x8A, 0x18, 0x66, 0x05, 0x84, 0xFB, 0x74, 0xFD, + 0xB7, 0x00, 0xA2, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFE, + 0xFF, 0xA5, 0x00, 0xB2, 0x00, 0x65, 0xFD, 0x8E, 0xFB, 0xA1, 0x05, + 0xC7, 0x18, 0x6F, 0x21, 0x45, 0x15, 0x9B, 0x02, 0x40, 0xFB, 0x38, + 0xFE, 0xE7, 0x00, 0x78, 0x00, 0xF8, 0xFF, 0xFE, 0xFF, 0x0B, 0x00, + 0xCC, 0x00, 0x5E, 0x00, 0xA7, 0xFC, 0x44, 0xFC, 0xCA, 0x08, 0xAC, + 0x1B, 0xAD, 0x20, 0xC9, 0x11, 0x3B, 0x00, 0x54, 0xFB, 0xF1, 0xFE, + 0xFB, 0x00, 0x51, 0x00, 0xF7, 0xFF, 0xFB, 0xFF, 0x20, 0x00, 0xEA, + 0x00, 0xE8, 0xFF, 0x00, 0xFC, 0x6E, 0xFD, 0x32, 0x0C, 0x16, 0x1E, + 0x38, 0x1F, 0x3A, 0x0E, 0x51, 0xFE, 0xB1, 0xFB, 0x96, 0xFF, 0xF6, + 0x00, 0x30, 0x00, 0xF9, 0xFF, 0xF8, 0xFF, 0x3D, 0x00, 0xFA, 0x00, + 0x54, 0xFF, 0x82, 0xFB, 0x12, 0xFF, 0xBC, 0x0F, 0xEA, 0x1F, 0x21, + 0x1D, 0xBB, 0x0A, 0xE1, 0xFC, 0x43, 0xFC, 0x1E, 0x00, 0xDF, 0x00, + 0x16, 0x00, 0xFC, 0xFF, 0xF7, 0xFF, 0x61, 0x00, 0xF6, 0x00, 0xA5, + 0xFE, 0x42, 0xFB, 0x2F, 0x01, 0x47, 0x13, 0x15, 0x21, 0x80, 0x1A, + 0x6A, 0x07, 0xE9, 0xFB, 0xF6, 0xFC, 0x86, 0x00, 0xBC, 0x00, 0x05, + 0x00, 0xFF, 0xFF, 0xFA, 0xFF, 0x8A, 0x00, 0xD7, 0x00, 0xE6, 0xFD, + 0x51, 0xFB, 0xBD, 0x03, 0xB0, 0x16, 0x89, 0x21, 0x71, 0x17, 0x63, + 0x04, 0x61, 0xFB, 0xB8, 0xFD, 0xCB, 0x00, 0x93, 0x00, 0xFB, 0xFF, + 0x00, 0x00, 0xFF, 0xFF, 0x02, 0x00, 0xB3, 0x00, 0x99, 0x00, 0x22, + 0xFD, 0xC0, 0xFB, 0xB0, 0x06, 0xD4, 0x19, 0x41, 0x21, 0x14, 0x14, + 0xBC, 0x01, 0x3D, 0xFB, 0x7A, 0xFE, 0xF1, 0x00, 0x6A, 0x00, 0xF7, + 0xFF, 0xFD, 0xFF, 0x12, 0x00, 0xD7, 0x00, 0x39, 0x00, 0x6A, 0xFC, + 0x9D, 0xFC, 0xF2, 0x09, 0x91, 0x1C, 0x3F, 0x20, 0x8E, 0x10, 0x84, + 0xFF, 0x6D, 0xFB, 0x2D, 0xFF, 0xFC, 0x00, 0x45, 0x00, 0xF7, 0xFF, + 0xFA, 0xFF, 0x29, 0x00, 0xF2, 0x00, 0xB8, 0xFF, 0xCF, 0xFB, 0xF1, + 0xFD, 0x69, 0x0D, 0xCA, 0x1E, 0x90, 0x1E, 0x01, 0x0D, 0xC4, 0xFD, + 0xDF, 0xFB, 0xC9, 0xFF, 0xF0, 0x00, 0x26, 0x00, 0xFA, 0xFF, 0xF7, + 0xFF, 0x49, 0x00, 0xFC, 0x00, 0x1A, 0xFF, 0x64, 0xFB, 0xC0, 0xFF, + 0xF7, 0x10, 0x66, 0x20, 0x46, 0x1C, 0x8E, 0x09, 0x7E, 0xFC, 0x7E, + 0xFC, 0x46, 0x00, 0xD4, 0x00, 0x0F, 0x00, 0xFD, 0xFF, 0xF7, 0xFF, + 0x6F, 0x00, 0xEE, 0x00, 0x64, 0xFE, 0x3D, 0xFB, 0x05, 0x02, 0x7B, + 0x14, 0x53, 0x21, 0x7C, 0x19, 0x54, 0x06, 0xAE, 0xFB, 0x38, 0xFD, + 0xA1, 0x00, 0xAE, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFC, + 0xFF, 0x98, 0x00, 0xC5, 0x00, 0xA2, 0xFD, 0x6C, 0xFB, 0xB8, 0x04, + 0xCF, 0x17, 0x85, 0x21, 0x4E, 0x16, 0x6C, 0x03, 0x4A, 0xFB, 0xFC, + 0xFD, 0xDC, 0x00, 0x85, 0x00, 0xF9, 0xFF, 0xFF, 0xFF, 0x07, 0x00, + 0xC0, 0x00, 0x7B, 0x00, 0xE0, 0xFC, 0x00, 0xFC, 0xC9, 0x07, 0xD3, + 0x1A, 0xFC, 0x20, 0xDF, 0x12, 0xEA, 0x00, 0x46, 0xFB, 0xBA, 0xFE, + 0xF8, 0x00, 0x5D, 0x00, 0xF7, 0xFF, 0xFC, 0xFF, 0x19, 0x00, 0xE2, + 0x00, 0x10, 0x00, 0x30, 0xFC, 0x05, 0xFD, 0x21, 0x0B, 0x66, 0x1D, + 0xBD, 0x1F, 0x53, 0x0F, 0xDB, 0xFE, 0x8E, 0xFB, 0x66, 0xFF, 0xFA, + 0x00, 0x3A, 0x00, 0xF8, 0xFF, 0xF9, 0xFF, 0x34, 0x00, 0xF7, 0x00, + 0x84, 0xFF, 0xA4, 0xFB, 0x84, 0xFE, 0xA3, 0x0E, 0x6C, 0x1F, 0xD6, + 0x1D, 0xCB, 0x0B, 0x45, 0xFD, 0x12, 0xFC, 0xF8, 0xFF, 0xE7, 0x00, + 0x1D, 0x00, 0xFB, 0xFF, 0xF7, 0xFF, 0x56, 0x00, 0xFA, 0x00, 0xDD, + 0xFE, 0x4E, 0xFB, 0x7C, 0x00, 0x32, 0x12, 0xCC, 0x20, 0x5C, 0x1B, + 0x69, 0x08, 0x29, 0xFC, 0xBC, 0xFC, 0x69, 0x00, 0xC7, 0x00, 0x09, + 0x00, 0xFE, 0xFF, 0xF8, 0xFF, 0x7D, 0x00, 0xE3, 0x00, 0x21, 0xFE, + 0x43, 0xFB, 0xE9, 0x02, 0xA9, 0x15, 0x79, 0x21, 0x6B, 0x18, 0x48, + 0x05, 0x80, 0xFB, 0x7C, 0xFD, 0xB9, 0x00, 0xA0, 0x00, 0xFD, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xA6, 0x00, 0xAF, 0x00, 0x5E, + 0xFD, 0x93, 0xFB, 0xBE, 0x05, 0xE5, 0x18, 0x6B, 0x21, 0x23, 0x15, + 0x82, 0x02, 0x3F, 0xFB, 0x3F, 0xFE, 0xE9, 0x00, 0x77, 0x00, 0xF8, + 0xFF, 0xFE, 0xFF, 0x0C, 0x00, 0xCD, 0x00, 0x5A, 0x00, 0xA0, 0xFC, + 0x4D, 0xFC, 0xEA, 0x08, 0xC6, 0x1B, 0xA1, 0x20, 0xA6, 0x11, 0x26, + 0x00, 0x57, 0xFB, 0xF8, 0xFE, 0xFB, 0x00, 0x50, 0x00, 0xF7, 0xFF, + 0xFB, 0xFF, 0x21, 0x00, 0xEB, 0x00, 0xE3, 0xFF, 0xFA, 0xFB, 0x7C, + 0xFD, 0x54, 0x0C, 0x2B, 0x1E, 0x26, 0x1F, 0x17, 0x0E, 0x41, 0xFE, + 0xB6, 0xFB, 0x9C, 0xFF, 0xF5, 0x00, 0x2F, 0x00, 0xF9, 0xFF, 0xF8, + 0xFF, 0x3F, 0x00, 0xFB, 0x00, 0x4D, 0xFF, 0x7F, 0xFB, 0x24, 0xFF, + 0xDF, 0x0F, 0xF9, 0x1F, 0x09, 0x1D, 0x99, 0x0A, 0xD5, 0xFC, 0x49, + 0xFC, 0x23, 0x00, 0xDD, 0x00, 0x16, 0x00, 0xFC, 0xFF, 0xF7, 0xFF, + 0x63, 0x00, 0xF5, 0x00, 0x9E, 0xFE, 0x41, 0xFB, 0x46, 0x01, 0x69, + 0x13, 0x1D, 0x21, 0x63, 0x1A, 0x4B, 0x07, 0xE2, 0xFB, 0xFD, 0xFC, + 0x89, 0x00, 0xBA, 0x00, 0x04, 0x00, 0xFF, 0xFF, 0xFA, 0xFF, 0x8B, + 0x00, 0xD5, 0x00, 0xDE, 0xFD, 0x53, 0xFB, 0xD9, 0x03, 0xD0, 0x16, + 0x8A, 0x21, 0x51, 0x17, 0x47, 0x04, 0x5E, 0xFB, 0xC0, 0xFD, 0xCD, + 0x00, 0x92, 0x00, 0xFB, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x02, 0x00, + 0xB4, 0x00, 0x96, 0x00, 0x1B, 0xFD, 0xC7, 0xFB, 0xCF, 0x06, 0xF0, + 0x19, 0x3A, 0x21, 0xF2, 0x13, 0xA4, 0x01, 0x3E, 0xFB, 0x81, 0xFE, + 0xF2, 0x00, 0x69, 0x00, 0xF7, 0xFF, 0xFD, 0xFF, 0x12, 0x00, 0xD9, + 0x00, 0x35, 0x00, 0x63, 0xFC, 0xA8, 0xFC, 0x13, 0x0A, 0xA9, 0x1C, + 0x32, 0x20, 0x6B, 0x10, 0x71, 0xFF, 0x71, 0xFB, 0x34, 0xFF, 0xFB, + 0x00, 0x44, 0x00, 0xF8, 0xFF, 0xFA, 0xFF, 0x2B, 0x00, 0xF3, 0x00, + 0xB3, 0xFF, 0xCA, 0xFB, 0x01, 0xFE, 0x8C, 0x0D, 0xDD, 0x1E, 0x7C, + 0x1E, 0xDE, 0x0C, 0xB5, 0xFD, 0xE4, 0xFB, 0xCE, 0xFF, 0xEF, 0x00, + 0x25, 0x00, 0xFA, 0xFF, 0xF7, 0xFF, 0x4A, 0x00, 0xFC, 0x00, 0x13, + 0xFF, 0x61, 0xFB, 0xD4, 0xFF, 0x1A, 0x11, 0x72, 0x20, 0x2D, 0x1C, + 0x6D, 0x09, 0x74, 0xFC, 0x85, 0xFC, 0x4A, 0x00, 0xD2, 0x00, 0x0F, + 0x00, 0xFD, 0xFF, 0xF7, 0xFF, 0x70, 0x00, 0xED, 0x00, 0x5D, 0xFE, + 0x3D, 0xFB, 0x1E, 0x02, 0x9C, 0x14, 0x58, 0x21, 0x5E, 0x19, 0x36, + 0x06, 0xA8, 0xFB, 0x40, 0xFD, 0xA4, 0x00, 0xAD, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0xFC, 0xFF, 0x9A, 0x00, 0xC3, 0x00, 0x9A, + 0xFD, 0x6F, 0xFB, 0xD5, 0x04, 0xEF, 0x17, 0x83, 0x21, 0x2D, 0x16, + 0x52, 0x03, 0x49, 0xFB, 0x04, 0xFE, 0xDD, 0x00, 0x83, 0x00, 0xF9, + 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0xC2, 0x00, 0x78, 0x00, 0xD9, 0xFC, + 0x08, 0xFC, 0xE9, 0x07, 0xEF, 0x1A, 0xF3, 0x20, 0xBC, 0x12, 0xD4, + 0x00, 0x47, 0xFB, 0xC1, 0xFE, 0xF8, 0x00, 0x5B, 0x00, 0xF7, 0xFF, + 0xFC, 0xFF, 0x1A, 0x00, 0xE3, 0x00, 0x0B, 0x00, 0x2A, 0xFC, 0x12, + 0xFD, 0x42, 0x0B, 0x7D, 0x1D, 0xAD, 0x1F, 0x2F, 0x0F, 0xC9, 0xFE, + 0x92, 0xFB, 0x6C, 0xFF, 0xF9, 0x00, 0x38, 0x00, 0xF8, 0xFF, 0xF9, + 0xFF, 0x35, 0x00, 0xF8, 0x00, 0x7E, 0xFF, 0x9F, 0xFB, 0x95, 0xFE, + 0xC6, 0x0E, 0x7C, 0x1F, 0xC0, 0x1D, 0xA9, 0x0B, 0x38, 0xFD, 0x18, + 0xFC, 0xFD, 0xFF, 0xE6, 0x00, 0x1D, 0x00, 0xFB, 0xFF, 0xF7, 0xFF, + 0x57, 0x00, 0xFA, 0x00, 0xD6, 0xFE, 0x4C, 0xFB, 0x92, 0x00, 0x54, + 0x12, 0xD6, 0x20, 0x41, 0x1B, 0x49, 0x08, 0x20, 0xFC, 0xC3, 0xFC, + 0x6D, 0x00, 0xC6, 0x00, 0x09, 0x00, 0xFE, 0xFF, 0xF8, 0xFF, 0x7E, + 0x00, 0xE2, 0x00, 0x1A, 0xFE, 0x44, 0xFB, 0x03, 0x03, 0xCA, 0x15, + 0x7C, 0x21, 0x4C, 0x18, 0x2B, 0x05, 0x7B, 0xFB, 0x83, 0xFD, 0xBC, + 0x00, 0x9E, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xA8, 0x00, 0xAD, 0x00, 0x56, 0xFD, 0x98, 0xFB, 0xDC, 0x05, 0x04, + 0x19, 0x66, 0x21, 0x02, 0x15, 0x69, 0x02, 0x3E, 0xFB, 0x47, 0xFE, + 0xEA, 0x00, 0x75, 0x00, 0xF8, 0xFF, 0xFE, 0xFF, 0x0D, 0x00, 0xCE, + 0x00, 0x56, 0x00, 0x99, 0xFC, 0x56, 0xFC, 0x0B, 0x09, 0xE0, 0x1B, + 0x96, 0x20, 0x83, 0x11, 0x11, 0x00, 0x59, 0xFB, 0xFF, 0xFE, 0xFB, + 0x00, 0x4E, 0x00, 0xF7, 0xFF, 0xFB, 0xFF, 0x22, 0x00, 0xEC, 0x00, + 0xDE, 0xFF, 0xF5, 0xFB, 0x8A, 0xFD, 0x77, 0x0C, 0x3F, 0x1E, 0x14, + 0x1F, 0xF5, 0x0D, 0x31, 0xFE, 0xBB, 0xFB, 0xA2, 0xFF, 0xF5, 0x00, + 0x2E, 0x00, 0xF9, 0xFF, 0xF8, 0xFF, 0x40, 0x00, 0xFB, 0x00, 0x47, + 0xFF, 0x7B, 0xFB, 0x37, 0xFF, 0x02, 0x10, 0x07, 0x20, 0xF2, 0x1C, + 0x78, 0x0A, 0xCA, 0xFC, 0x50, 0xFC, 0x27, 0x00, 0xDC, 0x00, 0x15, + 0x00, 0xFC, 0xFF, 0xF7, 0xFF, 0x64, 0x00, 0xF5, 0x00, 0x97, 0xFE, + 0x40, 0xFB, 0x5D, 0x01, 0x8B, 0x13, 0x25, 0x21, 0x47, 0x1A, 0x2C, + 0x07, 0xDB, 0xFB, 0x05, 0xFD, 0x8C, 0x00, 0xB9, 0x00, 0x04, 0x00, + 0xFF, 0xFF, 0xFA, 0xFF, 0x8D, 0x00, 0xD3, 0x00, 0xD6, 0xFD, 0x56, + 0xFB, 0xF4, 0x03, 0xF0, 0x16, 0x8A, 0x21, 0x31, 0x17, 0x2B, 0x04, + 0x5B, 0xFB, 0xC7, 0xFD, 0xCF, 0x00, 0x90, 0x00, 0xFA, 0xFF, 0x00, + 0x00, 0xFF, 0xFF, 0x03, 0x00, 0xB6, 0x00, 0x92, 0x00, 0x13, 0xFD, + 0xCD, 0xFB, 0xEE, 0x06, 0x0D, 0x1A, 0x33, 0x21, 0xD0, 0x13, 0x8C, + 0x01, 0x3E, 0xFB, 0x88, 0xFE, 0xF3, 0x00, 0x67, 0x00, 0xF7, 0xFF, + 0x06, 0x00, 0x1D, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0xA1, 0x02, 0xA6, + 0xF8, 0x56, 0x02, 0xA5, 0x28, 0xA5, 0x28, 0x56, 0x02, 0xA6, 0xF8, + 0xA1, 0x02, 0xFE, 0x00, 0x03, 0xFF, 0x1D, 0x00, 0x06, 0x00, 0x00, + 0x00, 0x21, 0x00, 0xA6, 0xFF, 0x3F, 0xFF, 0x0B, 0x03, 0x42, 0xFE, + 0x3E, 0xF8, 0x7F, 0x15, 0xAC, 0x30, 0x7F, 0x15, 0x3E, 0xF8, 0x42, + 0xFE, 0x0B, 0x03, 0x3F, 0xFF, 0xA6, 0xFF, 0x21, 0x00, 0x00, 0x00, + 0xFA, 0xFF, 0xCE, 0xFF, 0x14, 0x01, 0x00, 0xFD, 0x35, 0x06, 0xD5, + 0xF4, 0xDA, 0x15, 0x92, 0x40, 0xAE, 0xFE, 0xF3, 0xFC, 0x68, 0x03, + 0x86, 0xFD, 0x51, 0x01, 0x8B, 0xFF, 0x11, 0x00, 0x01, 0x00, 0xEC, + 0xFF, 0xF9, 0xFF, 0xC6, 0x00, 0x55, 0xFD, 0x35, 0x06, 0x90, 0xF3, + 0xE5, 0x1C, 0x6B, 0x3D, 0x71, 0xFA, 0x34, 0xFF, 0x46, 0x02, 0xFF, + 0xFD, 0x2D, 0x01, 0x90, 0xFF, 0x10, 0x00, 0x03, 0x00, 0xDB, 0xFF, + 0x2D, 0x00, 0x60, 0x00, 0xE1, 0xFD, 0xCE, 0x05, 0xED, 0xF2, 0xF3, + 0x23, 0x20, 0x39, 0x22, 0xF7, 0x44, 0x01, 0x1F, 0x01, 0x89, 0xFE, + 0xFB, 0x00, 0x9C, 0xFF, 0x0D, 0x00, 0x06, 0x00, 0xC9, 0xFF, 0x68, + 0x00, 0xE5, 0xFF, 0xA0, 0xFE, 0xFB, 0x04, 0x0C, 0xF3, 0xC5, 0x2A, + 0xD8, 0x33, 0xC9, 0xF4, 0x0B, 0x03, 0x05, 0x00, 0x1A, 0xFF, 0xC1, + 0x00, 0xAD, 0xFF, 0x0A, 0x00, 0x09, 0x00, 0xB5, 0xFF, 0xA5, 0x00, + 0x5C, 0xFF, 0x8C, 0xFF, 0xBF, 0x03, 0x06, 0xF4, 0x22, 0x31, 0xC8, + 0x2D, 0x63, 0xF3, 0x76, 0x04, 0x08, 0xFF, 0xA7, 0xFF, 0x84, 0x00, + 0xC0, 0xFF, 0x07, 0x00, 0x0C, 0x00, 0xA4, 0xFF, 0xE1, 0x00, 0xCB, + 0xFE, 0x9B, 0x00, 0x21, 0x02, 0xEE, 0xF5, 0xCD, 0x36, 0x24, 0x27, + 0xE1, 0xF2, 0x7A, 0x05, 0x33, 0xFE, 0x2A, 0x00, 0x47, 0x00, 0xD3, + 0xFF, 0x04, 0x00, 0x0F, 0x00, 0x95, 0xFF, 0x17, 0x01, 0x3D, 0xFE, + 0xBD, 0x01, 0x30, 0x00, 0xCC, 0xF8, 0x92, 0x3B, 0x2A, 0x20, 0x2E, + 0xF3, 0x12, 0x06, 0x8F, 0xFD, 0x9A, 0x00, 0x10, 0x00, 0xE5, 0xFF, + 0x02, 0x00, 0x10, 0x00, 0x8C, 0xFF, 0x42, 0x01, 0xBB, 0xFD, 0xE4, + 0x02, 0x01, 0xFE, 0x9C, 0xFC, 0x45, 0x3F, 0x16, 0x19, 0x2D, 0xF4, + 0x41, 0x06, 0x21, 0xFD, 0xF3, 0x00, 0xE0, 0xFF, 0xF4, 0xFF, 0x01, + 0x00, 0x10, 0x00, 0x8B, 0xFF, 0x5D, 0x01, 0x4F, 0xFD, 0xFB, 0x03, + 0xB2, 0xFB, 0x53, 0x01, 0xC2, 0x41, 0x24, 0x12, 0xBA, 0xF5, 0x0F, + 0x06, 0xE9, 0xFC, 0x33, 0x01, 0xBB, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x93, 0xFF, 0x63, 0x01, 0x04, 0xFD, 0xEF, 0x04, 0x62, + 0xF9, 0xD7, 0x06, 0xF2, 0x42, 0x8D, 0x0B, 0xB0, 0xF7, 0x87, 0x05, + 0xE6, 0xFC, 0x58, 0x01, 0xA0, 0xFF, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x00, 0xA5, 0xFF, 0x52, 0x01, 0xE2, 0xFC, 0xAD, 0x05, + 0x35, 0xF7, 0x08, 0x0D, 0xCB, 0x42, 0x81, 0x05, 0xE8, 0xF9, 0xBB, + 0x04, 0x12, 0xFD, 0x64, 0x01, 0x90, 0xFF, 0x0E, 0x00, 0x00, 0x00, + 0xFE, 0xFF, 0xC2, 0xFF, 0x27, 0x01, 0xF1, 0xFC, 0x22, 0x06, 0x54, + 0xF5, 0xB8, 0x13, 0x4A, 0x41, 0x29, 0x00, 0x3C, 0xFC, 0xBD, 0x03, + 0x66, 0xFD, 0x58, 0x01, 0x8A, 0xFF, 0x11, 0x00, 0x01, 0x00, 0xF1, + 0xFF, 0xEB, 0xFF, 0xE1, 0x00, 0x35, 0xFD, 0x40, 0x06, 0xE4, 0xF3, + 0xB7, 0x1A, 0x85, 0x3E, 0xA6, 0xFB, 0x86, 0xFE, 0xA0, 0x02, 0xD7, + 0xFD, 0x39, 0x01, 0x8E, 0xFF, 0x10, 0x00, 0x03, 0x00, 0xE1, 0xFF, + 0x1C, 0x00, 0x82, 0x00, 0xB0, 0xFD, 0xF9, 0x05, 0x0C, 0xF3, 0xCB, + 0x21, 0x8F, 0x3A, 0x0D, 0xF8, 0xA9, 0x00, 0x79, 0x01, 0x5D, 0xFE, + 0x0B, 0x01, 0x98, 0xFF, 0x0E, 0x00, 0x05, 0x00, 0xCE, 0xFF, 0x55, + 0x00, 0x0D, 0x00, 0x60, 0xFE, 0x48, 0x05, 0xEC, 0xF2, 0xB6, 0x28, + 0x91, 0x35, 0x68, 0xF5, 0x88, 0x02, 0x5A, 0x00, 0xED, 0xFE, 0xD4, + 0x00, 0xA8, 0xFF, 0x0B, 0x00, 0x08, 0x00, 0xBB, 0xFF, 0x92, 0x00, + 0x87, 0xFF, 0x3F, 0xFF, 0x2B, 0x04, 0xA1, 0xF3, 0x3D, 0x2F, 0xB8, + 0x2F, 0xB8, 0xF3, 0x11, 0x04, 0x52, 0xFF, 0x7C, 0xFF, 0x97, 0x00, + 0xBA, 0xFF, 0x08, 0x00, 0x0B, 0x00, 0xA9, 0xFF, 0xCF, 0x00, 0xF8, + 0xFE, 0x44, 0x00, 0xAA, 0x02, 0x3E, 0xF5, 0x24, 0x35, 0x3B, 0x29, + 0xF2, 0xF2, 0x35, 0x05, 0x70, 0xFE, 0x03, 0x00, 0x5A, 0x00, 0xCD, + 0xFF, 0x05, 0x00, 0x0E, 0x00, 0x99, 0xFF, 0x07, 0x01, 0x68, 0xFE, + 0x63, 0x01, 0xD0, 0x00, 0xD0, 0xF7, 0x35, 0x3A, 0x55, 0x22, 0x02, + 0xF3, 0xEF, 0x05, 0xBC, 0xFD, 0x7A, 0x00, 0x20, 0x00, 0xDF, 0xFF, + 0x03, 0x00, 0x10, 0x00, 0x8E, 0xFF, 0x36, 0x01, 0xE1, 0xFD, 0x8A, + 0x02, 0xB2, 0xFE, 0x56, 0xFB, 0x40, 0x3E, 0x42, 0x1B, 0xCE, 0xF3, + 0x3E, 0x06, 0x3D, 0xFD, 0xDB, 0x00, 0xEE, 0xFF, 0xF0, 0xFF, 0x01, + 0x00, 0x11, 0x00, 0x8A, 0xFF, 0x57, 0x01, 0x6D, 0xFD, 0xA8, 0x03, + 0x69, 0xFC, 0xC8, 0xFF, 0x20, 0x41, 0x40, 0x14, 0x33, 0xF5, 0x28, + 0x06, 0xF5, 0xFC, 0x22, 0x01, 0xC5, 0xFF, 0xFD, 0xFF, 0x00, 0x00, + 0x0F, 0x00, 0x8F, 0xFF, 0x64, 0x01, 0x17, 0xFD, 0xA9, 0x04, 0x16, + 0xFA, 0x10, 0x05, 0xB8, 0x42, 0x87, 0x0D, 0x0D, 0xF7, 0xB9, 0x05, + 0xE2, 0xFC, 0x50, 0x01, 0xA7, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0A, 0x00, 0x9E, 0xFF, 0x5A, 0x01, 0xE8, 0xFC, 0x7A, 0x05, + 0xDA, 0xF7, 0x10, 0x0B, 0xFB, 0x42, 0x4B, 0x07, 0x35, 0xF9, 0x00, + 0x05, 0x00, 0xFD, 0x63, 0x01, 0x94, 0xFF, 0x0D, 0x00, 0x00, 0x00, + 0x01, 0x00, 0xB8, 0xFF, 0x37, 0x01, 0xE7, 0xFC, 0x07, 0x06, 0xDE, + 0xF5, 0x9F, 0x11, 0xE4, 0x41, 0xB8, 0x01, 0x84, 0xFB, 0x0F, 0x04, + 0x48, 0xFD, 0x5E, 0x01, 0x8B, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF5, + 0xFF, 0xDD, 0xFF, 0xF9, 0x00, 0x1B, 0xFD, 0x41, 0x06, 0x47, 0xF4, + 0x8B, 0x18, 0x81, 0x3F, 0xF1, 0xFC, 0xD5, 0xFD, 0xFA, 0x02, 0xB2, + 0xFD, 0x45, 0x01, 0x8C, 0xFF, 0x11, 0x00, 0x02, 0x00, 0xE6, 0xFF, + 0x0C, 0x00, 0xA2, 0x00, 0x85, 0xFD, 0x1A, 0x06, 0x3C, 0xF3, 0x9F, + 0x1F, 0xE6, 0x3B, 0x0E, 0xF9, 0x07, 0x00, 0xD4, 0x01, 0x33, 0xFE, + 0x1B, 0x01, 0x94, 0xFF, 0x0F, 0x00, 0x04, 0x00, 0xD4, 0xFF, 0x43, + 0x00, 0x33, 0x00, 0x25, 0xFE, 0x89, 0x05, 0xE0, 0xF2, 0x9C, 0x26, + 0x33, 0x37, 0x1E, 0xF6, 0xFD, 0x01, 0xB0, 0x00, 0xC0, 0xFE, 0xE6, + 0x00, 0xA2, 0xFF, 0x0C, 0x00, 0x07, 0x00, 0xC1, 0xFF, 0x7F, 0x00, + 0xB2, 0xFF, 0xF6, 0xFE, 0x8E, 0x04, 0x51, 0xF3, 0x49, 0x2D, 0x98, + 0x31, 0x23, 0xF4, 0xA2, 0x03, 0xA0, 0xFF, 0x51, 0xFF, 0xAA, 0x00, + 0xB4, 0xFF, 0x09, 0x00, 0x0A, 0x00, 0xAE, 0xFF, 0xBD, 0x00, 0x25, + 0xFF, 0xF1, 0xFF, 0x2B, 0x03, 0xA5, 0xF4, 0x68, 0x33, 0x48, 0x2B, + 0x17, 0xF3, 0xE7, 0x04, 0xB1, 0xFE, 0xDB, 0xFF, 0x6C, 0x00, 0xC7, + 0xFF, 0x06, 0x00, 0x0D, 0x00, 0x9E, 0xFF, 0xF7, 0x00, 0x94, 0xFE, + 0x09, 0x01, 0x6A, 0x01, 0xEB, 0xF6, 0xC1, 0x38, 0x7D, 0x24, 0xE8, + 0xF2, 0xC1, 0x05, 0xEE, 0xFD, 0x57, 0x00, 0x31, 0x00, 0xDA, 0xFF, + 0x03, 0x00, 0x10, 0x00, 0x91, 0xFF, 0x29, 0x01, 0x09, 0xFE, 0x2F, + 0x02, 0x5F, 0xFF, 0x27, 0xFA, 0x20, 0x3D, 0x70, 0x1D, 0x7D, 0xF3, + 0x31, 0x06, 0x5E, 0xFD, 0xBF, 0x00, 0xFD, 0xFF, 0xEB, 0xFF, 0x02, + 0x00, 0x11, 0x00, 0x8B, 0xFF, 0x4E, 0x01, 0x8E, 0xFD, 0x52, 0x03, + 0x20, 0xFD, 0x52, 0xFE, 0x60, 0x40, 0x63, 0x16, 0xB7, 0xF4, 0x39, + 0x06, 0x05, 0xFD, 0x0F, 0x01, 0xD1, 0xFF, 0xF9, 0xFF, 0x00, 0x00, + 0x10, 0x00, 0x8D, 0xFF, 0x62, 0x01, 0x2E, 0xFD, 0x5E, 0x04, 0xCC, + 0xFA, 0x5B, 0x03, 0x5E, 0x42, 0x8E, 0x0F, 0x71, 0xF6, 0xE4, 0x05, + 0xE2, 0xFC, 0x45, 0x01, 0xAF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0B, 0x00, 0x99, 0xFF, 0x60, 0x01, 0xF2, 0xFC, 0x40, 0x05, + 0x85, 0xF8, 0x26, 0x09, 0x0C, 0x43, 0x26, 0x09, 0x85, 0xF8, 0x40, + 0x05, 0xF2, 0xFC, 0x60, 0x01, 0x99, 0xFF, 0x0B, 0x00, 0x00, 0x00, + 0x04, 0x00, 0xAF, 0xFF, 0x45, 0x01, 0xE2, 0xFC, 0xE4, 0x05, 0x71, + 0xF6, 0x8E, 0x0F, 0x5E, 0x42, 0x5B, 0x03, 0xCC, 0xFA, 0x5E, 0x04, + 0x2E, 0xFD, 0x62, 0x01, 0x8D, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xF9, + 0xFF, 0xD1, 0xFF, 0x0F, 0x01, 0x05, 0xFD, 0x39, 0x06, 0xB7, 0xF4, + 0x63, 0x16, 0x60, 0x40, 0x52, 0xFE, 0x20, 0xFD, 0x52, 0x03, 0x8E, + 0xFD, 0x4E, 0x01, 0x8B, 0xFF, 0x11, 0x00, 0x02, 0x00, 0xEB, 0xFF, + 0xFD, 0xFF, 0xBF, 0x00, 0x5E, 0xFD, 0x31, 0x06, 0x7D, 0xF3, 0x70, + 0x1D, 0x20, 0x3D, 0x27, 0xFA, 0x5F, 0xFF, 0x2F, 0x02, 0x09, 0xFE, + 0x29, 0x01, 0x91, 0xFF, 0x10, 0x00, 0x03, 0x00, 0xDA, 0xFF, 0x31, + 0x00, 0x57, 0x00, 0xEE, 0xFD, 0xC1, 0x05, 0xE8, 0xF2, 0x7D, 0x24, + 0xC1, 0x38, 0xEB, 0xF6, 0x6A, 0x01, 0x09, 0x01, 0x94, 0xFE, 0xF7, + 0x00, 0x9E, 0xFF, 0x0D, 0x00, 0x06, 0x00, 0xC7, 0xFF, 0x6C, 0x00, + 0xDB, 0xFF, 0xB1, 0xFE, 0xE7, 0x04, 0x17, 0xF3, 0x48, 0x2B, 0x68, + 0x33, 0xA5, 0xF4, 0x2B, 0x03, 0xF1, 0xFF, 0x25, 0xFF, 0xBD, 0x00, + 0xAE, 0xFF, 0x0A, 0x00, 0x09, 0x00, 0xB4, 0xFF, 0xAA, 0x00, 0x51, + 0xFF, 0xA0, 0xFF, 0xA2, 0x03, 0x23, 0xF4, 0x98, 0x31, 0x49, 0x2D, + 0x51, 0xF3, 0x8E, 0x04, 0xF6, 0xFE, 0xB2, 0xFF, 0x7F, 0x00, 0xC1, + 0xFF, 0x07, 0x00, 0x0C, 0x00, 0xA2, 0xFF, 0xE6, 0x00, 0xC0, 0xFE, + 0xB0, 0x00, 0xFD, 0x01, 0x1E, 0xF6, 0x33, 0x37, 0x9C, 0x26, 0xE0, + 0xF2, 0x89, 0x05, 0x25, 0xFE, 0x33, 0x00, 0x43, 0x00, 0xD4, 0xFF, + 0x04, 0x00, 0x0F, 0x00, 0x94, 0xFF, 0x1B, 0x01, 0x33, 0xFE, 0xD4, + 0x01, 0x07, 0x00, 0x0E, 0xF9, 0xE6, 0x3B, 0x9F, 0x1F, 0x3C, 0xF3, + 0x1A, 0x06, 0x85, 0xFD, 0xA2, 0x00, 0x0C, 0x00, 0xE6, 0xFF, 0x02, + 0x00, 0x11, 0x00, 0x8C, 0xFF, 0x45, 0x01, 0xB2, 0xFD, 0xFA, 0x02, + 0xD5, 0xFD, 0xF1, 0xFC, 0x81, 0x3F, 0x8B, 0x18, 0x47, 0xF4, 0x41, + 0x06, 0x1B, 0xFD, 0xF9, 0x00, 0xDD, 0xFF, 0xF5, 0xFF, 0x01, 0x00, + 0x10, 0x00, 0x8B, 0xFF, 0x5E, 0x01, 0x48, 0xFD, 0x0F, 0x04, 0x84, + 0xFB, 0xB8, 0x01, 0xE4, 0x41, 0x9F, 0x11, 0xDE, 0xF5, 0x07, 0x06, + 0xE7, 0xFC, 0x37, 0x01, 0xB8, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x0D, + 0x00, 0x94, 0xFF, 0x63, 0x01, 0x00, 0xFD, 0x00, 0x05, 0x35, 0xF9, + 0x4B, 0x07, 0xFB, 0x42, 0x10, 0x0B, 0xDA, 0xF7, 0x7A, 0x05, 0xE8, + 0xFC, 0x5A, 0x01, 0x9E, 0xFF, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x00, 0xA7, 0xFF, 0x50, 0x01, 0xE2, 0xFC, 0xB9, 0x05, 0x0D, + 0xF7, 0x87, 0x0D, 0xB8, 0x42, 0x10, 0x05, 0x16, 0xFA, 0xA9, 0x04, + 0x17, 0xFD, 0x64, 0x01, 0x8F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0xFD, + 0xFF, 0xC5, 0xFF, 0x22, 0x01, 0xF5, 0xFC, 0x28, 0x06, 0x33, 0xF5, + 0x40, 0x14, 0x20, 0x41, 0xC8, 0xFF, 0x69, 0xFC, 0xA8, 0x03, 0x6D, + 0xFD, 0x57, 0x01, 0x8A, 0xFF, 0x11, 0x00, 0x01, 0x00, 0xF0, 0xFF, + 0xEE, 0xFF, 0xDB, 0x00, 0x3D, 0xFD, 0x3E, 0x06, 0xCE, 0xF3, 0x42, + 0x1B, 0x40, 0x3E, 0x56, 0xFB, 0xB2, 0xFE, 0x8A, 0x02, 0xE1, 0xFD, + 0x36, 0x01, 0x8E, 0xFF, 0x10, 0x00, 0x03, 0x00, 0xDF, 0xFF, 0x20, + 0x00, 0x7A, 0x00, 0xBC, 0xFD, 0xEF, 0x05, 0x02, 0xF3, 0x55, 0x22, + 0x35, 0x3A, 0xD0, 0xF7, 0xD0, 0x00, 0x63, 0x01, 0x68, 0xFE, 0x07, + 0x01, 0x99, 0xFF, 0x0E, 0x00, 0x05, 0x00, 0xCD, 0xFF, 0x5A, 0x00, + 0x03, 0x00, 0x70, 0xFE, 0x35, 0x05, 0xF2, 0xF2, 0x3B, 0x29, 0x24, + 0x35, 0x3E, 0xF5, 0xAA, 0x02, 0x44, 0x00, 0xF8, 0xFE, 0xCF, 0x00, + 0xA9, 0xFF, 0x0B, 0x00, 0x08, 0x00, 0xBA, 0xFF, 0x97, 0x00, 0x7C, + 0xFF, 0x52, 0xFF, 0x11, 0x04, 0xB8, 0xF3, 0xB8, 0x2F, 0x3D, 0x2F, + 0xA1, 0xF3, 0x2B, 0x04, 0x3F, 0xFF, 0x87, 0xFF, 0x92, 0x00, 0xBB, + 0xFF, 0x08, 0x00, 0x0B, 0x00, 0xA8, 0xFF, 0xD4, 0x00, 0xED, 0xFE, + 0x5A, 0x00, 0x88, 0x02, 0x68, 0xF5, 0x91, 0x35, 0xB6, 0x28, 0xEC, + 0xF2, 0x48, 0x05, 0x60, 0xFE, 0x0D, 0x00, 0x55, 0x00, 0xCE, 0xFF, + 0x05, 0x00, 0x0E, 0x00, 0x98, 0xFF, 0x0B, 0x01, 0x5D, 0xFE, 0x79, + 0x01, 0xA9, 0x00, 0x0D, 0xF8, 0x8F, 0x3A, 0xCB, 0x21, 0x0C, 0xF3, + 0xF9, 0x05, 0xB0, 0xFD, 0x82, 0x00, 0x1C, 0x00, 0xE1, 0xFF, 0x03, + 0x00, 0x10, 0x00, 0x8E, 0xFF, 0x39, 0x01, 0xD7, 0xFD, 0xA0, 0x02, + 0x86, 0xFE, 0xA6, 0xFB, 0x85, 0x3E, 0xB7, 0x1A, 0xE4, 0xF3, 0x40, + 0x06, 0x35, 0xFD, 0xE1, 0x00, 0xEB, 0xFF, 0xF1, 0xFF, 0x01, 0x00, + 0x11, 0x00, 0x8A, 0xFF, 0x58, 0x01, 0x66, 0xFD, 0xBD, 0x03, 0x3C, + 0xFC, 0x29, 0x00, 0x4A, 0x41, 0xB8, 0x13, 0x54, 0xF5, 0x22, 0x06, + 0xF1, 0xFC, 0x27, 0x01, 0xC2, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0x0E, + 0x00, 0x90, 0xFF, 0x64, 0x01, 0x12, 0xFD, 0xBB, 0x04, 0xE8, 0xF9, + 0x81, 0x05, 0xCB, 0x42, 0x08, 0x0D, 0x35, 0xF7, 0xAD, 0x05, 0xE2, + 0xFC, 0x52, 0x01, 0xA5, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0xA0, 0xFF, 0x58, 0x01, 0xE6, 0xFC, 0x87, 0x05, 0xB0, + 0xF7, 0x8D, 0x0B, 0xF2, 0x42, 0xD7, 0x06, 0x62, 0xF9, 0xEF, 0x04, + 0x04, 0xFD, 0x63, 0x01, 0x93, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xBB, 0xFF, 0x33, 0x01, 0xE9, 0xFC, 0x0F, 0x06, 0xBA, 0xF5, + 0x24, 0x12, 0xC2, 0x41, 0x53, 0x01, 0xB2, 0xFB, 0xFB, 0x03, 0x4F, + 0xFD, 0x5D, 0x01, 0x8B, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF4, 0xFF, + 0xE0, 0xFF, 0xF3, 0x00, 0x21, 0xFD, 0x41, 0x06, 0x2D, 0xF4, 0x16, + 0x19, 0x45, 0x3F, 0x9C, 0xFC, 0x01, 0xFE, 0xE4, 0x02, 0xBB, 0xFD, + 0x42, 0x01, 0x8C, 0xFF, 0x10, 0x00, 0x02, 0x00, 0xE5, 0xFF, 0x10, + 0x00, 0x9A, 0x00, 0x8F, 0xFD, 0x12, 0x06, 0x2E, 0xF3, 0x2A, 0x20, + 0x92, 0x3B, 0xCC, 0xF8, 0x30, 0x00, 0xBD, 0x01, 0x3D, 0xFE, 0x17, + 0x01, 0x95, 0xFF, 0x0F, 0x00, 0x04, 0x00, 0xD3, 0xFF, 0x47, 0x00, + 0x2A, 0x00, 0x33, 0xFE, 0x7A, 0x05, 0xE1, 0xF2, 0x24, 0x27, 0xCD, + 0x36, 0xEE, 0xF5, 0x21, 0x02, 0x9B, 0x00, 0xCB, 0xFE, 0xE1, 0x00, + 0xA4, 0xFF, 0x0C, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0x84, 0x00, 0xA7, + 0xFF, 0x08, 0xFF, 0x76, 0x04, 0x63, 0xF3, 0xC8, 0x2D, 0x22, 0x31, + 0x06, 0xF4, 0xBF, 0x03, 0x8C, 0xFF, 0x5C, 0xFF, 0xA5, 0x00, 0xB5, + 0xFF, 0x09, 0x00, 0x0A, 0x00, 0xAD, 0xFF, 0xC1, 0x00, 0x1A, 0xFF, + 0x05, 0x00, 0x0B, 0x03, 0xC9, 0xF4, 0xD8, 0x33, 0xC5, 0x2A, 0x0C, + 0xF3, 0xFB, 0x04, 0xA0, 0xFE, 0xE5, 0xFF, 0x68, 0x00, 0xC9, 0xFF, + 0x06, 0x00, 0x0D, 0x00, 0x9C, 0xFF, 0xFB, 0x00, 0x89, 0xFE, 0x1F, + 0x01, 0x44, 0x01, 0x22, 0xF7, 0x20, 0x39, 0xF3, 0x23, 0xED, 0xF2, + 0xCE, 0x05, 0xE1, 0xFD, 0x60, 0x00, 0x2D, 0x00, 0xDB, 0xFF, 0x03, + 0x00, 0x10, 0x00, 0x90, 0xFF, 0x2D, 0x01, 0xFF, 0xFD, 0x46, 0x02, + 0x34, 0xFF, 0x71, 0xFA, 0x6B, 0x3D, 0xE5, 0x1C, 0x90, 0xF3, 0x35, + 0x06, 0x55, 0xFD, 0xC6, 0x00, 0xF9, 0xFF, 0xEC, 0xFF, 0x01, 0x00, + 0x11, 0x00, 0x8B, 0xFF, 0x51, 0x01, 0x86, 0xFD, 0x68, 0x03, 0xF3, + 0xFC, 0xAE, 0xFE, 0x92, 0x40, 0xDA, 0x15, 0xD5, 0xF4, 0x35, 0x06, + 0x00, 0xFD, 0x14, 0x01, 0xCE, 0xFF, 0xFA, 0xFF, 0x00, 0x00, 0x0F, + 0x00, 0x8D, 0xFF, 0x63, 0x01, 0x28, 0xFD, 0x71, 0x04, 0x9E, 0xFA, + 0xC7, 0x03, 0x79, 0x42, 0x0B, 0x0F, 0x97, 0xF6, 0xDA, 0x05, 0xE2, + 0xFC, 0x48, 0x01, 0xAD, 0xFF, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0B, 0x00, 0x9A, 0xFF, 0x5F, 0x01, 0xEF, 0xFC, 0x4F, 0x05, 0x5A, + 0xF8, 0x9F, 0x09, 0x0A, 0x43, 0xAE, 0x08, 0xB1, 0xF8, 0x30, 0x05, + 0xF5, 0xFC, 0x61, 0x01, 0x97, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x03, + 0x00, 0xB1, 0xFF, 0x41, 0x01, 0xE3, 0xFC, 0xED, 0x05, 0x4C, 0xF6, + 0x11, 0x10, 0x42, 0x42, 0xF1, 0x02, 0xFA, 0xFA, 0x4B, 0x04, 0x34, + 0xFD, 0x61, 0x01, 0x8C, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF8, 0xFF, + 0xD4, 0xFF, 0x0A, 0x01, 0x0A, 0xFD, 0x3C, 0x06, 0x9A, 0xF4, 0xED, + 0x16, 0x2A, 0x40, 0xF8, 0xFD, 0x4D, 0xFD, 0x3C, 0x03, 0x97, 0xFD, + 0x4C, 0x01, 0x8B, 0xFF, 0x11, 0x00, 0x02, 0x00, 0xEA, 0xFF, 0x00, + 0x00, 0xB8, 0x00, 0x67, 0xFD, 0x2C, 0x06, 0x6B, 0xF3, 0xFC, 0x1D, + 0xD3, 0x3C, 0xDF, 0xF9, 0x89, 0xFF, 0x18, 0x02, 0x13, 0xFE, 0x26, + 0x01, 0x92, 0xFF, 0x0F, 0x00, 0x04, 0x00, 0xD9, 0xFF, 0x36, 0x00, + 0x4E, 0x00, 0xFB, 0xFD, 0xB4, 0x05, 0xE4, 0xF2, 0x04, 0x25, 0x5F, + 0x38, 0xB6, 0xF6, 0x90, 0x01, 0xF3, 0x00, 0x9F, 0xFE, 0xF3, 0x00, + 0x9F, 0xFF, 0x0D, 0x00, 0x06, 0x00, 0xC6, 0xFF, 0x71, 0x00, 0xD1, + 0xFF, 0xC2, 0xFE, 0xD1, 0x04, 0x23, 0xF3, 0xC9, 0x2B, 0xF5, 0x32, + 0x83, 0xF4, 0x49, 0x03, 0xDC, 0xFF, 0x30, 0xFF, 0xB8, 0x00, 0xB0, + 0xFF, 0x0A, 0x00, 0x09, 0x00, 0xB3, 0xFF, 0xAE, 0x00, 0x46, 0xFF, + 0xB4, 0xFF, 0x85, 0x03, 0x42, 0xF4, 0x0E, 0x32, 0xCA, 0x2C, 0x41, + 0xF3, 0xA5, 0x04, 0xE4, 0xFE, 0xBC, 0xFF, 0x7A, 0x00, 0xC3, 0xFF, + 0x07, 0x00, 0x0D, 0x00, 0xA1, 0xFF, 0xEA, 0x00, 0xB5, 0xFE, 0xC6, + 0x00, 0xD9, 0x01, 0x4F, 0xF6, 0x99, 0x37, 0x16, 0x26, 0xE0, 0xF2, + 0x98, 0x05, 0x16, 0xFE, 0x3C, 0x00, 0x3F, 0x00, 0xD6, 0xFF, 0x04, + 0x00, 0x0F, 0x00, 0x93, 0xFF, 0x1F, 0x01, 0x28, 0xFE, 0xEB, 0x01, + 0xDD, 0xFF, 0x52, 0xF9, 0x36, 0x3C, 0x13, 0x1F, 0x4B, 0xF3, 0x20, + 0x06, 0x7B, 0xFD, 0xA9, 0x00, 0x08, 0x00, 0xE7, 0xFF, 0x02, 0x00, + 0x11, 0x00, 0x8C, 0xFF, 0x47, 0x01, 0xA9, 0xFD, 0x10, 0x03, 0xA8, + 0xFD, 0x47, 0xFD, 0xBB, 0x3F, 0x01, 0x18, 0x62, 0xF4, 0x40, 0x06, + 0x15, 0xFD, 0xFF, 0x00, 0xDA, 0xFF, 0xF6, 0xFF, 0x01, 0x00, 0x10, + 0x00, 0x8B, 0xFF, 0x5F, 0x01, 0x41, 0xFD, 0x23, 0x04, 0x56, 0xFB, + 0x1F, 0x02, 0x06, 0x42, 0x19, 0x11, 0x02, 0xF6, 0xFF, 0x05, 0xE5, + 0xFC, 0x3B, 0x01, 0xB6, 0xFF, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, + 0x95, 0xFF, 0x62, 0x01, 0xFC, 0xFC, 0x10, 0x05, 0x09, 0xF9, 0xC1, + 0x07, 0x03, 0x43, 0x94, 0x0A, 0x05, 0xF8, 0x6C, 0x05, 0xEA, 0xFC, + 0x5C, 0x01, 0x9D, 0xFF, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x00, 0xA9, 0xFF, 0x4D, 0x01, 0xE1, 0xFC, 0xC4, 0x05, 0xE6, 0xF6, + 0x08, 0x0E, 0xA5, 0x42, 0xA1, 0x04, 0x43, 0xFA, 0x97, 0x04, 0x1D, + 0xFD, 0x64, 0x01, 0x8F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0xFC, 0xFF, + 0xC8, 0xFF, 0x1E, 0x01, 0xF8, 0xFC, 0x2D, 0x06, 0x13, 0xF5, 0xC8, + 0x14, 0xF2, 0x40, 0x69, 0xFF, 0x97, 0xFC, 0x92, 0x03, 0x75, 0xFD, + 0x55, 0x01, 0x8A, 0xFF, 0x11, 0x00, 0x01, 0x00, 0xEF, 0xFF, 0xF2, + 0xFF, 0xD4, 0x00, 0x45, 0xFD, 0x3B, 0x06, 0xB8, 0xF3, 0xCE, 0x1B, + 0xFB, 0x3D, 0x08, 0xFB, 0xDE, 0xFE, 0x73, 0x02, 0xEB, 0xFD, 0x33, + 0x01, 0x8F, 0xFF, 0x10, 0x00, 0x03, 0x00, 0xDE, 0xFF, 0x25, 0x00, + 0x71, 0x00, 0xC8, 0xFD, 0xE5, 0x05, 0xFA, 0xF2, 0xDF, 0x22, 0xDB, + 0x39, 0x94, 0xF7, 0xF7, 0x00, 0x4C, 0x01, 0x73, 0xFE, 0x03, 0x01, + 0x9A, 0xFF, 0x0E, 0x00, 0x05, 0x00, 0xCC, 0xFF, 0x5E, 0x00, 0xF9, + 0xFF, 0x80, 0xFE, 0x23, 0x05, 0xF9, 0xF2, 0xC0, 0x29, 0xB8, 0x34, + 0x16, 0xF5, 0xCB, 0x02, 0x2F, 0x00, 0x03, 0xFF, 0xCA, 0x00, 0xAA, + 0xFF, 0x0B, 0x00, 0x08, 0x00, 0xB8, 0xFF, 0x9B, 0x00, 0x72, 0xFF, + 0x65, 0xFF, 0xF6, 0x03, 0xD1, 0xF3, 0x31, 0x30, 0xC1, 0x2E, 0x8B, + 0xF3, 0x45, 0x04, 0x2D, 0xFF, 0x92, 0xFF, 0x8D, 0x00, 0xBD, 0xFF, + 0x08, 0x00, 0x0C, 0x00, 0xA6, 0xFF, 0xD8, 0x00, 0xE2, 0xFE, 0x6F, + 0x00, 0x66, 0x02, 0x93, 0xF5, 0xFB, 0x35, 0x31, 0x28, 0xE7, 0xF2, + 0x59, 0x05, 0x51, 0xFE, 0x17, 0x00, 0x50, 0x00, 0xD0, 0xFF, 0x05, + 0x00, 0x0E, 0x00, 0x97, 0xFF, 0x0F, 0x01, 0x53, 0xFE, 0x90, 0x01, + 0x81, 0x00, 0x4B, 0xF8, 0xE6, 0x3A, 0x3F, 0x21, 0x16, 0xF3, 0x02, + 0x06, 0xA5, 0xFD, 0x8A, 0x00, 0x18, 0x00, 0xE2, 0xFF, 0x02, 0x00, + 0x10, 0x00, 0x8D, 0xFF, 0x3C, 0x01, 0xCE, 0xFD, 0xB7, 0x02, 0x5A, + 0xFE, 0xF7, 0xFB, 0xC6, 0x3E, 0x2C, 0x1A, 0xFC, 0xF3, 0x41, 0x06, + 0x2E, 0xFD, 0xE7, 0x00, 0xE7, 0xFF, 0xF2, 0xFF, 0x01, 0x00, 0x10, + 0x00, 0x8B, 0xFF, 0x5A, 0x01, 0x5E, 0xFD, 0xD2, 0x03, 0x0E, 0xFC, + 0x8B, 0x00, 0x75, 0x41, 0x32, 0x13, 0x75, 0xF5, 0x1C, 0x06, 0xEE, + 0xFC, 0x2B, 0x01, 0xC0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0E, 0x00, + 0x91, 0xFF, 0x64, 0x01, 0x0D, 0xFD, 0xCD, 0x04, 0xBB, 0xF9, 0xF2, + 0x05, 0xD9, 0x42, 0x88, 0x0C, 0x5E, 0xF7, 0xA1, 0x05, 0xE3, 0xFC, + 0x54, 0x01, 0xA3, 0xFF, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, + 0x00, 0xA2, 0xFF, 0x56, 0x01, 0xE5, 0xFC, 0x94, 0x05, 0x87, 0xF7, + 0x0A, 0x0C, 0xE6, 0x42, 0x64, 0x06, 0x8E, 0xF9, 0xDE, 0x04, 0x09, + 0xFD, 0x64, 0x01, 0x92, 0xFF, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xBD, 0xFF, 0x2F, 0x01, 0xEC, 0xFC, 0x16, 0x06, 0x98, 0xF5, 0xAB, + 0x12, 0x9C, 0x41, 0xEE, 0x00, 0xE0, 0xFB, 0xE6, 0x03, 0x57, 0xFD, + 0x5B, 0x01, 0x8B, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF3, 0xFF, 0xE4, + 0xFF, 0xED, 0x00, 0x27, 0xFD, 0x41, 0x06, 0x14, 0xF4, 0xA1, 0x19, + 0x06, 0x3F, 0x49, 0xFC, 0x2E, 0xFE, 0xCD, 0x02, 0xC4, 0xFD, 0x3F, + 0x01, 0x8D, 0xFF, 0x10, 0x00, 0x02, 0x00, 0xE3, 0xFF, 0x14, 0x00, + 0x92, 0x00, 0x9A, 0xFD, 0x0A, 0x06, 0x22, 0xF3, 0xB4, 0x20, 0x3C, + 0x3B, 0x8B, 0xF8, 0x58, 0x00, 0xA7, 0x01, 0x48, 0xFE, 0x13, 0x01, + 0x96, 0xFF, 0x0F, 0x00, 0x04, 0x00, 0xD1, 0xFF, 0x4C, 0x00, 0x20, + 0x00, 0x42, 0xFE, 0x6A, 0x05, 0xE3, 0xF2, 0xAB, 0x27, 0x66, 0x36, + 0xC0, 0xF5, 0x44, 0x02, 0x85, 0x00, 0xD7, 0xFE, 0xDD, 0x00, 0xA5, + 0xFF, 0x0C, 0x00, 0x07, 0x00, 0xBE, 0xFF, 0x89, 0x00, 0x9D, 0xFF, + 0x1A, 0xFF, 0x5E, 0x04, 0x76, 0xF3, 0x45, 0x2E, 0xAA, 0x30, 0xEB, + 0xF3, 0xDB, 0x03, 0x79, 0xFF, 0x67, 0xFF, 0xA0, 0x00, 0xB7, 0xFF, + 0x09, 0x00, 0x0B, 0x00, 0xAC, 0xFF, 0xC6, 0x00, 0x0E, 0xFF, 0x1A, + 0x00, 0xEB, 0x02, 0xEF, 0xF4, 0x49, 0x34, 0x43, 0x2A, 0x02, 0xF3, + 0x0F, 0x05, 0x90, 0xFE, 0xEF, 0xFF, 0x63, 0x00, 0xCA, 0xFF, 0x06, + 0x00, 0x0E, 0x00, 0x9B, 0xFF, 0xFF, 0x00, 0x7E, 0xFE, 0x36, 0x01, + 0x1E, 0x01, 0x5B, 0xF7, 0x7E, 0x39, 0x69, 0x23, 0xF3, 0xF2, 0xD9, + 0x05, 0xD4, 0xFD, 0x69, 0x00, 0x29, 0x00, 0xDD, 0xFF, 0x03, 0x00, + 0x10, 0x00, 0x90, 0xFF, 0x30, 0x01, 0xF5, 0xFD, 0x5C, 0x02, 0x09, + 0xFF, 0xBC, 0xFA, 0xB5, 0x3D, 0x5A, 0x1C, 0xA3, 0xF3, 0x38, 0x06, + 0x4D, 0xFD, 0xCD, 0x00, 0xF5, 0xFF, 0xED, 0xFF, 0x01, 0x00, 0x11, + 0x00, 0x8B, 0xFF, 0x53, 0x01, 0x7E, 0xFD, 0x7D, 0x03, 0xC5, 0xFC, + 0x0B, 0xFF, 0xC3, 0x40, 0x51, 0x15, 0xF4, 0xF4, 0x31, 0x06, 0xFC, + 0xFC, 0x19, 0x01, 0xCB, 0xFF, 0xFB, 0xFF, 0x00, 0x00, 0x0F, 0x00, + 0x8E, 0xFF, 0x63, 0x01, 0x22, 0xFD, 0x84, 0x04, 0x71, 0xFA, 0x34, + 0x04, 0x90, 0x42, 0x89, 0x0E, 0xBE, 0xF6, 0xCF, 0x05, 0xE1, 0xFC, + 0x4A, 0x01, 0xAB, 0xFF, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, + 0x00, 0x9B, 0xFF, 0x5D, 0x01, 0xEC, 0xFC, 0x5D, 0x05, 0x2F, 0xF8, + 0x19, 0x0A, 0x07, 0x43, 0x37, 0x08, 0xDD, 0xF8, 0x21, 0x05, 0xF8, + 0xFC, 0x62, 0x01, 0x96, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x03, 0x00, + 0xB4, 0xFF, 0x3E, 0x01, 0xE4, 0xFC, 0xF6, 0x05, 0x26, 0xF6, 0x95, + 0x10, 0x26, 0x42, 0x87, 0x02, 0x28, 0xFB, 0x37, 0x04, 0x3B, 0xFD, + 0x60, 0x01, 0x8C, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF7, 0xFF, 0xD7, + 0xFF, 0x04, 0x01, 0x0F, 0xFD, 0x3E, 0x06, 0x7D, 0xF4, 0x76, 0x17, + 0xF4, 0x3F, 0x9F, 0xFD, 0x7B, 0xFD, 0x26, 0x03, 0xA0, 0xFD, 0x4A, + 0x01, 0x8B, 0xFF, 0x11, 0x00, 0x02, 0x00, 0xE9, 0xFF, 0x04, 0x00, + 0xB1, 0x00, 0x71, 0xFD, 0x26, 0x06, 0x5A, 0xF3, 0x88, 0x1E, 0x87, + 0x3C, 0x98, 0xF9, 0xB3, 0xFF, 0x02, 0x02, 0x1E, 0xFE, 0x22, 0x01, + 0x93, 0xFF, 0x0F, 0x00, 0x04, 0x00, 0xD7, 0xFF, 0x3A, 0x00, 0x45, + 0x00, 0x09, 0xFE, 0xA7, 0x05, 0xE1, 0xF2, 0x8D, 0x25, 0xFD, 0x37, + 0x82, 0xF6, 0xB5, 0x01, 0xDC, 0x00, 0xAA, 0xFE, 0xEE, 0x00, 0xA0, + 0xFF, 0x0D, 0x00, 0x06, 0x00, 0xC4, 0xFF, 0x76, 0x00, 0xC7, 0xFF, + 0xD3, 0xFE, 0xBC, 0x04, 0x31, 0xF3, 0x4A, 0x2C, 0x83, 0x32, 0x61, + 0xF4, 0x68, 0x03, 0xC8, 0xFF, 0x3B, 0xFF, 0xB3, 0x00, 0xB1, 0xFF, + 0x0A, 0x00, 0x0A, 0x00, 0xB1, 0xFF, 0xB3, 0x00, 0x3B, 0xFF, 0xC8, + 0xFF, 0x68, 0x03, 0x61, 0xF4, 0x83, 0x32, 0x4A, 0x2C, 0x31, 0xF3, + 0xBC, 0x04, 0xD3, 0xFE, 0xC7, 0xFF, 0x76, 0x00, 0xC4, 0xFF, 0x06, + 0x00, 0x0D, 0x00, 0xA0, 0xFF, 0xEE, 0x00, 0xAA, 0xFE, 0xDC, 0x00, + 0xB5, 0x01, 0x82, 0xF6, 0xFD, 0x37, 0x8D, 0x25, 0xE1, 0xF2, 0xA7, + 0x05, 0x09, 0xFE, 0x45, 0x00, 0x3A, 0x00, 0xD7, 0xFF, 0x04, 0x00, + 0x0F, 0x00, 0x93, 0xFF, 0x22, 0x01, 0x1E, 0xFE, 0x02, 0x02, 0xB3, + 0xFF, 0x98, 0xF9, 0x87, 0x3C, 0x88, 0x1E, 0x5A, 0xF3, 0x26, 0x06, + 0x71, 0xFD, 0xB1, 0x00, 0x04, 0x00, 0xE9, 0xFF, 0x02, 0x00, 0x11, + 0x00, 0x8B, 0xFF, 0x4A, 0x01, 0xA0, 0xFD, 0x26, 0x03, 0x7B, 0xFD, + 0x9F, 0xFD, 0xF4, 0x3F, 0x76, 0x17, 0x7D, 0xF4, 0x3E, 0x06, 0x0F, + 0xFD, 0x04, 0x01, 0xD7, 0xFF, 0xF7, 0xFF, 0x01, 0x00, 0x10, 0x00, + 0x8C, 0xFF, 0x60, 0x01, 0x3B, 0xFD, 0x37, 0x04, 0x28, 0xFB, 0x87, + 0x02, 0x26, 0x42, 0x95, 0x10, 0x26, 0xF6, 0xF6, 0x05, 0xE4, 0xFC, + 0x3E, 0x01, 0xB4, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x96, + 0xFF, 0x62, 0x01, 0xF8, 0xFC, 0x21, 0x05, 0xDD, 0xF8, 0x37, 0x08, + 0x07, 0x43, 0x19, 0x0A, 0x2F, 0xF8, 0x5D, 0x05, 0xEC, 0xFC, 0x5D, + 0x01, 0x9B, 0xFF, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, + 0xAB, 0xFF, 0x4A, 0x01, 0xE1, 0xFC, 0xCF, 0x05, 0xBE, 0xF6, 0x89, + 0x0E, 0x90, 0x42, 0x34, 0x04, 0x71, 0xFA, 0x84, 0x04, 0x22, 0xFD, + 0x63, 0x01, 0x8E, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0xFB, 0xFF, 0xCB, + 0xFF, 0x19, 0x01, 0xFC, 0xFC, 0x31, 0x06, 0xF4, 0xF4, 0x51, 0x15, + 0xC3, 0x40, 0x0B, 0xFF, 0xC5, 0xFC, 0x7D, 0x03, 0x7E, 0xFD, 0x53, + 0x01, 0x8B, 0xFF, 0x11, 0x00, 0x01, 0x00, 0xED, 0xFF, 0xF5, 0xFF, + 0xCD, 0x00, 0x4D, 0xFD, 0x38, 0x06, 0xA3, 0xF3, 0x5A, 0x1C, 0xB5, + 0x3D, 0xBC, 0xFA, 0x09, 0xFF, 0x5C, 0x02, 0xF5, 0xFD, 0x30, 0x01, + 0x90, 0xFF, 0x10, 0x00, 0x03, 0x00, 0xDD, 0xFF, 0x29, 0x00, 0x69, + 0x00, 0xD4, 0xFD, 0xD9, 0x05, 0xF3, 0xF2, 0x69, 0x23, 0x7E, 0x39, + 0x5B, 0xF7, 0x1E, 0x01, 0x36, 0x01, 0x7E, 0xFE, 0xFF, 0x00, 0x9B, + 0xFF, 0x0E, 0x00, 0x06, 0x00, 0xCA, 0xFF, 0x63, 0x00, 0xEF, 0xFF, + 0x90, 0xFE, 0x0F, 0x05, 0x02, 0xF3, 0x43, 0x2A, 0x49, 0x34, 0xEF, + 0xF4, 0xEB, 0x02, 0x1A, 0x00, 0x0E, 0xFF, 0xC6, 0x00, 0xAC, 0xFF, + 0x0B, 0x00, 0x09, 0x00, 0xB7, 0xFF, 0xA0, 0x00, 0x67, 0xFF, 0x79, + 0xFF, 0xDB, 0x03, 0xEB, 0xF3, 0xAA, 0x30, 0x45, 0x2E, 0x76, 0xF3, + 0x5E, 0x04, 0x1A, 0xFF, 0x9D, 0xFF, 0x89, 0x00, 0xBE, 0xFF, 0x07, + 0x00, 0x0C, 0x00, 0xA5, 0xFF, 0xDD, 0x00, 0xD7, 0xFE, 0x85, 0x00, + 0x44, 0x02, 0xC0, 0xF5, 0x66, 0x36, 0xAB, 0x27, 0xE3, 0xF2, 0x6A, + 0x05, 0x42, 0xFE, 0x20, 0x00, 0x4C, 0x00, 0xD1, 0xFF, 0x04, 0x00, + 0x0F, 0x00, 0x96, 0xFF, 0x13, 0x01, 0x48, 0xFE, 0xA7, 0x01, 0x58, + 0x00, 0x8B, 0xF8, 0x3C, 0x3B, 0xB4, 0x20, 0x22, 0xF3, 0x0A, 0x06, + 0x9A, 0xFD, 0x92, 0x00, 0x14, 0x00, 0xE3, 0xFF, 0x02, 0x00, 0x10, + 0x00, 0x8D, 0xFF, 0x3F, 0x01, 0xC4, 0xFD, 0xCD, 0x02, 0x2E, 0xFE, + 0x49, 0xFC, 0x06, 0x3F, 0xA1, 0x19, 0x14, 0xF4, 0x41, 0x06, 0x27, + 0xFD, 0xED, 0x00, 0xE4, 0xFF, 0xF3, 0xFF, 0x01, 0x00, 0x10, 0x00, + 0x8B, 0xFF, 0x5B, 0x01, 0x57, 0xFD, 0xE6, 0x03, 0xE0, 0xFB, 0xEE, + 0x00, 0x9C, 0x41, 0xAB, 0x12, 0x98, 0xF5, 0x16, 0x06, 0xEC, 0xFC, + 0x2F, 0x01, 0xBD, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x92, + 0xFF, 0x64, 0x01, 0x09, 0xFD, 0xDE, 0x04, 0x8E, 0xF9, 0x64, 0x06, + 0xE6, 0x42, 0x0A, 0x0C, 0x87, 0xF7, 0x94, 0x05, 0xE5, 0xFC, 0x56, + 0x01, 0xA2, 0xFF, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0xA3, 0xFF, 0x54, 0x01, 0xE3, 0xFC, 0xA1, 0x05, 0x5E, 0xF7, 0x88, + 0x0C, 0xD9, 0x42, 0xF2, 0x05, 0xBB, 0xF9, 0xCD, 0x04, 0x0D, 0xFD, + 0x64, 0x01, 0x91, 0xFF, 0x0E, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, + 0xFF, 0x2B, 0x01, 0xEE, 0xFC, 0x1C, 0x06, 0x75, 0xF5, 0x32, 0x13, + 0x75, 0x41, 0x8B, 0x00, 0x0E, 0xFC, 0xD2, 0x03, 0x5E, 0xFD, 0x5A, + 0x01, 0x8B, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF2, 0xFF, 0xE7, 0xFF, + 0xE7, 0x00, 0x2E, 0xFD, 0x41, 0x06, 0xFC, 0xF3, 0x2C, 0x1A, 0xC6, + 0x3E, 0xF7, 0xFB, 0x5A, 0xFE, 0xB7, 0x02, 0xCE, 0xFD, 0x3C, 0x01, + 0x8D, 0xFF, 0x10, 0x00, 0x02, 0x00, 0xE2, 0xFF, 0x18, 0x00, 0x8A, + 0x00, 0xA5, 0xFD, 0x02, 0x06, 0x16, 0xF3, 0x3F, 0x21, 0xE6, 0x3A, + 0x4B, 0xF8, 0x81, 0x00, 0x90, 0x01, 0x53, 0xFE, 0x0F, 0x01, 0x97, + 0xFF, 0x0E, 0x00, 0x05, 0x00, 0xD0, 0xFF, 0x50, 0x00, 0x17, 0x00, + 0x51, 0xFE, 0x59, 0x05, 0xE7, 0xF2, 0x31, 0x28, 0xFB, 0x35, 0x93, + 0xF5, 0x66, 0x02, 0x6F, 0x00, 0xE2, 0xFE, 0xD8, 0x00, 0xA6, 0xFF, + 0x0C, 0x00, 0x08, 0x00, 0xBD, 0xFF, 0x8D, 0x00, 0x92, 0xFF, 0x2D, + 0xFF, 0x45, 0x04, 0x8B, 0xF3, 0xC1, 0x2E, 0x31, 0x30, 0xD1, 0xF3, + 0xF6, 0x03, 0x65, 0xFF, 0x72, 0xFF, 0x9B, 0x00, 0xB8, 0xFF, 0x08, + 0x00, 0x0B, 0x00, 0xAA, 0xFF, 0xCA, 0x00, 0x03, 0xFF, 0x2F, 0x00, + 0xCB, 0x02, 0x16, 0xF5, 0xB8, 0x34, 0xC0, 0x29, 0xF9, 0xF2, 0x23, + 0x05, 0x80, 0xFE, 0xF9, 0xFF, 0x5E, 0x00, 0xCC, 0xFF, 0x05, 0x00, + 0x0E, 0x00, 0x9A, 0xFF, 0x03, 0x01, 0x73, 0xFE, 0x4C, 0x01, 0xF7, + 0x00, 0x94, 0xF7, 0xDB, 0x39, 0xDF, 0x22, 0xFA, 0xF2, 0xE5, 0x05, + 0xC8, 0xFD, 0x71, 0x00, 0x25, 0x00, 0xDE, 0xFF, 0x03, 0x00, 0x10, + 0x00, 0x8F, 0xFF, 0x33, 0x01, 0xEB, 0xFD, 0x73, 0x02, 0xDE, 0xFE, + 0x08, 0xFB, 0xFB, 0x3D, 0xCE, 0x1B, 0xB8, 0xF3, 0x3B, 0x06, 0x45, + 0xFD, 0xD4, 0x00, 0xF2, 0xFF, 0xEF, 0xFF, 0x01, 0x00, 0x11, 0x00, + 0x8A, 0xFF, 0x55, 0x01, 0x75, 0xFD, 0x92, 0x03, 0x97, 0xFC, 0x69, + 0xFF, 0xF2, 0x40, 0xC8, 0x14, 0x13, 0xF5, 0x2D, 0x06, 0xF8, 0xFC, + 0x1E, 0x01, 0xC8, 0xFF, 0xFC, 0xFF, 0x00, 0x00, 0x0F, 0x00, 0x8F, + 0xFF, 0x64, 0x01, 0x1D, 0xFD, 0x97, 0x04, 0x43, 0xFA, 0xA1, 0x04, + 0xA5, 0x42, 0x08, 0x0E, 0xE6, 0xF6, 0xC4, 0x05, 0xE1, 0xFC, 0x4D, + 0x01, 0xA9, 0xFF, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, + 0x9D, 0xFF, 0x5C, 0x01, 0xEA, 0xFC, 0x6C, 0x05, 0x05, 0xF8, 0x94, + 0x0A, 0x03, 0x43, 0xC1, 0x07, 0x09, 0xF9, 0x10, 0x05, 0xFC, 0xFC, + 0x62, 0x01, 0x95, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x02, 0x00, 0xB6, + 0xFF, 0x3B, 0x01, 0xE5, 0xFC, 0xFF, 0x05, 0x02, 0xF6, 0x19, 0x11, + 0x06, 0x42, 0x1F, 0x02, 0x56, 0xFB, 0x23, 0x04, 0x41, 0xFD, 0x5F, + 0x01, 0x8B, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF6, 0xFF, 0xDA, 0xFF, + 0xFF, 0x00, 0x15, 0xFD, 0x40, 0x06, 0x62, 0xF4, 0x01, 0x18, 0xBB, + 0x3F, 0x47, 0xFD, 0xA8, 0xFD, 0x10, 0x03, 0xA9, 0xFD, 0x47, 0x01, + 0x8C, 0xFF, 0x11, 0x00, 0x02, 0x00, 0xE7, 0xFF, 0x08, 0x00, 0xA9, + 0x00, 0x7B, 0xFD, 0x20, 0x06, 0x4B, 0xF3, 0x13, 0x1F, 0x36, 0x3C, + 0x52, 0xF9, 0xDD, 0xFF, 0xEB, 0x01, 0x28, 0xFE, 0x1F, 0x01, 0x93, + 0xFF, 0x0F, 0x00, 0x04, 0x00, 0xD6, 0xFF, 0x3F, 0x00, 0x3C, 0x00, + 0x16, 0xFE, 0x98, 0x05, 0xE0, 0xF2, 0x16, 0x26, 0x99, 0x37, 0x4F, + 0xF6, 0xD9, 0x01, 0xC6, 0x00, 0xB5, 0xFE, 0xEA, 0x00, 0xA1, 0xFF, + 0x0D, 0x00, 0x07, 0x00, 0xC3, 0xFF, 0x7A, 0x00, 0xBC, 0xFF, 0xE4, + 0xFE, 0xA5, 0x04, 0x41, 0xF3, 0xCA, 0x2C, 0x0E, 0x32, 0x42, 0xF4, + 0x85, 0x03, 0xB4, 0xFF, 0x46, 0xFF, 0xAE, 0x00, 0xB3, 0xFF, 0x09, + 0x00, 0x0A, 0x00, 0xB0, 0xFF, 0xB8, 0x00, 0x30, 0xFF, 0xDC, 0xFF, + 0x49, 0x03, 0x83, 0xF4, 0xF5, 0x32, 0xC9, 0x2B, 0x23, 0xF3, 0xD1, + 0x04, 0xC2, 0xFE, 0xD1, 0xFF, 0x71, 0x00, 0xC6, 0xFF, 0x06, 0x00, + 0x0D, 0x00, 0x9F, 0xFF, 0xF3, 0x00, 0x9F, 0xFE, 0xF3, 0x00, 0x90, + 0x01, 0xB6, 0xF6, 0x5F, 0x38, 0x04, 0x25, 0xE4, 0xF2, 0xB4, 0x05, + 0xFB, 0xFD, 0x4E, 0x00, 0x36, 0x00, 0xD9, 0xFF, 0x04, 0x00, 0x0F, + 0x00, 0x92, 0xFF, 0x26, 0x01, 0x13, 0xFE, 0x18, 0x02, 0x89, 0xFF, + 0xDF, 0xF9, 0xD3, 0x3C, 0xFC, 0x1D, 0x6B, 0xF3, 0x2C, 0x06, 0x67, + 0xFD, 0xB8, 0x00, 0x00, 0x00, 0xEA, 0xFF, 0x02, 0x00, 0x11, 0x00, + 0x8B, 0xFF, 0x4C, 0x01, 0x97, 0xFD, 0x3C, 0x03, 0x4D, 0xFD, 0xF8, + 0xFD, 0x2A, 0x40, 0xED, 0x16, 0x9A, 0xF4, 0x3C, 0x06, 0x0A, 0xFD, + 0x0A, 0x01, 0xD4, 0xFF, 0xF8, 0xFF, 0x01, 0x00, 0x10, 0x00, 0x8C, + 0xFF, 0x61, 0x01, 0x34, 0xFD, 0x4B, 0x04, 0xFA, 0xFA, 0xF1, 0x02, + 0x42, 0x42, 0x11, 0x10, 0x4C, 0xF6, 0xED, 0x05, 0xE3, 0xFC, 0x41, + 0x01, 0xB1, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x97, 0xFF, + 0x61, 0x01, 0xF5, 0xFC, 0x30, 0x05, 0xB1, 0xF8, 0xAE, 0x08, 0x0A, + 0x43, 0x9F, 0x09, 0x5A, 0xF8, 0x4F, 0x05, 0xEF, 0xFC, 0x5F, 0x01, + 0x9A, 0xFF, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0xAD, + 0xFF, 0x48, 0x01, 0xE2, 0xFC, 0xDA, 0x05, 0x97, 0xF6, 0x0B, 0x0F, + 0x79, 0x42, 0xC7, 0x03, 0x9E, 0xFA, 0x71, 0x04, 0x28, 0xFD, 0x63, + 0x01, 0x8D, 0xFF, 0x0F, 0x00 +}; + +static u16 +CoefficientSizes[] = { + /* Playback */ + 0x00C0, 0x5000, 0x0060, 0x2800, 0x0040, 0x0060, 0x1400, 0x0000, + /* Record */ + 0x0020, 0x1260, 0x0020, 0x1260, 0x0000, 0x0040, 0x1260, 0x0000, +}; + +#ifndef JUST_DATA + +static u16 +nm256_getStartOffset (u8 which) +{ + u16 offset = 0; + + while (which-- > 0) + offset += CoefficientSizes[which]; + + return offset; +} + +static void +nm256_loadOneCoefficient (struct nm256_info *card, u32 port, u16 which) +{ + u32 coeffBuf = (which < 8) ? card->coeffBuf : card->allCoeffBuf; + u16 offset = nm256_getStartOffset (which); + u16 size = CoefficientSizes[which]; + + card->coeffsCurrent = 0; + + if (nm256_debug) + printk (KERN_INFO "NM256: Loading coefficient buffer 0x%x-0x%x with coefficient %d\n", + coeffBuf, coeffBuf + size - 1, which); + nm256_writeBuffer8 (card, coefficients + offset, 1, coeffBuf, size); + nm256_writePort32 (card, 2, port + 0, coeffBuf); + nm256_writePort32 (card, 2, port + 4, coeffBuf + size - 1); +} + +static void +nm256_loadAllCoefficients (struct nm256_info *card) +{ + nm256_writeBuffer8 (card, coefficients, 1, card->allCoeffBuf, + NM_TOTAL_COEFF_COUNT * 4); + card->coeffsCurrent = 1; +} + +void +nm256_loadCoefficient (struct nm256_info *card, int which, int number) +{ + static u16 addrs[3] = { 0x1c, 0x21c, 0x408 }; + /* The enable register for the specified engine. */ + u32 poffset = (which == 1 ? 0x200 : 1); + + if (nm256_readPort8 (card, 2, poffset) & 1) { + printk (KERN_ERR "NM256: Engine was enabled while loading coefficients!\n"); + return; + } + + /* The recording engine uses coefficient values 8-15. */ + if (which == 1) + number += 8; + + if (! nm256_cachedCoefficients (card)) + nm256_loadOneCoefficient (card, addrs[which], number); + else { + u32 base = card->allCoeffBuf; + u32 offset = nm256_getStartOffset (number); + u32 endOffset = offset + CoefficientSizes[number]; + + if (nm256_debug) + printk (KERN_DEBUG "loading coefficient %d at port 0x%x, offset %d (0x%x-0x%x)\n", + number, addrs[which], offset, base + offset, + base + endOffset - 1); + + if (! card->coeffsCurrent) + nm256_loadAllCoefficients (card); + + nm256_writePort32 (card, 2, addrs[which], base + offset); + nm256_writePort32 (card, 2, addrs[which] + 4, base + endOffset - 1); + } +} + +#endif /* JUST_DATA */ + +#endif + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sound/opl3.c linux.ac/drivers/sound/opl3.c --- linux.vanilla/drivers/sound/opl3.c Wed Aug 19 22:48:30 1998 +++ linux.ac/drivers/sound/opl3.c Mon Sep 20 15:54:03 1999 @@ -32,8 +32,6 @@ #include "sound_config.h" #include "soundmodule.h" -#ifdef CONFIG_YM3812 - #include "opl3.h" #define MAX_VOICE 18 @@ -1218,10 +1216,10 @@ SOUND_LOCK_END; } +MODULE_PARM(io, "i"); + #endif EXPORT_SYMBOL(opl3_init); EXPORT_SYMBOL(opl3_detect); -MODULE_PARM(io, "i"); -#endif diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sound/opl3sa.c linux.ac/drivers/sound/opl3sa.c --- linux.vanilla/drivers/sound/opl3sa.c Mon Jan 4 19:37:30 1999 +++ linux.ac/drivers/sound/opl3sa.c Tue Sep 14 21:24:09 1999 @@ -187,7 +187,7 @@ { #if defined(CONFIG_UART401) && defined(CONFIG_MIDI) unsigned char conf; - static char irq_bits[] = { + static signed char irq_bits[] = { -1, -1, -1, -1, -1, 1, -1, 2, -1, 3, 4 }; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sound/sb_audio.c linux.ac/drivers/sound/sb_audio.c --- linux.vanilla/drivers/sound/sb_audio.c Fri Jan 15 06:59:47 1999 +++ linux.ac/drivers/sound/sb_audio.c Sun Sep 12 01:41:20 1999 @@ -742,6 +742,14 @@ restore_flags(flags); } + +/* + * This fails on the Cyrix MediaGX. If you don't have the DMA enabled + * before the first sample arrives it locks up. However even if you + * do enable the DMA in time you just get DMA timeouts and missing + * interrupts and stuff, so for now I've not bothered fixing this either. + */ + static void sb16_audio_start_input(int dev, unsigned long buf, int count, int intrflag) { unsigned long flags, cnt; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sound/sb_card.c linux.ac/drivers/sound/sb_card.c --- linux.vanilla/drivers/sound/sb_card.c Tue Apr 13 00:18:27 1999 +++ linux.ac/drivers/sound/sb_card.c Sun Sep 12 21:42:06 1999 @@ -179,7 +179,7 @@ return -ENODEV; #ifdef CONFIG_MIDI config_mpu.io_base = mpu_io; - if (mpu_io && probe_sbmpu(&config_mpu)) + if (probe_sbmpu(&config_mpu)) sbmpu = 1; if (sbmpu) attach_sbmpu(&config_mpu); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sound/sb_common.c linux.ac/drivers/sound/sb_common.c --- linux.vanilla/drivers/sound/sb_common.c Thu Aug 26 14:42:15 1999 +++ linux.ac/drivers/sound/sb_common.c Mon Sep 13 02:08:18 1999 @@ -1216,7 +1216,17 @@ last_devc = 0; if (hw_config->io_base <= 0) + { + /* The real vibra16 is fine about this, but we have to go + wipe up after Cyrix again */ + + if(devc->model == MDL_SB16 && devc->minor >= 12) + { + unsigned char bits = sb_getmixer(devc, 0x84) & ~0x06; + sb_setmixer(devc, 0x84, bits | 0x02); /* Disable MPU */ + } return 0; + } #if defined(CONFIG_SOUND_MPU401) if (devc->model == MDL_ESS) diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sound/sb_ess.c linux.ac/drivers/sound/sb_ess.c --- linux.vanilla/drivers/sound/sb_ess.c Thu Aug 26 14:42:15 1999 +++ linux.ac/drivers/sound/sb_ess.c Mon Sep 20 15:15:49 1999 @@ -1209,15 +1209,6 @@ break; } - /* AAS: info stolen from ALSA: these boards have different clocks */ - switch(devc->submodel) { - case SUBMDL_ES1869: - case SUBMDL_ES1887: - case SUBMDL_ES1888: - devc->caps |= SB_CAP_ES18XX_RATE; - break; - } - hw_config->name = name; /* FKS: sb_dsp_reset to enable extended mode???? */ sb_dsp_reset(devc); /* Turn on extended mode */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sound/soundcard.c linux.ac/drivers/sound/soundcard.c --- linux.vanilla/drivers/sound/soundcard.c Sun Mar 7 23:22:06 1999 +++ linux.ac/drivers/sound/soundcard.c Mon Sep 20 16:23:23 1999 @@ -39,6 +39,7 @@ #endif /* __KERNEL__ */ #include #include +#include #include "soundmodule.h" struct notifier_block *sound_locker=(struct notifier_block *)0; @@ -375,60 +376,76 @@ static ssize_t sound_read(struct file *file, char *buf, size_t count, loff_t *ppos) { int dev = MINOR(file->f_dentry->d_inode->i_rdev); + int ret = -EINVAL; + /* + * The OSS drivers aren't remotely happy without this locking, + * and unless someone fixes them when they are about to bite the + * big one anyway, we might as well bandage here.. + */ + + lock_kernel(); + DEB(printk("sound_read(dev=%d, count=%d)\n", dev, count)); switch (dev & 0x0f) { case SND_DEV_STATUS: - return sndstat_file_read(file, buf, count, ppos); + ret = sndstat_file_read(file, buf, count, ppos); #ifdef CONFIG_AUDIO case SND_DEV_DSP: case SND_DEV_DSP16: case SND_DEV_AUDIO: - return audio_read(dev, file, buf, count); + ret = audio_read(dev, file, buf, count); + break; #endif #ifdef CONFIG_SEQUENCER case SND_DEV_SEQ: case SND_DEV_SEQ2: - return sequencer_read(dev, file, buf, count); + ret = sequencer_read(dev, file, buf, count); + break; #endif #ifdef CONFIG_MIDI case SND_DEV_MIDIN: - return MIDIbuf_read(dev, file, buf, count); + ret = MIDIbuf_read(dev, file, buf, count); #endif - - default:; } - return -EINVAL; + unlock_kernel(); + return ret; } static ssize_t sound_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { int dev = MINOR(file->f_dentry->d_inode->i_rdev); - + int ret = -EINVAL; + + lock_kernel(); DEB(printk("sound_write(dev=%d, count=%d)\n", dev, count)); switch (dev & 0x0f) { #ifdef CONFIG_SEQUENCER case SND_DEV_SEQ: case SND_DEV_SEQ2: - return sequencer_write(dev, file, buf, count); + ret = sequencer_write(dev, file, buf, count); + break; #endif #ifdef CONFIG_AUDIO case SND_DEV_DSP: case SND_DEV_DSP16: case SND_DEV_AUDIO: - return audio_write(dev, file, buf, count); + ret = audio_write(dev, file, buf, count); + break; #endif #ifdef CONFIG_MIDI case SND_DEV_MIDIN: - return MIDIbuf_write(dev, file, buf, count); + ret = MIDIbuf_write(dev, file, buf, count); + break; #endif } - return -EINVAL; + unlock_kernel(); + return ret; } static long long sound_lseek(struct file *file, long long offset, int orig) @@ -858,8 +875,11 @@ int traceinit = 0; static int dmabuf = 0; +static int dmabug = 0; + MODULE_PARM(traceinit, "i"); MODULE_PARM(dmabuf, "i"); +MODULE_PARM(dmabug, "i"); int init_module(void) { @@ -868,6 +888,15 @@ int i; trace_init=traceinit; + +#ifdef HAS_BRIDGE_BUGGY_FUNC + if(dmabug) + isa_dma_bridge_buggy = dmabug; +#else + if(dmabug) + printk(KERN_ERR "sound: rebuild with PCI_QUIRKS enabled to configure this.\n"); +#endif + /* * "sound=" command line handling by Harald Milz. */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sound/vwsnd.c linux.ac/drivers/sound/vwsnd.c --- linux.vanilla/drivers/sound/vwsnd.c Sat Sep 11 00:54:11 1999 +++ linux.ac/drivers/sound/vwsnd.c Mon Sep 20 20:16:41 1999 @@ -142,7 +142,8 @@ #include #include #include -#include +#include +#include #include "sound_config.h" diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/Config.in linux.ac/drivers/usb/Config.in --- linux.vanilla/drivers/usb/Config.in Tue Sep 7 22:07:06 1999 +++ linux.ac/drivers/usb/Config.in Thu Sep 16 16:30:36 1999 @@ -10,39 +10,42 @@ tristate 'Support for USB (EXPERIMENTAL!)' CONFIG_USB if [ ! "$CONFIG_USB" = "n" ]; then - dep_tristate 'UHCI (intel PIIX4 and others) support' CONFIG_USB_UHCI \ +comment 'USB Controllers' + dep_tristate ' UHCI (Intel PIIX4 and others) support' CONFIG_USB_UHCI \ $CONFIG_USB - dep_tristate 'OHCI (compaq and some others) support' CONFIG_USB_OHCI \ + dep_tristate ' OHCI (Compaq and some others) support' CONFIG_USB_OHCI \ $CONFIG_USB - if [ "$CONFIG_USB_OHCI" != "n" ]; then - bool ' Enable tons of OHCI debugging output' CONFIG_USB_OHCI_DEBUG - fi - dep_tristate 'OHCI-HCD (other OHCI opt. Virt. Root Hub) support' \ + if [ "$CONFIG_USB_OHCI" != "n" ]; then + bool ' Enable tons of OHCI debugging output' CONFIG_USB_OHCI_DEBUG + fi + dep_tristate ' OHCI-HCD (other OHCI opt. Virt. Root Hub) support' \ CONFIG_USB_OHCI_HCD $CONFIG_USB - if [ "$CONFIG_USB_OHCI_HCD" != "n" ]; then - bool ' OHCI-HCD Virtual Root Hub' CONFIG_USB_OHCI_VROOTHUB - fi + if [ "$CONFIG_USB_OHCI_HCD" != "n" ]; then + bool ' OHCI-HCD Virtual Root Hub' CONFIG_USB_OHCI_VROOTHUB + fi - bool 'Enable lots of ISOC debugging output' CONFIG_USB_DEBUG_ISOC +comment 'Miscellaneous USB options' + bool ' Enable lots of ISOC debugging output' CONFIG_USB_DEBUG_ISOC + if [ "$CONFIG_PROC_FS" != "n" ]; then + bool ' Preliminary /proc/bus/usb support' CONFIG_USB_PROC + fi + dep_tristate ' EZUSB Firmware downloader' CONFIG_USB_EZUSB $CONFIG_USB - dep_tristate 'USB hub support' CONFIG_USB_HUB $CONFIG_USB - dep_tristate 'USB mouse support' CONFIG_USB_MOUSE $CONFIG_USB - dep_tristate 'USB HP scanner support' CONFIG_USB_HP_SCANNER $CONFIG_USB - dep_tristate 'USB keyboard support' CONFIG_USB_KBD $CONFIG_USB - dep_tristate 'USB audio parsing support' CONFIG_USB_AUDIO $CONFIG_USB - dep_tristate 'USB Communications Device Class (ACM) support' CONFIG_USB_ACM $CONFIG_USB - dep_tristate 'USB Printer support' CONFIG_USB_PRINTER $CONFIG_USB - dep_tristate 'USB CPiA Camera support' CONFIG_USB_CPIA $CONFIG_USB - dep_tristate 'USB SCSI Support' CONFIG_USB_SCSI $CONFIG_USB - if [ "$CONFIG_USB_SCSI" != "n" ]; then - dep_tristate ' USB SCSI verbose debug' CONFIG_USB_SCSI_DEBUG $CONFIG_USB_SCSI - fi - dep_tristate 'EZUSB Firmware downloader' CONFIG_USB_EZUSB $CONFIG_USB - dep_tristate 'USS720 parport driver' CONFIG_USB_USS720 $CONFIG_USB $CONFIG_PARPORT - if [ "$CONFIG_PROC_FS" != "n" ]; then - bool 'Preliminary /proc/bus/usb support' CONFIG_USB_PROC - fi +comment 'USB Devices' + dep_tristate ' USB hub support (Required!)' CONFIG_USB_HUB $CONFIG_USB + dep_tristate ' USB mouse support' CONFIG_USB_MOUSE $CONFIG_USB + dep_tristate ' USB HP scanner support' CONFIG_USB_HP_SCANNER $CONFIG_USB + dep_tristate ' USB keyboard support' CONFIG_USB_KBD $CONFIG_USB + dep_tristate ' USB audio parsing support' CONFIG_USB_AUDIO $CONFIG_USB + dep_tristate ' USB Communications Device Class (ACM) support' CONFIG_USB_ACM $CONFIG_USB + dep_tristate ' USB Printer support' CONFIG_USB_PRINTER $CONFIG_USB + dep_tristate ' USB CPiA Camera support' CONFIG_USB_CPIA $CONFIG_USB + dep_tristate ' USB SCSI Support' CONFIG_USB_SCSI $CONFIG_USB + if [ "$CONFIG_USB_SCSI" != "n" ]; then + dep_tristate ' USB SCSI verbose debug' CONFIG_USB_SCSI_DEBUG $CONFIG_USB_SCSI + fi + dep_tristate ' USS720 parport driver' CONFIG_USB_USS720 $CONFIG_USB $CONFIG_PARPORT fi endmenu diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/README.ohci linux.ac/drivers/usb/README.ohci --- linux.vanilla/drivers/usb/README.ohci Mon Jul 5 22:33:51 1999 +++ linux.ac/drivers/usb/README.ohci Thu Sep 16 16:30:36 1999 @@ -1,5 +1,17 @@ [This is the readme for ohci.c, ohci-debug.c and ohci.h] +September 05, 1999 17:03:21 + +I haven't updated this file in a while. I have started merging good +ideas from the ohci-hcd driver into this code as well as simplifying +the code where I can. Isochronous transfers still need to be ported +over from ohci-hcd. Large control and bulk transfers should be +working much better now. + +A big thanks goes to 3Com and APC for donating me a modem and UPS to +test with! They aren't working with OHCI quite yet but we hope to +change that soon. + June 23, 1999 00:31:20 PST I now have bulk support in a reasonably working state. The only diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/acm.c linux.ac/drivers/usb/acm.c --- linux.vanilla/drivers/usb/acm.c Sat Sep 11 00:54:11 1999 +++ linux.ac/drivers/usb/acm.c Mon Sep 20 16:57:32 1999 @@ -108,7 +108,7 @@ dr.value = status; dr.index = 0; dr.length = 0; - acm->dev->bus->op->control_msg(acm->dev, usb_sndctrlpipe(acm->dev,0), &dr, NULL, 0); + acm->dev->bus->op->control_msg(acm->dev, usb_sndctrlpipe(acm->dev,0), &dr, NULL, 0, HZ); acm->ctrlstate=status; } @@ -124,7 +124,7 @@ dr.value = coding; dr.index = 0; dr.length = 0; - acm->dev->bus->op->control_msg(acm->dev, usb_sndctrlpipe(acm->dev,0), &dr, NULL, 0); + acm->dev->bus->op->control_msg(acm->dev, usb_sndctrlpipe(acm->dev,0), &dr, NULL, 0, HZ); acm->linecoding=coding; } @@ -521,7 +521,8 @@ interface->bNumEndpoints != 2) continue; - if ((endpoint->bEndpointAddress & 0x80) == 0x80) + /* if ((endpoint->bEndpointAddress & 0x80) == 0x80) */ + if ((endpoint->bEndpointAddress & 0x80) != 0x80) swapped = 1; /*With a bulk input */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/audio.c linux.ac/drivers/usb/audio.c --- linux.vanilla/drivers/usb/audio.c Sat Sep 11 00:54:11 1999 +++ linux.ac/drivers/usb/audio.c Mon Sep 20 17:00:28 1999 @@ -1,25 +1,2495 @@ +/*****************************************************************************/ + +/* + * audio.c -- USB Audio Class driver + * + * Copyright (C) 1999 + * Alan Cox (alan@lxorguk.ukuu.org.uk) + * Thomas Sailer (sailer@ife.ee.ethz.ch) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * + * 1999-09-07: Alan Cox + * Parsing Audio descriptor patch + * 1999-09-08: Thomas Sailer + * Added OSS compatible data io functions; both parts of the + * driver remain to be glued together + * 1999-09-10: Thomas Sailer + * Beautified the driver. Added sample format conversions. + * Still not properly glued with the parsing code. + * The parsing code seems to have its problems btw, + * Since it parses all available configs but doesn't + * store which iface/altsetting belongs to which config. + * 1999-09-20: Thomas Sailer + * Threw out Alan's parsing code and implemented my own one. + * You cannot reasonnably linearly parse audio descriptors, + * especially the AudioClass descriptors have to be considered + * pointer lists. Mixer parsing untested, due to lack of device. + * First stab at synch pipe implementation, the Dallas USB DAC + * wants to use an Asynch out pipe. usb_audio_state now basically + * only contains lists of mixer and wave devices. We can therefore + * now have multiple mixer/wave devices per USB device. + * + */ + +/* + * Strategy: + * + * Alan Cox and Thomas Sailer are starting to dig at opposite ends and + * are hoping to meet in the middle, just like tunnel diggers :) + * Alan tackles the descriptor parsing, Thomas the actual data IO and the + * OSS compatible interface. + * + * Data IO implementation issues + * + * A mmap'able ring buffer per direction is implemented, because + * almost every OSS app expects it. It is however impractical to + * transmit/receive USB data directly into and out of the ring buffer, + * due to alignment and synchronisation issues. Instead, the ring buffer + * feeds a constant time delay line that handles the USB issues. + * + * Now we first try to find an alternate setting that exactly matches + * the sample format requested by the user. If we find one, we do not + * need to perform any sample rate conversions. If there is no matching + * altsetting, we choose the closest one and perform sample format + * conversions. We never do sample rate conversion; these are too + * expensive to be performed in the kernel. + * + * Current status: + * - The IO code seems to work a couple of frames, but then gets + * UHCI into a "complaining" mode, i.e. uhci won't work again until + * removed and reloaded, it will not even notice disconnect/reconnect + * events. + * It seems to work more stably on OHCI-HCD. + * + * Generally: Due to the brokenness of the Audio Class spec + * it seems generally impossible to write a generic Audio Class driver, + * so a reasonable driver should implement the features that are actually + * used. + * + * Parsing implementation issues + * + * One cannot reasonably parse the AudioClass descriptors linearly. + * Therefore the current implementation features routines to look + * for a specific descriptor in the descriptor list. + * + * How does the parsing work? First, all interfaces are searched + * for an AudioControl class interface. If found, the config descriptor + * that belongs to the current configuration is fetched from the device. + * Then the HEADER descriptor is fetched. It contains a list of + * all AudioStreaming and MIDIStreaming devices. This list is then walked, + * and all AudioStreaming interfaces are classified into input and output + * interfaces (according to the endpoint0 direction in altsetting1) (MIDIStreaming + * is currently not supported). The input & output list is then used + * to group inputs and outputs together and issued pairwise to the + * AudioStreaming class parser. Finally, all OUTPUT_TERMINAL descriptors + * are walked and issued to the mixer construction routine. + * + * The AudioStreaming parser simply enumerates all altsettings belonging + * to the specified interface. It looks for AS_GENERAL and FORMAT_TYPE + * class specific descriptors to extract the sample format/sample rate + * data. Only sample format types PCM and PCM8 are supported right now, and + * only FORMAT_TYPE_I is handled. The isochronous data endpoint needs to + * be the first endpoint of the interface, and the optional synchronisation + * isochronous endpoint the second one. + * + * Mixer construction works as follows: The various TERMINAL and UNIT + * descriptors span a tree from the root (OUTPUT_TERMINAL) through the + * intermediate nodes (UNITs) to the leaves (INPUT_TERMINAL). We walk + * that tree in a depth first manner. FEATURE_UNITs may contribute volume, + * bass and treble sliders to the mixer, MIXER_UNITs volume sliders. + * The terminal type encoded in the INPUT_TERMINALs feeds a heuristic + * to determine "meaningful" OSS slider numbers, however we will see + * how well this works in practice. Other features are not used at the + * moment, they seem less often used. Also, it seems difficult at least + * to construct recording source switches from SELECTOR_UNITs, but + * since there are not many USB ADC's available, we leave that for later. + */ + +/*****************************************************************************/ + #include #include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "usb.h" +#include "audio.h" + +#define AUDIO_DEBUG 1 + +#define SND_DEV_DSP16 5 + +/* --------------------------------------------------------------------- */ + +/* + * Linked list of all audio devices... + */ +static struct list_head audiodevs = LIST_HEAD_INIT(audiodevs); +static DECLARE_MUTEX(open_sem); + +/* + * wait queue for processes wanting to open an USB audio device + */ +static DECLARE_WAIT_QUEUE_HEAD(open_wait); + + +#define MAXFORMATS MAX_ALT +#define DMABUFSHIFT 17 /* 128k worth of DMA buffer */ +#define NRSGBUF (1U<<(DMABUFSHIFT-PAGE_SHIFT)) + +/* + * This influences: + * - Latency + * - Interrupt rate + * - Synchronisation behaviour + * Don't touch this if you don't understand all of the above. + */ +#define DESCFRAMES 4 + +#define MIXFLG_STEREOIN 1 +#define MIXFLG_STEREOOUT 2 + +struct mixerchannel { + __u16 value; + __u16 osschannel; /* number of the OSS channel */ + __s16 minval, maxval; + __u8 unitid; + __u8 selector; + __u8 chnum; + __u8 flags; +}; + +struct audioformat { + unsigned int format; + unsigned int sratelo; + unsigned int sratehi; + unsigned char altsetting; +}; + +struct dmabuf { + /* buffer data format */ + unsigned int format; + unsigned int srate; + /* physical buffer */ + unsigned char *sgbuf[NRSGBUF]; + unsigned bufsize; + unsigned numfrag; + unsigned fragshift; + unsigned wrptr, rdptr; + unsigned total_bytes; + int count; + unsigned error; /* over/underrun */ + wait_queue_head_t wait; + /* redundant, but makes calculations easier */ + unsigned fragsize; + unsigned dmasize; + /* OSS stuff */ + unsigned mapped:1; + unsigned ready:1; + unsigned ossfragshift; + int ossmaxfrags; + unsigned subdivision; +}; + +struct usb_audio_state; + +#define FLG_NEXTID 1 +#define FLG_ID0RUNNING 2 +#define FLG_ID1RUNNING 4 +#define FLG_SYNCNEXTID 8 +#define FLG_SYNC0RUNNING 16 +#define FLG_SYNC1RUNNING 32 +#define FLG_RUNNING 64 + +struct usb_audiodev { + struct list_head list; + struct usb_audio_state *state; + + /* soundcore stuff */ + int dev_audio; + + /* wave stuff */ + mode_t open_mode; + spinlock_t lock; /* DMA buffer access spinlock */ + + struct usbin { + unsigned int interface; /* Interface number */ + unsigned int format; /* USB data format */ + unsigned int datapipe; /* the data input pipe */ + unsigned int syncpipe; /* the synchronisation pipe - 0 for anything but adaptive IN mode */ + unsigned int syncinterval; /* P for adaptive IN mode, 0 otherwise */ + unsigned int freqn; /* nominal sampling rate in USB format, i.e. fs/1000 in Q10.14 */ + unsigned int phase; /* phase accumulator */ + unsigned int flags; /* see FLG_ defines */ + + struct usb_isoc_desc *dataiso[2]; /* ISO descriptors for the data endpoint */ + unsigned char *data[2]; /* data pages associated with the ISO descriptors */ + + struct usb_isoc_desc *synciso[2]; /* ISO sync pipe descriptor if needed */ + unsigned char *syncdata[2]; /* data page for sync data */ + + struct dmabuf dma; + } usbin; + + struct usbout { + unsigned int interface; /* Interface number */ + unsigned int format; /* USB data format */ + unsigned int datapipe; /* the data input pipe */ + unsigned int syncpipe; /* the synchronisation pipe - 0 for anything but asynchronous OUT mode */ + unsigned int syncinterval; /* P for asynchronous OUT mode, 0 otherwise */ + unsigned int freqn; /* nominal sampling rate in USB format, i.e. fs/1000 in Q10.14 */ + unsigned int freqm; /* momentary sampling rate in USB format, i.e. fs/1000 in Q10.14 */ + unsigned int phase; /* phase accumulator */ + unsigned int flags; /* see FLG_ defines */ + + struct usb_isoc_desc *dataiso[2]; /* ISO descriptors for the data endpoint */ + unsigned char *data[2]; /* data pages associated with the ISO descriptors */ + + struct usb_isoc_desc *synciso[2]; /* ISO sync pipe descriptor if needed */ + unsigned char *syncdata[2]; /* data page for sync data */ + + struct dmabuf dma; + } usbout; + + + unsigned int numfmtin, numfmtout; + struct audioformat fmtin[MAXFORMATS]; + struct audioformat fmtout[MAXFORMATS]; +}; + +struct usb_mixerdev { + struct list_head list; + struct usb_audio_state *state; + + /* soundcore stuff */ + int dev_mixer; + + unsigned char iface; /* interface number of the AudioControl interface */ + + /* USB format descriptions */ + unsigned int numch, modcnt; + + /* mixch is last and gets allocated dynamically */ + struct mixerchannel ch[0]; +}; + +struct usb_audio_state { + struct list_head audiodev; + + /* USB device */ + struct usb_device *usbdev; + + struct list_head audiolist; + struct list_head mixerlist; + + unsigned count; /* usage counter; NOTE: the usb stack is also considered a user */ +}; + +/* private audio format extensions */ +#define AFMT_STEREO 0x80000000 +#define AFMT_ISSTEREO(x) ((x) & AFMT_STEREO) +#define AFMT_IS16BIT(x) ((x) & (AFMT_S16_LE|AFMT_S16_BE|AFMT_U16_LE|AFMT_U16_BE)) +#define AFMT_ISUNSIGNED(x) ((x) & (AFMT_U8|AFMT_U16_LE|AFMT_U16_BE)) +#define AFMT_BYTESSHIFT(x) ((AFMT_ISSTEREO(x) ? 1 : 0) + (AFMT_IS16BIT(x) ? 1 : 0)) +#define AFMT_BYTES(x) (1<= 0x10000) { + x >>= 16; + r += 16; + } + if (x >= 0x100) { + x >>= 8; + r += 8; + } + if (x >= 0x10) { + x >>= 4; + r += 4; + } + if (x >= 4) { + x >>= 2; + r += 2; + } + if (x >= 2) + r++; + return r; +} + +/* --------------------------------------------------------------------- */ + +/* + * OSS compatible ring buffer management. The ring buffer may be mmap'ed into + * an application address space. + * + * I first used the rvmalloc stuff copied from bttv. Alan Cox did not like it, so + * we now use an array of pointers to a single page each. This saves us the + * kernel page table manipulations, but we have to do a page table alike mechanism + * (though only one indirection) in software. + */ + +static void dmabuf_release(struct dmabuf *db) +{ + unsigned int nr; + void *p; + + for(nr = 0; nr < NRSGBUF; nr++) { + if (!(p = db->sgbuf[nr])) + continue; + mem_map_unreserve(MAP_NR(p)); + free_page((unsigned long)p); + db->sgbuf[nr] = NULL; + } + db->mapped = db->ready = 0; +} + +static int dmabuf_init(struct dmabuf *db) +{ + unsigned int nr, bytepersec, bufs; + void *p; + + /* initialize some fields */ + db->rdptr = db->wrptr = db->total_bytes = db->count = db->error = 0; + /* calculate required buffer size */ + bytepersec = db->srate << AFMT_BYTESSHIFT(db->format); + bufs = 1U << DMABUFSHIFT; + if (db->ossfragshift) { + if ((1000 << db->ossfragshift) < bytepersec) + db->fragshift = ld2(bytepersec/1000); + else + db->fragshift = db->ossfragshift; + } else { + db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1)); + if (db->fragshift < 3) + db->fragshift = 3; + } + db->numfrag = bufs >> db->fragshift; + while (db->numfrag < 4 && db->fragshift > 3) { + db->fragshift--; + db->numfrag = bufs >> db->fragshift; + } + db->fragsize = 1 << db->fragshift; + if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag) + db->numfrag = db->ossmaxfrags; + db->dmasize = db->numfrag << db->fragshift; + for(nr = 0; nr < NRSGBUF; nr++) { + if (!db->sgbuf[nr]) { + p = (void *)get_free_page(GFP_KERNEL); + if (!p) + return -ENOMEM; + db->sgbuf[nr] = p; + mem_map_reserve(MAP_NR(p)); + } + memset(db->sgbuf[nr], AFMT_ISUNSIGNED(db->format) ? 0x80 : 0, PAGE_SIZE); + if ((nr << PAGE_SHIFT) >= db->dmasize) + break; + } + db->bufsize = nr << PAGE_SHIFT; + db->ready = 1; + printk(KERN_DEBUG "dmabuf_init: bytepersec %d bufs %d ossfragshift %d ossmaxfrags %d " + "fragshift %d fragsize %d numfrag %d dmasize %d bufsize %d\n", + bytepersec, bufs, db->ossfragshift, db->ossmaxfrags, db->fragshift, db->fragsize, + db->numfrag, db->dmasize, db->bufsize); + return 0; +} + +static int dmabuf_mmap(struct dmabuf *db, unsigned long start, unsigned long size, pgprot_t prot) +{ + unsigned int nr; + + if (!db->ready || db->mapped || (start | size) & (PAGE_SIZE-1) || size > db->bufsize) + return -EINVAL; + size >>= PAGE_SHIFT; + for(nr = 0; nr < size; nr++) + if (!db->sgbuf[nr]) + return -EINVAL; + db->mapped = 1; + for(nr = 0; nr < size; nr++) { + if (remap_page_range(start, virt_to_phys(db->sgbuf[nr]), PAGE_SIZE, prot)) + return -EAGAIN; + start += PAGE_SIZE; + } + return 0; +} + +static void dmabuf_copyin(struct dmabuf *db, const void *buffer, unsigned int size) +{ + unsigned int pgrem, rem; + + for (;;) { + if (size <= 0) + return; + pgrem = ((~db->wrptr) & (PAGE_SIZE-1)) + 1; + if (pgrem > size) + pgrem = size; + rem = db->dmasize - db->wrptr; + if (pgrem > rem) + pgrem = rem; + memcpy((db->sgbuf[db->wrptr >> PAGE_SHIFT]) + (db->wrptr & (PAGE_SIZE-1)), buffer, pgrem); + size -= pgrem; + (char *)buffer += pgrem; + db->wrptr += pgrem; + if (db->wrptr >= db->dmasize) + db->wrptr = 0; + } +} + +static void dmabuf_copyout(struct dmabuf *db, void *buffer, unsigned int size) +{ + unsigned int pgrem, rem; + + for (;;) { + if (size <= 0) + return; + pgrem = ((~db->rdptr) & (PAGE_SIZE-1)) + 1; + if (pgrem > size) + pgrem = size; + rem = db->dmasize - db->rdptr; + if (pgrem > rem) + pgrem = rem; + memcpy(buffer, (db->sgbuf[db->rdptr >> PAGE_SHIFT]) + (db->rdptr & (PAGE_SIZE-1)), pgrem); + size -= pgrem; + (char *)buffer += pgrem; + db->rdptr += pgrem; + if (db->rdptr >= db->dmasize) + db->rdptr = 0; + } +} + +static int dmabuf_copyin_user(struct dmabuf *db, unsigned int ptr, const void *buffer, unsigned int size) +{ + unsigned int pgrem, rem; + + if (!db->ready || db->mapped) + return -EINVAL; + for (;;) { + if (size <= 0) + return 0; + pgrem = ((~ptr) & (PAGE_SIZE-1)) + 1; + if (pgrem > size) + pgrem = size; + rem = db->dmasize - ptr; + if (pgrem > rem) + pgrem = rem; + copy_from_user_ret((db->sgbuf[ptr >> PAGE_SHIFT]) + (ptr & (PAGE_SIZE-1)), buffer, pgrem, -EFAULT); + size -= pgrem; + (char *)buffer += pgrem; + ptr += pgrem; + if (ptr >= db->dmasize) + ptr = 0; + } +} + +static int dmabuf_copyout_user(struct dmabuf *db, unsigned int ptr, void *buffer, unsigned int size) +{ + unsigned int pgrem, rem; + + if (!db->ready || db->mapped) + return -EINVAL; + for (;;) { + if (size <= 0) + return 0; + pgrem = ((~ptr) & (PAGE_SIZE-1)) + 1; + if (pgrem > size) + pgrem = size; + rem = db->dmasize - ptr; + if (pgrem > rem) + pgrem = rem; + copy_to_user_ret(buffer, (db->sgbuf[ptr >> PAGE_SHIFT]) + (ptr & (PAGE_SIZE-1)), pgrem, -EFAULT); + size -= pgrem; + (char *)buffer += pgrem; + ptr += pgrem; + if (ptr >= db->dmasize) + ptr = 0; + } +} + +/* --------------------------------------------------------------------- */ +/* + * USB I/O code. We do sample format conversion if necessary + */ + +static void usbin_stop(struct usb_audiodev *as) +{ + struct usbin *u = &as->usbin; + unsigned long flags; + unsigned int i; + + spin_lock_irqsave(&as->lock, flags); + u->flags &= ~FLG_RUNNING; + i = u->flags; + spin_unlock_irqrestore(&as->lock, flags); + while (i & (FLG_ID0RUNNING|FLG_ID1RUNNING|FLG_SYNC0RUNNING|FLG_SYNC1RUNNING)) { + schedule_timeout(1); + spin_lock_irqsave(&as->lock, flags); + i = u->flags; + spin_unlock_irqrestore(&as->lock, flags); + } + if (u->dataiso[0]) + usb_free_isoc(u->dataiso[0]); + if (u->dataiso[1]) + usb_free_isoc(u->dataiso[1]); + if (u->synciso[0]) + usb_free_isoc(u->synciso[0]); + if (u->synciso[1]) + usb_free_isoc(u->synciso[1]); + u->dataiso[0] = u->dataiso[1] = u->synciso[0] = u->synciso[1] = NULL; +} + +static void usbin_release(struct usb_audiodev *as) +{ + struct usbin *u = &as->usbin; + + usbin_stop(as); + if (u->data[0]) + free_page((unsigned long)u->data[0]); + if (u->data[1]) + free_page((unsigned long)u->data[1]); + if (u->syncdata[0]) + free_page((unsigned long)u->syncdata[0]); + if (u->syncdata[1]) + free_page((unsigned long)u->syncdata[1]); + u->data[0] = u->data[1] = u->syncdata[0] = u->syncdata[1] = NULL; +} + +static void usbin_convert(struct usbin *u, unsigned char *buffer, unsigned int samples) +{ + union { + __s16 s[64]; + unsigned char b[0]; + } tmp; + unsigned int scnt, maxs, ufmtsh, dfmtsh, cnt, i; + __s16 *sp, *sp2, s; + unsigned char *bp; + + ufmtsh = AFMT_BYTESSHIFT(u->format); + dfmtsh = AFMT_BYTESSHIFT(u->dma.format); + maxs = (AFMT_ISSTEREO(u->dma.format | u->format)) ? 32 : 64; + while (samples > 0) { + scnt = samples; + if (scnt > maxs) + scnt = maxs; + cnt = scnt; + if (AFMT_ISSTEREO(u->format)) + cnt <<= 1; + sp = tmp.s + cnt; + switch (u->format & ~AFMT_STEREO) { + case AFMT_U8: + for (bp = buffer+cnt, i = 0; i < cnt; i++) { + bp--; + sp--; + *sp = (*bp ^ 0x80) << 8; + } + break; + + case AFMT_S8: + for (bp = buffer+cnt, i = 0; i < cnt; i++) { + bp--; + sp--; + *sp = *bp << 8; + } + break; + + case AFMT_U16_LE: + for (bp = buffer+2*cnt, i = 0; i < cnt; i++) { + bp -= 2; + sp--; + *sp = (bp[0] | (bp[1] << 8)) ^ 0x8000; + } + break; + + case AFMT_U16_BE: + for (bp = buffer+2*cnt, i = 0; i < cnt; i++) { + bp -= 2; + sp--; + *sp = (bp[1] | (bp[0] << 8)) ^ 0x8000; + } + break; + + case AFMT_S16_LE: + for (bp = buffer+2*cnt, i = 0; i < cnt; i++) { + bp -= 2; + sp--; + *sp = bp[0] | (bp[1] << 8); + } + break; + + case AFMT_S16_BE: + for (bp = buffer+2*cnt, i = 0; i < cnt; i++) { + bp -= 2; + sp--; + *sp = bp[1] | (bp[0] << 8); + } + break; + } + if (!AFMT_ISSTEREO(u->format) && AFMT_ISSTEREO(u->dma.format)) { + /* expand from mono to stereo */ + for (sp = tmp.s+scnt, sp2 = tmp.s+2*scnt, i = 0; i < scnt; i++) { + sp--; + sp2 -= 2; + sp2[0] = sp2[1] = sp[0]; + } + } + if (AFMT_ISSTEREO(u->format) && !AFMT_ISSTEREO(u->dma.format)) { + /* contract from stereo to mono */ + for (sp = sp2 = tmp.s, i = 0; i < scnt; i++, sp++, sp2 += 2) + sp[0] = (sp2[0] + sp2[1]) >> 1; + } + cnt = scnt; + if (AFMT_ISSTEREO(u->dma.format)) + cnt <<= 1; + sp = tmp.s; + bp = tmp.b; + switch (u->dma.format & ~AFMT_STEREO) { + case AFMT_U8: + for (i = 0; i < cnt; i++, sp++, bp++) + *bp = (*sp >> 8) ^ 0x80; + break; + + case AFMT_S8: + for (i = 0; i < cnt; i++, sp++, bp++) + *bp = *sp >> 8; + break; + + case AFMT_U16_LE: + for (i = 0; i < cnt; i++, sp++, bp += 2) { + s = *sp; + bp[0] = s; + bp[1] = (s >> 8) ^ 0x80; + } + break; + + case AFMT_U16_BE: + for (i = 0; i < cnt; i++, sp++, bp += 2) { + s = *sp; + bp[1] = s; + bp[0] = (s >> 8) ^ 0x80; + } + break; + + case AFMT_S16_LE: + for (i = 0; i < cnt; i++, sp++, bp += 2) { + s = *sp; + bp[0] = s; + bp[1] = s >> 8; + } + break; + + case AFMT_S16_BE: + for (i = 0; i < cnt; i++, sp++, bp += 2) { + s = *sp; + bp[1] = s; + bp[0] = s >> 8; + } + break; + } + dmabuf_copyin(&u->dma, tmp.b, scnt << dfmtsh); + buffer += scnt << ufmtsh; + samples -= scnt; + } +} + +static int usbin_prepare_desc(struct usbin *u, struct usb_isoc_desc *id) +{ + unsigned int i, maxsize; + + maxsize = (u->freqn + 0x3fff) >> (14 - AFMT_BYTESSHIFT(u->format)); + printk(KERN_DEBUG "usbin_prepare_desc: maxsize %d freq 0x%x format 0x%x\n", maxsize, u->freqn, u->format); + for (i = 0; i < DESCFRAMES; i++) + id->frames[i].frame_length = maxsize; + return 0; +} + +/* + * return value: 0 if descriptor should be restarted, -1 otherwise + * convert sample format on the fly if necessary + */ +static int usbin_retire_desc(struct usbin *u, struct usb_isoc_desc *id) +{ + unsigned int i, ufmtsh, dfmtsh, err = 0, cnt, scnt, dmafree, maxsize; + unsigned char *cp = id->data; + + ufmtsh = AFMT_BYTESSHIFT(u->format); + maxsize = (u->freqn + 0x3fff) >> (14 - ufmtsh); + dfmtsh = AFMT_BYTESSHIFT(u->dma.format); + for (i = 0; i < DESCFRAMES; i++, cp += maxsize) { + if (id->frames[i].frame_status) { + printk(KERN_DEBUG "usbin_retire_desc: frame %u status %d\n", i, id->frames[i].frame_status); + continue; + } + scnt = id->frames[i].frame_length >> ufmtsh; + if (!scnt) + continue; + cnt = scnt << dfmtsh; + if (!u->dma.mapped) { + dmafree = u->dma.dmasize - u->dma.count; + if (cnt > dmafree) { + scnt = dmafree >> dfmtsh; + cnt = scnt << dfmtsh; + err++; + } + } + u->dma.count += cnt; + if (u->format == u->dma.format) { + /* we do not need format conversion */ + dmabuf_copyin(&u->dma, cp, cnt); + } else { + /* we need sampling format conversion */ + usbin_convert(u, cp, scnt); + } + } + if (err) + u->dma.error++; + if (u->dma.count >= (signed)u->dma.fragsize) + wake_up(&u->dma.wait); + return err ? -1 : 0; +} + +static int usbin_completed(int status, void *__buffer, int rval, void *dev_id) +{ +#if 0 + struct usb_isoc_desc *id = (struct usb_isoc_desc *)dev_id; + struct usb_audiodev *as = (struct usb_audiodev *)id->context; +#else + struct usb_audiodev *as = (struct usb_audiodev *)dev_id; + struct usb_isoc_desc *id; +#endif + struct usbin *u = &as->usbin; + unsigned int next, idmask; + + printk(KERN_DEBUG "usbin_completed: status %d rval %d flags 0x%x\n", status, rval, u->flags); + spin_lock(&as->lock); + next = !(u->flags & FLG_NEXTID); + idmask = FLG_ID1RUNNING >> next; + u->flags = (u->flags & ~(FLG_NEXTID | idmask)) | next; + id = u->dataiso[!next]; + if (!usbin_retire_desc(u, id) && + u->flags & FLG_RUNNING && + !usbin_prepare_desc(u, id) && + !usb_run_isoc(id, u->dataiso[next])) { + u->flags |= idmask; + } else { + u->flags &= ~FLG_RUNNING; + printk(KERN_DEBUG "usbin_completed: descriptor not restarted\n"); + } + spin_unlock(&as->lock); + return 0; +} + +/* + * we output sync data + */ +static int usbin_sync_prepare_desc(struct usbin *u, struct usb_isoc_desc *id) +{ + unsigned char *cp = id->data; + unsigned int i; + + for (i = 0; i < DESCFRAMES; i++, cp += 3) { + id->frames[i].frame_length = 3; + cp[0] = u->freqn; + cp[1] = u->freqn >> 8; + cp[2] = u->freqn >> 16; + } + return 0; +} + +/* + * return value: 0 if descriptor should be restarted, -1 otherwise + */ +static int usbin_sync_retire_desc(struct usbin *u, struct usb_isoc_desc *id) +{ + unsigned int i; + + for (i = 0; i < DESCFRAMES; i++) { + if (id->frames[i].frame_status) { + printk(KERN_DEBUG "usbin_sync_retire_desc: frame %u status %d\n", i, id->frames[i].frame_status); + continue; + } + } + return 0; +} + +static int usbin_sync_completed(int status, void *__buffer, int rval, void *dev_id) +{ +#if 0 + struct usb_isoc_desc *id = (struct usb_isoc_desc *)dev_id; + struct usb_audiodev *as = (struct usb_audiodev *)id->context; +#else + struct usb_audiodev *as = (struct usb_audiodev *)dev_id; + struct usb_isoc_desc *id; +#endif + struct usbin *u = &as->usbin; + unsigned int next, idmask; + + printk(KERN_DEBUG "usbin_sync_completed: status %d rval %d flags 0x%x\n", status, rval, u->flags); + spin_lock(&as->lock); + next = !(u->flags & FLG_SYNCNEXTID); + idmask = FLG_SYNC1RUNNING >> next; + u->flags = (u->flags & ~(FLG_SYNCNEXTID | idmask)) | (-next & FLG_SYNCNEXTID); + id = u->synciso[!next]; + if (!usbin_sync_retire_desc(u, id) && + u->flags & FLG_RUNNING && + !usbin_sync_prepare_desc(u, id) && + !usb_run_isoc(id, u->synciso[next])) { + u->flags |= idmask; + } else { + u->flags &= ~FLG_RUNNING; + printk(KERN_DEBUG "usbin_sync_completed: descriptor not restarted\n"); + } + spin_unlock(&as->lock); + return 0; +} + +static void usbin_start(struct usb_audiodev *as) +{ + struct usb_device *dev = as->state->usbdev; + struct usbin *u = &as->usbin; + struct usb_isoc_desc *id; + unsigned long flags; + unsigned int which, i; + + printk(KERN_DEBUG "usbin_start: device %d ufmt %d dfmt %d srate %d\n", + dev->devnum, u->format, u->dma.format, u->dma.srate); + /* allocate USB storage if not already done */ + /* UHCI wants the data to be page aligned - this is silly */ + if (!u->data[0]) + u->data[0] = (void *)get_free_page(GFP_KERNEL); + if (!u->data[1]) + u->data[1] = (void *)get_free_page(GFP_KERNEL); + if (!u->dataiso[0] && usb_init_isoc(dev, u->datapipe, DESCFRAMES, as, u->dataiso+0)) { + printk(KERN_ERR "usbaudio: cannot init isoc descriptor device %d pipe 0x%08x\n", + dev->devnum, u->datapipe); + u->dataiso[0] = NULL; + } + if (!u->dataiso[1] && usb_init_isoc(dev, u->datapipe, DESCFRAMES, as, u->dataiso+1)) { + printk(KERN_ERR "usbaudio: cannot init isoc descriptor device %d pipe 0x%08x\n", + dev->devnum, u->datapipe); + u->dataiso[1] = NULL; + } + if (u->syncpipe) { + if (!u->syncdata[0]) + u->syncdata[0] = (void *)get_free_page(GFP_KERNEL); + if (!u->syncdata[1]) + u->syncdata[1] = (void *)get_free_page(GFP_KERNEL); + if (!u->synciso[0] && usb_init_isoc(dev, u->syncpipe, DESCFRAMES, as, u->synciso+0)) { + printk(KERN_ERR "usbaudio: cannot init isoc descriptor device %d pipe 0x%08x\n", + dev->devnum, u->syncpipe); + u->synciso[0] = NULL; + } + if (!u->synciso[1] && usb_init_isoc(dev, u->syncpipe, DESCFRAMES, as, u->synciso+1)) { + printk(KERN_ERR "usbaudio: cannot init isoc descriptor device %d pipe 0x%08x\n", + dev->devnum, u->syncpipe); + u->synciso[1] = NULL; + } + } + if (!u->data[0] || !u->data[1] || !u->dataiso[0] || !u->dataiso[1] || + (u->syncpipe && (!u->syncdata[0] || !u->syncdata[1] || !u->synciso[0] || !u->synciso[1]))) { + printk(KERN_ERR "usbaudio: cannot start playback device %d\n", dev->devnum); + return; + } + spin_lock_irqsave(&as->lock, flags); + if (!(u->flags & FLG_RUNNING)) { + u->freqn = ((u->dma.srate << 11) + 62) / 125; /* this will overflow at approx 2MSPS */ + u->phase = 0; + } + u->flags |= FLG_RUNNING; + if (!(u->flags & (FLG_ID0RUNNING|FLG_ID1RUNNING))) { + id = u->dataiso[0]; + id->start_type = START_ASAP; + id->start_frame = 0; + id->callback_frames = /*0*/DESCFRAMES; + id->callback_fn = usbin_completed; + id->data = u->data[0]; + id->buf_size = PAGE_SIZE; + u->flags &= ~FLG_NEXTID; + if (!usbin_prepare_desc(u, id) && !usb_run_isoc(id, NULL)) + u->flags |= FLG_ID0RUNNING; + else + u->flags &= ~FLG_RUNNING; + } + i = u->flags & (FLG_ID0RUNNING|FLG_ID1RUNNING); + if (u->flags & FLG_RUNNING && (i == FLG_ID0RUNNING || i == FLG_ID1RUNNING)) { + which = !(u->flags & FLG_ID1RUNNING); + id = u->dataiso[which]; + id->callback_frames = /*0*/DESCFRAMES; + id->callback_fn = usbin_completed; + id->data = u->data[which]; + id->buf_size = PAGE_SIZE; + if (!usbin_prepare_desc(u, id) && !usb_run_isoc(id, u->dataiso[!which])) + u->flags |= FLG_ID0RUNNING << which; + else + u->flags &= ~FLG_RUNNING; + } + if (u->syncpipe) { + if (!(u->flags & (FLG_SYNC0RUNNING|FLG_SYNC1RUNNING))) { + id = u->synciso[0]; + id->start_type = START_ASAP; + id->start_frame = 0; + id->callback_frames = /*0*/DESCFRAMES; + id->callback_fn = usbin_sync_completed; + id->data = u->syncdata[0]; + id->buf_size = PAGE_SIZE; + u->flags &= ~FLG_SYNCNEXTID; + if (!usbin_sync_prepare_desc(u, id) && !usb_run_isoc(id, NULL)) + u->flags |= FLG_SYNC0RUNNING; + else + u->flags &= ~FLG_RUNNING; + } + i = u->flags & (FLG_SYNC0RUNNING|FLG_SYNC1RUNNING); + if (u->flags & FLG_RUNNING && (i == FLG_SYNC0RUNNING || i == FLG_SYNC1RUNNING)) { + which = !(u->flags & FLG_SYNC1RUNNING); + id = u->synciso[which]; + id->callback_frames = /*0*/DESCFRAMES; + id->callback_fn = usbin_sync_completed; + id->data = u->syncdata[which]; + id->buf_size = PAGE_SIZE; + if (!usbin_sync_prepare_desc(u, id) && !usb_run_isoc(id, u->synciso[!which])) + u->flags |= FLG_SYNC0RUNNING << which; + else + u->flags &= ~FLG_RUNNING; + } + } + spin_unlock_irqrestore(&as->lock, flags); +} + +static void usbout_stop(struct usb_audiodev *as) +{ + struct usbout *u = &as->usbout; + unsigned long flags; + unsigned int i; + + spin_lock_irqsave(&as->lock, flags); + u->flags &= ~FLG_RUNNING; + i = u->flags; + spin_unlock_irqrestore(&as->lock, flags); + while (i & (FLG_ID0RUNNING|FLG_ID1RUNNING|FLG_SYNC0RUNNING|FLG_SYNC1RUNNING)) { + schedule_timeout(1); + spin_lock_irqsave(&as->lock, flags); + i = u->flags; + spin_unlock_irqrestore(&as->lock, flags); + } + if (u->dataiso[0]) + usb_free_isoc(u->dataiso[0]); + if (u->dataiso[1]) + usb_free_isoc(u->dataiso[1]); + if (u->synciso[0]) + usb_free_isoc(u->synciso[0]); + if (u->synciso[1]) + usb_free_isoc(u->synciso[1]); + u->dataiso[0] = u->dataiso[1] = u->synciso[0] = u->synciso[1] = NULL; +} + +static void usbout_release(struct usb_audiodev *as) +{ + struct usbout *u = &as->usbout; + + usbout_stop(as); + if (u->data[0]) + free_page((unsigned long)u->data[0]); + if (u->data[1]) + free_page((unsigned long)u->data[1]); + if (u->syncdata[0]) + free_page((unsigned long)u->syncdata[0]); + if (u->syncdata[1]) + free_page((unsigned long)u->syncdata[1]); + u->data[0] = u->data[1] = u->syncdata[0] = u->syncdata[1] = NULL; +} + +static void usbout_convert(struct usbout *u, unsigned char *buffer, unsigned int samples) +{ + union { + __s16 s[64]; + unsigned char b[0]; + } tmp; + unsigned int scnt, maxs, ufmtsh, dfmtsh, cnt, i; + __s16 *sp, *sp2, s; + unsigned char *bp; + + ufmtsh = AFMT_BYTESSHIFT(u->format); + dfmtsh = AFMT_BYTESSHIFT(u->dma.format); + maxs = (AFMT_ISSTEREO(u->dma.format | u->format)) ? 32 : 64; + while (samples > 0) { + scnt = samples; + if (scnt > maxs) + scnt = maxs; + cnt = scnt; + if (AFMT_ISSTEREO(u->dma.format)) + cnt <<= 1; + dmabuf_copyout(&u->dma, tmp.b, scnt << dfmtsh); + sp = tmp.s + cnt; + switch (u->dma.format & ~AFMT_STEREO) { + case AFMT_U8: + for (bp = tmp.b+cnt, i = 0; i < cnt; i++) { + bp--; + sp--; + *sp = (*bp ^ 0x80) << 8; + } + break; + + case AFMT_S8: + for (bp = tmp.b+cnt, i = 0; i < cnt; i++) { + bp--; + sp--; + *sp = *bp << 8; + } + break; + + case AFMT_U16_LE: + for (bp = tmp.b+2*cnt, i = 0; i < cnt; i++) { + bp -= 2; + sp--; + *sp = (bp[0] | (bp[1] << 8)) ^ 0x8000; + } + break; + + case AFMT_U16_BE: + for (bp = tmp.b+2*cnt, i = 0; i < cnt; i++) { + bp -= 2; + sp--; + *sp = (bp[1] | (bp[0] << 8)) ^ 0x8000; + } + break; + + case AFMT_S16_LE: + for (bp = tmp.b+2*cnt, i = 0; i < cnt; i++) { + bp -= 2; + sp--; + *sp = bp[0] | (bp[1] << 8); + } + break; + + case AFMT_S16_BE: + for (bp = tmp.b+2*cnt, i = 0; i < cnt; i++) { + bp -= 2; + sp--; + *sp = bp[1] | (bp[0] << 8); + } + break; + } + if (!AFMT_ISSTEREO(u->dma.format) && AFMT_ISSTEREO(u->format)) { + /* expand from mono to stereo */ + for (sp = tmp.s+scnt, sp2 = tmp.s+2*scnt, i = 0; i < scnt; i++) { + sp--; + sp2 -= 2; + sp2[0] = sp2[1] = sp[0]; + } + } + if (AFMT_ISSTEREO(u->dma.format) && !AFMT_ISSTEREO(u->format)) { + /* contract from stereo to mono */ + for (sp = sp2 = tmp.s, i = 0; i < scnt; i++, sp++, sp2 += 2) + sp[0] = (sp2[0] + sp2[1]) >> 1; + } + cnt = scnt; + if (AFMT_ISSTEREO(u->format)) + cnt <<= 1; + sp = tmp.s; + bp = buffer; + switch (u->format & ~AFMT_STEREO) { + case AFMT_U8: + for (i = 0; i < cnt; i++, sp++, bp++) + *bp = (*sp >> 8) ^ 0x80; + break; + + case AFMT_S8: + for (i = 0; i < cnt; i++, sp++, bp++) + *bp = *sp >> 8; + break; + + case AFMT_U16_LE: + for (i = 0; i < cnt; i++, sp++, bp += 2) { + s = *sp; + bp[0] = s; + bp[1] = (s >> 8) ^ 0x80; + } + break; + + case AFMT_U16_BE: + for (i = 0; i < cnt; i++, sp++, bp += 2) { + s = *sp; + bp[1] = s; + bp[0] = (s >> 8) ^ 0x80; + } + break; + + case AFMT_S16_LE: + for (i = 0; i < cnt; i++, sp++, bp += 2) { + s = *sp; + bp[0] = s; + bp[1] = s >> 8; + } + break; + + case AFMT_S16_BE: + for (i = 0; i < cnt; i++, sp++, bp += 2) { + s = *sp; + bp[1] = s; + bp[0] = s >> 8; + } + break; + } + buffer += scnt << ufmtsh; + samples -= scnt; + } +} + +static int usbout_prepare_desc(struct usbout *u, struct usb_isoc_desc *id) +{ + unsigned int i, ufmtsh, dfmtsh, err = 0, cnt, scnt; + unsigned char *cp = id->data; + + ufmtsh = AFMT_BYTESSHIFT(u->format); + dfmtsh = AFMT_BYTESSHIFT(u->dma.format); + for (i = 0; i < DESCFRAMES; i++) { + u->phase = (u->phase & 0x3fff) + u->freqm; + scnt = u->phase >> 14; + if (!scnt) { + id->frames[i].frame_length = 0; + continue; + } + cnt = scnt << dfmtsh; + if (!u->dma.mapped) { + if (cnt > u->dma.count) { + scnt = u->dma.count >> dfmtsh; + cnt = scnt << dfmtsh; + err++; + } + u->dma.count -= cnt; + } else + u->dma.count += cnt; + if (u->format == u->dma.format) { + /* we do not need format conversion */ + dmabuf_copyout(&u->dma, cp, cnt); + } else { + /* we need sampling format conversion */ + usbout_convert(u, cp, scnt); + } + cnt = scnt << ufmtsh; + id->frames[i].frame_length = cnt; + cp += cnt; + } + if (err) + u->dma.error++; + if (u->dma.mapped) { + if (u->dma.count >= (signed)u->dma.fragsize) + wake_up(&u->dma.wait); + } else { + if ((signed)u->dma.dmasize >= u->dma.count + (signed)u->dma.fragsize) + wake_up(&u->dma.wait); + } + return err ? -1 : 0; +} + +/* + * return value: 0 if descriptor should be restarted, -1 otherwise + */ +static int usbout_retire_desc(struct usbout *u, struct usb_isoc_desc *id) +{ + unsigned int i; + + for (i = 0; i < DESCFRAMES; i++) { + if (id->frames[i].frame_status) { + printk(KERN_DEBUG "usbout_retire_desc: frame %u status %d\n", i, id->frames[i].frame_status); + continue; + } + } + return 0; +} + +static int usbout_completed(int status, void *__buffer, int rval, void *dev_id) +{ +#if 0 + struct usb_isoc_desc *id = (struct usb_isoc_desc *)dev_id; + struct usb_audiodev *as = (struct usb_audiodev *)id->context; +#else + struct usb_audiodev *as = (struct usb_audiodev *)dev_id; + struct usb_isoc_desc *id; +#endif + struct usbout *u = &as->usbout; + unsigned int next, idmask; + + printk(KERN_DEBUG "usbout_completed: status %d rval %d flags 0x%x\n", status, rval, u->flags); + spin_lock(&as->lock); + next = !(u->flags & FLG_NEXTID); + idmask = FLG_ID1RUNNING >> next; + u->flags = (u->flags & ~(FLG_NEXTID | idmask)) | next; + id = u->dataiso[!next]; + if (!usbout_retire_desc(u, id) && + u->flags & FLG_RUNNING && + !usbout_prepare_desc(u, id) && + !usb_run_isoc(id, u->dataiso[next])) { + u->flags |= idmask; + } else { + u->flags &= ~FLG_RUNNING; + printk(KERN_DEBUG "usbout_completed: descriptor not restarted\n"); + } + spin_unlock(&as->lock); + return 0; +} + +static int usbout_sync_prepare_desc(struct usbout *u, struct usb_isoc_desc *id) +{ + unsigned int i; + + for (i = 0; i < DESCFRAMES; i++) + id->frames[i].frame_length = 3; + return 0; +} + +/* + * return value: 0 if descriptor should be restarted, -1 otherwise + */ +static int usbout_sync_retire_desc(struct usbout *u, struct usb_isoc_desc *id) +{ + unsigned char *cp = id->data; + unsigned int i, f; + + for (i = 0; i < DESCFRAMES; i++, cp += 3) { + if (id->frames[i].frame_status) { + printk(KERN_DEBUG "usbout_sync_retire_desc: frame %u status %d\n", i, id->frames[i].frame_status); + continue; + } + if (id->frames[i].frame_length < 3) { + printk(KERN_DEBUG "usbout_sync_retire_desc: frame %u length %d\n", i, id->frames[i].frame_length); + continue; + } + f = cp[0] | (cp[1] << 8) | (cp[2] << 16); + if (abs(f - u->freqn) > (u->freqn >> 3)) { + printk(KERN_WARNING "usbout_sync_retire_desc: requested frequency %u (nominal %u) out of range!\n", f, u->freqn); + continue; + } + u->freqm = f; + } + return 0; +} + +static int usbout_sync_completed(int status, void *__buffer, int rval, void *dev_id) +{ +#if 0 + struct usb_isoc_desc *id = (struct usb_isoc_desc *)dev_id; + struct usb_audiodev *as = (struct usb_audiodev *)id->context; +#else + struct usb_audiodev *as = (struct usb_audiodev *)dev_id; + struct usb_isoc_desc *id; +#endif + struct usbout *u = &as->usbout; + unsigned int next, idmask; + + printk(KERN_DEBUG "usbout_sync_completed: status %d rval %d flags 0x%x\n", status, rval, u->flags); + spin_lock(&as->lock); + next = !(u->flags & FLG_SYNCNEXTID); + idmask = FLG_SYNC1RUNNING >> next; + u->flags = (u->flags & ~(FLG_SYNCNEXTID | idmask)) | (-next & FLG_SYNCNEXTID); + id = u->synciso[!next]; + if (!usbout_sync_retire_desc(u, id) && + u->flags & FLG_RUNNING && + !usbout_sync_prepare_desc(u, id) && + !usb_run_isoc(id, u->synciso[next])) { + u->flags |= idmask; + } else { + u->flags &= ~FLG_RUNNING; + printk(KERN_DEBUG "usbout_sync_completed: descriptor not restarted\n"); + } + spin_unlock(&as->lock); + return 0; +} + +static void usbout_start(struct usb_audiodev *as) +{ + struct usb_device *dev = as->state->usbdev; + struct usbout *u = &as->usbout; + struct usb_isoc_desc *id; + unsigned long flags; + unsigned int which, i; + + printk(KERN_DEBUG "usbout_start: device %d ufmt %d dfmt %d srate %d\n", + dev->devnum, u->format, u->dma.format, u->dma.srate); + /* allocate USB storage if not already done */ + /* UHCI wants the data to be page aligned - this is silly */ + if (!u->data[0]) + u->data[0] = (void *)get_free_page(GFP_KERNEL); + if (!u->data[1]) + u->data[1] = (void *)get_free_page(GFP_KERNEL); + if (!u->dataiso[0] && usb_init_isoc(dev, u->datapipe, DESCFRAMES, as, u->dataiso+0)) { + printk(KERN_ERR "usbaudio: cannot init isoc descriptor device %d pipe 0x%08x\n", + dev->devnum, u->datapipe); + u->dataiso[0] = NULL; + } + if (!u->dataiso[1] && usb_init_isoc(dev, u->datapipe, DESCFRAMES, as, u->dataiso+1)) { + printk(KERN_ERR "usbaudio: cannot init isoc descriptor device %d pipe 0x%08x\n", + dev->devnum, u->datapipe); + u->dataiso[1] = NULL; + } + if (u->syncpipe) { + if (!u->syncdata[0]) + u->syncdata[0] = (void *)get_free_page(GFP_KERNEL); + if (!u->syncdata[1]) + u->syncdata[1] = (void *)get_free_page(GFP_KERNEL); + if (!u->synciso[0] && usb_init_isoc(dev, u->syncpipe, DESCFRAMES, as, u->synciso+0)) { + printk(KERN_ERR "usbaudio: cannot init isoc descriptor device %d pipe 0x%08x\n", + dev->devnum, u->syncpipe); + u->synciso[0] = NULL; + } + if (!u->synciso[1] && usb_init_isoc(dev, u->syncpipe, DESCFRAMES, as, u->synciso+1)) { + printk(KERN_ERR "usbaudio: cannot init isoc descriptor device %d pipe 0x%08x\n", + dev->devnum, u->syncpipe); + u->synciso[1] = NULL; + } + } + if (!u->data[0] || !u->data[1] || !u->dataiso[0] || !u->dataiso[1] || + (u->syncpipe && (!u->syncdata[0] || !u->syncdata[1] || !u->synciso[0] || !u->synciso[1]))) { + printk(KERN_ERR "usbaudio: cannot start playback device %d\n", dev->devnum); + return; + } + spin_lock_irqsave(&as->lock, flags); + if (!(u->flags & FLG_RUNNING)) { + u->freqn = u->freqm = ((u->dma.srate << 11) + 62) / 125; /* this will overflow at approx 2MSPS */ + u->phase = 0; + } + u->flags |= FLG_RUNNING; + if (!(u->flags & (FLG_ID0RUNNING|FLG_ID1RUNNING))) { + id = u->dataiso[0]; + id->start_type = START_ASAP; + id->start_frame = 0; + id->callback_frames = /*0*/DESCFRAMES; + id->callback_fn = usbout_completed; + id->data = u->data[0]; + id->buf_size = PAGE_SIZE; + u->flags &= ~FLG_NEXTID; + if (!usbout_prepare_desc(u, id) && !usb_run_isoc(id, NULL)) + u->flags |= FLG_ID0RUNNING; + else + u->flags &= ~FLG_RUNNING; + } + i = u->flags & (FLG_ID0RUNNING|FLG_ID1RUNNING); + if (u->flags & FLG_RUNNING && (i == FLG_ID0RUNNING || i == FLG_ID1RUNNING)) { + which = !(u->flags & FLG_ID1RUNNING); + id = u->dataiso[which]; + id->callback_frames = /*0*/DESCFRAMES; + id->callback_fn = usbout_completed; + id->data = u->data[which]; + id->buf_size = PAGE_SIZE; + if (!usbout_prepare_desc(u, id) && !usb_run_isoc(id, u->dataiso[!which])) + u->flags |= FLG_ID0RUNNING << which; + else + u->flags &= ~FLG_RUNNING; + } + if (u->syncpipe) { + if (!(u->flags & (FLG_SYNC0RUNNING|FLG_SYNC1RUNNING))) { + id = u->synciso[0]; + id->start_type = START_ASAP; + id->start_frame = 0; + id->callback_frames = /*0*/DESCFRAMES; + id->callback_fn = usbout_sync_completed; + id->data = u->syncdata[0]; + id->buf_size = PAGE_SIZE; + u->flags &= ~FLG_NEXTID; + if (!usbout_sync_prepare_desc(u, id) && !usb_run_isoc(id, NULL)) + u->flags |= FLG_SYNC0RUNNING; + else + u->flags &= ~FLG_RUNNING; + } + i = u->flags & (FLG_SYNC0RUNNING|FLG_SYNC1RUNNING); + if (u->flags & FLG_RUNNING && (i == FLG_SYNC0RUNNING || i == FLG_SYNC1RUNNING)) { + which = !(u->flags & FLG_SYNC1RUNNING); + id = u->synciso[which]; + id->callback_frames = /*0*/DESCFRAMES; + id->callback_fn = usbout_sync_completed; + id->data = u->syncdata[which]; + id->buf_size = PAGE_SIZE; + if (!usbout_sync_prepare_desc(u, id) && !usb_run_isoc(id, u->synciso[!which])) + u->flags |= FLG_SYNC0RUNNING << which; + else + u->flags &= ~FLG_RUNNING; + } + } + spin_unlock_irqrestore(&as->lock, flags); +} + +/* --------------------------------------------------------------------- */ + +static unsigned int find_format(struct audioformat *afp, unsigned int nr, unsigned int fmt) +{ + unsigned int i; + + /* first find an exact match */ + for (i = 0; i < nr; i++) + if (afp[i].format == fmt) + return i; + /* second find a match with the same stereo/mono and 8bit/16bit property */ + for (i = 0; i < nr; i++) + if (!AFMT_ISSTEREO(afp[i].format) == !AFMT_ISSTEREO(fmt) && + !AFMT_IS16BIT(afp[i].format) == !AFMT_IS16BIT(fmt)) + return i; + /* third find a match with the same number of channels */ + for (i = 0; i < nr; i++) + if (!AFMT_ISSTEREO(afp[i].format) == !AFMT_ISSTEREO(fmt)) + return i; + /* return anything */ + return 0; +} + +static int set_format_in(struct usb_audiodev *as) +{ + struct usb_device *dev = as->state->usbdev; + struct usb_config_descriptor *config = dev->actconfig; + struct usb_interface_descriptor *alts; + struct usb_interface *iface; + struct usbin *u = &as->usbin; + struct dmabuf *d = &u->dma; + struct audioformat *fmt; + unsigned int fmtnr; + unsigned char data[3]; + + if (u->interface < 0 || u->interface >= config->bNumInterfaces) + return 0; + iface = &config->interface[u->interface]; + fmtnr = find_format(as->fmtin, as->numfmtin, d->format); + fmt = as->fmtin + fmtnr; + alts = &iface->altsetting[fmt->altsetting]; + u->format = fmt->format; + u->datapipe = usb_rcvisocpipe(dev, alts->endpoint[0].bEndpointAddress & 0xf); + u->syncpipe = u->syncinterval = 0; + if ((alts->endpoint[0].bmAttributes & 0x0c) == 0x08) { + if (alts->bNumEndpoints < 2 || + alts->endpoint[1].bmAttributes != 0x01 || + alts->endpoint[0].bSynchAddress == 0 || + alts->endpoint[1].bEndpointAddress != (alts->endpoint[0].bSynchAddress & 0x7f)) { + printk(KERN_ERR "usb_audio: device %d interface %d altsetting %d invalid synch pipe\n", + dev->devnum, u->interface, fmt->altsetting); + return -1; + } + u->syncpipe = usb_sndisocpipe(dev, alts->endpoint[1].bEndpointAddress & 0xf); + u->syncinterval = alts->endpoint[1].bRefresh; + } + if (d->srate < fmt->sratelo) + d->srate = fmt->sratelo; + if (d->srate > fmt->sratehi) + d->srate = fmt->sratehi; + if (usb_set_interface(dev, u->interface, fmt->altsetting) < 0) { + printk(KERN_WARNING "usbaudio: usb_set_interface failed, device %d interface %d altsetting %d\n", + dev->devnum, u->interface, fmt->altsetting); + return -1; + } + if (fmt->sratelo == fmt->sratehi) + return 0; + data[0] = d->srate; + data[1] = d->srate >> 8; + data[2] = d->srate >> 16; + if (usb_control_msg(dev, usb_snddefctrl(dev), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, + SAMPLING_FREQ_CONTROL << 8, usb_pipeendpoint(u->datapipe), data, 3, HZ) != 3) { + printk(KERN_ERR "usbaudio: failure to set sampling frequency device %d endpoint %d\n", + dev->devnum, usb_pipeendpoint(u->datapipe)); + return -1; + } + if (usb_control_msg(dev, usb_rcvdefctrl(dev), GET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN, + SAMPLING_FREQ_CONTROL << 8, usb_pipeendpoint(u->datapipe), data, 3, HZ) != 3) { + printk(KERN_ERR "usbaudio: failure to get sampling frequency device %d endpoint %d\n", + dev->devnum, usb_pipeendpoint(u->datapipe)); + return -1; + } + d->srate = data[0] | (data[1] << 8) | (data[2] << 16); + return 0; +} + +static int set_format_out(struct usb_audiodev *as) +{ + struct usb_device *dev = as->state->usbdev; + struct usb_config_descriptor *config = dev->actconfig; + struct usb_interface_descriptor *alts; + struct usb_interface *iface; + struct usbout *u = &as->usbout; + struct dmabuf *d = &u->dma; + struct audioformat *fmt; + unsigned int fmtnr; + unsigned char data[3]; + + if (u->interface < 0 || u->interface >= config->bNumInterfaces) + return 0; + iface = &config->interface[u->interface]; + fmtnr = find_format(as->fmtout, as->numfmtout, d->format); + fmt = as->fmtout + fmtnr; + u->format = fmt->format; + alts = &iface->altsetting[fmt->altsetting]; + u->datapipe = usb_sndisocpipe(dev, alts->endpoint[0].bEndpointAddress & 0xf); + u->syncpipe = u->syncinterval = 0; + if ((alts->endpoint[0].bmAttributes & 0x0c) == 0x04) { + if (alts->bNumEndpoints < 2 || + alts->endpoint[1].bmAttributes != 0x01 || + alts->endpoint[0].bSynchAddress == 0 || + alts->endpoint[1].bEndpointAddress != (alts->endpoint[0].bSynchAddress | 0x80)) { + printk(KERN_ERR "usb_audio: device %d interface %d altsetting %d invalid synch pipe\n", + dev->devnum, u->interface, fmt->altsetting); + return -1; + } + u->syncpipe = usb_rcvisocpipe(dev, alts->endpoint[1].bEndpointAddress & 0xf); + u->syncinterval = alts->endpoint[1].bRefresh; + } + if (d->srate < fmt->sratelo) + d->srate = fmt->sratelo; + if (d->srate > fmt->sratehi) + d->srate = fmt->sratehi; + if (usb_set_interface(dev, u->interface, fmt->altsetting) < 0) { + printk(KERN_WARNING "usbaudio: usb_set_interface failed, device %d interface %d altsetting %d\n", + dev->devnum, u->interface, fmt->altsetting); + return -1; + } + if (fmt->sratelo == fmt->sratehi) + return 0; + data[0] = d->srate; + data[1] = d->srate >> 8; + data[2] = d->srate >> 16; + if (usb_control_msg(dev, usb_snddefctrl(dev), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, + SAMPLING_FREQ_CONTROL << 8, usb_pipeendpoint(u->datapipe), data, 3, HZ) != 3) { + printk(KERN_ERR "usbaudio: failure to set sampling frequency device %d endpoint %d\n", + dev->devnum, usb_pipeendpoint(u->datapipe)); + return -1; + } + if (usb_control_msg(dev, usb_rcvdefctrl(dev), GET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN, + SAMPLING_FREQ_CONTROL << 8, usb_pipeendpoint(u->datapipe), data, 3, HZ) != 3) { + printk(KERN_ERR "usbaudio: failure to get sampling frequency device %d endpoint %d\n", + dev->devnum, usb_pipeendpoint(u->datapipe)); + return -1; + } + d->srate = data[0] | (data[1] << 8) | (data[2] << 16); + return 0; +} + +static int set_format(struct usb_audiodev *s, unsigned int fmode, unsigned int fmt, unsigned int srate) +{ + int ret1 = 0, ret2 = 0; + + if (!(fmode & (FMODE_READ|FMODE_WRITE))) + return -EINVAL; + if (fmode & FMODE_READ) { + usbin_stop(s); + s->usbin.dma.ready = 0; + if (fmt == AFMT_QUERY) + fmt = s->usbin.dma.format; + else + s->usbin.dma.format = fmt; + if (!srate) + srate = s->usbin.dma.srate; + else + s->usbin.dma.srate = srate; + } + if (fmode & FMODE_WRITE) { + usbout_stop(s); + s->usbout.dma.ready = 0; + if (fmt == AFMT_QUERY) + fmt = s->usbout.dma.format; + else + s->usbout.dma.format = fmt; + if (!srate) + srate = s->usbout.dma.srate; + else + s->usbout.dma.srate = srate; + } + if (fmode & FMODE_READ) + ret1 = set_format_in(s); + if (fmode & FMODE_WRITE) + ret2 = set_format_out(s); + return ret1 ? ret1 : ret2; +} + +/* --------------------------------------------------------------------- */ + +static int wrmixer(struct usb_mixerdev *ms, unsigned mixch, unsigned value) +{ + struct usb_device *dev = ms->state->usbdev; + unsigned char data[2]; + struct mixerchannel *ch; + int v1, v2, v3; + + if (mixch >= ms->numch) + return -1; + ch = &ms->ch[mixch]; + v3 = ch->maxval - ch->minval; + v1 = value & 0xff; + v2 = (value >> 8) & 0xff; + if (v1 > 100) + v1 = 100; + if (v2 > 100) + v2 = 100; + if (!(ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT))) + v2 = v1; + ch->value = v1 | (v2 << 8); + v1 = (v1 * v3) / 100 + ch->minval; + v2 = (v2 * v3) / 100 + ch->minval; + switch (ch->selector) { + case 0: /* mixer unit request */ + data[0] = v1; + data[1] = v1 >> 8; + if (usb_control_msg(dev, usb_snddefctrl(dev), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, + (ch->chnum << 8) | 1, ms->iface | (ch->unitid << 8), data, 2, HZ) < 2) + goto err; + if (!(ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT))) + return 0; + data[0] = v2; + data[1] = v2 >> 8; + if (usb_control_msg(dev, usb_snddefctrl(dev), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, + ((ch->chnum + !!(ch->flags & MIXFLG_STEREOIN)) << 8) | (1 + !!(ch->flags & MIXFLG_STEREOOUT)), + ms->iface | (ch->unitid << 8), data, 2, HZ) < 2) + goto err; + return 0; + + /* various feature unit controls */ + case VOLUME_CONTROL: + data[0] = v1; + data[1] = v1 >> 8; + if (usb_control_msg(dev, usb_snddefctrl(dev), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, + (ch->selector << 8) | ch->chnum, ms->iface | (ch->unitid << 8), data, 2, HZ) < 2) + goto err; + if (ch->chnum == 0) + return 0; + data[0] = v2; + data[1] = v2 >> 8; + if (usb_control_msg(dev, usb_snddefctrl(dev), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, + (ch->selector << 8) | (ch->chnum + 1), ms->iface | (ch->unitid << 8), data, 2, HZ) < 2) + goto err; + return 0; + + case BASS_CONTROL: + case MID_CONTROL: + case TREBLE_CONTROL: + data[0] = v1 >> 8; + if (usb_control_msg(dev, usb_snddefctrl(dev), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, + (ch->selector << 8) | ch->chnum, ms->iface | (ch->unitid << 8), data, 1, HZ) < 1) + goto err; + if (ch->chnum == 0) + return 0; + data[0] = v2 >> 8; + if (usb_control_msg(dev, usb_snddefctrl(dev), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, + (ch->selector << 8) | (ch->chnum + 1), ms->iface | (ch->unitid << 8), data, 1, HZ) < 1) + goto err; + return 0; + + default: + return -1; + } + return 0; + + err: + printk(KERN_ERR "usb_audio: mixer request device %u if %u unit %u ch %u selector %u failed\n", + dev->devnum, ms->iface, ch->unitid, ch->chnum, ch->selector); + return -1; +} + +/* --------------------------------------------------------------------- */ + +/* + * should be called with open_sem hold, so that no new processes + * look at the audio device to be destroyed + */ + +static void release(struct usb_audio_state *s) +{ + struct usb_audiodev *as; + struct usb_mixerdev *ms; + + s->count--; + if (s->count) { + up(&open_sem); + return; + } + up(&open_sem); + wake_up(&open_wait); + while (!list_empty(&s->audiolist)) { + as = list_entry(s->audiolist.next, struct usb_audiodev, list); + list_del(&as->list); + usbin_release(as); + usbout_release(as); + dmabuf_release(&as->usbin.dma); + dmabuf_release(&as->usbout.dma); + kfree(as); + } + while (!list_empty(&s->mixerlist)) { + ms = list_entry(s->mixerlist.next, struct usb_mixerdev, list); + list_del(&ms->list); + kfree(ms); + } + kfree(s); + MOD_DEC_USE_COUNT; +} + +extern inline int prog_dmabuf_in(struct usb_audiodev *as) +{ + usbin_stop(as); + return dmabuf_init(&as->usbin.dma); +} + +extern inline int prog_dmabuf_out(struct usb_audiodev *as) +{ + usbout_stop(as); + return dmabuf_init(&as->usbout.dma); +} -#include "usb.h" -#define AUDIO_DEBUG 1 +/* --------------------------------------------------------------------- */ -static int usb_audio_probe(struct usb_device *dev); -static void usb_audio_disconnect(struct usb_device *dev); -static LIST_HEAD(usb_audio_list); +static loff_t usb_audio_llseek(struct file *file, loff_t offset, int origin) +{ + return -ESPIPE; +} -struct usb_audio { - struct usb_device *dev; - struct list_head list; +/* --------------------------------------------------------------------- */ + +static int usb_audio_open_mixdev(struct inode *inode, struct file *file) +{ + int minor = MINOR(inode->i_rdev); + struct list_head *devs, *mdevs; + struct usb_mixerdev *ms; + struct usb_audio_state *s; + + down(&open_sem); + for (devs = audiodevs.next; devs != &audiodevs; devs = devs->next) { + s = list_entry(devs, struct usb_audio_state, audiodev); + for (mdevs = s->mixerlist.next; mdevs != &s->mixerlist; mdevs = mdevs->next) { + ms = list_entry(mdevs, struct usb_mixerdev, list); + if (ms->dev_mixer == minor) + goto mixer_found; + } + } + up(&open_sem); + return -ENODEV; + + mixer_found: + if (!s->usbdev) { + up(&open_sem); + return -EIO; + } + file->private_data = ms; + s->count++; + up(&open_sem); + return 0; +} + +static int usb_audio_release_mixdev(struct inode *inode, struct file *file) +{ + struct usb_mixerdev *ms = (struct usb_mixerdev *)file->private_data; + struct usb_audio_state *s = ms->state; + + down(&open_sem); + release(s); + return 0; +} + +static int usb_audio_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + struct usb_mixerdev *ms = (struct usb_mixerdev *)file->private_data; + int i, j, val; + + if (cmd == SOUND_MIXER_INFO) { + mixer_info info; + strncpy(info.id, "USB_AUDIO", sizeof(info.id)); + strncpy(info.name, "USB Audio Class Driver", sizeof(info.name)); + info.modify_counter = ms->modcnt; + if (copy_to_user((void *)arg, &info, sizeof(info))) + return -EFAULT; + return 0; + } + if (cmd == SOUND_OLD_MIXER_INFO) { + _old_mixer_info info; + strncpy(info.id, "USB_AUDIO", sizeof(info.id)); + strncpy(info.name, "USB Audio Class Driver", sizeof(info.name)); + if (copy_to_user((void *)arg, &info, sizeof(info))) + return -EFAULT; + return 0; + } + if (cmd == OSS_GETVERSION) + return put_user(SOUND_VERSION, (int *)arg); + if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int)) + return -EINVAL; + if (_IOC_DIR(cmd) == _IOC_READ) { + switch (_IOC_NR(cmd)) { + case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ + /* don't know how to handle this yet */ + return put_user(0, (int *)arg); + + case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */ + for (val = i = 0; i < ms->numch; i++) + val |= 1 << ms->ch[i].osschannel; + return put_user(val, (int *)arg); + + case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */ + /* don't know how to handle this yet */ + return put_user(0, (int *)arg); + + case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */ + for (val = i = 0; i < ms->numch; i++) + if (ms->ch[i].flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)) + val |= 1 << ms->ch[i].osschannel; + return put_user(0, (int *)arg); + + case SOUND_MIXER_CAPS: + return put_user(0, (int *)arg); + + default: + i = _IOC_NR(cmd); + if (i >= SOUND_MIXER_NRDEVICES) + return -EINVAL; + for (j = 0; j < ms->numch; j++) { + if (ms->ch[j].osschannel == i) { + return put_user(ms->ch[j].value, (int *)arg); + } + } + return -EINVAL; + } + } + if (_IOC_DIR(cmd) != (_IOC_READ|_IOC_WRITE)) + return -EINVAL; + ms->modcnt++; + switch (_IOC_NR(cmd)) { + case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ + get_user_ret(val, (int *)arg, -EFAULT); + /* set recording source: val */ + return 0; + + default: + i = _IOC_NR(cmd); + if (i >= SOUND_MIXER_NRDEVICES) + return -EINVAL; + for (j = 0; j < ms->numch && ms->ch[j].osschannel != i; j++); + if (j >= ms->numch) + return -EINVAL; + get_user_ret(val, (int *)arg, -EFAULT); + if (wrmixer(ms, j, val)) + return -EIO; + return put_user(ms->ch[j].value, (int *)arg); + } +} + +static /*const*/ struct file_operations usb_mixer_fops = { + &usb_audio_llseek, + NULL, /* read */ + NULL, /* write */ + NULL, /* readdir */ + NULL, /* poll */ + &usb_audio_ioctl_mixdev, + NULL, /* mmap */ + &usb_audio_open_mixdev, + NULL, /* flush */ + &usb_audio_release_mixdev, + NULL, /* fsync */ + NULL, /* fasync */ + NULL, /* check_media_change */ + NULL, /* revalidate */ + NULL, /* lock */ +}; + +/* --------------------------------------------------------------------- */ + +static int drain_out(struct usb_audiodev *as, int nonblock) +{ + DECLARE_WAITQUEUE(wait, current); + unsigned long flags; + int count, tmo; + + if (as->usbout.dma.mapped || !as->usbout.dma.ready) + return 0; + __set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&as->usbout.dma.wait, &wait); + for (;;) { + spin_lock_irqsave(&as->lock, flags); + count = as->usbout.dma.count; + spin_unlock_irqrestore(&as->lock, flags); + if (count <= 0) + break; + if (signal_pending(current)) + break; + if (nonblock) { + remove_wait_queue(&as->usbout.dma.wait, &wait); + set_current_state(TASK_RUNNING); + return -EBUSY; + } + tmo = 3 * HZ * count / as->usbout.dma.srate; + tmo >>= AFMT_BYTESSHIFT(as->usbout.dma.format); + if (!schedule_timeout(tmo + 1)) + printk(KERN_DEBUG "usbaudio: dma timed out??\n"); + } + remove_wait_queue(&as->usbout.dma.wait, &wait); + set_current_state(TASK_RUNNING); + if (signal_pending(current)) + return -ERESTARTSYS; + return 0; +} + +/* --------------------------------------------------------------------- */ + +static ssize_t usb_audio_read(struct file *file, char *buffer, size_t count, loff_t *ppos) +{ + struct usb_audiodev *as = (struct usb_audiodev *)file->private_data; + DECLARE_WAITQUEUE(wait, current); + ssize_t ret = 0; + unsigned long flags; + unsigned int ptr; + int cnt, err; + + if (ppos != &file->f_pos) + return -ESPIPE; + if (as->usbin.dma.mapped) + return -ENXIO; + if (!as->usbin.dma.ready && (ret = prog_dmabuf_in(as))) + return ret; + if (!access_ok(VERIFY_WRITE, buffer, count)) + return -EFAULT; + __set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&as->usbin.dma.wait, &wait); + while (count > 0) { + spin_lock_irqsave(&as->lock, flags); + ptr = as->usbin.dma.rdptr; + cnt = as->usbin.dma.count; + spin_unlock_irqrestore(&as->lock, flags); + if (cnt > count) + cnt = count; + if (cnt <= 0) { + usbin_start(as); + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } + continue; + } + if ((err = dmabuf_copyout_user(&as->usbin.dma, ptr, buffer, cnt))) { + if (!ret) + ret = err; + break; + } + ptr += cnt; + if (ptr >= as->usbin.dma.dmasize) + ptr -= as->usbin.dma.dmasize; + spin_lock_irqsave(&as->lock, flags); + as->usbin.dma.rdptr = ptr; + as->usbin.dma.count -= cnt; + spin_unlock_irqrestore(&as->lock, flags); + count -= cnt; + buffer += cnt; + ret += cnt; + } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&as->usbin.dma.wait, &wait); + return ret; +} + +static ssize_t usb_audio_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) +{ + struct usb_audiodev *as = (struct usb_audiodev *)file->private_data; + DECLARE_WAITQUEUE(wait, current); + ssize_t ret = 0; + unsigned long flags; + unsigned int ptr; + int cnt, err; + + if (ppos != &file->f_pos) + return -ESPIPE; + if (as->usbout.dma.mapped) + return -ENXIO; + if (!as->usbout.dma.ready && (ret = prog_dmabuf_out(as))) + return ret; + if (!access_ok(VERIFY_READ, buffer, count)) + return -EFAULT; + __set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&as->usbout.dma.wait, &wait); + while (count > 0) { + spin_lock_irqsave(&as->lock, flags); + if (as->usbout.dma.count < 0) { + as->usbout.dma.count = 0; + as->usbout.dma.rdptr = as->usbout.dma.wrptr; + } + ptr = as->usbout.dma.wrptr; + cnt = as->usbout.dma.dmasize - as->usbout.dma.count; + spin_unlock_irqrestore(&as->lock, flags); + if (cnt > count) + cnt = count; + if (cnt <= 0) { + usbout_start(as); + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } + continue; + } + if ((err = dmabuf_copyin_user(&as->usbout.dma, ptr, buffer, cnt))) { + if (!ret) + ret = err; + break; + } + ptr += cnt; + if (ptr >= as->usbout.dma.dmasize) + ptr -= as->usbout.dma.dmasize; + spin_lock_irqsave(&as->lock, flags); + as->usbout.dma.wrptr = ptr; + as->usbout.dma.count += cnt; + spin_unlock_irqrestore(&as->lock, flags); + count -= cnt; + buffer += cnt; + ret += cnt; + usbout_start(as); + } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&as->usbout.dma.wait, &wait); + return ret; +} + +static unsigned int usb_audio_poll(struct file *file, struct poll_table_struct *wait) +{ + struct usb_audiodev *as = (struct usb_audiodev *)file->private_data; + unsigned long flags; + unsigned int mask = 0; + + if (file->f_mode & FMODE_WRITE) { + if (!as->usbout.dma.ready) + prog_dmabuf_out(as); + poll_wait(file, &as->usbout.dma.wait, wait); + } + if (file->f_mode & FMODE_READ) { + if (!as->usbin.dma.ready) + prog_dmabuf_in(as); + poll_wait(file, &as->usbin.dma.wait, wait); + } + spin_lock_irqsave(&as->lock, flags); + if (file->f_mode & FMODE_READ) { + if (as->usbin.dma.count >= (signed)as->usbin.dma.fragsize) + mask |= POLLIN | POLLRDNORM; + } + if (file->f_mode & FMODE_WRITE) { + if (as->usbout.dma.mapped) { + if (as->usbout.dma.count >= (signed)as->usbout.dma.fragsize) + mask |= POLLOUT | POLLWRNORM; + } else { + if ((signed)as->usbout.dma.dmasize >= as->usbout.dma.count + (signed)as->usbout.dma.fragsize) + mask |= POLLOUT | POLLWRNORM; + } + } + spin_unlock_irqrestore(&as->lock, flags); + return mask; +} + +static int usb_audio_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct usb_audiodev *as = (struct usb_audiodev *)file->private_data; + struct dmabuf *db; + int ret; + + if (vma->vm_flags & VM_WRITE) { + if ((ret = prog_dmabuf_out(as)) != 0) + return ret; + db = &as->usbout.dma; + } else if (vma->vm_flags & VM_READ) { + if ((ret = prog_dmabuf_in(as)) != 0) + return ret; + db = &as->usbin.dma; + } else + return -EINVAL; + if (vma->vm_offset != 0) + return -EINVAL; + return dmabuf_mmap(db, vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot); +} + +static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + struct usb_audiodev *as = (struct usb_audiodev *)file->private_data; + struct usb_audio_state *s = as->state; + unsigned long flags; + audio_buf_info abinfo; + count_info cinfo; + int val, val2, mapped, ret; + + if (!s->usbdev) + return -EIO; + mapped = ((file->f_mode & FMODE_WRITE) && as->usbout.dma.mapped) || + ((file->f_mode & FMODE_READ) && as->usbin.dma.mapped); + switch (cmd) { + case OSS_GETVERSION: + return put_user(SOUND_VERSION, (int *)arg); + + case SNDCTL_DSP_SYNC: + if (file->f_mode & FMODE_WRITE) + return drain_out(as, 0/*file->f_flags & O_NONBLOCK*/); + return 0; + + case SNDCTL_DSP_SETDUPLEX: + return 0; + + case SNDCTL_DSP_GETCAPS: + return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | + DSP_CAP_MMAP | DSP_CAP_BATCH, (int *)arg); + + case SNDCTL_DSP_RESET: + if (file->f_mode & FMODE_WRITE) { + usbout_stop(as); + as->usbout.dma.rdptr = as->usbout.dma.wrptr = as->usbout.dma.count = as->usbout.dma.total_bytes = 0; + } + if (file->f_mode & FMODE_READ) { + usbin_stop(as); + as->usbin.dma.rdptr = as->usbin.dma.wrptr = as->usbin.dma.count = as->usbin.dma.total_bytes = 0; + } + return 0; + + case SNDCTL_DSP_SPEED: + get_user_ret(val, (int *)arg, -EFAULT); + if (val >= 0) { + if (val < 4000) + val = 4000; + if (val > 100000) + val = 100000; + if (set_format(as, file->f_mode, AFMT_QUERY, val)) + return -EIO; + } + return put_user((file->f_mode & FMODE_READ) ? as->usbin.dma.srate : as->usbout.dma.srate, (int *)arg); + + case SNDCTL_DSP_STEREO: + val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format; + if (set_format(as, file->f_mode, val2 | AFMT_STEREO, 0)) + return -EIO; + return 0; + + case SNDCTL_DSP_CHANNELS: + get_user_ret(val, (int *)arg, -EFAULT); + if (val != 0) { + val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format; + if (val == 1) + val2 &= ~AFMT_STEREO; + else + val2 |= AFMT_STEREO; + if (set_format(as, file->f_mode, val2, 0)) + return -EIO; + } + val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format; + return put_user(AFMT_ISSTEREO(val2) ? 2 : 1, (int *)arg); + + case SNDCTL_DSP_GETFMTS: /* Returns a mask */ + return put_user(AFMT_U8 | AFMT_U16_LE | AFMT_U16_BE | + AFMT_S8 | AFMT_S16_LE | AFMT_S16_BE, (int *)arg); + + case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/ + get_user_ret(val, (int *)arg, -EFAULT); + if (val != AFMT_QUERY) { + if (hweight32(val) != 1) + return -EINVAL; + if (!(val & (AFMT_U8 | AFMT_U16_LE | AFMT_U16_BE | + AFMT_S8 | AFMT_S16_LE | AFMT_S16_BE))) + return -EINVAL; + val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format; + val |= val2 & AFMT_STEREO; + if (set_format(as, file->f_mode, val, 0)) + return -EIO; + } + val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format; + return put_user(val2 & ~AFMT_STEREO, (int *)arg); + + case SNDCTL_DSP_POST: + return 0; + + case SNDCTL_DSP_GETTRIGGER: + val = 0; + if (file->f_mode & FMODE_READ && as->usbin.flags & FLG_RUNNING) + val |= PCM_ENABLE_INPUT; + if (file->f_mode & FMODE_WRITE && as->usbout.flags & FLG_RUNNING) + val |= PCM_ENABLE_OUTPUT; + return put_user(val, (int *)arg); + + case SNDCTL_DSP_SETTRIGGER: + get_user_ret(val, (int *)arg, -EFAULT); + if (file->f_mode & FMODE_READ) { + if (val & PCM_ENABLE_INPUT) { + if (!as->usbin.dma.ready && (ret = prog_dmabuf_in(as))) + return ret; + usbin_start(as); + } else + usbin_stop(as); + } + if (file->f_mode & FMODE_WRITE) { + if (val & PCM_ENABLE_OUTPUT) { + if (!as->usbout.dma.ready && (ret = prog_dmabuf_out(as))) + return ret; + usbout_start(as); + } else + usbout_stop(as); + } + return 0; + + case SNDCTL_DSP_GETOSPACE: + if (!(file->f_mode & FMODE_WRITE)) + return -EINVAL; + if (!(as->usbout.flags & FLG_RUNNING) && (val = prog_dmabuf_out(as)) != 0) + return val; + spin_lock_irqsave(&as->lock, flags); + abinfo.fragsize = as->usbout.dma.fragsize; + abinfo.bytes = as->usbout.dma.dmasize - as->usbout.dma.count; + abinfo.fragstotal = as->usbout.dma.numfrag; + abinfo.fragments = abinfo.bytes >> as->usbout.dma.fragshift; + spin_unlock_irqrestore(&as->lock, flags); + return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; + + case SNDCTL_DSP_GETISPACE: + if (!(file->f_mode & FMODE_READ)) + return -EINVAL; + if (!(as->usbin.flags & FLG_RUNNING) && (val = prog_dmabuf_in(as)) != 0) + return val; + spin_lock_irqsave(&as->lock, flags); + abinfo.fragsize = as->usbin.dma.fragsize; + abinfo.bytes = as->usbin.dma.count; + abinfo.fragstotal = as->usbin.dma.numfrag; + abinfo.fragments = abinfo.bytes >> as->usbin.dma.fragshift; + spin_unlock_irqrestore(&as->lock, flags); + return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; + + case SNDCTL_DSP_NONBLOCK: + file->f_flags |= O_NONBLOCK; + return 0; + + case SNDCTL_DSP_GETODELAY: + if (!(file->f_mode & FMODE_WRITE)) + return -EINVAL; + spin_lock_irqsave(&as->lock, flags); + val = as->usbout.dma.count; + spin_unlock_irqrestore(&as->lock, flags); + return put_user(val, (int *)arg); + + case SNDCTL_DSP_GETIPTR: + if (!(file->f_mode & FMODE_READ)) + return -EINVAL; + spin_lock_irqsave(&as->lock, flags); + cinfo.bytes = as->usbin.dma.total_bytes; + cinfo.blocks = as->usbin.dma.count >> as->usbin.dma.fragshift; + cinfo.ptr = as->usbin.dma.wrptr; + if (as->usbin.dma.mapped) + as->usbin.dma.count &= as->usbin.dma.fragsize-1; + spin_unlock_irqrestore(&as->lock, flags); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)); + + case SNDCTL_DSP_GETOPTR: + if (!(file->f_mode & FMODE_WRITE)) + return -EINVAL; + spin_lock_irqsave(&as->lock, flags); + cinfo.bytes = as->usbout.dma.total_bytes; + cinfo.blocks = as->usbout.dma.count >> as->usbout.dma.fragshift; + cinfo.ptr = as->usbout.dma.rdptr; + if (as->usbout.dma.mapped) + as->usbout.dma.count &= as->usbout.dma.fragsize-1; + spin_unlock_irqrestore(&as->lock, flags); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)); + + case SNDCTL_DSP_GETBLKSIZE: + if (file->f_mode & FMODE_WRITE) { + if ((val = prog_dmabuf_out(as))) + return val; + return put_user(as->usbout.dma.fragsize, (int *)arg); + } + if ((val = prog_dmabuf_in(as))) + return val; + return put_user(as->usbin.dma.fragsize, (int *)arg); + + case SNDCTL_DSP_SETFRAGMENT: + get_user_ret(val, (int *)arg, -EFAULT); + if (file->f_mode & FMODE_READ) { + as->usbin.dma.ossfragshift = val & 0xffff; + as->usbin.dma.ossmaxfrags = (val >> 16) & 0xffff; + if (as->usbin.dma.ossfragshift < 4) + as->usbin.dma.ossfragshift = 4; + if (as->usbin.dma.ossfragshift > 15) + as->usbin.dma.ossfragshift = 15; + if (as->usbin.dma.ossmaxfrags < 4) + as->usbin.dma.ossmaxfrags = 4; + } + if (file->f_mode & FMODE_WRITE) { + as->usbout.dma.ossfragshift = val & 0xffff; + as->usbout.dma.ossmaxfrags = (val >> 16) & 0xffff; + if (as->usbout.dma.ossfragshift < 4) + as->usbout.dma.ossfragshift = 4; + if (as->usbout.dma.ossfragshift > 15) + as->usbout.dma.ossfragshift = 15; + if (as->usbout.dma.ossmaxfrags < 4) + as->usbout.dma.ossmaxfrags = 4; + } + return 0; + + case SNDCTL_DSP_SUBDIVIDE: + if ((file->f_mode & FMODE_READ && as->usbin.dma.subdivision) || + (file->f_mode & FMODE_WRITE && as->usbout.dma.subdivision)) + return -EINVAL; + get_user_ret(val, (int *)arg, -EFAULT); + if (val != 1 && val != 2 && val != 4) + return -EINVAL; + if (file->f_mode & FMODE_READ) + as->usbin.dma.subdivision = val; + if (file->f_mode & FMODE_WRITE) + as->usbout.dma.subdivision = val; + return 0; + + case SOUND_PCM_READ_RATE: + return put_user((file->f_mode & FMODE_READ) ? as->usbin.dma.srate : as->usbout.dma.srate, (int *)arg); + + case SOUND_PCM_READ_CHANNELS: + val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format; + return put_user(AFMT_ISSTEREO(val2) ? 2 : 1, (int *)arg); + + case SOUND_PCM_READ_BITS: + val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format; + return put_user(AFMT_IS16BIT(val2) ? 16 : 8, (int *)arg); + + case SOUND_PCM_WRITE_FILTER: + case SNDCTL_DSP_SETSYNCRO: + case SOUND_PCM_READ_FILTER: + return -EINVAL; + } + return -ENOIOCTLCMD; +} + +static int usb_audio_open(struct inode *inode, struct file *file) +{ + int minor = MINOR(inode->i_rdev); + DECLARE_WAITQUEUE(wait, current); + struct list_head *devs, *adevs; + struct usb_audiodev *as; + struct usb_audio_state *s; + + for (;;) { + down(&open_sem); + for (devs = audiodevs.next; devs != &audiodevs; devs = devs->next) { + s = list_entry(devs, struct usb_audio_state, audiodev); + for (adevs = s->audiolist.next; adevs != &s->audiolist; adevs = adevs->next) { + as = list_entry(adevs, struct usb_audiodev, list); + if (!((as->dev_audio ^ minor) & ~0xf)) + goto device_found; + } + } + up(&open_sem); + return -ENODEV; + + device_found: + if (!s->usbdev) { + up(&open_sem); + return -EIO; + } + /* wait for device to become free */ + if (!(as->open_mode & file->f_mode)) + break; + if (file->f_flags & O_NONBLOCK) { + up(&open_sem); + return -EBUSY; + } + __set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&open_wait, &wait); + up(&open_sem); + schedule(); + __set_current_state(TASK_RUNNING); + remove_wait_queue(&open_wait, &wait); + if (signal_pending(current)) + return -ERESTARTSYS; + } + if (file->f_mode & FMODE_READ) + as->usbin.dma.ossfragshift = as->usbin.dma.ossmaxfrags = as->usbin.dma.subdivision = 0; + if (file->f_mode & FMODE_WRITE) + as->usbout.dma.ossfragshift = as->usbout.dma.ossmaxfrags = as->usbout.dma.subdivision = 0; + if (set_format(as, file->f_mode, ((minor & 0xf) == SND_DEV_DSP16) ? AFMT_S16_LE : AFMT_U8 /* AFMT_ULAW */, 8000)) { + up(&open_sem); + return -EIO; + } + file->private_data = as; + as->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); + s->count++; + up(&open_sem); + return 0; +} + +static int usb_audio_release(struct inode *inode, struct file *file) +{ + struct usb_audiodev *as = (struct usb_audiodev *)file->private_data; + struct usb_audio_state *s = as->state; + + if (file->f_mode & FMODE_WRITE) + drain_out(as, file->f_flags & O_NONBLOCK); + down(&open_sem); + if (file->f_mode & FMODE_WRITE) { + usbout_stop(as); + if (s->usbdev) + usb_set_interface(s->usbdev, as->usbout.interface, 0); + dmabuf_release(&as->usbout.dma); + usbout_release(as); + } + if (file->f_mode & FMODE_READ) { + usbin_stop(as); + if (s->usbdev) + usb_set_interface(s->usbdev, as->usbin.interface, 0); + dmabuf_release(&as->usbin.dma); + usbin_release(as); + } + as->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); + release(s); + wake_up(&open_wait); + return 0; +} - void *irq_handle; - unsigned int irqpipe; +static /*const*/ struct file_operations usb_audio_fops = { + &usb_audio_llseek, + &usb_audio_read, + &usb_audio_write, + NULL, /* readdir */ + &usb_audio_poll, + &usb_audio_ioctl, + &usb_audio_mmap, + &usb_audio_open, + NULL, /* flush */ + &usb_audio_release, + NULL, /* fsync */ + NULL, /* fasync */ + NULL, /* check_media_change */ + NULL, /* revalidate */ + NULL, /* lock */ }; +/* --------------------------------------------------------------------- */ + +/* + * TO DO in order to get to the point of building an OSS interface + * structure, let alone playing music.. + * + * Use kmalloc/kfree for the descriptors we build + * Write the descriptor->OSS convertor code + * Figure how we deal with mixers + * Check alternate configurations. For now assume we will find one + * zero bandwidth (idle) config and one or more live one pers interface. + */ + +static int usb_audio_probe(struct usb_device *dev); +static void usb_audio_disconnect(struct usb_device *dev); + static struct usb_driver usb_audio_driver = { "audio", usb_audio_probe, @@ -32,7 +2502,7 @@ static int usb_audio_irq(int state, void *buffer, int len, void *dev_id) { #if 0 - struct usb_audio *aud = (struct usb_audio *)dev_id; + struct usb_audio_device *aud = (struct usb_audio_device *)dev_id; printk("irq on %p\n", aud); #endif @@ -41,107 +2511,943 @@ } #endif -static int usb_audio_probe(struct usb_device *dev) +static void *find_descriptor(void *descstart, unsigned int desclen, void *after, + u8 dtype, int iface, int altsetting) { - struct usb_interface_descriptor *interface; - struct usb_audio *aud; - int i; - int na=0; - - for (i=0; iconfig[0].bNumInterfaces; i++) { - interface = &dev->config->interface[i].altsetting[0]; - - if (interface->bInterfaceClass != 1) - continue; - - printk(KERN_INFO "USB audio device detected.\n"); - - switch(interface->bInterfaceSubClass) { - case 0x01: - printk(KERN_INFO "audio: control device\n"); - break; - case 0x02: - printk(KERN_INFO "audio: streaming\n"); - break; - case 0x03: - printk(KERN_INFO "audio: nonstreaming\n"); - break; + u8 *p, *end, *next; + int ifc = -1, as = -1; + + p = descstart; + end = p + desclen; + for (; p < end;) { + if (p[0] < 2) + return NULL; + next = p + p[0]; + if (next > end) + return NULL; + if (p[1] == USB_DT_INTERFACE) { + /* minimum length of interface descriptor */ + if (p[0] < 9) + return NULL; + ifc = p[2]; + as = p[3]; + } + if (p[1] == dtype && (!after || (void *)p > after) && + (iface == -1 || iface == ifc) && (altsetting == -1 || altsetting == as)) { + return p; } - na++; + p = next; } - - if (!na) - return -1; + return NULL; +} - aud = kmalloc(sizeof(struct usb_audio), GFP_KERNEL); - if (!aud) - return -1; +static void *find_csinterface_descriptor(void *descstart, unsigned int desclen, void *after, u8 dsubtype, int iface, int altsetting) +{ + unsigned char *p; - memset(aud, 0, sizeof(*aud)); - aud->dev = dev; - dev->private = aud; + p = find_descriptor(descstart, desclen, after, USB_DT_CS_INTERFACE, iface, altsetting); + while (p) { + if (p[0] >= 3 && p[2] == dsubtype) + return p; + p = find_descriptor(descstart, desclen, p, USB_DT_CS_INTERFACE, iface, altsetting); + } + return NULL; +} -/* - if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) { - printk (KERN_INFO "Failed usb_set_configuration: Audio\n"); - break; +static void *find_audiocontrol_unit(void *descstart, unsigned int desclen, void *after, u8 unit, int iface) +{ + unsigned char *p; + + p = find_descriptor(descstart, desclen, after, USB_DT_CS_INTERFACE, iface, -1); + while (p) { + if (p[0] >= 4 && p[2] >= INPUT_TERMINAL && p[2] <= EXTENSION_UNIT && p[3] == unit) + return p; + p = find_descriptor(descstart, desclen, p, USB_DT_CS_INTERFACE, iface, -1); } - usb_set_protocol(dev, 0); - usb_set_idle(dev, 0, 0); -*/ - -/* - aud->irqpipe = usb_rcvctrlpipe(dev, endpoint->bEndpointAddress); - na = usb_request_irq(dev, aud->irqpipe, - usb_audio_irq, endpoint->bInterval, - aud, &aud->irq_handle); - if (na) { - printk (KERN_WARNING "usb-audio: usb_request_irq failed (0x%x)\n", na); + return NULL; +} + +static void usb_audio_parsestreaming(struct usb_audio_state *s, unsigned char *buffer, unsigned int buflen, int asifin, int asifout) +{ + struct usb_device *dev = s->usbdev; + struct usb_audiodev *as; + struct usb_config_descriptor *config = dev->actconfig; + struct usb_interface_descriptor *alts; + struct usb_interface *iface; + struct audioformat *fp; + unsigned char *fmt; + unsigned int i, j, k, format; + + if (!(as = kmalloc(sizeof(struct usb_audiodev), GFP_KERNEL))) + return; + memset(as, 0, sizeof(struct usb_audiodev)); + init_waitqueue_head(&as->usbin.dma.wait); + init_waitqueue_head(&as->usbout.dma.wait); + spin_lock_init(&as->lock); + as->state = s; + as->usbin.interface = asifin; + as->usbout.interface = asifout; + /* search for input formats */ + if (asifin >= 0) { + iface = &config->interface[asifin]; + for (i = 0; i < iface->num_altsetting; i++) { + alts = &iface->altsetting[i]; + if (alts->bInterfaceClass != USB_CLASS_AUDIO || alts->bInterfaceSubClass != 2) + continue; + if (alts->bNumEndpoints < 1) { + printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u does not have an endpoint\n", + dev->devnum, asifin, i); + continue; + } + if ((alts->endpoint[0].bmAttributes & 0x03) != 0x01 || + !(alts->endpoint[0].bEndpointAddress & 0x80)) { + printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u first endpoint not isochronous in\n", + dev->devnum, asifin, i); + continue; + } + fmt = find_csinterface_descriptor(buffer, buflen, NULL, AS_GENERAL, asifin, i); + if (!fmt) { + printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n", + dev->devnum, asifin, i); + continue; + } + if (fmt[0] < 7 || fmt[6] != 0 || (fmt[5] != 1 && fmt[5] != 2)) { + printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u format not supported\n", + dev->devnum, asifin, i); + continue; + } + format = (fmt[5] == 2) ? (AFMT_U16_LE | AFMT_U8) : (AFMT_S16_LE | AFMT_S8); + fmt = find_csinterface_descriptor(buffer, buflen, NULL, FORMAT_TYPE, asifin, i); + if (!fmt) { + printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n", + dev->devnum, asifin, i); + continue; + } + if (fmt[0] < 8+3*(fmt[7] ? fmt[7] : 2) || fmt[3] != 1) { + printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not supported\n", + dev->devnum, asifin, i); + continue; + } + if (fmt[4] < 1 || fmt[4] > 2 || fmt[5] < 1 || fmt[5] > 2) { + printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u unsupported channels %u framesize %u\n", + dev->devnum, asifin, i, fmt[4], fmt[5]); + continue; + } + if (as->numfmtin >= MAXFORMATS) + continue; + fp = &as->fmtin[as->numfmtin++]; + if (fmt[5] == 2) + format &= (AFMT_U16_LE | AFMT_S16_LE); + else + format &= (AFMT_U8 | AFMT_S8); + if (fmt[4] == 2) + format |= AFMT_STEREO; + fp->format = format; + fp->altsetting = i; + fp->sratelo = fp->sratehi = fmt[8] | (fmt[9] << 8) | (fmt[10] << 16); + for (j = fmt[7] ? (fmt[7]-1) : 1; j > 0; j--) { + k = fmt[8+3*j] | (fmt[9+3*j] << 8) | (fmt[10+3*j] << 16); + if (k > fp->sratehi) + fp->sratehi = k; + if (k < fp->sratelo) + fp->sratelo = k; + } + printk(KERN_INFO "usb_audio: device %u interface %u altsetting %u: format 0x%08x sratelo %u sratehi %u\n", + dev->devnum, asifin, i, fp->format, fp->sratelo, fp->sratehi); + } + } + /* search for output formats */ + if (asifout >= 0) { + iface = &config->interface[asifout]; + for (i = 0; i < iface->num_altsetting; i++) { + alts = &iface->altsetting[i]; + if (alts->bInterfaceClass != USB_CLASS_AUDIO || alts->bInterfaceSubClass != 2) + continue; + if (alts->bNumEndpoints < 1) { + printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u does not have an endpoint\n", + dev->devnum, asifout, i); + continue; + } + if ((alts->endpoint[0].bmAttributes & 0x03) != 0x01 || + (alts->endpoint[0].bEndpointAddress & 0x80)) { + printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u first endpoint not isochronous out\n", + dev->devnum, asifout, i); + continue; + } + fmt = find_csinterface_descriptor(buffer, buflen, NULL, AS_GENERAL, asifout, i); + if (!fmt) { + printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n", + dev->devnum, asifout, i); + continue; + } + if (fmt[0] < 7 || fmt[6] != 0 || (fmt[5] != 1 && fmt[5] != 2)) { + printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u format not supported\n", + dev->devnum, asifout, i); + continue; + } + format = (fmt[5] == 2) ? (AFMT_U16_LE | AFMT_U8) : (AFMT_S16_LE | AFMT_S8); + fmt = find_csinterface_descriptor(buffer, buflen, NULL, FORMAT_TYPE, asifout, i); + if (!fmt) { + printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n", + dev->devnum, asifout, i); + continue; + } + if (fmt[0] < 8+3*(fmt[7] ? fmt[7] : 2) || fmt[3] != 1) { + printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not supported\n", + dev->devnum, asifout, i); + continue; + } + if (fmt[4] < 1 || fmt[4] > 2 || fmt[5] < 1 || fmt[5] > 2) { + printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u unsupported channels %u framesize %u\n", + dev->devnum, asifout, i, fmt[4], fmt[5]); + continue; + } + if (as->numfmtout >= MAXFORMATS) + continue; + fp = &as->fmtout[as->numfmtout++]; + if (fmt[5] == 2) + format &= (AFMT_U16_LE | AFMT_S16_LE); + else + format &= (AFMT_U8 | AFMT_S8); + if (fmt[4] == 2) + format |= AFMT_STEREO; + fp->format = format; + fp->altsetting = i; + fp->sratelo = fp->sratehi = fmt[8] | (fmt[9] << 8) | (fmt[10] << 16); + for (j = fmt[7] ? (fmt[7]-1) : 1; j > 0; j--) { + k = fmt[8+3*j] | (fmt[9+3*j] << 8) | (fmt[10+3*j] << 16); + if (k > fp->sratehi) + fp->sratehi = k; + if (k < fp->sratelo) + fp->sratelo = k; + } + printk(KERN_INFO "usb_audio: device %u interface %u altsetting %u: format 0x%08x sratelo %u sratehi %u\n", + dev->devnum, asifout, i, fp->format, fp->sratelo, fp->sratehi); + } + } + if (as->numfmtin == 0 && as->numfmtout == 0) { + kfree(as); + return; + } + if ((as->dev_audio = register_sound_dsp(&usb_audio_fops, -1)) < 0) { + printk(KERN_ERR "usb_audio: cannot register dsp\n"); + kfree(as); + return; + } + /* everything successful */ + list_add_tail(&as->list, &s->audiolist); +} + +struct consmixstate { + struct usb_audio_state *s; + unsigned char *buffer; + unsigned int buflen; + unsigned int ctrlif; + struct mixerchannel mixch[SOUND_MIXER_NRDEVICES]; + unsigned int nrmixch; + unsigned int mixchmask; + unsigned long unitbitmap[32/sizeof(unsigned long)]; + /* return values */ + unsigned int nrchannels; + unsigned int termtype; + unsigned int chconfig; +}; + +static struct mixerchannel *getmixchannel(struct consmixstate *state, unsigned int nr) +{ + struct mixerchannel *c; + + if (nr >= SOUND_MIXER_NRDEVICES) { + printk(KERN_ERR "usb_audio: invalid OSS mixer channel %u\n", nr); + return NULL; + } + if (!(state->mixchmask & (1 << nr))) { + printk(KERN_WARNING "usb_audio: OSS mixer channel %u already in use\n", nr); + return NULL; } -*/ + c = &state->mixch[state->nrmixch++]; + c->osschannel = nr; + state->mixchmask &= ~(1 << nr); + return c; +} + +static unsigned int getvolchannel(struct consmixstate *state) +{ + unsigned int u; + + if ((state->termtype & 0xff00) == 0x0000 && !(state->mixchmask & SOUND_MASK_VOLUME)) + return SOUND_MIXER_VOLUME; + if ((state->termtype & 0xff00) == 0x0100) { + if (!(state->mixchmask & SOUND_MASK_PCM)) + return SOUND_MIXER_PCM; + if (!(state->mixchmask & SOUND_MASK_ALTPCM)) + return SOUND_MIXER_ALTPCM; + } + if ((state->termtype & 0xff00) == 0x0200 && !(state->mixchmask & SOUND_MASK_MIC)) + return SOUND_MIXER_MIC; + if ((state->termtype & 0xff00) == 0x0300 && !(state->mixchmask & SOUND_MASK_SPEAKER)) + return SOUND_MIXER_SPEAKER; + if ((state->termtype & 0xff00) == 0x0300 && !(state->mixchmask & SOUND_MASK_SPEAKER)) + return SOUND_MIXER_SPEAKER; + if ((state->termtype & 0xff00) == 0x0500) { + if (!(state->mixchmask & SOUND_MASK_PHONEIN)) + return SOUND_MIXER_PHONEIN; + if (!(state->mixchmask & SOUND_MASK_PHONEOUT)) + return SOUND_MIXER_PHONEOUT; + } + if (state->termtype >= 0x710 && state->termtype <= 0x711 && !(state->mixchmask & SOUND_MASK_RADIO)) + return SOUND_MIXER_RADIO; + if (state->termtype >= 0x709 && state->termtype <= 0x70f && !(state->mixchmask & SOUND_MASK_VIDEO)) + return SOUND_MIXER_VIDEO; + u = ffs(state->mixchmask & (SOUND_MASK_LINE | SOUND_MASK_CD | SOUND_MASK_LINE1 | SOUND_MASK_LINE2 | SOUND_MASK_LINE3 | + SOUND_MASK_DIGITAL1 | SOUND_MASK_DIGITAL2 | SOUND_MASK_DIGITAL3)); + return u-1; +} + +static void prepmixch(struct consmixstate *state) +{ + struct usb_device *dev = state->s->usbdev; + struct mixerchannel *ch; + unsigned char buf[2]; + __s16 v1; + unsigned int v2, v3; + + if (!state->nrmixch || state->nrmixch > SOUND_MIXER_NRDEVICES) + return; + ch = &state->mixch[state->nrmixch-1]; + switch (ch->selector) { + case 0: /* mixer unit request */ + if (usb_control_msg(dev, usb_rcvdefctrl(dev), GET_MIN, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + (ch->chnum << 8) | 1, state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 2) + goto err; + ch->minval = buf[0] | (buf[1] << 8); + if (usb_control_msg(dev, usb_rcvdefctrl(dev), GET_MAX, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + (ch->chnum << 8) | 1, state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 2) + goto err; + ch->maxval = buf[0] | (buf[1] << 8); + v2 = ch->maxval - ch->minval; + if (!v2) + v2 = 1; + if (usb_control_msg(dev, usb_rcvdefctrl(dev), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + (ch->chnum << 8) | 1, state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 2) + goto err; + v1 = buf[0] | (buf[1] << 8); + v3 = v1 - ch->minval; + v3 = 100 * v3 / v2; + if (v3 > 100) + v3 = 100; + ch->value = v3; + if (ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)) { + if (usb_control_msg(dev, usb_rcvdefctrl(dev), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + ((ch->chnum + !!(ch->flags & MIXFLG_STEREOIN)) << 8) | (1 + !!(ch->flags & MIXFLG_STEREOOUT)), + state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 2) + goto err; + v1 = buf[0] | (buf[1] << 8); + v3 = v1 - ch->minval; + v3 = 100 * v3 / v2; + if (v3 > 100) + v3 = 100; + } + ch->value |= v3 << 8; + break; - list_add(&aud->list, &usb_audio_list); + /* various feature unit controls */ + case VOLUME_CONTROL: + if (usb_control_msg(dev, usb_rcvdefctrl(dev), GET_MIN, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 2) + goto err; + ch->minval = buf[0] | (buf[1] << 8); + if (usb_control_msg(dev, usb_rcvdefctrl(dev), GET_MAX, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 2) + goto err; + ch->maxval = buf[0] | (buf[1] << 8); + if (usb_control_msg(dev, usb_rcvdefctrl(dev), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 2) + goto err; + v1 = buf[0] | (buf[1] << 8); + v2 = ch->maxval - ch->minval; + v3 = v1 - ch->minval; + if (!v2) + v2 = 1; + v3 = 100 * v3 / v2; + if (v3 > 100) + v3 = 100; + ch->value = v3; + if (ch->chnum != 0) { + if (usb_control_msg(dev, usb_rcvdefctrl(dev), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + (ch->selector << 8) | (ch->chnum + 1), state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 2) + goto err; + v1 = buf[0] | (buf[1] << 8); + v3 = v1 - ch->minval; + v3 = 100 * v3 / v2; + if (v3 > 100) + v3 = 100; + } + ch->value |= v3 << 8; + break; - return 0; + case BASS_CONTROL: + case MID_CONTROL: + case TREBLE_CONTROL: + if (usb_control_msg(dev, usb_rcvdefctrl(dev), GET_MIN, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 1, HZ) < 1) + goto err; + ch->minval = buf[0] << 8; + if (usb_control_msg(dev, usb_rcvdefctrl(dev), GET_MAX, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 1, HZ) < 1) + goto err; + ch->maxval = buf[0] << 8; + if (usb_control_msg(dev, usb_rcvdefctrl(dev), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 1, HZ) < 1) + goto err; + v1 = buf[0] << 8; + v2 = ch->maxval - ch->minval; + v3 = v1 - ch->minval; + if (!v2) + v2 = 1; + v3 = 100 * v3 / v2; + if (v3 > 100) + v3 = 100; + ch->value = v3; + if (ch->chnum != 0) { + if (usb_control_msg(dev, usb_rcvdefctrl(dev), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + (ch->selector << 8) | (ch->chnum + 1), state->ctrlif | (ch->unitid << 8), buf, 1, HZ) < 1) + goto err; + v1 = buf[0] << 8; + v3 = v1 - ch->minval; + v3 = 100 * v3 / v2; + if (v3 > 100) + v3 = 100; + } + ch->value |= v3 << 8; + break; + + default: + goto err; + } + return; + + err: + printk(KERN_ERR "usb_audio: mixer request device %u if %u unit %u ch %u selector %u failed\n", + dev->devnum, state->ctrlif, ch->unitid, ch->chnum, ch->selector); + if (state->nrmixch) + state->nrmixch--; } -static void usb_audio_disconnect(struct usb_device *dev) + +static void usb_audio_recurseunit(struct consmixstate *state, unsigned char unitid); + +extern inline int checkmixbmap(unsigned char *bmap, unsigned char flg, unsigned int inidx, unsigned int numoch) +{ + unsigned int idx; + + idx = inidx*numoch; + if (!(bmap[idx >> 3] & (1 << (idx & 7)))) + return 0; + if (!(flg & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT))) + return 1; + idx = (inidx+!!(flg & MIXFLG_STEREOIN))*numoch+!!(flg & MIXFLG_STEREOOUT); + if (!(bmap[idx >> 3] & (1 << (idx & 7)))) + return 0; + return 1; +} + +static void usb_audio_mixerunit(struct consmixstate *state, unsigned char *mixer) +{ + unsigned int nroutch = mixer[5+mixer[4]]; + unsigned int chidx[SOUND_MIXER_NRDEVICES+1]; + unsigned int termt[SOUND_MIXER_NRDEVICES]; + unsigned char flg = (nroutch >= 2) ? MIXFLG_STEREOOUT : 0; + struct mixerchannel *ch; + unsigned int i; + + if (!mixer[4]) { + printk(KERN_ERR "usb_audio: unit %u invalid MIXER_UNIT descriptor\n", mixer[3]); + return; + } + if (mixer[4] > SOUND_MIXER_NRDEVICES) { + printk(KERN_ERR "usb_audio: mixer unit %u: too many input pins\n", mixer[3]); + return; + } + chidx[0] = 0; + for (i = 0; i < mixer[4]; i++) { + usb_audio_recurseunit(state, mixer[5+i]); + chidx[i+1] = chidx[i] + state->nrchannels; + termt[i] = state->termtype; + } + state->termtype = 0; + state->chconfig = mixer[6+mixer[4]] | (mixer[7+mixer[4]] << 8); + if (mixer[0] < 10+mixer[4]+((nroutch * chidx[mixer[4]] + 7) >> 3)) { + printk(KERN_ERR "usb_audio: unit %u invalid MIXER_UNIT descriptor (bitmap too small)\n", mixer[3]); + return; + } + for (i = 0; i < mixer[4]; i++) { + state->termtype = termt[i]; + if (chidx[i+1]-chidx[i] >= 2) { + flg |= MIXFLG_STEREOIN; + if (checkmixbmap(&mixer[9+mixer[4]], flg, chidx[i], nroutch)) { + ch = getmixchannel(state, getvolchannel(state)); + if (ch) { + ch->unitid = mixer[3]; + ch->selector = 0; + ch->chnum = chidx[i]+1; + ch->flags = flg; + prepmixch(state); + } + continue; + } + } + flg &= ~MIXFLG_STEREOIN; + if (checkmixbmap(&mixer[9+mixer[4]], flg, chidx[i], nroutch)) { + ch = getmixchannel(state, getvolchannel(state)); + if (ch) { + ch->unitid = mixer[3]; + ch->selector = 0; + ch->chnum = chidx[i]+1; + ch->flags = flg; + prepmixch(state); + } + } + } + state->termtype = 0; +} + +static void usb_audio_selectorunit(struct consmixstate *state, unsigned char *selector) { - struct usb_audio *aud = (struct usb_audio*) dev->private; + unsigned int chnum, i; - if (!aud) + if (!selector[4]) { + printk(KERN_ERR "usb_audio: unit %u invalid SELECTOR_UNIT descriptor\n", selector[3]); return; + } + usb_audio_recurseunit(state, selector[5]); + chnum = state->nrchannels; + for (i = 1; i < selector[4]; i++) { + usb_audio_recurseunit(state, selector[5+i]); + if (chnum != state->nrchannels) { + printk(KERN_ERR "usb_audio: selector unit %u: input pins with varying channel numbers\n", selector[3]); + state->termtype = 0; + state->chconfig = 0; + state->nrchannels = 0; + return; + } + } + state->termtype = 0; + state->chconfig = 0; +} - list_del(&aud->list); +/* in the future we might try to handle 3D etc. effect units */ - usb_release_irq(aud->dev, aud->irq_handle, aud->irqpipe); +static void usb_audio_processingunit(struct consmixstate *state, unsigned char *proc) +{ + unsigned int i; - kfree(aud); - dev->private = NULL; + for (i = 0; i < proc[6]; i++) + usb_audio_recurseunit(state, proc[7+i]); + state->nrchannels = proc[7+proc[6]]; + state->termtype = 0; + state->chconfig = proc[8+proc[6]] | (proc[9+proc[6]] << 8); } -int usb_audio_init(void) +static void usb_audio_featureunit(struct consmixstate *state, unsigned char *ftr) { - usb_register(&usb_audio_driver); + struct mixerchannel *ch; + unsigned short chftr, mchftr; + + usb_audio_recurseunit(state, ftr[4]); + if (state->nrchannels == 0) { + printk(KERN_ERR "usb_audio: feature unit %u source has no channels\n", ftr[3]); + return; + } + if (state->nrchannels > 2) + printk(KERN_WARNING "usb_audio: feature unit %u: OSS mixer interface does not support more than 2 channels\n", ftr[3]); + if (ftr[0] < 7+ftr[5]*(1+state->nrchannels)) { + printk(KERN_ERR "usb_audio: unit %u: invalid FEATURE_UNIT descriptor\n", ftr[3]); + return; + } + mchftr = ftr[6]; + chftr = ftr[6+ftr[5]]; + if (state->nrchannels > 1) + chftr &= ftr[6+2*ftr[5]]; + /* volume control */ + if (chftr & 2) { + ch = getmixchannel(state, getvolchannel(state)); + if (ch) { + ch->unitid = ftr[3]; + ch->selector = VOLUME_CONTROL; + ch->chnum = 1; + ch->flags = MIXFLG_STEREOIN | MIXFLG_STEREOOUT; + prepmixch(state); + } + } else if (mchftr & 2) { + ch = getmixchannel(state, getvolchannel(state)); + if (ch) { + ch->unitid = ftr[3]; + ch->selector = VOLUME_CONTROL; + ch->chnum = 0; + ch->flags = 0; + prepmixch(state); + } + } + /* bass control */ + if (chftr & 4) { + ch = getmixchannel(state, SOUND_MIXER_BASS); + if (ch) { + ch->unitid = ftr[3]; + ch->selector = BASS_CONTROL; + ch->chnum = 1; + ch->flags = MIXFLG_STEREOIN | MIXFLG_STEREOOUT; + prepmixch(state); + } + } else if (mchftr & 4) { + ch = getmixchannel(state, getvolchannel(state)); + if (ch) { + ch->unitid = ftr[3]; + ch->selector = BASS_CONTROL; + ch->chnum = 0; + ch->flags = 0; + prepmixch(state); + } + } + /* treble control */ + if (chftr & 16) { + ch = getmixchannel(state, SOUND_MIXER_TREBLE); + if (ch) { + ch->unitid = ftr[3]; + ch->selector = TREBLE_CONTROL; + ch->chnum = 1; + ch->flags = MIXFLG_STEREOIN | MIXFLG_STEREOOUT; + prepmixch(state); + } + } else if (mchftr & 16) { + ch = getmixchannel(state, getvolchannel(state)); + if (ch) { + ch->unitid = ftr[3]; + ch->selector = TREBLE_CONTROL; + ch->chnum = 0; + ch->flags = 0; + prepmixch(state); + } + } +} + +static void usb_audio_recurseunit(struct consmixstate *state, unsigned char unitid) +{ + unsigned char *p1; + + if (test_and_set_bit(unitid, &state->unitbitmap)) { + printk(KERN_ERR "usb_audio: mixer path recursion detected, unit %d!\n", unitid); + return; + } + p1 = find_audiocontrol_unit(state->buffer, state->buflen, NULL, unitid, state->ctrlif); + if (!p1) { + printk(KERN_ERR "usb_audio: unit %d not found!\n", unitid); + return; + } + state->nrchannels = 0; + state->termtype = 0; + state->chconfig = 0; + switch (p1[2]) { + case INPUT_TERMINAL: + if (p1[0] < 12) { + printk(KERN_ERR "usb_audio: unit %u: invalid INPUT_TERMINAL descriptor\n", unitid); + return; + } + state->nrchannels = p1[7]; + state->termtype = p1[4] | (p1[5] << 8); + state->chconfig = p1[8] | (p1[9] << 8); + return; + + case MIXER_UNIT: + if (p1[0] < 10 || p1[0] < 10+p1[4]) { + printk(KERN_ERR "usb_audio: unit %u: invalid MIXER_UNIT descriptor\n", unitid); + return; + } + usb_audio_mixerunit(state, p1); + return; + + case SELECTOR_UNIT: + if (p1[0] < 6 || p1[0] < 6+p1[4]) { + printk(KERN_ERR "usb_audio: unit %u: invalid SELECTOR_UNIT descriptor\n", unitid); + return; + } + usb_audio_selectorunit(state, p1); + return; + + case FEATURE_UNIT: + if (p1[0] < 7 || p1[0] < 7+p1[5]) { + printk(KERN_ERR "usb_audio: unit %u: invalid FEATURE_UNIT descriptor\n", unitid); + return; + } + usb_audio_featureunit(state, p1); + return; + + case PROCESSING_UNIT: + if (p1[0] < 13 || p1[0] < 13+p1[6] || p1[0] < 13+p1[6]+p1[11+p1[6]] || p1[0] < 13+p1[6]+p1[11+p1[6]]+p1[13+p1[6]+p1[11+p1[6]]]) { + printk(KERN_ERR "usb_audio: unit %u: invalid PROCESSING_UNIT descriptor\n", unitid); + return; + } + usb_audio_processingunit(state, p1); + return; + + case EXTENSION_UNIT: + if (p1[0] < 13 || p1[0] < 13+p1[6] || p1[0] < 13+p1[6]+p1[11+p1[6]]) { + printk(KERN_ERR "usb_audio: unit %u: invalid EXTENSION_UNIT descriptor\n", unitid); + return; + } + { + unsigned int i; + + for (i = 0; i < p1[6]; i++) + usb_audio_recurseunit(state, p1[7+i]); + } + state->nrchannels = p1[7+p1[6]]; + state->chconfig = p1[8+p1[6]] | (p1[9+p1[6]] << 8); + state->termtype = 0; + return; + + default: + printk(KERN_ERR "usb_audio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]); + return; + } +} + +static void usb_audio_constructmixer(struct usb_audio_state *s, unsigned char *buffer, unsigned int buflen, unsigned int ctrlif, unsigned char *oterm) +{ + struct usb_mixerdev *ms; + struct consmixstate state; + + memset(&state, 0, sizeof(state)); + state.s = s; + state.nrmixch = 0; + state.mixchmask = ~0; + state.buffer = buffer; + state.buflen = buflen; + state.ctrlif = ctrlif; + set_bit(oterm[3], &state.unitbitmap); /* mark terminal ID as visited */ + printk(KERN_INFO "usb_audio: constructing mixer for Terminal %u type 0x%04x\n", + oterm[3], oterm[4] | (oterm[5] << 8)); + usb_audio_recurseunit(&state, oterm[7]); + if (!state.nrmixch) { + printk(KERN_INFO "usb_audio: no mixer controls found for Terminal %u\n", oterm[3]); + return; + } + if (!(ms = kmalloc(sizeof(struct usb_mixerdev)+state.nrmixch*sizeof(struct mixerchannel), GFP_KERNEL))) + return; + memset(ms, 0, sizeof(struct usb_mixerdev)); + memcpy(&ms->ch, &state.mixch, state.nrmixch*sizeof(struct mixerchannel)); + ms->state = s; + ms->iface = ctrlif; + ms->numch = state.nrmixch; + if ((ms->dev_mixer = register_sound_mixer(&usb_mixer_fops, -1)) < 0) { + printk(KERN_ERR "usb_audio: cannot register mixer\n"); + kfree(ms); + return; + } + list_add_tail(&ms->list, &s->mixerlist); +} + +static int usb_audio_parsecontrol(struct usb_device *dev, unsigned char *buffer, unsigned int buflen, unsigned int ctrlif) +{ + struct usb_audio_state *s; + struct usb_config_descriptor *config = dev->actconfig; + struct usb_interface *iface; + unsigned char ifin[USB_MAXINTERFACES], ifout[USB_MAXINTERFACES]; + unsigned char *p1; + unsigned int i, j, numifin = 0, numifout = 0; + + if (!(s = kmalloc(sizeof(struct usb_audio_state), GFP_KERNEL))) + return -1; + memset(s, 0, sizeof(struct usb_audio_state)); + INIT_LIST_HEAD(&s->audiolist); + INIT_LIST_HEAD(&s->mixerlist); + s->usbdev = dev; + s->count = 1; + /* find audiocontrol interface */ + if (!(p1 = find_csinterface_descriptor(buffer, buflen, NULL, HEADER, ctrlif, -1))) { + printk(KERN_ERR "usb_audio: device %d audiocontrol interface %u no HEADER found\n", + dev->devnum, ctrlif); + goto ret; + } + if (p1[0] < 8 + p1[7]) { + printk(KERN_ERR "usb_audio: device %d audiocontrol interface %u HEADER error\n", + dev->devnum, ctrlif); + goto ret; + } + if (!p1[7]) + printk(KERN_INFO "usb_audio: device %d audiocontrol interface %u has no AudioStreaming and MidiStreaming interfaces\n", + dev->devnum, ctrlif); + for (i = 0; i < p1[7]; i++) { + j = p1[8+i]; + if (j >= config->bNumInterfaces) { + printk(KERN_ERR "usb_audio: device %d audiocontrol interface %u interface %u does not exist\n", + dev->devnum, ctrlif, j); + continue; + } + iface = &config->interface[j]; + if (iface->altsetting[0].bInterfaceClass != USB_CLASS_AUDIO) { + printk(KERN_ERR "usb_audio: device %d audiocontrol interface %u interface %u is not an AudioClass interface\n", + dev->devnum, ctrlif, j); + continue; + } + if (iface->altsetting[0].bInterfaceSubClass == 3) { + printk(KERN_INFO "usb_audio: device %d audiocontrol interface %u interface %u MIDIStreaming not supported\n", + dev->devnum, ctrlif, j); + continue; + } + if (iface->altsetting[0].bInterfaceSubClass != 2) { + printk(KERN_ERR "usb_audio: device %d audiocontrol interface %u interface %u invalid AudioClass subtype\n", + dev->devnum, ctrlif, j); + continue; + } + if (iface->num_altsetting < 2 || + iface->altsetting[0].bNumEndpoints > 0) { + printk(KERN_ERR "usb_audio: device %d audiocontrol interface %u altsetting 0 not zero bandwidth\n", + dev->devnum, ctrlif); + continue; + } + if (iface->altsetting[1].bNumEndpoints < 1) { + printk(KERN_ERR "usb_audio: device %d audiocontrol interface %u interface %u has no endpoint\n", + dev->devnum, ctrlif, j); + continue; + } + /* note: this requires the data endpoint to be ep0 and the optional sync + ep to be ep1, which seems to be the case */ + if (iface->altsetting[1].endpoint[0].bEndpointAddress & USB_DIR_IN) { + if (numifin < USB_MAXINTERFACES) + ifin[numifin++] = j; + } else { + if (numifout < USB_MAXINTERFACES) + ifout[numifout++] = j; + } + } + printk(KERN_INFO "usb_audio: device %d audiocontrol interface %u has %u input and %u output AudioStreaming interfaces\n", + dev->devnum, ctrlif, numifin, numifout); + for (i = 0; i < numifin && i < numifout; i++) + usb_audio_parsestreaming(s, buffer, buflen, ifin[i], ifout[i]); + for (j = i; j < numifin; j++) + usb_audio_parsestreaming(s, buffer, buflen, ifin[i], -1); + for (j = i; j < numifout; j++) + usb_audio_parsestreaming(s, buffer, buflen, -1, ifout[i]); + /* now walk through all OUTPUT_TERMINAL descriptors to search for mixers */ + p1 = find_csinterface_descriptor(buffer, buflen, NULL, OUTPUT_TERMINAL, ctrlif, -1); + while (p1) { + if (p1[0] >= 9) + usb_audio_constructmixer(s, buffer, buflen, ctrlif, p1); + p1 = find_csinterface_descriptor(buffer, buflen, p1, OUTPUT_TERMINAL, ctrlif, -1); + } + + ret: + if (list_empty(&s->audiolist) && list_empty(&s->mixerlist)) { + kfree(s); + return -1; + } + /* everything successful */ + dev->private = s; + down(&open_sem); + list_add_tail(&s->audiodev, &audiodevs); + up(&open_sem); + MOD_INC_USE_COUNT; return 0; } -/* - * Support functions for parsing - */ - -void usb_audio_interface(struct usb_interface_descriptor *interface, u8 *data) +/* we only care for the currently active configuration */ + +static int usb_audio_probe(struct usb_device *dev) { -#ifdef AUDIO_DEBUG - printk(KERN_DEBUG "usb_audio_interface.\n"); -#endif + struct usb_config_descriptor *config = dev->actconfig; + unsigned char *buffer; + unsigned char buf[8]; + unsigned int i, buflen; + int ret; + + for (i = 0; i < config->bNumInterfaces; i++) + if (config->interface[i].altsetting[0].bInterfaceClass == USB_CLASS_AUDIO && + config->interface[i].altsetting[0].bInterfaceSubClass == 1) /* audiocontrol interface found */ + goto audioctrlfound; + printk(KERN_DEBUG "usb_audio: vendor id 0x%04x, product id 0x%04x contains no AudioControl interface\n", + dev->descriptor.idVendor, dev->descriptor.idProduct); + return -1; + + audioctrlfound: + /* find which configuration number is active */ + for (i = 0; i < dev->descriptor.bNumConfigurations; i++) + if (dev->config+i == config) + goto configfound; + printk(KERN_ERR "usb_audio: cannot find active configuration number of device %d\n", dev->devnum); + return -1; + + configfound: + ret = usb_get_descriptor(dev, USB_DT_CONFIG, i, buf, 8); + if (ret) { + printk(KERN_ERR "usb_audio: cannot get first 8 bytes of config descriptor %d of device %d\n", i, dev->devnum); + return -1; + } + if (buf[1] != USB_DT_CONFIG || buf[0] < 9) { + printk(KERN_ERR "usb_audio: invalid config descriptor %d of device %d\n", i, dev->devnum); + return -1; + } + buflen = buf[2] | (buf[3] << 8); + if (!(buffer = kmalloc(buflen, GFP_KERNEL))) + return -1; + ret = usb_get_descriptor(dev, USB_DT_CONFIG, i, buffer, buflen); + if (ret) { + kfree(buffer); + printk(KERN_ERR "usb_audio: cannot get config descriptor %d of device %d\n", i, dev->devnum); + return -1; + } + /* find first audio control interface; we currently cannot handle more than one */ + for (i = 0; i < config->bNumInterfaces; i++) { + if (config->interface[i].altsetting[0].bInterfaceClass != USB_CLASS_AUDIO || + config->interface[i].altsetting[0].bInterfaceSubClass != 1) + continue; + /* audiocontrol interface found */ + if (!usb_audio_parsecontrol(dev, buffer, buflen, i)) + return 0; + } + return -1; } -void usb_audio_endpoint(struct usb_endpoint_descriptor *interface, u8 *data) + +/* a revoke facility would make things simpler */ + +static void usb_audio_disconnect(struct usb_device *dev) { -#ifdef AUDIO_DEBUG - printk(KERN_DEBUG "usb_audio_interface.\n"); + struct usb_audio_state *s = (struct usb_audio_state *)dev->private; + struct list_head *list; + struct usb_audiodev *as; + struct usb_mixerdev *ms; + + down(&open_sem); + list_del(&s->audiodev); + INIT_LIST_HEAD(&s->audiodev); + s->usbdev = NULL; + /* deregister all audio and mixer devices, so no new processes can open this device */ + for(list = s->audiolist.next; list != &s->audiolist; list = list->next) { + as = list_entry(list, struct usb_audiodev, list); + if (as->dev_audio >= 0) + unregister_sound_dsp(as->dev_audio); + as->dev_audio = -1; + } + for(list = s->mixerlist.next; list != &s->mixerlist; list = list->next) { + ms = list_entry(list, struct usb_mixerdev, list); + if (ms->dev_mixer >= 0) + unregister_sound_mixer(ms->dev_mixer); + } +#if 0 + if(aud->irq_handle) + usb_release_irq(dev, aud->irq_handle, aud->irqpipe); + aud->irq_handle = NULL; #endif + release(s); + wake_up(&open_wait); + dev->private = NULL; +} + +int usb_audio_init(void) +{ + usb_register(&usb_audio_driver); + return 0; } #ifdef MODULE @@ -156,4 +3462,3 @@ } #endif - diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/audio.h linux.ac/drivers/usb/audio.h --- linux.vanilla/drivers/usb/audio.h Thu Jan 1 01:00:00 1970 +++ linux.ac/drivers/usb/audio.h Mon Sep 20 15:52:50 1999 @@ -0,0 +1,116 @@ +#define USB_DT_CS_DEVICE 0x21 +#define USB_DT_CS_CONFIG 0x22 +#define USB_DT_CS_STRING 0x23 +#define USB_DT_CS_INTERFACE 0x24 +#define USB_DT_CS_ENDPOINT 0x25 + +#define CS_AUDIO_UNDEFINED 0x20 +#define CS_AUDIO_DEVICE 0x21 +#define CS_AUDIO_CONFIGURATION 0x22 +#define CS_AUDIO_STRING 0x23 +#define CS_AUDIO_INTERFACE 0x24 +#define CS_AUDIO_ENDPOINT 0x25 + +#define HEADER 0x01 +#define INPUT_TERMINAL 0x02 +#define OUTPUT_TERMINAL 0x03 +#define MIXER_UNIT 0x04 +#define SELECTOR_UNIT 0x05 +#define FEATURE_UNIT 0x06 +#define PROCESSING_UNIT 0x07 +#define EXTENSION_UNIT 0x08 + +#define AS_GENERAL 0x01 +#define FORMAT_TYPE 0x02 +#define FORMAT_SPECIFIC 0x03 + +#define EP_GENERAL 0x01 + +#define MAX_CHAN 9 +#define MAX_FREQ 16 +#define MAX_IFACE 8 +#define MAX_FORMAT 8 +#define MAX_ALT 8 + +struct usb_audio_terminal +{ + u8 flags; + u8 assoc; + u16 type; /* Mic etc */ + u8 channels; + u8 source; + u16 chancfg; +}; + +struct usb_audio_format +{ + u8 type; + u8 channels; + u8 num_freq; + u8 sfz; + u8 bits; + u16 freq[MAX_FREQ]; +}; + +struct usb_audio_interface +{ + u8 terminal; + u8 delay; + u16 num_formats; + u16 format_type; + u8 flags; + u8 idleconf; /* Idle config */ +#define AU_IFACE_FOUND 1 + struct usb_audio_format format[MAX_FORMAT]; +}; + +struct usb_audio_device +{ + struct list_head list; + u8 mixer; + u8 selector; + void *irq_handle; + u8 num_channels; + u8 num_dsp_iface; + u8 channel_map[MAX_CHAN]; + struct usb_audio_terminal terminal[MAX_CHAN]; + struct usb_audio_interface interface[MAX_IFACE][MAX_ALT]; +}; + + + +/* Audio Class specific Request Codes */ + +#define SET_CUR 0x01 +#define GET_CUR 0x81 +#define SET_MIN 0x02 +#define GET_MIN 0x82 +#define SET_MAX 0x03 +#define GET_MAX 0x83 +#define SET_RES 0x04 +#define GET_RES 0x84 +#define SET_MEM 0x05 +#define GET_MEM 0x85 +#define GET_STAT 0xff + +/* Terminal Control Selectors */ + +#define COPY_PROTECT_CONTROL 0x01 + +/* Feature Unit Control Selectors */ + +#define MUTE_CONTROL 0x01 +#define VOLUME_CONTROL 0x02 +#define BASS_CONTROL 0x03 +#define MID_CONTROL 0x04 +#define TREBLE_CONTROL 0x05 +#define GRAPHIC_EQUALIZER_CONTROL 0x06 +#define AUTOMATIC_GAIN_CONTROL 0x07 +#define DELAY_CONTROL 0x08 +#define BASS_BOOST_CONTROL 0x09 +#define LOUDNESS_CONTROL 0x0a + +/* Endpoint Control Selectors */ + +#define SAMPLING_FREQ_CONTROL 0x01 +#define PITCH_CONTROL 0x02 diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/cpia.c linux.ac/drivers/usb/cpia.c --- linux.vanilla/drivers/usb/cpia.c Sat Sep 11 00:54:11 1999 +++ linux.ac/drivers/usb/cpia.c Mon Sep 20 17:00:15 1999 @@ -28,452 +28,509 @@ #define CPIA_DEBUG /* Gobs of debugging info */ +/* Video Size 384 x 288 x 3 bytes for RGB */ #define MAX_FRAME_SIZE (384 * 288 * 3) /*******************************/ /* Memory management functions */ /*******************************/ -/* convert virtual user memory address to physical address */ -/* (virt_to_phys only works for kmalloced kernel memory) */ +#define MDEBUG(x) do { } while(0) /* Debug memory management */ -static inline unsigned long uvirt_to_phys(unsigned long adr) +/* Given PGD from the address space's page table, return the kernel + * virtual mapping of the physical memory mapped at ADR. + */ +static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr) { - pgd_t *pgd; - pmd_t *pmd; - pte_t *ptep, pte; - - pgd = pgd_offset(current->mm, adr); - if (pgd_none(*pgd)) - return 0; - pmd = pmd_offset(pgd, adr); - if (pmd_none(*pmd)) - return 0; - ptep = pte_offset(pmd, adr/*&(~PGDIR_MASK)*/); - pte = *ptep; - if(pte_present(pte)) - return - virt_to_phys((void *)(pte_page(pte)|(adr&(PAGE_SIZE-1)))); - return 0; + unsigned long ret = 0UL; + pmd_t *pmd; + pte_t *ptep, pte; + + if (!pgd_none(*pgd)) { + pmd = pmd_offset(pgd, adr); + if (!pmd_none(*pmd)) { + ptep = pte_offset(pmd, adr); + pte = *ptep; + if (pte_present(pte)) + ret = (pte_page(pte) | (adr & (PAGE_SIZE-1))); + } + } + MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret)); + return ret; } -static inline unsigned long uvirt_to_bus(unsigned long adr) +static inline unsigned long uvirt_to_bus(unsigned long adr) { - return virt_to_bus(phys_to_virt(uvirt_to_phys(adr))); -} + unsigned long kva, ret; -/* convert virtual kernel memory address to physical address */ -/* (virt_to_phys only works for kmalloced kernel memory) */ + kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr); + ret = virt_to_bus((void *)kva); + MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret)); + return ret; +} -static inline unsigned long kvirt_to_phys(unsigned long adr) +static inline unsigned long kvirt_to_bus(unsigned long adr) { - return uvirt_to_phys(VMALLOC_VMADDR(adr)); + unsigned long va, kva, ret; + + va = VMALLOC_VMADDR(adr); + kva = uvirt_to_kva(pgd_offset_k(va), va); + ret = virt_to_bus((void *)kva); + MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret)); + return ret; } -static inline unsigned long kvirt_to_bus(unsigned long adr) +/* Here we want the physical address of the memory. + * This is used when initializing the contents of the + * area and marking the pages as reserved. + */ +static inline unsigned long kvirt_to_pa(unsigned long adr) { - return uvirt_to_bus(VMALLOC_VMADDR(adr)); -} + unsigned long va, kva, ret; + va = VMALLOC_VMADDR(adr); + kva = uvirt_to_kva(pgd_offset_k(va), va); + ret = __pa(kva); + MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret)); + return ret; +} -static void * rvmalloc(unsigned long size) +static void *rvmalloc(unsigned long size) { - void * mem; + void *mem; unsigned long adr, page; - + + /* Round it off to PAGE_SIZE */ size += (PAGE_SIZE - 1); size &= ~(PAGE_SIZE - 1); - mem=vmalloc(size); - if (mem) - { - memset(mem, 0, size); /* Clear the ram out, no junk to the user */ - adr=(unsigned long) mem; - while (size > 0) - { - page = kvirt_to_phys(adr); - mem_map_reserve(MAP_NR(phys_to_virt(page))); - adr+=PAGE_SIZE; - if (size > PAGE_SIZE) - size-=PAGE_SIZE; - else - size=0; - } + mem = vmalloc(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) { + page = kvirt_to_pa(adr); + mem_map_reserve(MAP_NR(__va(page))); + adr += PAGE_SIZE; + if (size > PAGE_SIZE) + size -= PAGE_SIZE; + else + size = 0; } + return mem; } -static void rvfree(void * mem, unsigned long size) +static void rvfree(void *mem, unsigned long size) { unsigned long adr, page; - + + if (!mem) + return; + size += (PAGE_SIZE - 1); size &= ~(PAGE_SIZE - 1); - if (mem) - { - adr=(unsigned long) mem; - while (size > 0) - { - page = kvirt_to_phys(adr); - mem_map_unreserve(MAP_NR(phys_to_virt(page))); - adr+=PAGE_SIZE; - if (size > PAGE_SIZE) - size-=PAGE_SIZE; - else - size=0; - } - vfree(mem); + adr=(unsigned long) mem; + while (size > 0) { + page = kvirt_to_pa(adr); + mem_map_unreserve(MAP_NR(__va(page))); + adr += PAGE_SIZE; + if (size > PAGE_SIZE) + size -= PAGE_SIZE; + else + size = 0; } + vfree(mem); } -int usb_cpia_get_version(struct usb_device *dev, void *buf) +static int usb_cpia_get_version(struct usb_device *dev, void *buf) { - devrequest dr; - - dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE) | 0x80; - dr.request = USB_REQ_CPIA_GET_VERSION; - dr.value = 0; - dr.index = 0; - dr.length = 4; - - return dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, buf, 4); + return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + USB_REQ_CPIA_GET_VERSION, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, 0, buf, 4, HZ); } -int usb_cpia_get_pnp_id(struct usb_device *dev, void *buf) +#ifdef NOTUSED +static int usb_cpia_get_pnp_id(struct usb_device *dev, void *buf) { - devrequest dr; - - dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE) | 0x80; - dr.request = USB_REQ_CPIA_GET_PNP_ID; - dr.value = 0; - dr.index = 0; - dr.length = 6; - - return dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, buf, 6); + return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + USB_REQ_CPIA_GET_PNP_ID, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, 0, buf, 6, HZ); } +#endif -int usb_cpia_get_camera_status(struct usb_device *dev, void *buf) +#ifdef NOTUSED +static int usb_cpia_get_camera_status(struct usb_device *dev, void *buf) { - devrequest dr; - - dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE) | 0x80; - dr.request = USB_REQ_CPIA_GET_CAMERA_STATUS; - dr.value = 0; - dr.index = 0; - dr.length = 8; - - return dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, buf, 8); + return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + USB_REQ_CPIA_GET_CAMERA_STATUS, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, 0, buf, 8, HZ); } +#endif -int usb_cpia_goto_hi_power(struct usb_device *dev) +static int usb_cpia_goto_hi_power(struct usb_device *dev) { - devrequest dr; - - dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE); - dr.request = USB_REQ_CPIA_GOTO_HI_POWER; - dr.value = 0; - dr.index = 0; - dr.length = 0; - - return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); + return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_CPIA_GOTO_HI_POWER, USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, 0, NULL, 0, HZ); } -int usb_cpia_get_vp_version(struct usb_device *dev, void *buf) +static int usb_cpia_get_vp_version(struct usb_device *dev, void *buf) { - devrequest dr; - - dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE); - dr.request = USB_REQ_CPIA_GET_VP_VERSION; - dr.value = 0; - dr.index = 0; - dr.length = 4; - - return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, buf, 4); + return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + USB_REQ_CPIA_GET_VP_VERSION, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, 0, buf, 4, HZ); } -int usb_cpia_set_sensor_fps(struct usb_device *dev, int sensorbaserate, int sensorclkdivisor) +static int usb_cpia_set_sensor_fps(struct usb_device *dev, int sensorbaserate, int sensorclkdivisor) { - devrequest dr; - - dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE); - dr.request = USB_REQ_CPIA_SET_SENSOR_FPS; - dr.value = (sensorclkdivisor << 8) + sensorbaserate; - dr.index = 0; - dr.length = 0; - - return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); + return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_CPIA_SET_SENSOR_FPS, + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + (sensorbaserate << 8) + sensorclkdivisor, 0, NULL, 0, HZ); } -int usb_cpia_grab_frame(struct usb_device *dev, int streamstartline) +static int usb_cpia_grab_frame(struct usb_device *dev, int streamstartline) { - devrequest dr; - - dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE); - dr.request = USB_REQ_CPIA_GRAB_FRAME; - dr.value = streamstartline << 8; - dr.index = 0; - dr.length = 0; - - return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); + return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_CPIA_GRAB_FRAME, USB_TYPE_VENDOR | USB_RECIP_DEVICE, + streamstartline << 8, 0, NULL, 0, HZ); } -int usb_cpia_upload_frame(struct usb_device *dev, int forceupload) +static int usb_cpia_upload_frame(struct usb_device *dev, int forceupload) { - devrequest dr; - - dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE); - dr.request = USB_REQ_CPIA_UPLOAD_FRAME; - dr.value = forceupload; - dr.index = 0; - dr.length = 0; - - return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); + return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_CPIA_UPLOAD_FRAME, + USB_TYPE_VENDOR | USB_RECIP_DEVICE, forceupload, 0, NULL, 0, HZ); } -int usb_cpia_set_grab_mode(struct usb_device *dev, int continuousgrab) +static int usb_cpia_set_grab_mode(struct usb_device *dev, int continuousgrab) { - devrequest dr; - - dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE); - dr.request = USB_REQ_CPIA_SET_GRAB_MODE; - dr.value = continuousgrab; - dr.index = 0; - dr.length = 0; - - return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); + return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_CPIA_SET_GRAB_MODE, + USB_TYPE_VENDOR | USB_RECIP_DEVICE, continuousgrab, + 0, NULL, 0, HZ); } -int usb_cpia_set_format(struct usb_device *dev, int size, int subsample, int order) +static int usb_cpia_set_format(struct usb_device *dev, int size, int subsample, int order) { - devrequest dr; - - dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE); - dr.request = USB_REQ_CPIA_SET_FORMAT; - dr.value = (subsample << 8) + size; - dr.index = order; - dr.length = 0; - - return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); + return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_CPIA_SET_FORMAT, + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + (subsample << 8) + size, order, NULL, 0, HZ); } -int usb_cpia_set_compression(struct usb_device *dev, int compmode, int decimation) +static int usb_cpia_set_roi(struct usb_device *dev, int colstart, int colend, int rowstart, int rowend) { - devrequest dr; - - dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE); - dr.request = USB_REQ_CPIA_SET_COMPRESSION; - dr.value = (decimation << 8) + compmode; - dr.index = 0; - dr.length = 0; - - return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); + return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_CPIA_SET_ROI, + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + (colend << 8) + colstart, (rowend << 8) + rowstart, + NULL, 0, HZ); } -int usb_cpia_initstreamcap(struct usb_device *dev, int skipframes, int streamstartline) +static int usb_cpia_set_compression(struct usb_device *dev, int compmode, int decimation) { - devrequest dr; - - dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE); - dr.request = USB_REQ_CPIA_INIT_STREAM_CAP; - dr.value = (streamstartline << 8) + skipframes; - dr.index = 0; - dr.length = 0; - - return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); + return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_CPIA_SET_COMPRESSION, + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + (decimation << 8) + compmode, 0, NULL, 0, HZ); } -int usb_cpia_finistreamcap(struct usb_device *dev) +#ifdef NOTUSED +static int usb_cpia_initstreamcap(struct usb_device *dev, int skipframes, int streamstartline) { - devrequest dr; - - dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE); - dr.request = USB_REQ_CPIA_FINI_STREAM_CAP; - dr.value = 0; - dr.index = 0; - dr.length = 0; - - return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); + return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_CPIA_INIT_STREAM_CAP, + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + (streamstartline << 8) + skipframes, 0, NULL, 0, HZ); } -int usb_cpia_startstreamcap(struct usb_device *dev) +static int usb_cpia_finistreamcap(struct usb_device *dev) { - devrequest dr; - - dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE); - dr.request = USB_REQ_CPIA_START_STREAM_CAP; - dr.value = 0; - dr.index = 0; - dr.length = 0; - - return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); + return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_CPIA_FINI_STREAM_CAP, + USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, 0, NULL, 0, HZ); } -int usb_cpia_endstreamcap(struct usb_device *dev) +static int usb_cpia_startstreamcap(struct usb_device *dev) { - devrequest dr; - - dr.requesttype = (USB_TYPE_VENDOR | USB_RECIP_DEVICE); - dr.request = USB_REQ_CPIA_END_STREAM_CAP; - dr.value = 0; - dr.index = 0; - dr.length = 0; + return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_CPIA_START_STREAM_CAP, + USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, 0, NULL, 0, HZ); +} - return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); +static int usb_cpia_endstreamcap(struct usb_device *dev) +{ + return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_CPIA_END_STREAM_CAP, + USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, 0, NULL, 0, HZ); } +#endif /* How much data is left in the scratch buf? */ #define scratch_left(x) (cpia->scratchlen - (int)((char *)x - (char *)cpia->scratch)) static void cpia_parse_data(struct usb_cpia *cpia) { + struct cpia_frame *frame, *pframe; unsigned char *data = cpia->scratch; unsigned long l; - int done; - done = 0; - while (!done && scratch_left(data)) { - switch (cpia->state) { + frame = &cpia->frame[cpia->curframe]; + pframe = &cpia->frame[(cpia->curframe - 1 + CPIA_NUMFRAMES) % CPIA_NUMFRAMES]; + + while (1) { + if (!scratch_left(data)) + goto out; + + switch (frame->scanstate) { case STATE_SCANNING: { - unsigned char *begin = data; + struct cpia_frame_header *header; /* We need atleast 2 bytes for the magic value */ - if (scratch_left(data) < 2) { - done = 1; - break; - } + if (scratch_left(data) < 2) + goto out; + + header = (struct cpia_frame_header *)data; - /* 0x1968 is magic */ - printk("header: %X\n", (*data << 8) + *(data + 1)); - if ((*data == 0x19) && (*(data + 1) == 0x68)) { - cpia->state = STATE_HEADER; - printk("moving to header\n"); + if (be16_to_cpup(&header->magic) == CPIA_MAGIC) { + frame->scanstate = STATE_HEADER; break; } /* Woops, lost the header, find the end of the frame */ - if (scratch_left(data) < 4) { - done = 1; - break; - } + if (scratch_left(data) < 4) + goto out; - printk("Scanning for end of frame\n"); + /* See if we found the end of the frame */ while (scratch_left(data) >= 4) { - if ((*data == 0xFF) && - (*(data + 1) == 0xFF) && - (*(data + 2) == 0xFF) && - (*(data + 3) == 0xFF)) { + if (*((__u32 *)data) == 0xFFFFFFFF) { +printk("found end of frame\n"); data += 4; - break; +goto error; } data++; } -#ifdef CPIA_DEBUG - printk("scan: scanned %d bytes\n", data-begin); -#endif break; } case STATE_HEADER: /* We need atleast 64 bytes for the header */ - if (scratch_left(data) < 64) { - done = 1; - break; - } + if (scratch_left(data) < + sizeof(struct cpia_frame_header)) + goto out; + + memcpy(&frame->header, data, + sizeof(struct cpia_frame_header)); + /* Skip over the header */ + data += sizeof(struct cpia_frame_header); + + frame->hdrwidth = (frame->header.col_end - + frame->header.col_start) * 8; + frame->hdrheight = (frame->header.row_end - + frame->header.row_start) * 4; #ifdef CPIA_DEBUG - printk("header: framerate %d\n", data[41]); + printk("cpia: frame size %dx%d\n", + frame->hdrwidth, frame->hdrheight); + printk("cpia: frame %scompressed\n", + frame->header.comp_enable ? "" : "not "); #endif - data += 64; + frame->scanstate = STATE_LINES; + frame->curline = 0; - cpia->state = STATE_LINES; - break; case STATE_LINES: { - unsigned char *begin = data; - int found = 0; - - while (scratch_left(data)) { - if (*data == 0xFD) { - data++; - found = 1; - break; - } else if ((*data == 0xFF) && - (scratch_left(data) >= 3) && - (*(data + 1) == 0xFF) && - (*(data + 2) == 0xFF) && - (*(data + 3) == 0xFF)) { - data += 4; - cpia->curline = 144; - found = 1; - break; - } - - data++; + unsigned char *f, *end; + unsigned int len; + int i; + int y, u, y1, v, r, g, b; + + /* We want atleast 2 bytes for the length */ + if (scratch_left(data) < 2) + goto out; + + /* Grab the length */ + len = data[0] + (data[1] << 8); + +printk("line %d, %d bytes long\n", frame->curline, len); + /* Check to make sure it's nothing outrageous */ + if (len > (frame->hdrwidth * 2) + 1) { + printk(KERN_INFO "cpia: bad length, resynching\n"); + goto error; } - if (data-begin == 355 && cpia->frame[cpia->curframe].width != 64) { - int i; - char *f = cpia->frame[cpia->curframe].data, *b = begin; - - b += 2; - f += (cpia->frame[cpia->curframe].width * 3) * cpia->curline; - - for (i = 0; i < 176; i++) - f[(i * 3) + 0] = - f[(i * 3) + 1] = - f[(i * 3) + 2] = - b[(i * 2)]; + /* Make sure there's enough data for the entire line */ + if (scratch_left(data + 2) < len) + goto out; + + /* Skip over the length */ + data += 2; + + /* Is the end of the line there */ + if (data[len - 1] != 0xFD) { + printk(KERN_INFO "cpia: lost synch\n"); +end = data + len - 1 - 4; +printk("%02X %02X %02X %02X %02X %02X %02X %02X\n", +end[0], end[1], +end[2], end[3], +end[4], end[5], +end[6], end[7]); + goto error; } - if (found) { - cpia->curline++; - if (cpia->curline >= 144) { - wake_up(&cpia->wq); - cpia->state = STATE_SCANNING; - cpia->curline = 0; - cpia->curframe = -1; - done = 1; + /* Start at the beginning */ + end = data + len - 1; + + f = frame->data + (frame->width * 3 * frame->curline); + + if (frame->header.comp_enable) { + unsigned char *fp; + + /* We use the previous frame as a reference */ + fp = pframe->data + + (frame->width * 3 * frame->curline); + + while (data < end) { + if (*data & 1) { + /* Compress RLE data */ + i = *data >> 1; + memcpy(f, fp, i * 3); + f += (i * 3); + fp += (i * 3); + data++; + } else { + /* Raw data */ + +#define LIMIT(x) ((((x)>0xffffff)?0xff0000:(((x)<=0xffff)?0:(x)&0xff0000))>>16) + +y = *data++ - 16; +u = *data++ - 128; +y1 = *data++ - 16; +v = *data++ - 128; +r = 104635 * v; +g = -25690 * u + -53294 * v; +b = 132278 * u; +y *= 76310; +y1 *= 76310; +*f++ = LIMIT(b + y); *f++ = LIMIT(g + y); *f++ = LIMIT(r + y); +*f++ = LIMIT(b + y1); *f++ = LIMIT(g + y1); *f++ = LIMIT(r + y1); + fp += 6; +/* + f[0] = f[1] = f[2] = *data; + f += 3; + data += 2; + fp += 3; +*/ + } } } else { - data = begin; - done = 1; + /* Raw data */ + while (data < end) { +y = *data++ - 16; +u = *data++ - 128; +y1 = *data++ - 16; +v = *data++ - 128; +r = 104635 * v; +g = -25690 * u + -53294 * v; +b = 132278 * u; +y *= 76310; +y1 *= 76310; +*f++ = LIMIT(b + y); *f++ = LIMIT(g + y); *f++ = LIMIT(r + y); +*f++ = LIMIT(b + y1); *f++ = LIMIT(g + y1); *f++ = LIMIT(r + y1); + } } - + +#ifdef CPIA_DEBUG + /* Make sure we found the end correctly */ + if (*data != 0xFD) + printk("cpia: missed end!\n"); +#endif + + /* Skip the last byte */ + data++; + + if (++frame->curline >= frame->hdrheight) + goto nextframe; + break; } } } +nextframe: + if (scratch_left(data) >= 4 && *((__u32 *)data) == 0xFFFFFFFF) { + data += 4; +printk("end of frame found normally\n"); +} + + frame->grabstate = FRAME_DONE; + cpia->curframe = -1; + + /* This will cause the process to request another frame */ + if (waitqueue_active(&frame->wq)) + wake_up_interruptible(&frame->wq); + + goto out; + +error: + frame->grabstate = FRAME_ERROR; + cpia->curframe = -1; + cpia->compress = 0; + + /* This will cause the process to request another frame */ + if (waitqueue_active(&frame->wq)) + wake_up_interruptible(&frame->wq); + +out: +printk("scanned %d bytes, %d left\n", data - cpia->scratch, scratch_left(data)); /* Grab the remaining */ l = scratch_left(data); memmove(cpia->scratch, data, l); - cpia->scratchlen = l; } /* - * For the moment there is no actual data compression (making blocks - * of data contiguous). This just checks the "frames" array for errors. + * Make all of the blocks of data contiguous */ -static int cpia_compress_isochronous(struct usb_isoc_desc *isodesc) +static int cpia_compress_isochronous(struct usb_cpia *cpia, struct usb_isoc_desc *isodesc) { - char *data = isodesc->data; + unsigned char *cdata, *data; int i, totlen = 0; + cdata = isodesc->data; + data = cpia->scratch + cpia->scratchlen; for (i = 0; i < isodesc->frame_count; i++) { - int n = isodesc->frames [i].frame_length; - int st = isodesc->frames [i].frame_status; - + int n = isodesc->frames[i].frame_length; #ifdef CPIA_DEBUG - /* Debugging */ + int st = isodesc->frames[i].frame_status; + if (st) printk(KERN_DEBUG "cpia data error: [%d] len=%d, status=%X\n", i, n, st); #endif + if ((cpia->scratchlen + n) > SCRATCH_BUF_SIZE) { + printk(KERN_ERR "cpia: scratch buf overflow!\n"); + return 0; + } + + if (n) + memmove(data, cdata, n); + data += n; + totlen += n; + cpia->scratchlen += n; + cdata += isodesc->frame_size; } return totlen; @@ -481,157 +538,114 @@ static int cpia_isoc_irq(int status, void *__buffer, int len, void *dev_id) { - struct usb_cpia *cpia = dev_id; - struct usb_device *dev = cpia->dev; + struct usb_cpia *cpia = (struct usb_cpia *)dev_id; struct cpia_sbuf *sbuf; int i; - char *p; if (!cpia->streaming) { printk("oops, not streaming, but interrupt\n"); return 0; } - if (cpia->curframe < 0) { - if (cpia->frame[0].state == FRAME_READY) { - cpia->curframe = 0; - cpia->frame[0].state = FRAME_GRABBING; -#ifdef CPIA_DEBUG - printk("capturing to frame 0\n"); -#endif - } else if (cpia->frame[1].state == FRAME_READY) { - cpia->curframe = 1; - cpia->frame[1].state = FRAME_GRABBING; -#ifdef CPIA_DEBUG - printk("capturing to frame 1\n"); -#endif -#ifdef CPIA_DEBUG - } else - printk("no frame available\n"); -#else - } -#endif - } - - sbuf = &cpia->sbuf[cpia->receivesbuf]; - + sbuf = &cpia->sbuf[cpia->cursbuf]; usb_kill_isoc(sbuf->isodesc); - /* Do something to it now */ - sbuf->len = cpia_compress_isochronous(sbuf->isodesc); + /* Copy the data received into our scratch buffer */ + len = cpia_compress_isochronous(cpia, sbuf->isodesc); -#ifdef CPIA_DEBUG - if (sbuf->len) - printk("%d bytes received\n", sbuf->len); -#endif +printk("%d bytes received\n", len); + /* If we don't have a frame we're current working on, complain */ + if (len) { + if (cpia->curframe < 0) + printk("cpia: received data, but no frame available\n"); + else + cpia_parse_data(cpia); + } - if (sbuf->len && cpia->curframe >= 0) { - if (sbuf->len > (SCRATCH_BUF_SIZE - cpia->scratchlen)) { - printk("overflow!\n"); - return 0; - } - memcpy(cpia->scratch + cpia->scratchlen, sbuf->data, sbuf->len); - cpia->scratchlen += sbuf->len; + for (i = 0; i < FRAMES_PER_DESC; i++) + sbuf->isodesc->frames[i].frame_length = FRAME_SIZE_PER_DESC; - cpia_parse_data(cpia); - } + /* Move to the next sbuf */ + cpia->cursbuf = (cpia->cursbuf + 1) % CPIA_NUMSBUF; /* Reschedule this block of Isochronous desc */ - /* - usb_run_isoc(sbuf->isodesc, NULL); - */ -/* - usb_schedule_isochronous(dev, sbuf->isodesc, cpia->sbuf[(cpia->receivesbuf + 2) % 3].isodesc); -*/ - - /* Move to the next one */ - cpia->receivesbuf = (cpia->receivesbuf + 1) % 3; + usb_run_isoc(sbuf->isodesc, cpia->sbuf[cpia->cursbuf].isodesc); - return 1; + return -1; } -int cpia_init_isoc(struct usb_cpia *cpia) +static int cpia_init_isoc(struct usb_cpia *cpia) { struct usb_device *dev = cpia->dev; struct usb_isoc_desc *id; int fx, err; - cpia->receivesbuf = 0; - + cpia->curframe = -1; + cpia->cursbuf = 0; cpia->scratchlen = 0; - cpia->curline = 0; - cpia->state = STATE_SCANNING; - /* ALT_ISOC is only doing double-buffering, not triple. */ - err = usb_init_isoc (dev, usb_rcvisocpipe (dev, 1), FRAMES_PER_DESC, cpia, - &cpia->sbuf[0].isodesc); - if (err) - printk ("cpia_init_isoc: usb_init_isoc() ret. %d\n", err); - err = usb_init_isoc (dev, usb_rcvisocpipe (dev, 1), FRAMES_PER_DESC, cpia, - &cpia->sbuf[1].isodesc); - if (err) - printk ("cpia_init_isoc: usb_init_isoc() ret. %d\n", err); + /* We double buffer the Iso lists */ + err = usb_init_isoc(dev, usb_rcvisocpipe(dev, 1), FRAMES_PER_DESC, + cpia, &cpia->sbuf[0].isodesc); + if (err) { + printk(KERN_ERR "cpia_init_isoc: usb_init_isoc() ret %d\n", + err); + return -ENOMEM; + } - if (!cpia->sbuf[0].isodesc || !cpia->sbuf[1].isodesc) { - if (cpia->sbuf[0].isodesc) - usb_free_isoc (cpia->sbuf[0].isodesc); - if (cpia->sbuf[1].isodesc) - usb_free_isoc (cpia->sbuf[1].isodesc); + err = usb_init_isoc(dev, usb_rcvisocpipe(dev, 1), FRAMES_PER_DESC, + cpia, &cpia->sbuf[1].isodesc); + if (err) { + printk(KERN_ERR "cpia_init_isoc: usb_init_isoc() ret %d\n", + err); + usb_free_isoc (cpia->sbuf[0].isodesc); return -ENOMEM; } -#if 0 - cpia->sbuf[0].isodesc = usb_allocate_isochronous(dev, usb_rcvisocpipe(dev,1), cpia->sbuf[0].data, STREAM_BUF_SIZE, 960, cpia_isoc_irq, cpia); - cpia->sbuf[1].isodesc = usb_allocate_isochronous(dev, usb_rcvisocpipe(dev,1), cpia->sbuf[1].data, STREAM_BUF_SIZE, 960, cpia_isoc_irq, cpia); - cpia->sbuf[2].isodesc = usb_allocate_isochronous(dev, usb_rcvisocpipe(dev,1), cpia->sbuf[2].data, STREAM_BUF_SIZE, 960, cpia_isoc_irq, cpia); -#endif #ifdef CPIA_DEBUG printk("isodesc[0] @ %p\n", cpia->sbuf[0].isodesc); printk("isodesc[1] @ %p\n", cpia->sbuf[1].isodesc); -#if 0 - printk("isodesc[2] @ %p\n", cpia->sbuf[2].isodesc); -#endif #endif /* Set the Isoc. desc. parameters. */ /* First for desc. [0] */ - id = cpia->sbuf [0].isodesc; + id = cpia->sbuf[0].isodesc; id->start_type = START_ASAP; id->callback_frames = 10; /* on every 10th frame */ id->callback_fn = cpia_isoc_irq; id->data = cpia->sbuf[0].data; id->buf_size = FRAME_SIZE_PER_DESC * FRAMES_PER_DESC; for (fx = 0; fx < FRAMES_PER_DESC; fx++) - id->frames [fx].frame_length = FRAME_SIZE_PER_DESC; + id->frames[fx].frame_length = FRAME_SIZE_PER_DESC; /* and the desc. [1] */ - id = cpia->sbuf [1].isodesc; + id = cpia->sbuf[1].isodesc; id->start_type = 0; /* will follow the first desc. */ id->callback_frames = 10; /* on every 10th frame */ id->callback_fn = cpia_isoc_irq; id->data = cpia->sbuf[1].data; id->buf_size = FRAME_SIZE_PER_DESC * FRAMES_PER_DESC; for (fx = 0; fx < FRAMES_PER_DESC; fx++) - id->frames [fx].frame_length = FRAME_SIZE_PER_DESC; + id->frames[fx].frame_length = FRAME_SIZE_PER_DESC; - usb_run_isoc (cpia->sbuf[0].isodesc, NULL); - usb_run_isoc (cpia->sbuf[1].isodesc, cpia->sbuf[0].isodesc); - -#if 0 - usb_schedule_isochronous(dev, cpia->sbuf[0].isodesc, NULL); - usb_schedule_isochronous(dev, cpia->sbuf[1].isodesc, cpia->sbuf[0].isodesc); - usb_schedule_isochronous(dev, cpia->sbuf[2].isodesc, cpia->sbuf[1].isodesc); -#endif + usb_run_isoc(cpia->sbuf[0].isodesc, NULL); + usb_run_isoc(cpia->sbuf[1].isodesc, cpia->sbuf[0].isodesc); #ifdef CPIA_DEBUG printk("done scheduling\n"); #endif - if (usb_set_interface(cpia->dev, 1, 3)) { - printk("cpia_set_interface error\n"); - return -EINVAL; + /* Alternate interface 3 is is the biggest frame size */ + if (usb_set_interface(cpia->dev, 1, 3) < 0) { + printk("usb_set_interface error\n"); + return -EBUSY; } - usb_cpia_startstreamcap(cpia->dev); +#if 0 + if (usb_cpia_grab_frame(dev, 120) < 0) { + printk(KERN_INFO "cpia_grab_frame error\n"); + return -EBUSY; + } +#endif cpia->streaming = 1; #ifdef CPIA_DEBUG @@ -641,41 +655,102 @@ return 0; } -void cpia_stop_isoc(struct usb_cpia *cpia) +static void cpia_stop_isoc(struct usb_cpia *cpia) { - struct usb_device *dev = cpia->dev; - if (!cpia->streaming) return; cpia->streaming = 0; - /* Stop the streaming */ - usb_cpia_endstreamcap(cpia->dev); + /* Turn off continuous grab */ + if (usb_cpia_set_grab_mode(cpia->dev, 0) < 0) { + printk(KERN_INFO "cpia_set_grab_mode error\n"); + return /* -EBUSY */; + } + +#if 0 + if (usb_cpia_grab_frame(cpia->dev, 0) < 0) { + printk(KERN_INFO "cpia_grab_frame error\n"); + return /* -EBUSY */; + } +#endif /* Set packet size to 0 */ - if (usb_set_interface(cpia->dev, 1, 0)) { - printk("cpia_set_interface error\n"); + if (usb_set_interface(cpia->dev, 1, 0) < 0) { + printk(KERN_INFO "usb_set_interface error\n"); return /* -EINVAL */; } /* Unschedule all of the iso td's */ - usb_kill_isoc (cpia->sbuf[1].isodesc); - usb_kill_isoc (cpia->sbuf[0].isodesc); -#if 0 - usb_unschedule_isochronous(dev, cpia->sbuf[2].isodesc); - usb_unschedule_isochronous(dev, cpia->sbuf[1].isodesc); - usb_unschedule_isochronous(dev, cpia->sbuf[0].isodesc); -#endif + usb_kill_isoc(cpia->sbuf[1].isodesc); + usb_kill_isoc(cpia->sbuf[0].isodesc); /* Delete them all */ - usb_free_isoc (cpia->sbuf[1].isodesc); - usb_free_isoc (cpia->sbuf[0].isodesc); -#if 0 - usb_delete_isochronous(dev, cpia->sbuf[2].isodesc); - usb_delete_isochronous(dev, cpia->sbuf[1].isodesc); - usb_delete_isochronous(dev, cpia->sbuf[0].isodesc); -#endif + usb_free_isoc(cpia->sbuf[1].isodesc); + usb_free_isoc(cpia->sbuf[0].isodesc); +} + +static int cpia_new_frame(struct usb_cpia *cpia, int framenum) +{ + struct cpia_frame *frame; + int width, height; + +printk("new frame %d\n", framenum); + if (framenum == -1) { + int i; + for (i = 0; i < CPIA_NUMFRAMES; i++) + if (cpia->frame[i].grabstate == FRAME_READY) + break; + + if (i >= CPIA_NUMFRAMES) { + printk("no frame ready\n"); + return 0; + } + + framenum = i; +printk("using frame %d\n", framenum); + } + + if (cpia->curframe != -1 && cpia->curframe != framenum) + return 0; + + frame = &cpia->frame[framenum]; + width = frame->width; + height = frame->height; + + /* Make sure it's not too big */ + if (width > 352) + width = 352; + width = (width / 8) * 8; /* Multiple of 8 */ + + if (height > 288) + height = 288; + height = (height / 4) * 4; /* Multiple of 4 */ + + /* Set the ROI they want */ + if (usb_cpia_set_roi(cpia->dev, 0, width / 8, 0, height / 4) < 0) + return -EBUSY; + + if (usb_cpia_set_compression(cpia->dev, cpia->compress ? 1 : 0, 0) < 0) { + printk(KERN_INFO "cpia_set_compression error\n"); + return -EBUSY; + } + + /* We want a fresh frame every 30 we get */ + cpia->compress = (cpia->compress + 1) % 30; + + /* Grab the frame */ + if (usb_cpia_upload_frame(cpia->dev, 1) < 0) { + printk(KERN_INFO "cpia_upload_frame error\n"); + return -EBUSY; + } + + frame->grabstate = FRAME_GRABBING; + frame->scanstate = STATE_SCANNING; + + cpia->curframe = framenum; + + return 0; } /* Video 4 Linux API */ @@ -688,13 +763,14 @@ printk("cpia_open\n"); #endif + cpia->frame[0].grabstate = FRAME_UNUSED; + cpia->frame[1].grabstate = FRAME_UNUSED; + + /* Allocate memory for the frame buffers */ cpia->fbuf = rvmalloc(2 * MAX_FRAME_SIZE); if (!cpia->fbuf) goto open_err_ret; - cpia->frame[0].state = FRAME_DONE; - cpia->frame[1].state = FRAME_DONE; - cpia->frame[0].data = cpia->fbuf; cpia->frame[1].data = cpia->fbuf + MAX_FRAME_SIZE; #ifdef CPIA_DEBUG @@ -710,37 +786,17 @@ if (!cpia->sbuf[1].data) goto open_err_on1; -#if 0 - cpia->sbuf[0].data = kmalloc(STREAM_BUF_SIZE, GFP_KERNEL); - if (!cpia->sbuf[0].data) - goto open_err_on0; - - cpia->sbuf[1].data = kmalloc(STREAM_BUF_SIZE, GFP_KERNEL); - if (!cpia->sbuf[1].data) - goto open_err_on1; - - cpia->sbuf[2].data = kmalloc(STREAM_BUF_SIZE, GFP_KERNEL); - if (!cpia->sbuf[2].data) - goto open_err_on2; -#endif - #ifdef CPIA_DEBUG printk("sbuf[0] @ %p\n", cpia->sbuf[0].data); printk("sbuf[1] @ %p\n", cpia->sbuf[1].data); -#if 0 - printk("sbuf[2] @ %p\n", cpia->sbuf[2].data); -#endif #endif - cpia->curframe = -1; - cpia->receivesbuf = 0; - - usb_cpia_initstreamcap(cpia->dev, 0, 60); - err = cpia_init_isoc(cpia); if (err) goto open_err_on2; + MOD_INC_USE_COUNT; + return 0; open_err_on2: @@ -761,13 +817,12 @@ printk("cpia_close\n"); #endif - cpia_stop_isoc(cpia); + MOD_DEC_USE_COUNT; - usb_cpia_finistreamcap(cpia->dev); + cpia_stop_isoc(cpia); rvfree(cpia->fbuf, 2 * MAX_FRAME_SIZE); - kfree(cpia->sbuf[2].data); kfree(cpia->sbuf[1].data); kfree(cpia->sbuf[0].data); } @@ -791,23 +846,32 @@ { struct video_capability b; +#ifdef CPIA_DEBUG + printk("GCAP\n"); +#endif + strcpy(b.name, "CPiA USB Camera"); - b.type = VID_TYPE_CAPTURE /* | VID_TYPE_SUBCAPTURE */; + b.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE; b.channels = 1; b.audios = 0; - b.maxwidth = 176 /* 352 */; - b.maxheight = 144 /* 240 */; - b.minwidth = 176 /* (Something small?) */; - b.minheight = 144 /* " " */; + b.maxwidth = 352; /* CIF */ + b.maxheight = 288; /* " */ + b.minwidth = 176; /* QCIF */ + b.minheight = 144; /* " */ if (copy_to_user(arg, &b, sizeof(b))) return -EFAULT; + return 0; } case VIDIOCGCHAN: { struct video_channel v; +#ifdef CPIA_DEBUG + printk("GCHAN\n"); +#endif + if (copy_from_user(&v, arg, sizeof(v))) return -EFAULT; if (v.channel != 0) @@ -826,47 +890,14 @@ { int v; - if (copy_from_user(&v, arg, sizeof(v))) - return -EFAULT; - - if (v != 0) - return -EINVAL; - - return 0; - } - case VIDIOCGTUNER: - { - struct video_tuner v; - - if (copy_from_user(&v, arg, sizeof(v))) - return -EFAULT; - - if (v.tuner) - return -EINVAL; - - strcpy(v.name, "Format"); - - v.rangelow = 0; - v.rangehigh = 0; - v.flags = 0; - v.mode = VIDEO_MODE_AUTO; - - if (copy_to_user(arg, &v, sizeof(v))) - return -EFAULT; - - return 0; - } - case VIDIOCSTUNER: - { - struct video_tuner v; +#ifdef CPIA_DEBUG + printk("SCHAN\n"); +#endif if (copy_from_user(&v, arg, sizeof(v))) return -EFAULT; - if (v.tuner) - return -EINVAL; - - if (v.mode != VIDEO_MODE_AUTO) + if (v != 0) return -EINVAL; return 0; @@ -875,6 +906,10 @@ { struct video_picture p; +#ifdef CPIA_DEBUG + printk("GPICT\n"); +#endif + p.colour = 0x8000; /* Damn British people :) */ p.hue = 0x8000; p.brightness = 180 << 8; /* XXX */ @@ -895,6 +930,10 @@ { struct video_picture p; +#ifdef CPIA_DEBUG + printk("SPICT\n"); +#endif + if (copy_from_user(&p, arg, sizeof(p))) return -EFAULT; @@ -910,7 +949,7 @@ struct video_window vw; #ifdef CPIA_DEBUG - printk("VIDIOCSWIN\n"); + printk("SWIN\n"); #endif if (copy_from_user(&vw, arg, sizeof(vw))) @@ -924,6 +963,8 @@ if (vw.width != 144) return -EINVAL; + cpia->compress = 0; + return 0; } case VIDIOCGWIN: @@ -931,7 +972,7 @@ struct video_window vw; #ifdef CPIA_DEBUG - printk("VIDIOCGWIN\n"); + printk("GWIN\n"); #endif vw.x = 0; @@ -949,6 +990,9 @@ case VIDIOCGMBUF: { struct video_mbuf vm; +#ifdef CPIA_DEBUG + printk("MBUF\n"); +#endif memset(&vm, 0, sizeof(vm)); vm.size = MAX_FRAME_SIZE * 2; @@ -965,6 +1009,7 @@ { struct video_mmap vm; + if (copy_from_user((void *)&vm, (void *)arg, sizeof(vm))) return -EFAULT; @@ -980,53 +1025,85 @@ if ((vm.frame != 0) && (vm.frame != 1)) return -EINVAL; + if (cpia->frame[vm.frame].grabstate == FRAME_GRABBING) + return -EBUSY; + + /* Don't compress if the size changed */ + if ((cpia->frame[vm.frame].width != vm.width) || + (cpia->frame[vm.frame].height != vm.height)) + cpia->compress = 0; + cpia->frame[vm.frame].width = vm.width; cpia->frame[vm.frame].height = vm.height; - /* Mark it as free */ - cpia->frame[vm.frame].state = FRAME_READY; + /* Mark it as ready */ + cpia->frame[vm.frame].grabstate = FRAME_READY; - return 0; + return cpia_new_frame(cpia, vm.frame); } case VIDIOCSYNC: { int frame; +#ifdef CPIA_DEBUG + printk("SYNC\n"); +#endif + if (copy_from_user((void *)&frame, arg, sizeof(int))) return -EFAULT; #ifdef CPIA_DEBUG - printk("syncing to frame %d\n", frame); + printk("cpia: syncing to frame %d\n", frame); #endif - switch (cpia->frame[frame].state) { - case FRAME_UNUSED: - return -EINVAL; - case FRAME_READY: - case FRAME_GRABBING: - interruptible_sleep_on(&cpia->wq); - case FRAME_DONE: - cpia->frame[frame].state = FRAME_UNUSED; - break; + + switch (cpia->frame[frame].grabstate) { + case FRAME_UNUSED: + return -EINVAL; + case FRAME_READY: + case FRAME_GRABBING: +redo: + do { +printk("enter sleeping\n"); + interruptible_sleep_on(&cpia->frame[frame].wq); +printk("back from sleeping\n"); + if (signal_pending(current)) + return -EINTR; + } while (cpia->frame[frame].grabstate == + FRAME_GRABBING); + + if (cpia->frame[frame].grabstate == + FRAME_ERROR) { + int ret; + + if ((ret = cpia_new_frame(cpia, frame)) < 0) + return ret; + goto redo; + } + case FRAME_DONE: + cpia->frame[frame].grabstate = FRAME_UNUSED; + break; } + #ifdef CPIA_DEBUG - printk("synced to frame %d\n", frame); + printk("cpia: finished, synced to frame %d\n", frame); #endif - return 0; + + return cpia_new_frame(cpia, -1); } + case VIDIOCKEY: + return 0; case VIDIOCCAPTURE: return -EINVAL; case VIDIOCGFBUF: - return -EINVAL; case VIDIOCSFBUF: return -EINVAL; - case VIDIOCKEY: - return 0; - case VIDIOCGFREQ: + case VIDIOCGTUNER: + case VIDIOCSTUNER: return -EINVAL; + case VIDIOCGFREQ: case VIDIOCSFREQ: return -EINVAL; case VIDIOCGAUDIO: - return -EINVAL; case VIDIOCSAUDIO: return -EINVAL; default: @@ -1037,17 +1114,14 @@ static long cpia_read(struct video_device *dev, char *buf, unsigned long count, int noblock) { +#if 0 struct usb_cpia *cpia = (struct usb_cpia *)dev; int len; +#endif #ifdef CPIA_DEBUG printk("cpia_read: %ld bytes\n", count); #endif -#if 0 - len = cpia_capture(cpia, buf, count); - - return len; -#endif return 0; } @@ -1064,17 +1138,17 @@ return -EINVAL; pos = (unsigned long)cpia->fbuf; - while (size > 0) - { - page = kvirt_to_phys(pos); + while (size > 0) { + page = kvirt_to_pa(pos); if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) return -EAGAIN; - start+=PAGE_SIZE; - pos+=PAGE_SIZE; + + start += PAGE_SIZE; + pos += PAGE_SIZE; if (size > PAGE_SIZE) - size-=PAGE_SIZE; + size -= PAGE_SIZE; else - size=0; + size = 0; } return 0; @@ -1097,87 +1171,92 @@ 0 }; -static void usb_cpia_configure(struct usb_cpia *cpia) +static int usb_cpia_configure(struct usb_cpia *cpia) { struct usb_device *dev = cpia->dev; unsigned char version[4]; - unsigned char pnpid[6]; - unsigned char camerastat[8]; - unsigned char *buf; - if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) { - printk (KERN_INFO " Failed usb_set_configuration: CPIA\n"); - return; + if (usb_set_configuration(dev, dev->config[0].bConfigurationValue) < 0) { + printk(KERN_INFO "cpia: usb_set_configuration failed\n"); + return -EBUSY; } - if (usb_cpia_get_version(dev, version)) { - printk("cpia_get_version error\n"); - return; + /* Set packet size to 0 */ + if (usb_set_interface(dev, 1, 0) < 0) { + printk(KERN_INFO "usb_set_interface error\n"); + return -EBUSY; } - printk("cpia: Firmware v%d.%d, VC Hardware v%d.%d\n", - version[0], version[1], version[2], version[3]); - - if (usb_cpia_get_pnp_id(dev, pnpid)) { - printk("cpia_get_pnp_id error\n"); - return; + if (usb_cpia_get_version(dev, version) < 0) { + printk(KERN_INFO "cpia_get_version error\n"); + return -EBUSY; } - printk("cpia: PnP Id: Vendor: %X, Product: %X, Revision: %X\n", - (pnpid[1] << 8) + pnpid[0], (pnpid[3] << 8) + pnpid[2], - (pnpid[5] << 8) + pnpid[4]); + printk("cpia: Firmware v%d.%d, VC Hardware v%d.%d\n", + version[0], version[1], version[2], version[3]); memcpy(&cpia->vdev, &cpia_template, sizeof(cpia_template)); - init_waitqueue_head(&cpia->wq); + init_waitqueue_head(&cpia->frame[0].wq); + init_waitqueue_head(&cpia->frame[1].wq); if (video_register_device(&cpia->vdev, VFL_TYPE_GRABBER) == -1) { - printk("video_register_device failed\n"); - return; + printk(KERN_INFO "video_register_device failed\n"); + return -EBUSY; } - if (usb_cpia_goto_hi_power(dev)) { - printk("cpia_goto_hi_power error\n"); - return; + if (usb_cpia_goto_hi_power(dev) < 0) { + printk(KERN_INFO "cpia_goto_hi_power error\n"); + goto error; } - if (usb_cpia_get_vp_version(dev, version)) { - printk("cpia_get_vp_version error\n"); - return; + if (usb_cpia_get_vp_version(dev, version) < 0) { + printk(KERN_INFO "cpia_get_vp_version error\n"); + goto error; } printk("cpia: VP v%d rev %d\n", version[0], version[1]); printk("cpia: Camera Head ID %04X\n", (version[3] << 8) + version[2]); - /* Turn off continuous grab */ - if (usb_cpia_set_grab_mode(dev, 1)) { - printk("cpia_set_grab_mode error\n"); - return; + /* Turn on continuous grab */ + if (usb_cpia_set_grab_mode(dev, 1) < 0) { + printk(KERN_INFO "cpia_set_grab_mode error\n"); + goto error; } /* Set up the sensor to be 30fps */ - if (usb_cpia_set_sensor_fps(dev, 1, 0)) { - printk("cpia_set_sensor_fps error\n"); - return; + if (usb_cpia_set_sensor_fps(dev, 1, 0) < 0) { + printk(KERN_INFO "cpia_set_sensor_fps error\n"); + goto error; } - /* Set video into QCIF mode, and order into YUYV mode */ - if (usb_cpia_set_format(dev, CPIA_QCIF, 1, CPIA_YUYV)) { - printk("cpia_set_format error\n"); - return; + /* Set video into CIF mode, and order into YUYV mode */ + if (usb_cpia_set_format(dev, CPIA_CIF, 1, CPIA_YUYV) < 0) { + printk(KERN_INFO "cpia_set_format error\n"); + goto error; } /* Turn off compression */ - if (usb_cpia_set_compression(dev, 0, 0)) { - printk("cpia_set_compression error\n"); - return; + if (usb_cpia_set_compression(dev, 0, 0) < 0) { + printk(KERN_INFO "cpia_set_compression error\n"); + goto error; } + + cpia->compress = 0; + + return 0; + +error: + video_unregister_device(&cpia->vdev); + + kfree(cpia); + + return -EBUSY; } static int cpia_probe(struct usb_device *dev) { struct usb_interface_descriptor *interface; - struct usb_endpoint_descriptor *endpoint; struct usb_cpia *cpia; /* We don't handle multi-config cameras */ @@ -1191,6 +1270,8 @@ return -1; if (dev->descriptor.idProduct != 0x0002) return -1; + + /* Checking vendor/product should be enough, but what the hell */ if (interface->bInterfaceClass != 0xFF) return -1; if (interface->bInterfaceSubClass != 0x00) @@ -1209,9 +1290,7 @@ dev->private = cpia; cpia->dev = dev; - usb_cpia_configure(cpia); - - return 0; + return usb_cpia_configure(cpia); } static void cpia_disconnect(struct usb_device *dev) @@ -1231,9 +1310,6 @@ { NULL, NULL } }; -/* - * This should be a separate module. - */ int usb_cpia_init(void) { usb_register(&cpia_driver); @@ -1241,6 +1317,11 @@ return 0; } +void usb_cpia_cleanup(void) +{ + usb_deregister(&cpia_driver); +} + #ifdef MODULE int init_module(void) { @@ -1249,6 +1330,7 @@ void cleanup_module(void) { + usb_cpia_cleanup(); } #endif diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/cpia.h linux.ac/drivers/usb/cpia.h --- linux.vanilla/drivers/usb/cpia.h Tue Sep 7 22:07:06 1999 +++ linux.ac/drivers/usb/cpia.h Wed Sep 15 23:54:19 1999 @@ -78,9 +78,10 @@ #define CPIA_YUYV 0 #define CPIA_UYVY 1 -#define STREAM_BUF_SIZE (PAGE_SIZE * 4) +#define STREAM_BUF_SIZE (PAGE_SIZE * 4) +/* #define STREAM_BUF_SIZE (FRAMES_PER_DESC * FRAME_SIZE_PER_DESC) */ -#define SCRATCH_BUF_SIZE (STREAM_BUF_SIZE * 2) +#define SCRATCH_BUF_SIZE (STREAM_BUF_SIZE * 2) #define FRAMES_PER_DESC 10 #define FRAME_SIZE_PER_DESC 960 /* Shouldn't be hardcoded */ @@ -91,54 +92,97 @@ STATE_LINES, /* Parsing lines */ }; +#define CPIA_MAGIC 0x1968 +struct cpia_frame_header { + __u16 magic; /* 0 - 1 */ + __u16 timestamp; /* 2 - 3 */ + __u16 unused; /* 4 - 5 */ + __u16 timestamp1; /* 6 - 7 */ + __u8 unused1[8]; /* 8 - 15 */ + __u8 video_size; /* 16 0 = QCIF, 1 = CIF */ + __u8 sub_sample; /* 17 0 = 4:2:0, 1 = 4:2:2 */ + __u8 yuv_order; /* 18 0 = YUYV, 1 = UYVY */ + __u8 unused2[5]; /* 19 - 23 */ + __u8 col_start; /* 24 */ + __u8 col_end; /* 25 */ + __u8 row_start; /* 26 */ + __u8 row_end; /* 27 */ + __u8 comp_enable; /* 28 0 = non compressed, 1 = compressed */ + __u8 decimation; /* 29 0 = no decimation, 1 = decimation */ + __u8 y_thresh; /* 30 */ + __u8 uv_thresh; /* 31 */ + __u8 system_state; /* 32 */ + __u8 grab_state; /* 33 */ + __u8 stream_state; /* 34 */ + __u8 fatal_error; /* 35 */ + __u8 cmd_error; /* 36 */ + __u8 debug_flags; /* 37 */ + __u8 camera_state_7; /* 38 */ + __u8 camera_state_8; /* 39 */ + __u8 cr_achieved; /* 40 */ + __u8 fr_achieved; /* 41 */ + __u8 unused3[22]; /* 42 - 63 */ +}; + struct usb_device; struct cpia_sbuf { char *data; - int len; struct usb_isoc_desc *isodesc; -#if 0 - void *isodesc; -#endif }; enum { - FRAME_READY, /* Ready to grab into */ + FRAME_UNUSED, /* Unused (no MCAPTURE) */ + FRAME_READY, /* Ready to start grabbing */ FRAME_GRABBING, /* In the process of being grabbed into */ FRAME_DONE, /* Finished grabbing, but not been synced yet */ - FRAME_UNUSED, /* Unused (no MCAPTURE) */ + FRAME_ERROR, /* Something bad happened while processing */ }; struct cpia_frame { - char *data; - int width; - int height; - int state; + char *data; /* Frame buffer */ + + struct cpia_frame_header header; /* Header from stream */ + + int width; /* Width application is expecting */ + int height; /* Height */ + + int hdrwidth; /* Width the frame actually is */ + int hdrheight; /* Height */ + + int grabstate; /* State of grabbing */ + int scanstate; /* State of scanning */ + + int curline; /* Line of frame we're working on */ + + wait_queue_head_t wq; /* Processes waiting */ }; +#define CPIA_NUMFRAMES 2 +#define CPIA_NUMSBUF 2 + struct usb_cpia { struct video_device vdev; /* Device structure */ struct usb_device *dev; - int streaming; + int streaming; /* Are we streaming Isochronous? */ + int grabbing; /* Are we grabbing? */ - char *fbuf; /* Videodev buffer area */ + int compress; /* Should the next frame be compressed? */ - int curframe; - struct cpia_frame frame[2]; /* Double buffering */ + char *fbuf; /* Videodev buffer area */ - int receivesbuf; /* Current receiving sbuf */ - struct cpia_sbuf sbuf[3]; /* Triple buffering */ + int curframe; + struct cpia_frame frame[CPIA_NUMFRAMES]; /* Double buffering */ - int state; /* Current scanning state */ - int curline; + int cursbuf; /* Current receiving sbuf */ + struct cpia_sbuf sbuf[CPIA_NUMSBUF]; /* Double buffering */ - char scratch[SCRATCH_BUF_SIZE]; + /* Scratch space from the Isochronous pipe */ + unsigned char scratch[SCRATCH_BUF_SIZE]; int scratchlen; - - wait_queue_head_t wq; }; #endif diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/ezusb.c linux.ac/drivers/usb/ezusb.c --- linux.vanilla/drivers/usb/ezusb.c Sat Sep 11 00:54:11 1999 +++ linux.ac/drivers/usb/ezusb.c Mon Sep 20 17:00:01 1999 @@ -27,7 +27,8 @@ * Implemented EZUSB_SETINTERFACE, more sanity checks for EZUSB_BULK. * Preliminary ISO support * 0.3 01.09.99 Async Bulk and ISO support - * 0.4 01.09.99 + * 0.4 01.09.99 Set callback_frames to the total number of frames to make + * it work with OHCI-HCD * */ @@ -40,9 +41,10 @@ #include #include #include -#include #include +#include + #include "usb.h" #include "ezusb.h" @@ -76,9 +78,9 @@ /* --------------------------------------------------------------------- */ -extern inline unsigned ld2(unsigned int x) +extern inline unsigned int ld2(unsigned int x) { - unsigned r = 0; + unsigned int r = 0; if (x >= 0x10000) { x >>= 16; @@ -101,6 +103,17 @@ return r; } +#if 0 +/* why doesn't this work properly on i386? */ +extern inline unsigned int ld2(unsigned int x) +{ + unsigned int r; + + __asm__("bsrl %1,%0" : "=r" (r) : "g" (x)); + return r; +} +#endif + /* --------------------------------------------------------------------- */ extern __inline__ void async_removelist(struct async *as) @@ -173,22 +186,41 @@ /* --------------------------------------------------------------------- */ -static int async_completed(int status, void *__buffer, int rval, void *dev_id) +static int bulk_completed(int status, void *__buffer, int rval, void *dev_id) { struct async *as = (struct async *)dev_id; struct ezusb *ez = as->ez; unsigned cnt; -printk(KERN_DEBUG "ezusb: async_completed: status %d rval %d\n", status, rval); +printk(KERN_DEBUG "ezusb: bulk_completed: status %d rval %d\n", status, rval); as->completed.length = rval; - if (as->numframes > 0) { - as->completed.status = USB_ST_NOERROR; - for (cnt = 0; cnt < as->numframes; cnt++) { - as->completed.isostat[cnt].status = as->desc.iso->frames[cnt].frame_status; - as->completed.isostat[cnt].length = as->desc.iso->frames[cnt].frame_length; - } - } else - as->completed.status = status; + as->completed.status = status; + spin_lock(&ez->lock); + list_del(&as->asynclist); + list_add_tail(&as->asynclist, &ez->async_completed); + spin_unlock(&ez->lock); + wake_up(&ez->wait); + return 0; +} + +static int iso_completed(int status, void *__buffer, int rval, void *dev_id) +{ +#if 1 + struct async *as = (struct async *)dev_id; +#else + struct usb_isoc_desc *id = (struct usb_isoc_desc *)dev_id; + struct async *as = (struct async *)id->context; +#endif + struct ezusb *ez = as->ez; + unsigned cnt; + +printk(KERN_DEBUG "ezusb: iso_completed: status %d rval %d\n", status, rval); + as->completed.length = rval; + as->completed.status = USB_ST_NOERROR; + for (cnt = 0; cnt < as->numframes; cnt++) { + as->completed.isostat[cnt].status = as->desc.iso->frames[cnt].frame_status; + as->completed.isostat[cnt].length = as->desc.iso->frames[cnt].frame_length; + } spin_lock(&ez->lock); list_del(&as->asynclist); list_add_tail(&as->asynclist, &ez->async_completed); @@ -264,7 +296,6 @@ unsigned ret = 0; unsigned len; unsigned char b[64]; - devrequest dr; int i; if (*ppos < 0 || *ppos >= 0x10000) @@ -280,15 +311,10 @@ len = sizeof(b); if (pos + len > 0x10000) len = 0x10000 - pos; - dr.requesttype = 0xc0; - dr.request = 0xa0; - dr.value = pos; - dr.index = 0; - dr.length = len; - i = ez->usbdev->bus->op->control_msg(ez->usbdev, usb_rcvctrlpipe(ez->usbdev, 0), &dr, b, len); + i = usb_control_msg(ez->usbdev, usb_rcvctrlpipe(ez->usbdev, 0), 0xa0, 0xc0, pos, 0, b, len, HZ); if (i) { up(&ez->mutex); - printk(KERN_WARNING "ezusb: upload failed pos %u len %u ret %d\n", dr.value, dr.length, i); + printk(KERN_WARNING "ezusb: upload failed pos %u len %u ret %d\n", pos, len, i); *ppos = pos; if (ret) return ret; @@ -318,7 +344,6 @@ unsigned ret = 0; unsigned len; unsigned char b[64]; - devrequest dr; int i; if (*ppos < 0 || *ppos >= 0x10000) @@ -341,15 +366,10 @@ return ret; return -EFAULT; } - dr.requesttype = 0x40; - dr.request = 0xa0; - dr.value = pos; - dr.index = 0; - dr.length = len; - i = ez->usbdev->bus->op->control_msg(ez->usbdev, usb_sndctrlpipe(ez->usbdev, 0), &dr, b, len); + i = usb_control_msg(ez->usbdev, usb_sndctrlpipe(ez->usbdev, 0), 0xa0, 0x40, pos, 0, b, len, HZ); if (i) { up(&ez->mutex); - printk(KERN_WARNING "ezusb: download failed pos %u len %u ret %d\n", dr.value, dr.length, i); + printk(KERN_WARNING "ezusb: download failed pos %u len %u ret %d\n", pos, len, i); *ppos = pos; if (ret) return ret; @@ -401,7 +421,7 @@ static int ezusb_control(struct usb_device *usbdev, unsigned char requesttype, unsigned char request, unsigned short value, unsigned short index, unsigned short length, - void *data) + unsigned int timeout, void *data) { unsigned char *tbuf = NULL; unsigned int pipe; @@ -429,7 +449,7 @@ } } } - i = usb_control_msg(usbdev, pipe, request, requesttype, value, index, tbuf, length); + i = usb_control_msg(usbdev, pipe, request, requesttype, value, index, tbuf, length, timeout); if (i < 0) { if (length > 0) free_page((unsigned long)tbuf); @@ -444,7 +464,7 @@ return i; } -static int ezusb_bulk(struct usb_device *usbdev, unsigned int ep, unsigned int length, void *data) +static int ezusb_bulk(struct usb_device *usbdev, unsigned int ep, unsigned int length, unsigned int timeout, void *data) { unsigned char *tbuf = NULL; unsigned int pipe; @@ -473,7 +493,7 @@ } } } - ret = usbdev->bus->op->bulk_msg(usbdev, pipe, tbuf, length, &len2); + ret = usbdev->bus->op->bulk_msg(usbdev, pipe, tbuf, length, &len2, timeout); if (ret < 0) { if (length > 0) free_page((unsigned long)tbuf); @@ -553,7 +573,7 @@ } } async_newpending(as); - if (!(as->desc.bulk = usb_request_bulk(ez->usbdev, pipe, async_completed, as->data, ab->len, as))) { + if (!(as->desc.bulk = usb_request_bulk(ez->usbdev, pipe, bulk_completed, as->data, ab->len, as))) { async_removelist(as); goto err_inval; } @@ -592,6 +612,7 @@ if (!(maxpkt = usb_maxpacket(ez->usbdev, pipe, !(ai->ep & 0x80)))) return -EINVAL; dsize = maxpkt * ai->framecnt; +printk(KERN_DEBUG "ezusb: iso: dsize %d\n", dsize); if (dsize > 65536) return -EINVAL; order = ld2(dsize >> PAGE_SHIFT); @@ -603,6 +624,7 @@ assize = sizeof(struct async) + ai->framecnt * sizeof(struct ezusb_isoframestat); if (!(as = kmalloc(assize, GFP_KERNEL))) return -ENOMEM; +printk(KERN_DEBUG "ezusb: iso: assize %d\n", assize); memset(as, 0, assize); INIT_LIST_HEAD(&as->asynclist); as->ez = ez; @@ -630,8 +652,8 @@ } as->desc.iso->start_type = START_ABSOLUTE; as->desc.iso->start_frame = ai->startframe; - as->desc.iso->callback_frames = 0; - as->desc.iso->callback_fn = async_completed; + as->desc.iso->callback_frames = /*0*/ai->framecnt; + as->desc.iso->callback_fn = iso_completed; as->desc.iso->data = as->data; as->desc.iso->buf_size = dsize; for (j = 0; j < ai->framecnt; j++) { @@ -709,9 +731,13 @@ DECLARE_WAITQUEUE(wait, current); struct usb_proc_ctrltransfer pctrl; struct usb_proc_bulktransfer pbulk; + struct usb_proc_old_ctrltransfer opctrl; + struct usb_proc_old_bulktransfer opbulk; struct usb_proc_setinterface psetintf; struct ezusb_ctrltransfer ctrl; struct ezusb_bulktransfer bulk; + struct ezusb_old_ctrltransfer octrl; + struct ezusb_old_bulktransfer obulk; struct ezusb_setinterface setintf; struct ezusb_asyncbulk abulk; struct ezusb_asynciso aiso; @@ -732,7 +758,8 @@ break; } ret = ezusb_control(ez->usbdev, pctrl.requesttype, pctrl.request, - pctrl.value, pctrl.index, pctrl.length, pctrl.data); + pctrl.value, pctrl.index, pctrl.length, + (pctrl.timeout * HZ + 500) / 1000, pctrl.data); break; case USB_PROC_BULK: @@ -740,7 +767,25 @@ ret = -EFAULT; break; } - ret = ezusb_bulk(ez->usbdev, pbulk.ep, pbulk.len, pbulk.data); + ret = ezusb_bulk(ez->usbdev, pbulk.ep, pbulk.len, + (pbulk.timeout * HZ + 500) / 1000, pbulk.data); + break; + + case USB_PROC_OLD_CONTROL: + if (copy_from_user(&opctrl, (void *)arg, sizeof(opctrl))) { + ret = -EFAULT; + break; + } + ret = ezusb_control(ez->usbdev, opctrl.requesttype, opctrl.request, + opctrl.value, opctrl.index, opctrl.length, HZ, opctrl.data); + break; + + case USB_PROC_OLD_BULK: + if (copy_from_user(&opbulk, (void *)arg, sizeof(opbulk))) { + ret = -EFAULT; + break; + } + ret = ezusb_bulk(ez->usbdev, opbulk.ep, opbulk.len, 5*HZ, opbulk.data); break; case USB_PROC_RESETEP: @@ -772,12 +817,9 @@ ret = -EFAULT; break; } - if (ctrl.dlen != ctrl.length) { - ret = -EINVAL; - break; - } ret = ezusb_control(ez->usbdev, ctrl.requesttype, ctrl.request, - ctrl.value, ctrl.index, ctrl.length, ctrl.data); + ctrl.value, ctrl.index, ctrl.length, + (ctrl.timeout * HZ + 500) / 1000, ctrl.data); break; case EZUSB_BULK: @@ -785,7 +827,29 @@ ret = -EFAULT; break; } - ret = ezusb_bulk(ez->usbdev, bulk.ep, bulk.len, bulk.data); + ret = ezusb_bulk(ez->usbdev, bulk.ep, bulk.len, + (bulk.timeout * HZ + 500) / 1000, bulk.data); + break; + + case EZUSB_OLD_CONTROL: + if (copy_from_user(&octrl, (void *)arg, sizeof(octrl))) { + ret = -EFAULT; + break; + } + if (octrl.dlen != octrl.length) { + ret = -EINVAL; + break; + } + ret = ezusb_control(ez->usbdev, octrl.requesttype, octrl.request, + octrl.value, octrl.index, octrl.length, HZ, octrl.data); + break; + + case EZUSB_OLD_BULK: + if (copy_from_user(&obulk, (void *)arg, sizeof(obulk))) { + ret = -EFAULT; + break; + } + ret = ezusb_bulk(ez->usbdev, obulk.ep, obulk.len, 5*HZ, obulk.data); break; case EZUSB_RESETEP: @@ -813,6 +877,7 @@ break; case EZUSB_ASYNCCOMPLETED: + as = NULL; current->state = TASK_INTERRUPTIBLE; add_wait_queue(&ez->wait, &wait); for (;;) { @@ -928,9 +993,11 @@ if (usbdev->descriptor.bNumConfigurations != 1) return -1; +#if 0 /* We don't handle multiple interfaces */ if (usbdev->config[0].bNumInterfaces != 1) return -1; +#endif down(&ez->mutex); if (ez->usbdev) { diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/ezusb.h linux.ac/drivers/usb/ezusb.h --- linux.vanilla/drivers/usb/ezusb.h Tue Sep 7 22:07:06 1999 +++ linux.ac/drivers/usb/ezusb.h Mon Sep 20 15:52:49 1999 @@ -31,6 +31,23 @@ /* --------------------------------------------------------------------- */ +struct ezusb_old_ctrltransfer { + /* keep in sync with usb.h:devrequest */ + unsigned char requesttype; + unsigned char request; + unsigned short value; + unsigned short index; + unsigned short length; + unsigned int dlen; + void *data; +}; + +struct ezusb_old_bulktransfer { + unsigned int ep; + unsigned int len; + void *data; +}; + struct ezusb_ctrltransfer { /* keep in sync with usb.h:devrequest */ unsigned char requesttype; @@ -38,14 +55,14 @@ unsigned short value; unsigned short index; unsigned short length; - /* pointer to data */ - unsigned dlen; + unsigned int timeout; /* in milliseconds */ void *data; }; struct ezusb_bulktransfer { unsigned int ep; unsigned int len; + unsigned int timeout; /* in milliseconds */ void *data; }; @@ -84,8 +101,10 @@ struct ezusb_isoframestat isostat[0]; }; -#define EZUSB_CONTROL _IOWR('E', 0, struct ezusb_ctrltransfer) +#define EZUSB_CONTROL _IOWR('E', 1, struct ezusb_ctrltransfer) #define EZUSB_BULK _IOWR('E', 2, struct ezusb_bulktransfer) +#define EZUSB_OLD_CONTROL _IOWR('E', 0, struct ezusb_old_ctrltransfer) +#define EZUSB_OLD_BULK _IOWR('E', 2, struct ezusb_old_bulktransfer) #define EZUSB_RESETEP _IOR('E', 3, unsigned int) #define EZUSB_SETINTERFACE _IOR('E', 4, struct ezusb_setinterface) #define EZUSB_SETCONFIGURATION _IOR('E', 5, unsigned int) diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/hp_scanner.c linux.ac/drivers/usb/hp_scanner.c --- linux.vanilla/drivers/usb/hp_scanner.c Sat Sep 11 00:54:11 1999 +++ linux.ac/drivers/usb/hp_scanner.c Mon Sep 20 16:57:52 1999 @@ -130,7 +130,7 @@ return bytes_written ? bytes_written : -EINTR; } - result = hps->hpscan_dev->bus->op->bulk_msg(hps->hpscan_dev,usb_sndbulkpipe(hps->hpscan_dev, 2), obuf, thistime, &partial); + result = hps->hpscan_dev->bus->op->bulk_msg(hps->hpscan_dev,usb_sndbulkpipe(hps->hpscan_dev, 2), obuf, thistime, &partial, HZ*10); //printk(KERN_DEBUG "write stats: result:%d thistime:%lu partial:%lu\n", result, thistime, partial); @@ -188,7 +188,7 @@ return -ENODEV; this_read = (count > IBUF_SIZE) ? IBUF_SIZE : count; - result = hps->hpscan_dev->bus->op->bulk_msg(hps->hpscan_dev, usb_rcvbulkpipe(hps->hpscan_dev, 1), ibuf, this_read, &partial); + result = hps->hpscan_dev->bus->op->bulk_msg(hps->hpscan_dev, usb_rcvbulkpipe(hps->hpscan_dev, 1), ibuf, this_read, &partial, HZ*10); printk(KERN_DEBUG "read stats: result:%d this_read:%u partial:%lu\n", result, this_read, partial); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/hub.c linux.ac/drivers/usb/hub.c --- linux.vanilla/drivers/usb/hub.c Sat Sep 11 00:54:11 1999 +++ linux.ac/drivers/usb/hub.c Mon Sep 20 16:57:40 1999 @@ -34,33 +34,33 @@ { return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB, - USB_DT_HUB << 8, 0, data, size); + USB_DT_HUB << 8, 0, data, size, HZ); } static int usb_clear_port_feature(struct usb_device *dev, int port, int feature) { return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port, NULL, 0); + USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port, NULL, 0, HZ); } static int usb_set_port_feature(struct usb_device *dev, int port, int feature) { return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - USB_REQ_SET_FEATURE, USB_RT_PORT, feature, port, NULL, 0); + USB_REQ_SET_FEATURE, USB_RT_PORT, feature, port, NULL, 0, HZ); } static int usb_get_hub_status(struct usb_device *dev, void *data) { /* FIXME: Don't hardcode 4 */ return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB, 0, 0, data, 4); + USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB, 0, 0, data, 4, HZ); } static int usb_get_port_status(struct usb_device *dev, int port, void *data) { /* FIXME: Don't hardcode 4 */ return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port, data, 4); + USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port, data, 4, HZ); } /* diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/keyboard.c linux.ac/drivers/usb/keyboard.c --- linux.vanilla/drivers/usb/keyboard.c Sat Sep 11 00:54:11 1999 +++ linux.ac/drivers/usb/keyboard.c Sat Sep 18 01:53:21 1999 @@ -21,7 +21,7 @@ #define PCKBD_RELEASED 0x80 #define PCKBD_NEEDS_E0 0x80 -#define USBKBD_MODIFIER_BASE 120 +#define USBKBD_MODIFIER_BASE 224 #define USBKBD_KEYCODE_OFFSET 2 #define USBKBD_KEYCODE_COUNT 6 diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/keymap.c linux.ac/drivers/usb/keymap.c --- linux.vanilla/drivers/usb/keymap.c Mon May 24 17:31:36 1999 +++ linux.ac/drivers/usb/keymap.c Thu Sep 16 16:30:36 1999 @@ -22,7 +22,7 @@ 0xbd, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1d, 0x2a, 0x38, 0xdb, 0x9d, 0x36, 0xb8, 0xdc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -42,7 +42,7 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1d, 0x2a, 0x38, 0xdb, 0x9d, 0x36, 0xb8, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/mouse.c linux.ac/drivers/usb/mouse.c --- linux.vanilla/drivers/usb/mouse.c Sat Sep 11 00:54:11 1999 +++ linux.ac/drivers/usb/mouse.c Mon Sep 20 16:59:46 1999 @@ -120,7 +120,7 @@ wake_up_interruptible(&mouse->wait); if (mouse->fasync) - kill_fasync(mouse->fasync, SIGIO); + kill_fasync(mouse->fasync, SIGIO, POLL_IN); return 1; } diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/ohci-debug.c linux.ac/drivers/usb/ohci-debug.c --- linux.vanilla/drivers/usb/ohci-debug.c Thu Aug 5 20:30:23 1999 +++ linux.ac/drivers/usb/ohci-debug.c Thu Sep 16 16:30:36 1999 @@ -80,7 +80,7 @@ printk(KERN_DEBUG " ohci ED:\n"); printk(KERN_DEBUG " status = 0x%x\n", stat); - printk(KERN_DEBUG " %sMPS %d%s%s%s%s tc%d e%d fa%d%s\n", + printk(KERN_DEBUG " %sMPS %d%s%s%s%s tc%d e%d fa%d [HCD_%d%s]\n", skip ? "Skip " : "", mps, isoc ? " Isoc." : "", @@ -91,7 +91,8 @@ toggle, endnum, funcaddr, - (stat & ED_ALLOCATED) ? " Allocated" : ""); + ohci_ed_hcdtype(ed) >> 27, + (stat & ED_ALLOCATED) ? ", Allocated" : ""); printk(KERN_DEBUG " tail_td = 0x%x\n", ed_tail_td(ed)); printk(KERN_DEBUG " head_td = 0x%x\n", ed_head_td(ed)); printk(KERN_DEBUG " next_ed = 0x%x\n", le32_to_cpup(&ed->next_ed)); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/ohci-hcd.c linux.ac/drivers/usb/ohci-hcd.c --- linux.vanilla/drivers/usb/ohci-hcd.c Sat Sep 11 00:54:11 1999 +++ linux.ac/drivers/usb/ohci-hcd.c Mon Sep 20 16:58:02 1999 @@ -14,7 +14,7 @@ * [ Open Host Controller Interface driver for USB. ] * [ (C) Copyright 1999 Linus Torvalds (uhci.c) ] * [ (C) Copyright 1999 Gregory P. Smith ] - * [ $Log: ohci.c,v $ ] + * [ _Log: ohci-hcd.c,v _ * [ Revision 1.1 1999/04/05 08:32:30 greg ] * * v4.2 1999/09/05 ISO API alpha, new dev alloc, neg Error-codes @@ -224,7 +224,7 @@ return 0; } -static int sohci_control_msg(struct usb_device *usb_dev, unsigned int pipe, devrequest *cmd, void *data, int len) +static int sohci_control_msg(struct usb_device *usb_dev, unsigned int pipe, devrequest *cmd, void *data, int len, int timeout) { DECLARE_WAITQUEUE(wait, current); struct ohci_state state = {0, TD_NOTACCESSED}; @@ -254,7 +254,7 @@ OHCI_DEBUG(printk("USB HC trans req ed %x: %x :", ed->hwINFO, (unsigned int ) ed); ) OHCI_DEBUG({ int i; for( i= 0; i<8 ;i++) printk(" %4x", ((unsigned int *) ed)[i]) ; printk("\n"); }; ) if (ED_STATE(ed) != ED_OPER) ohci_link_ed(ohci, ed); - schedule_timeout(HZ*5); + schedule_timeout(timeout); if(state.status == TD_NOTACCESSED) { current->state = TASK_UNINTERRUPTIBLE; @@ -266,7 +266,7 @@ return state.status; } -static int sohci_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, unsigned long *rval) +static int sohci_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, unsigned long *rval, int timeout) { DECLARE_WAITQUEUE(wait, current); struct ohci_state state = {0, TD_NOTACCESSED}; @@ -286,7 +286,7 @@ ohci_trans_req(ohci, ed, 0, NULL, data, len, (__OHCI_BAG) &state, (__OHCI_BAG) &wait,(usb_pipeout(pipe))?BULK_OUT:BULK_IN, sohci_blocking_handler); if (ED_STATE(ed) != ED_OPER) ohci_link_ed(ohci, ed); - schedule_timeout(HZ*5); + schedule_timeout(timeout); if(state.status == TD_NOTACCESSED) { current->state = TASK_UNINTERRUPTIBLE; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/ohci-hcd.h linux.ac/drivers/usb/ohci-hcd.h --- linux.vanilla/drivers/usb/ohci-hcd.h Sat Sep 11 00:54:11 1999 +++ linux.ac/drivers/usb/ohci-hcd.h Thu Sep 16 17:14:50 1999 @@ -12,7 +12,7 @@ * [ Open Host Controller Interface driver for USB. ] * [ (C) Copyright 1999 Linus Torvalds (uhci.c) ] * [ (C) Copyright 1999 Gregory P. Smith ] - * [ $Log: ohci.c,v $ ] + * [ _Log: ohci-hcd.h,v _ * [ Revision 1.1 1999/04/05 08:32:30 greg ] * * v4.0 1999/08/18 diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/ohci.c linux.ac/drivers/usb/ohci.c --- linux.vanilla/drivers/usb/ohci.c Sat Sep 11 00:54:11 1999 +++ linux.ac/drivers/usb/ohci.c Mon Sep 20 16:59:34 1999 @@ -15,7 +15,7 @@ * Architecture" book by Mindshare, Inc. It was a reasonable introduction * and overview of USB and the two dominant host controller interfaces * however you're better off just reading the real specs available - * from www.usb.org as you'll need them to get enough detailt to + * from www.usb.org as you'll need them to get enough details to * actually implement a HCD. The book has many typos and omissions * Beware, the specs are the victim of a committee. * @@ -24,7 +24,7 @@ * * No filesystems were harmed in the development of this code. * - * $Id: ohci.c,v 1.43 1999/05/16 22:35:24 greg Exp $ + * $Id: ohci.c,v 1.77 1999/09/16 04:30:19 greg Exp $ */ #include @@ -201,7 +201,6 @@ spin_unlock_irqrestore(&ohci_edtd_lock, flags); } /* ohci_add_ed_to_hw() */ - /* * Put a control ED on the controller's list */ @@ -275,24 +274,19 @@ for (;;) { int_ed = bus_to_virt(le32_to_cpup(&int_ed->next_ed)); /* stop if we get to the end or to another dummy ED. */ - if (int_ed == 0) - break; + if (!int_ed) + break; /* return NULL */ status = le32_to_cpup(&int_ed->status); - if ((status & OHCI_ED_FA) == 0) - break; + if ((status & OHCI_ED_FA) == 0) { + int_ed = NULL; + break; /* return NULL */ + } /* check whether all the appropriate fields match */ if ((status & 0x7ffa7ff) == req_status) - return int_ed; + break; /* return int_ed */ } - return 0; -} - -/* - * Put an isochronous ED on the controller's list - */ -inline void ohci_add_isoc_ed(struct ohci *ohci, struct ohci_ed *ed) -{ - ohci_add_periodic_ed(ohci, ed, 1); + spin_unlock_irqrestore(&ohci_edtd_lock, flags); + return int_ed; } @@ -326,14 +320,14 @@ * adds it to a list of EDs to destroy during the SOF interrupt * processing would be useful (and be callable from an interrupt). */ -void ohci_wait_for_ed_safe(struct ohci_regs *regs, struct ohci_ed *ed, int ed_type) +void ohci_wait_for_ed_safe(struct ohci_regs *regs, struct ohci_ed *ed) { __u32 *hw_listcurrent; /* tell the controller to skip this ED */ ed->status |= cpu_to_le32(OHCI_ED_SKIP); - switch (ed_type) { + switch (ohci_ed_hcdtype(ed)) { case HCD_ED_CONTROL: hw_listcurrent = ®s->ed_controlcurrent; break; @@ -370,7 +364,7 @@ * * Note that the SKIP bit is left on in the removed ED. */ -void ohci_remove_norm_ed_from_hw(struct ohci *ohci, struct ohci_ed *ed, int ed_type) +void ohci_remove_norm_ed_from_hw(struct ohci *ohci, struct ohci_ed *ed) { unsigned long flags; struct ohci_regs *regs = ohci->regs; @@ -378,6 +372,7 @@ __u32 bus_ed = virt_to_bus(ed); __u32 bus_cur; __u32 *hw_listhead_p; + __u32 ed_type = ohci_ed_hcdtype(ed); if (ed == NULL || !bus_ed) return; @@ -391,7 +386,9 @@ hw_listhead_p = ®s->ed_bulkhead; break; default: - printk(KERN_ERR "Unknown HCD ED type %d.\n", ed_type); +#ifdef OHCI_DEBUG + printk(KERN_ERR "Wrong HCD ED type: %d.\n", ed_type); +#endif return; } @@ -426,7 +423,7 @@ /* * Make sure this ED is not being accessed by the HC as we speak. */ - ohci_wait_for_ed_safe(regs, ed, ed_type); + ohci_wait_for_ed_safe(regs, ed); /* clear any links from the ED for safety */ ed->next_ed = 0; @@ -434,24 +431,6 @@ spin_unlock_irqrestore(&ohci_edtd_lock, flags); } /* ohci_remove_norm_ed_from_hw() */ -/* - * Remove an ED from the controller's control list. Note that the SKIP bit - * is left on in the removed ED. - */ -inline void ohci_remove_control_ed(struct ohci *ohci, struct ohci_ed *ed) -{ - ohci_remove_norm_ed_from_hw(ohci, ed, HCD_ED_CONTROL); -} - -/* - * Remove an ED from the controller's bulk list. Note that the SKIP bit - * is left on in the removed ED. - */ -inline void ohci_remove_bulk_ed(struct ohci *ohci, struct ohci_ed *ed) -{ - ohci_remove_norm_ed_from_hw(ohci, ed, HCD_ED_BULK); -} - /* * Remove a periodic ED from the host controller @@ -476,7 +455,7 @@ while (cur_ed) { if (ed == cur_ed) { /* remove the ED */ /* set its SKIP bit and be sure its not in use */ - ohci_wait_for_ed_safe(ohci->regs, ed, HCD_ED_INT); + ohci_wait_for_ed_safe(ohci->regs, ed); /* unlink it */ spin_lock_irqsave(&ohci_edtd_lock, flags); @@ -506,6 +485,20 @@ /* + * Remove an ED from the host controller, choosing + */ +void ohci_remove_ed(struct ohci *ohci, struct ohci_ed *ed) +{ + /* Remove the ED from the HC */ + if (ohci_ed_hcdtype(ed) & HCD_ED_NORMAL) { + ohci_remove_norm_ed_from_hw(ohci, ed); + } else { + ohci_remove_periodic_ed(ohci, ed); + } +} /* ohci_remove_ed() */ + + +/* * Remove all the EDs which have a given device address from a list. * Used when the device is unplugged. * Returns 1 if anything was changed. @@ -573,7 +566,7 @@ * Remove a TD from the given EDs TD list. The TD is freed as well. * (so far this function hasn't been needed) */ -static void ohci_remove_td_from_ed(struct ohci_td *td, struct ohci_ed *ed) +void ohci_remove_td_from_ed(struct ohci_td *td, struct ohci_ed *ed) { unsigned long flags; struct ohci_td *head_td; @@ -670,10 +663,9 @@ * pool. Return NULL if none are left. * * NOTE: This function does not allocate and attach the dummy_td. - * That is done in ohci_fill_ed(). FIXME: it should probably be moved - * into here. + * That is done in ohci_fill_ed(). [should we really do that here?] */ -static struct ohci_ed *ohci_get_free_ed(struct ohci_device *dev) +static struct ohci_ed *ohci_get_free_ed(struct ohci_device *dev, __u32 ed_type) { int idx; @@ -687,6 +679,7 @@ new_ed->status |= cpu_to_le32(OHCI_ED_SKIP); /* mark it as allocated */ allocate_ed(new_ed); + ohci_ed_set_hcdtype(new_ed, ed_type); new_ed->ohci_dev = dev; return new_ed; } @@ -764,8 +757,7 @@ * force the Allocated bit on. */ struct ohci_ed *ohci_fill_ed(struct ohci_device *dev, struct ohci_ed *ed, - int maxpacketsize, int lowspeed, int endp_id, - int isoc_tds) + int maxpacketsize, int lowspeed, int endp_id) { struct ohci_td *dummy_td; @@ -789,11 +781,12 @@ /* set the head TD to the dummy and clear the Carry & Halted bits */ ed->_head_td = ed->tail_td; - ed->status = cpu_to_le32( + ed->status &= cpu_to_le32(OHCI_ED_HCD_MASK); + ed->status |= cpu_to_le32( ed_set_maxpacket(maxpacketsize) | ed_set_speed(lowspeed) | (endp_id & 0x7ff) | - ((isoc_tds == 0) ? OHCI_ED_F_NORM : OHCI_ED_F_ISOC)); + ((ohci_ed_hcdtype(ed) != HCD_ED_ISOC) ? OHCI_ED_F_NORM : OHCI_ED_F_ISOC)); allocate_ed(ed); ed->next_ed = 0; @@ -959,7 +952,7 @@ /* Get an ED and TD */ interrupt_ed = ohci_get_periodic_ed(dev, period, pipe, 0); if (interrupt_ed == 0) { - interrupt_ed = ohci_get_free_ed(dev); + interrupt_ed = ohci_get_free_ed(dev, HCD_ED_INT); if (!interrupt_ed) { printk(KERN_ERR "Out of EDs on device %p in ohci_request_irq\n", dev); return (-ENOMEM); @@ -970,7 +963,7 @@ * device number (function address), and type of TD. */ ohci_fill_ed(dev, interrupt_ed, maxps, usb_pipeslow(pipe), - usb_pipe_endpdev(pipe), 0 /* normal TDs */); + usb_pipe_endpdev(pipe) ); interrupt_ed->status &= cpu_to_le32(~OHCI_ED_SKIP); /* Assimilate the new ED into the collective */ @@ -1077,7 +1070,7 @@ static void * ohci_generic_trans(struct usb_device *usb_dev, int pipe, int data_td_toggle, int round, int autofree, void *dev_id, usb_device_irq handler, void *data, int len, - int ed_type, struct ohci_td *setup_td, struct ohci_td *status_td) + __u32 ed_type, struct ohci_td *setup_td, struct ohci_td *status_td) { struct ohci_device *dev = usb_to_ohci(usb_dev); struct ohci_ed *trans_ed; @@ -1089,7 +1082,7 @@ printk(KERN_DEBUG "ohci_request_trans()\n"); #endif - trans_ed = ohci_get_free_ed(dev); + trans_ed = ohci_get_free_ed(dev, ed_type); if (!trans_ed) { printk("usb-ohci: couldn't get ED for dev %p\n", dev); return NULL; @@ -1142,8 +1135,7 @@ ohci_fill_ed(dev, trans_ed, usb_maxpacket(usb_dev, pipe, usb_pipeout(pipe)), usb_pipeslow(pipe), - usb_pipe_endpdev(pipe), - (ed_type == HCD_ED_ISOC) ); + usb_pipe_endpdev(pipe) ); /* initialize the toggle carry flag in the ED */ if (usb_gettoggle(usb_dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) @@ -1202,7 +1194,7 @@ * * This function is NOT safe to call from an interrupt. */ -static int ohci_terminate_trans(struct usb_device *usb_dev, void *handle, int ed_type) +static int ohci_terminate_trans(struct usb_device *usb_dev, void *handle) { struct ohci_ed *req_ed = (struct ohci_ed *) handle; struct ohci_device *dev = usb_to_ohci(usb_dev); @@ -1213,20 +1205,10 @@ /* stop the transfer & collect the number of bytes */ /* (this is the non-interrupt safe function call) */ - ohci_wait_for_ed_safe(regs, req_ed, ed_type); + ohci_wait_for_ed_safe(regs, req_ed); - /* Remove the ED from the appropriate HC list */ - switch (ed_type) { - case HCD_ED_ISOC: - ohci_remove_periodic_ed(dev->ohci, req_ed); - break; - case HCD_ED_CONTROL: - ohci_remove_control_ed(dev->ohci, req_ed); - break; - case HCD_ED_BULK: - ohci_remove_bulk_ed(dev->ohci, req_ed); - break; - } + /* Remove the ED from the HC */ + ohci_remove_ed(dev->ohci, req_ed); ohci_free_ed(req_ed); /* return it to the pool */ @@ -1252,7 +1234,15 @@ /* pass the TDs completion status back to control_msg */ if (dev_id) { int *completion_status = (int *)dev_id; - *completion_status = stats; + + switch (stats) { + case USB_ST_NOERROR: + case USB_ST_DATAOVERRUN: + *completion_status = len; + break; + default: + *completion_status = -stats; + } } wake_up(&control_wakeup); @@ -1274,13 +1264,13 @@ * This function can NOT be called from an interrupt. */ static int ohci_control_msg(struct usb_device *usb_dev, unsigned int pipe, - devrequest *cmd, void *data, int len) + devrequest *cmd, void *data, int len, int timeout) { struct ohci_device *dev = usb_to_ohci(usb_dev); void *trans_handle; struct ohci_td *setup_td, *status_td; DECLARE_WAITQUEUE(wait, current); - int completion_status = -1; + int completion_status = USB_ST_TIMEOUT; devrequest our_cmd; /* byte-swap fields of cmd if necessary */ @@ -1356,8 +1346,8 @@ return USB_ST_INTERNALERROR; } - /* wait a "reasonable" amount of time for it to complete */ - schedule_timeout(HZ); + /* wait a user defined amount of time for it to complete */ + schedule_timeout(timeout); remove_wait_queue(&control_wakeup, &wait); @@ -1369,9 +1359,12 @@ * Also, since the TDs were autofreed, there is no guarantee that * they haven't been reclaimed by another transfer by now... */ - if (completion_status != 0) { - const char *what = (completion_status < 0)? "timed out": - cc_names[completion_status & 0xf]; + if (completion_status < 0) { + const char *what; + if (completion_status == USB_ST_TIMEOUT) + what = "timed out"; + else + what = cc_names[(-completion_status) & 0xf]; printk(KERN_ERR "ohci_control_msg: %s on pipe %x cmd %x %x %x %x %x", what, pipe, cmd->requesttype, cmd->request, cmd->value, cmd->index, cmd->length); @@ -1422,10 +1415,8 @@ /* no TD cleanup, the TDs were auto-freed as they finished */ /* remove the generic_trans ED from the HC and free it */ - ohci_terminate_trans(usb_dev, trans_handle, HCD_ED_CONTROL); + ohci_terminate_trans(usb_dev, trans_handle); - if (completion_status < 0) - completion_status = USB_ST_TIMEOUT; return completion_status; } /* ohci_control_msg() */ @@ -1471,7 +1462,7 @@ */ static int ohci_terminate_bulk(struct usb_device *usb_dev, void * handle) { - return ohci_terminate_trans(usb_dev, handle, HCD_ED_CONTROL); + return ohci_terminate_trans(usb_dev, handle); } /* ohci_terminate_bulk() */ @@ -1536,24 +1527,6 @@ } /* ohci_bulk_msg_td_handler() */ -/* - * Request to send or receive bulk data for a blocking bulk_msg call. - * - * bulk_request->bytes_transferred_p is a pointer to an integer that - * will be set to the number of bytes that have been successfully - * transferred upon completion. The interrupt handler will update it - * after each internal TD completes successfully. - */ -static struct ohci_ed* ohci_request_bulk_msg(struct ohci_bulk_msg_request_state *bulk_request) -{ - /* initialize the internal counter */ - bulk_request->_bytes_done = 0; - - return ohci_request_bulk(bulk_request->usb_dev, bulk_request->pipe, - ohci_bulk_msg_td_handler, - bulk_request->data, bulk_request->length, - bulk_request); -} /* ohci_request_bulk_msg() */ static DECLARE_WAIT_QUEUE_HEAD(bulk_wakeup); @@ -1574,7 +1547,7 @@ } /* ohci_bulk_msg_completed() */ -static int ohci_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, unsigned long *bytes_transferred_p) +static int ohci_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, unsigned long *bytes_transferred_p, int timeout) { DECLARE_WAITQUEUE(wait, current); int completion_status = USB_ST_INTERNALERROR; @@ -1598,6 +1571,7 @@ req.bytes_transferred_p = bytes_transferred_p; req.dev_id = &completion_status; req.completion = ohci_bulk_msg_completed; + req._bytes_done = 0; if (bytes_transferred_p) *bytes_transferred_p = 0; @@ -1611,10 +1585,20 @@ current->state = TASK_UNINTERRUPTIBLE; add_wait_queue(&bulk_wakeup, &wait); - req_ed = ohci_request_bulk_msg(&req); + /* + * Request to send or receive bulk data for a blocking bulk_msg call. + * + * req.bytes_transferred_p is a pointer to an integer that + * will be set to the number of bytes that have been successfully + * transferred upon completion. The interrupt handler will update it + * after each internal TD completes successfully. + */ + req_ed = ohci_request_bulk(usb_dev, pipe, + ohci_bulk_msg_td_handler, + data, len, &req); - /* FIXME this should to wait for a caller specified time... */ - schedule_timeout(HZ*5); + /* wait for a caller specified time... */ + schedule_timeout(timeout); /* completion_status will only stay in this state of the * request never finished */ @@ -1629,7 +1613,7 @@ * a previously requested bulk transfer. -greg */ /* stop the transfer & collect the number of bytes */ - ohci_wait_for_ed_safe(regs, req_ed, HCD_ED_BULK); + ohci_wait_for_ed_safe(regs, req_ed); /* Get the number of bytes transferred out of the head TD * on the ED if it didn't finish while we were waiting. */ @@ -1659,7 +1643,7 @@ remove_wait_queue(&bulk_wakeup, &wait); /* remove the ED from the HC */ - ohci_remove_bulk_ed(usb_to_ohci(usb_dev)->ohci, req_ed); + ohci_remove_norm_ed_from_hw(usb_to_ohci(usb_dev)->ohci, req_ed); /* save the toggle value back into the usb_dev */ usb_settoggle(usb_dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), @@ -1681,31 +1665,19 @@ /* - * Allocate a new USB device to be attached to an OHCI controller + * Allocate a new USB device attached to this OHCI controller */ -static struct usb_device *ohci_usb_allocate(struct usb_device *parent) +static int ohci_dev_allocate(struct usb_device *usb_dev) { - struct usb_device *usb_dev; struct ohci_device *dev; int idx; /* - * Allocate the generic USB device - */ - usb_dev = kmalloc(sizeof(*usb_dev), GFP_KERNEL); - if (!usb_dev) - return NULL; - - memset(usb_dev, 0, sizeof(*usb_dev)); - - /* * Allocate an OHCI device (EDs and TDs for this device) */ dev = kmalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) { - kfree(usb_dev); - return NULL; - } + if (!dev) + return -1; memset(dev, 0, sizeof(*dev)); @@ -1721,80 +1693,71 @@ usb_dev->hcpriv = dev; dev->usb = usb_dev; - /* - * Link the device to its parent (hub, etc..) if any. - */ - usb_dev->parent = parent; + if (usb_dev->parent) + dev->ohci = usb_to_ohci(usb_dev->parent)->ohci; - if (parent) { - usb_dev->bus = parent->bus; - dev->ohci = usb_to_ohci(parent)->ohci; - } - - return usb_dev; -} /* ohci_usb_allocate() */ + return 0; +} /* ohci_dev_allocate() */ /* - * Free a usb device. - * - * TODO This function needs to take better care of the EDs and TDs, etc. + * Free a usb device on this ohci controller. */ -static int ohci_usb_deallocate(struct usb_device *usb_dev) +static int ohci_dev_deallocate(struct usb_device *usb_dev) { struct ohci_device *dev = usb_to_ohci(usb_dev); ohci_remove_device(dev->ohci, usb_dev->devnum); - /* kfree(usb_to_ohci(usb_dev)); */ - /* kfree(usb_dev); */ + kfree(usb_to_ohci(usb_dev)); return 0; } - -static void *ohci_alloc_isochronous (struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int maxsze, usb_device_irq completed, void *dev_id) +static int ohci_get_current_frame_number(struct usb_device *usb_dev) { - return NULL; + return USB_ST_NOTSUPPORTED; } -static void ohci_delete_isochronous (struct usb_device *dev, void *_isodesc) +static int ohci_alloc_isochronous (struct usb_device *usb_dev, +unsigned int pipe, int frame_count, void *context, +struct usb_isoc_desc **isocdesc) { - return; + return USB_ST_NOTSUPPORTED; } -static int ohci_sched_isochronous (struct usb_device *usb_dev, void *_isodesc, void *_pisodesc) +static void ohci_delete_isochronous (struct usb_isoc_desc *isocdesc) { - return USB_ST_NOTSUPPORTED; + return; } -static int ohci_unsched_isochronous (struct usb_device *usb_dev, void *_isodesc) +static int ohci_sched_isochronous (struct usb_isoc_desc *isocdesc, +struct usb_isoc_desc *pr_isocdesc) { return USB_ST_NOTSUPPORTED; } -static int ohci_compress_isochronous (struct usb_device *usb_dev, void *_isodesc) +static int ohci_unsched_isochronous (struct usb_isoc_desc *isocdesc) { return USB_ST_NOTSUPPORTED; } - /* * functions for the generic USB driver */ struct usb_operations ohci_device_operations = { - ohci_usb_allocate, - ohci_usb_deallocate, + ohci_dev_allocate, + ohci_dev_deallocate, ohci_control_msg, ohci_bulk_msg, ohci_request_irq, ohci_release_irq, ohci_request_bulk, ohci_terminate_bulk, + ohci_get_current_frame_number, ohci_alloc_isochronous, ohci_delete_isochronous, ohci_sched_isochronous, - ohci_unsched_isochronous, - ohci_compress_isochronous + ohci_unsched_isochronous }; @@ -1887,8 +1850,10 @@ /* Enter the USB Operational state & start the frames a flowing.. */ writel_set(OHCI_USB_OPER, &ohci->regs->control); - /* Enable control lists */ - writel_set(OHCI_USB_IE | OHCI_USB_CLE | OHCI_USB_BLE, &ohci->regs->control); + /* Enable control lists, claim the host controller */ + writel_set( + OHCI_USB_IE | OHCI_USB_CLE | OHCI_USB_BLE, + &ohci->regs->control); /* Force global power enable -gal@cs.uni-magdeburg.de */ /* @@ -1988,10 +1953,11 @@ /* * Allocate a device for the new thingy that's been attached */ - usb_dev = ohci_usb_allocate(root_hub->usb); - dev = usb_dev->hcpriv; + usb_dev = usb_alloc_dev(root_hub->usb, root_hub->usb->bus); + if (!usb_dev) + return; - dev->ohci = ohci; + dev = usb_dev->hcpriv; usb_connect(dev->usb); @@ -2360,6 +2326,8 @@ struct usb_bus *bus; struct ohci_device *dev; struct usb_device *usb; + struct ohci_hcca *hcca; + u32 ctrl; #if 0 printk(KERN_DEBUG "entering alloc_ohci %p\n", mem_base); @@ -2368,22 +2336,28 @@ ohci = kmalloc(sizeof(*ohci), GFP_KERNEL); if (!ohci) return NULL; - memset(ohci, 0, sizeof(*ohci)); ohci->irq = -1; ohci->regs = mem_base; INIT_LIST_HEAD(&ohci->interrupt_list); - bus = kmalloc(sizeof(*bus), GFP_KERNEL); - if (!bus) - return NULL; - - memset(bus, 0, sizeof(*bus)); + /* + * Allocate the Host Controller Communications Area on a 256 + * byte boundary. XXX take the easy way out and just grab a + * page as that's guaranteed to have a nice boundary. + */ + hcca = (struct ohci_hcca *) __get_free_page(GFP_KERNEL); + if (hcca == NULL) + goto au_free_ohci; + memset(hcca, 0, sizeof(struct ohci_hcca)); + + bus = usb_alloc_bus(&ohci_device_operations); + if (!bus) + goto au_free_hcca; ohci->bus = bus; bus->hcpriv = ohci; - bus->op = &ohci_device_operations; /* * Allocate the USB device structure and root hub. @@ -2393,25 +2367,21 @@ * a nice pool of memory with pointers to endpoint descriptors * for the different interrupts. */ - usb = ohci_usb_allocate(NULL); + usb = usb_alloc_dev(NULL, bus); if (!usb) - return NULL; + goto au_free_bus; - dev = usb_to_ohci(usb); - ohci->bus->root_hub= ohci_to_usb(dev); usb->bus = bus; + + dev = usb_to_ohci(usb); + dev->ohci = ohci; + dev->hcca = hcca; + + ohci->bus->root_hub = ohci_to_usb(dev); /* Initialize the root hub */ dev->ohci = ohci; /* link back to the controller */ - /* - * Allocate the Host Controller Communications Area on a 256 - * byte boundary. XXX take the easy way out and just grab a - * page as that's guaranteed to have a nice boundary. - */ - dev->hcca = (struct ohci_hcca *) __get_free_page(GFP_KERNEL); - memset(dev->hcca, 0, sizeof(struct ohci_hcca)); - /* Tell the controller where the HCCA is */ writel(virt_to_bus(dev->hcca), &ohci->regs->hcca); @@ -2431,6 +2401,25 @@ } printk(KERN_DEBUG "usb-ohci: %d root hub ports found\n", usb->maxchild); + + /* + * Fix up legacy mode + */ + + ctrl = readl(&ohci->regs->control); + if(ctrl&OHCI_USB_IR) + { + int ct = 0; + /* Ask SMM for the controls */ + writel(8, &ohci->regs->cmdstatus); + printk(KERN_INFO "usb-ohci: switching interface from legacy mode.\n"); + while((readl(&ohci->regs->control)&OHCI_USB_IR) && ct < 250) + { + udelay(100); + ct++; + } + } + /* * Initialize the ED polling "tree" (for simplicity's sake in * this driver many nodes in the tree will be identical) @@ -2485,6 +2474,15 @@ #endif return ohci; + +au_free_bus: + usb_free_bus(bus); +au_free_hcca: + free_page((unsigned long)hcca); +au_free_ohci: + kfree(ohci); + return NULL; + } /* alloc_ohci() */ @@ -2752,6 +2750,8 @@ /* If its OHCI, its memory */ if (mem_base & PCI_BASE_ADDRESS_SPACE_IO) return -ENODEV; + + pci_set_master(dev); /* Get the memory address and map it for IO */ mem_base = dev->resource[0].start; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/ohci.h linux.ac/drivers/usb/ohci.h --- linux.vanilla/drivers/usb/ohci.h Thu Aug 5 20:30:23 1999 +++ linux.ac/drivers/usb/ohci.h Mon Sep 20 16:23:38 1999 @@ -6,7 +6,7 @@ * * (C) Copyright 1999 Gregory P. Smith * - * $Id: ohci.h,v 1.24 1999/05/16 10:18:26 greg Exp $ + * $Id: ohci.h,v 1.40 1999/09/05 07:26:46 greg Exp $ */ #include @@ -148,19 +148,45 @@ #define OHCI_ED_EN (0xf << 7) #define OHCI_ED_FA (0x7f) + #define ed_get_en(ed) ((le32_to_cpup(&(ed)->status) & OHCI_ED_EN) >> 7) #define ed_get_fa(ed) (le32_to_cpup(&(ed)->status) & OHCI_ED_FA) /* NOTE: bits 27-31 of the status dword are reserved for the HCD */ +#define OHCI_ED_HCD_MASK (0x1f << 27) /* * We'll use this status flag for to mark if an ED is in use by the - * driver or not. If the bit is set, it is being used. + * driver or not. If the bit is set, it is being used. (bit 31) */ #define ED_ALLOCATED (1 << 31) #define ed_allocated(ed) (le32_to_cpup(&(ed).status) & ED_ALLOCATED) #define allocate_ed(ed) ((ed)->status |= cpu_to_le32(ED_ALLOCATED)) /* + * These store the endpoint transfer type for this ED in the status + * field. (bits 27 and 28) + * Bit 28: + * 0 = Periodic ED + * Bit 27: + * 0 = Isochronous + * 1 = Interrupt + * 1 = Normal ED + * Bit 27: + * 0 = Control + * 1 = Bulk + */ +#define HCD_ED_NORMAL (1 << 28) /* (2 << 27) */ +#define HCD_ED_ISOC (0) +#define HCD_ED_INT (1 << 27) +#define HCD_ED_CONTROL (2 << 27) +#define HCD_ED_BULK (3 << 27) +#define HCD_ED_MASK (3 << 27) + +#define ohci_ed_hcdtype(ed) (le32_to_cpup(&(ed)->status) & HCD_ED_MASK) +#define ohci_ed_set_hcdtype(ed, t) ( (ed)->status = ((ed)->status & ~cpu_to_le32(HCD_ED_MASK)) | cpu_to_le32((t) & HCD_ED_MASK) ) + + +/* * The HCCA (Host Controller Communications Area) is a 256 byte * structure defined in the OHCI spec. that the host controller is * told the base address of. It must be 256-byte aligned. @@ -299,15 +325,6 @@ } roothub; } __attribute((aligned(32))); -/* - * These are used by internal ED managing functions as a - * parameter to state the type of ED to deal with (when it matters). - */ -#define HCD_ED_ISOC (0) -#define HCD_ED_INT (1) -#define HCD_ED_CONTROL (2) -#define HCD_ED_BULK (3) - /* * Read a MMIO register and re-write it after ANDing with (m) */ @@ -368,12 +385,16 @@ /* * Control register masks */ +#define OHCI_USB_RESUME (1 << 6) #define OHCI_USB_OPER (2 << 6) #define OHCI_USB_SUSPEND (3 << 6) #define OHCI_USB_PLE (1 << 2) /* Periodic (interrupt) list enable */ #define OHCI_USB_IE (1 << 3) /* Isochronous list enable */ #define OHCI_USB_CLE (1 << 4) /* Control list enable */ #define OHCI_USB_BLE (1 << 5) /* Bulk list enable */ +#define OHCI_USB_IR (1 << 8) /* Int. Routing, HCD ownership */ +#define OHCI_USB_RWC (1 << 9) /* Remote Wakeup Connected */ +#define OHCI_USB_RWE (1 << 10) /* Remote Wakeup Enable */ /* * Command status register masks diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/printer.c linux.ac/drivers/usb/printer.c --- linux.vanilla/drivers/usb/printer.c Sat Sep 11 00:54:11 1999 +++ linux.ac/drivers/usb/printer.c Mon Sep 20 16:59:20 1999 @@ -58,7 +58,7 @@ dr.value = 0; dr.index = 0; dr.length = 1; - if (dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, &status, 1)) { + if (dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, &status, 1, HZ)) { return 0; } return status; @@ -104,7 +104,7 @@ dr.value = 0; dr.index = 0; dr.length = 0; - dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); + dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0, HZ); } static int open_printer(struct inode * inode, struct file * file) @@ -129,10 +129,11 @@ printer_check_status(p); - file->private_data = p; // printer_reset(p); init_waitqueue_head(&p->wait_q); + + MOD_INC_USE_COUNT; return 0; } @@ -143,13 +144,12 @@ free_page((unsigned long)p->obuf); p->isopen = 0; file->private_data = NULL; + /* free the resources if the printer is no longer around */ if(!p->pusb_dev) { minor_data[p->minor] = NULL; kfree(p); - - MOD_DEC_USE_COUNT; - } + MOD_DEC_USE_COUNT; return 0; } @@ -184,7 +184,7 @@ } result = p->pusb_dev->bus->op->bulk_msg(p->pusb_dev, usb_sndbulkpipe(p->pusb_dev, endpoint_num), - obuf, thistime, &partial); + obuf, thistime, &partial, HZ*20); if (partial) { obuf += partial; thistime -= partial; @@ -243,7 +243,7 @@ result = p->pusb_dev->bus->op->bulk_msg(p->pusb_dev, usb_rcvbulkpipe(p->pusb_dev, endpoint_num), - buf, this_read, &partial); + buf, this_read, &partial, HZ*20); /* unlike writes, we don't retry a NAK, just stop now */ if (!result & partial) @@ -344,7 +344,7 @@ dr.value = 0; dr.index = 0; dr.length = sizeof(ieee_id) - 1; - if (dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, ieee_id, sizeof(ieee_id)-1) == 0) { + if (dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, ieee_id, sizeof(ieee_id)-1, HZ) == 0) { if (ieee_id[1] < sizeof(ieee_id) - 1) ieee_id[ieee_id[1]+2] = '\0'; else @@ -373,7 +373,6 @@ minor_data[pp->minor] = NULL; kfree(pp); dev->private = NULL; /* just in case */ - MOD_DEC_USE_COUNT; } static struct usb_driver printer_driver = { @@ -402,8 +401,6 @@ { int result; - MOD_INC_USE_COUNT; - if ((result = register_chrdev(USB_PRINTER_MAJOR, "usblp", &usb_printer_fops)) < 0) { printk(KERN_WARNING "usbprinter: Cannot register device\n"); return result; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/proc_usb.c linux.ac/drivers/usb/proc_usb.c --- linux.vanilla/drivers/usb/proc_usb.c Sat Sep 11 00:54:11 1999 +++ linux.ac/drivers/usb/proc_usb.c Mon Sep 20 15:52:50 1999 @@ -509,8 +509,10 @@ struct usb_device *dev = (struct usb_device *)dp->data; struct ezusb_ctrltransfer ctrl; struct ezusb_bulktransfer bulk; + struct ezusb_old_ctrltransfer octrl; + struct ezusb_old_bulktransfer obulk; struct ezusb_setinterface setintf; - unsigned int len1, ep, pipe; + unsigned int len1, ep, pipe, cfg; unsigned long len2; unsigned char *tbuf; int i; @@ -525,24 +527,28 @@ if (!capable(CAP_SYS_RAWIO)) return -EPERM; copy_from_user_ret(&ctrl, (void *)arg, sizeof(ctrl), -EFAULT); - if (ctrl.dlen > PAGE_SIZE) + if (ctrl.length > PAGE_SIZE) return -EINVAL; if (!(tbuf = (unsigned char *)__get_free_page(GFP_KERNEL))) return -ENOMEM; if (ctrl.requesttype & 0x80) { - if (ctrl.dlen && !access_ok(VERIFY_WRITE, ctrl.data, ctrl.dlen)) { + if (ctrl.length && !access_ok(VERIFY_WRITE, ctrl.data, ctrl.length)) { free_page((unsigned long)tbuf); return -EINVAL; } - i = dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev, 0), (devrequest *)&ctrl, tbuf, ctrl.dlen); - if (!i && ctrl.dlen) { - copy_to_user_ret(ctrl.data, tbuf, ctrl.dlen, -EFAULT); + i = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ctrl.request, ctrl.requesttype, + ctrl.value, ctrl.index, tbuf, ctrl.length, + (ctrl.timeout * HZ + 500) / 1000); + if (!i && ctrl.length) { + copy_to_user_ret(ctrl.data, tbuf, ctrl.length, -EFAULT); } } else { - if (ctrl.dlen) { - copy_from_user_ret(tbuf, ctrl.data, ctrl.dlen, -EFAULT); + if (ctrl.length) { + copy_from_user_ret(tbuf, ctrl.data, ctrl.length, -EFAULT); } - i = dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev, 0), (devrequest *)&ctrl, tbuf, ctrl.dlen); + i = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ctrl.request, ctrl.requesttype, + ctrl.value, ctrl.index, tbuf, ctrl.length, + (ctrl.timeout * HZ + 500) / 1000); } free_page((unsigned long)tbuf); if (i) { @@ -577,7 +583,7 @@ free_page((unsigned long)tbuf); return -EINVAL; } - i = dev->bus->op->bulk_msg(dev, pipe, tbuf, len1, &len2); + i = dev->bus->op->bulk_msg(dev, pipe, tbuf, len1, &len2, (ctrl.timeout * HZ + 500) / 1000); if (!i && len2) { copy_to_user_ret(bulk.data, tbuf, len2, -EFAULT); } @@ -585,7 +591,7 @@ if (len1) { copy_from_user_ret(tbuf, bulk.data, len1, -EFAULT); } - i = dev->bus->op->bulk_msg(dev, pipe, tbuf, len1, &len2); + i = dev->bus->op->bulk_msg(dev, pipe, tbuf, len1, &len2, (ctrl.timeout * HZ + 500) / 1000); } free_page((unsigned long)tbuf); if (i) { @@ -595,6 +601,85 @@ } return len2; + case EZUSB_OLD_CONTROL: + if (obsolete_warn < 20) { + printk(KERN_WARNING "/proc/bus/usb: process %d (%s) used obsolete EZUSB_OLD_CONTROL ioctl\n", + current->pid, current->comm); + obsolete_warn++; + } + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + copy_from_user_ret(&octrl, (void *)arg, sizeof(octrl), -EFAULT); + if (octrl.dlen > PAGE_SIZE) + return -EINVAL; + if (!(tbuf = (unsigned char *)__get_free_page(GFP_KERNEL))) + return -ENOMEM; + if (octrl.requesttype & 0x80) { + if (octrl.dlen && !access_ok(VERIFY_WRITE, octrl.data, octrl.dlen)) { + free_page((unsigned long)tbuf); + return -EINVAL; + } + i = dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev, 0), (devrequest *)&octrl, tbuf, octrl.dlen, HZ); + if (!i && octrl.dlen) { + copy_to_user_ret(octrl.data, tbuf, octrl.dlen, -EFAULT); + } + } else { + if (octrl.dlen) { + copy_from_user_ret(tbuf, octrl.data, octrl.dlen, -EFAULT); + } + i = dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev, 0), (devrequest *)&octrl, tbuf, octrl.dlen, HZ); + } + free_page((unsigned long)tbuf); + if (i) { + printk(KERN_WARNING "procusb: EZUSB_OLD_CONTROL failed rqt %u rq %u len %u ret %d\n", + octrl.requesttype, octrl.request, octrl.length, i); + return -ENXIO; + } + return 0; + + case EZUSB_OLD_BULK: + if (obsolete_warn < 20) { + printk(KERN_WARNING "/proc/bus/usb: process %d (%s) used obsolete EZUSB_OLD_BULK ioctl\n", + current->pid, current->comm); + obsolete_warn++; + } + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + copy_from_user_ret(&obulk, (void *)arg, sizeof(obulk), -EFAULT); + if (obulk.ep & 0x80) + pipe = usb_rcvbulkpipe(dev, obulk.ep & 0x7f); + else + pipe = usb_sndbulkpipe(dev, obulk.ep & 0x7f); + if (!usb_maxpacket(dev, pipe, !(obulk.ep & 0x80))) + return -EINVAL; + len1 = obulk.len; + if (len1 > PAGE_SIZE) + len1 = PAGE_SIZE; + if (!(tbuf = (unsigned char *)__get_free_page(GFP_KERNEL))) + return -ENOMEM; + if (obulk.ep & 0x80) { + if (len1 && !access_ok(VERIFY_WRITE, obulk.data, len1)) { + free_page((unsigned long)tbuf); + return -EINVAL; + } + i = dev->bus->op->bulk_msg(dev, pipe, tbuf, len1, &len2, HZ*5); + if (!i && len2) { + copy_to_user_ret(obulk.data, tbuf, len2, -EFAULT); + } + } else { + if (len1) { + copy_from_user_ret(tbuf, obulk.data, len1, -EFAULT); + } + i = dev->bus->op->bulk_msg(dev, pipe, tbuf, len1, &len2, HZ*5); + } + free_page((unsigned long)tbuf); + if (i) { + printk(KERN_WARNING "procusb: EZUSB_OLD_BULK failed ep 0x%x len %u ret %d\n", + obulk.ep, obulk.len, i); + return -ENXIO; + } + return len2; + case EZUSB_RESETEP: if (obsolete_warn < 20) { printk(KERN_WARNING "/proc/bus/usb: process %d (%s) used obsolete EZUSB_RESETEP ioctl\n", @@ -621,6 +706,20 @@ if (usb_set_interface(dev, setintf.interface, setintf.altsetting)) return -EINVAL; return 0; + + case EZUSB_SETCONFIGURATION: + if (obsolete_warn < 20) { + printk(KERN_WARNING "/proc/bus/usb: process %d (%s) used obsolete EZUSB_SETCONFIGURATION ioctl\n", + current->pid, current->comm); + obsolete_warn++; + } + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + get_user_ret(cfg, (unsigned int *)arg, -EFAULT); + if (usb_set_configuration(dev, cfg) < 0) + return -EINVAL; + return 0; + } return -ENOIOCTLCMD; } @@ -633,8 +732,10 @@ struct usb_device *dev = (struct usb_device *)dp->data; struct usb_proc_ctrltransfer ctrl; struct usb_proc_bulktransfer bulk; + struct usb_proc_old_ctrltransfer octrl; + struct usb_proc_old_bulktransfer obulk; struct usb_proc_setinterface setintf; - unsigned int len1, ep, pipe; + unsigned int len1, ep, pipe, cfg; unsigned long len2; unsigned char *tbuf; int i; @@ -655,7 +756,7 @@ } i = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ctrl.request, ctrl.requesttype, ctrl.value, ctrl.index, tbuf, - ctrl.length); + ctrl.length, (ctrl.timeout * HZ + 500) / 1000); if (!i && ctrl.length) { copy_to_user_ret(ctrl.data, tbuf, ctrl.length, -EFAULT); } @@ -665,7 +766,7 @@ } i = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ctrl.request, ctrl.requesttype, ctrl.value, ctrl.index, tbuf, - ctrl.length); + ctrl.length, (ctrl.timeout * HZ + 500) / 1000); } free_page((unsigned long)tbuf); if (i) { @@ -695,7 +796,7 @@ free_page((unsigned long)tbuf); return -EINVAL; } - i = dev->bus->op->bulk_msg(dev, pipe, tbuf, len1, &len2); + i = dev->bus->op->bulk_msg(dev, pipe, tbuf, len1, &len2, (bulk.timeout * HZ + 500) / 1000); if (!i && len2) { copy_to_user_ret(bulk.data, tbuf, len2, -EFAULT); } @@ -703,7 +804,7 @@ if (len1) { copy_from_user_ret(tbuf, bulk.data, len1, -EFAULT); } - i = dev->bus->op->bulk_msg(dev, pipe, tbuf, len1, &len2); + i = dev->bus->op->bulk_msg(dev, pipe, tbuf, len1, &len2, (bulk.timeout * HZ + 500) / 1000); } free_page((unsigned long)tbuf); if (i) { @@ -713,6 +814,79 @@ } return len2; + case USB_PROC_OLD_CONTROL: + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + copy_from_user_ret(&octrl, (void *)arg, sizeof(octrl), -EFAULT); + if (octrl.length > PAGE_SIZE) + return -EINVAL; + if (!(tbuf = (unsigned char *)__get_free_page(GFP_KERNEL))) + return -ENOMEM; + if (octrl.requesttype & 0x80) { + if (octrl.length && !access_ok(VERIFY_WRITE, octrl.data, octrl.length)) { + free_page((unsigned long)tbuf); + return -EINVAL; + } + i = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), octrl.request, + octrl.requesttype, octrl.value, octrl.index, tbuf, + octrl.length, HZ); + if (!i && octrl.length) { + copy_to_user_ret(octrl.data, tbuf, octrl.length, -EFAULT); + } + } else { + if (octrl.length) { + copy_from_user_ret(tbuf, octrl.data, octrl.length, -EFAULT); + } + i = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), octrl.request, + octrl.requesttype, octrl.value, octrl.index, tbuf, + octrl.length, HZ); + } + free_page((unsigned long)tbuf); + if (i) { + printk(KERN_WARNING "/proc/bus/usb: USB_PROC_OLD_CONTROL failed rqt %u rq %u len %u ret %d\n", + octrl.requesttype, octrl.request, octrl.length, i); + return -ENXIO; + } + return 0; + + case USB_PROC_OLD_BULK: + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + copy_from_user_ret(&obulk, (void *)arg, sizeof(obulk), -EFAULT); + if (obulk.ep & 0x80) + pipe = usb_rcvbulkpipe(dev, obulk.ep & 0x7f); + else + pipe = usb_sndbulkpipe(dev, obulk.ep & 0x7f); + if (!usb_maxpacket(dev, pipe, !(obulk.ep & 0x80))) + return -EINVAL; + len1 = obulk.len; + if (len1 > PAGE_SIZE) + len1 = PAGE_SIZE; + if (!(tbuf = (unsigned char *)__get_free_page(GFP_KERNEL))) + return -ENOMEM; + if (obulk.ep & 0x80) { + if (len1 && !access_ok(VERIFY_WRITE, obulk.data, len1)) { + free_page((unsigned long)tbuf); + return -EINVAL; + } + i = dev->bus->op->bulk_msg(dev, pipe, tbuf, len1, &len2, HZ*5); + if (!i && len2) { + copy_to_user_ret(obulk.data, tbuf, len2, -EFAULT); + } + } else { + if (len1) { + copy_from_user_ret(tbuf, obulk.data, len1, -EFAULT); + } + i = dev->bus->op->bulk_msg(dev, pipe, tbuf, len1, &len2, HZ*5); + } + free_page((unsigned long)tbuf); + if (i) { + printk(KERN_WARNING "/proc/bus/usb: USB_PROC_OLD_BULK failed ep 0x%x len %u ret %d\n", + obulk.ep, obulk.len, i); + return -ENXIO; + } + return len2; + case USB_PROC_RESETEP: if (!capable(CAP_SYS_RAWIO)) return -EPERM; @@ -730,10 +904,21 @@ return -EINVAL; return 0; + case USB_PROC_SETCONFIGURATION: + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + get_user_ret(cfg, (unsigned int *)arg, -EFAULT); + if (usb_set_configuration(dev, cfg) < 0) + return -EINVAL; + return 0; + case EZUSB_CONTROL: case EZUSB_BULK: + case EZUSB_OLD_CONTROL: + case EZUSB_OLD_BULK: case EZUSB_RESETEP: case EZUSB_SETINTERFACE: + case EZUSB_SETCONFIGURATION: return usbdev_ioctl_ezusbcompat(inode, file, cmd, arg); } return -ENOIOCTLCMD; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/uchi.h linux.ac/drivers/usb/uchi.h --- linux.vanilla/drivers/usb/uchi.h Thu Jan 1 01:00:00 1970 +++ linux.ac/drivers/usb/uchi.h Thu Sep 16 17:14:46 1999 @@ -0,0 +1,293 @@ +#ifndef __LINUX_UHCI_H +#define __LINUX_UHCI_H + +#include + +#include "usb.h" + +/* + * Universal Host Controller Interface data structures and defines + */ + +/* Command register */ +#define USBCMD 0 +#define USBCMD_RS 0x0001 /* Run/Stop */ +#define USBCMD_HCRESET 0x0002 /* Host reset */ +#define USBCMD_GRESET 0x0004 /* Global reset */ +#define USBCMD_EGSM 0x0008 /* Global Suspend Mode */ +#define USBCMD_FGR 0x0010 /* Force Global Resume */ +#define USBCMD_SWDBG 0x0020 /* SW Debug mode */ +#define USBCMD_CF 0x0040 /* Config Flag (sw only) */ +#define USBCMD_MAXP 0x0080 /* Max Packet (0 = 32, 1 = 64) */ + +/* Status register */ +#define USBSTS 2 +#define USBSTS_USBINT 0x0001 /* Interrupt due to IOC */ +#define USBSTS_ERROR 0x0002 /* Interrupt due to error */ +#define USBSTS_RD 0x0004 /* Resume Detect */ +#define USBSTS_HSE 0x0008 /* Host System Error - basically PCI problems */ +#define USBSTS_HCPE 0x0010 /* Host Controller Process Error - the scripts were buggy */ +#define USBSTS_HCH 0x0020 /* HC Halted */ + +/* Interrupt enable register */ +#define USBINTR 4 +#define USBINTR_TIMEOUT 0x0001 /* Timeout/CRC error enable */ +#define USBINTR_RESUME 0x0002 /* Resume interrupt enable */ +#define USBINTR_IOC 0x0004 /* Interrupt On Complete enable */ +#define USBINTR_SP 0x0008 /* Short packet interrupt enable */ + +#define USBFRNUM 6 +#define USBFLBASEADD 8 +#define USBSOF 12 + +/* USB port status and control registers */ +#define USBPORTSC1 16 +#define USBPORTSC2 18 +#define USBPORTSC_CCS 0x0001 /* Current Connect Status ("device present") */ +#define USBPORTSC_CSC 0x0002 /* Connect Status Change */ +#define USBPORTSC_PE 0x0004 /* Port Enable */ +#define USBPORTSC_PEC 0x0008 /* Port Enable Change */ +#define USBPORTSC_LS 0x0030 /* Line Status */ +#define USBPORTSC_RD 0x0040 /* Resume Detect */ +#define USBPORTSC_LSDA 0x0100 /* Low Speed Device Attached */ +#define USBPORTSC_PR 0x0200 /* Port Reset */ +#define USBPORTSC_SUSP 0x1000 /* Suspend */ + +#define UHCI_NULL_DATA_SIZE 0x7ff /* for UHCI controller TD */ + +#define UHCI_PTR_BITS 0x000F +#define UHCI_PTR_TERM 0x0001 +#define UHCI_PTR_QH 0x0002 +#define UHCI_PTR_DEPTH 0x0004 + +#define UHCI_NUMFRAMES 1024 /* in the frame list [array] */ +#define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ +#define CAN_SCHEDULE_FRAMES 1000 /* how far future frames can be scheduled */ + +struct uhci_td; + +struct uhci_qh { + /* Hardware fields */ + __u32 link; /* Next queue */ + __u32 element; /* Queue element pointer */ + + /* Software fields */ + atomic_t refcnt; /* Reference counting */ + struct uhci_device *dev; /* The owning device */ + struct uhci_qh *skel; /* Skeleton head */ + + struct uhci_td *first; /* First TD in the chain */ + + wait_queue_head_t wakeup; +} __attribute__((aligned(16))); + +struct uhci_framelist { + __u32 frame[UHCI_NUMFRAMES]; +} __attribute__((aligned(4096))); + +/* + * for TD : + */ +#define TD_CTRL_SPD (1 << 29) /* Short Packet Detect */ +#define TD_CTRL_C_ERR_MASK (3 << 27) /* Error Counter bits */ +#define TD_CTRL_LS (1 << 26) /* Low Speed Device */ +#define TD_CTRL_IOS (1 << 25) /* Isochronous Select */ +#define TD_CTRL_IOC (1 << 24) /* Interrupt on Complete */ +#define TD_CTRL_ACTIVE (1 << 23) /* TD Active */ +#define TD_CTRL_STALLED (1 << 22) /* TD Stalled */ +#define TD_CTRL_DBUFERR (1 << 21) /* Data Buffer Error */ +#define TD_CTRL_BABBLE (1 << 20) /* Babble Detected */ +#define TD_CTRL_NAK (1 << 19) /* NAK Received */ +#define TD_CTRL_CRCTIMEO (1 << 18) /* CRC/Time Out Error */ +#define TD_CTRL_BITSTUFF (1 << 17) /* Bit Stuff Error */ +#define TD_CTRL_ACTLEN_MASK 0x7ff /* actual length, encoded as n - 1 */ + +#define TD_CTRL_ANY_ERROR (TD_CTRL_STALLED | TD_CTRL_DBUFERR | \ + TD_CTRL_BABBLE | TD_CTRL_CRCTIME | TD_CTRL_BITSTUFF) + +#define uhci_status_bits(ctrl_sts) (ctrl_sts & 0xFE0000) +#define uhci_actual_length(ctrl_sts) ((ctrl_sts + 1) & TD_CTRL_ACTLEN_MASK) /* 1-based */ + +#define uhci_ptr_to_virt(x) bus_to_virt(x & ~UHCI_PTR_BITS) + +/* + * for TD : + */ +#define UHCI_TD_REMOVE 0x0001 /* Remove when done */ + +/* + * for TD : (a.k.a. Token) + */ +#define TD_TOKEN_TOGGLE 19 + +#define uhci_maxlen(token) ((token) >> 21) +#define uhci_toggle(token) (((token) >> TD_TOKEN_TOGGLE) & 1) +#define uhci_endpoint(token) (((token) >> 15) & 0xf) +#define uhci_devaddr(token) (((token) >> 8) & 0x7f) +#define uhci_devep(token) (((token) >> 8) & 0x7ff) +#define uhci_packetid(token) ((token) & 0xff) +#define uhci_packetout(token) (uhci_packetid(token) != USB_PID_IN) +#define uhci_packetin(token) (uhci_packetid(token) == USB_PID_IN) + + +/* + * The documentation says "4 words for hardware, 4 words for software". + * + * That's silly, the hardware doesn't care. The hardware only cares that + * the hardware words are 16-byte aligned, and we can have any amount of + * sw space after the TD entry as far as I can tell. + * + * But let's just go with the documentation, at least for 32-bit machines. + * On 64-bit machines we probably want to take advantage of the fact that + * hw doesn't really care about the size of the sw-only area. + * + * Alas, not anymore, we have more than 4 words for software, woops + */ +struct uhci_td { + /* Hardware fields */ + __u32 link; + __u32 status; + __u32 info; + __u32 buffer; + + /* Software fields */ + unsigned int *backptr; /* Where to remove this from.. */ + struct list_head irq_list; /* Active interrupt list.. */ + + usb_device_irq completed; /* Completion handler routine */ + void *dev_id; + + atomic_t refcnt; /* Reference counting */ + struct uhci_device *dev; /* The owning device */ + struct uhci_qh *qh; /* QH this TD is a part of (ignored for Isochronous) */ + int flags; /* Remove, etc */ + int isoc_td_number; /* 0-relative number within a usb_isoc_desc. */ +} __attribute__((aligned(16))); + + +/* + * Note the alignment requirements of the entries + * + * Each UHCI device has pre-allocated QH and TD entries. + * You can use more than the pre-allocated ones, but I + * don't see you usually needing to. + */ +struct uhci; + +#if 0 +#define UHCI_MAXTD 64 + +#define UHCI_MAXQH 16 +#endif + +/* The usb device part must be first! Not anymore -jerdfelt */ +struct uhci_device { + struct usb_device *usb; + + atomic_t refcnt; + + struct uhci *uhci; +#if 0 + struct uhci_qh qh[UHCI_MAXQH]; /* These are the "common" qh's for each device */ + struct uhci_td td[UHCI_MAXTD]; +#endif + + unsigned long data[16]; +}; + +#define uhci_to_usb(uhci) ((uhci)->usb) +#define usb_to_uhci(usb) ((struct uhci_device *)(usb)->hcpriv) + +/* + * There are various standard queues. We set up several different + * queues for each of the three basic queue types: interrupt, + * control, and bulk. + * + * - There are various different interrupt latencies: ranging from + * every other USB frame (2 ms apart) to every 256 USB frames (ie + * 256 ms apart). Make your choice according to how obnoxious you + * want to be on the wire, vs how critical latency is for you. + * - The control list is done every frame. + * - There are 4 bulk lists, so that up to four devices can have a + * bulk list of their own and when run concurrently all four lists + * will be be serviced. + * + * This is a bit misleading, there are various interrupt latencies, but they + * vary a bit, interrupt2 isn't exactly 2ms, it can vary up to 4ms since the + * other queues can "override" it. interrupt4 can vary up to 8ms, etc. Minor + * problem + * + * In the case of the root hub, these QH's are just head's of qh's. Don't + * be scared, it kinda makes sense. Look at this wonderful picture care of + * Linus: + * + * generic-iso-QH -> dev1-iso-QH -> generic-irq-QH -> dev1-irq-QH -> ... + * | | | | + * End dev1-iso-TD1 End dev1-irq-TD1 + * | + * dev1-iso-TD2 + * | + * .... + * + * This may vary a bit (the UHCI docs don't explicitly say you can put iso + * transfers in QH's and all of their pictures don't have that either) but + * other than that, that is what we're doing now + * + * And now we don't put Iso transfers in QH's, so we don't waste one on it + * + * To keep with Linus' nomenclature, this is called the QH skeleton. These + * labels (below) are only signficant to the root hub's QH's + */ +#define UHCI_NUM_SKELQH 10 + +#define skel_int2_qh skelqh[0] +#define skel_int4_qh skelqh[1] +#define skel_int8_qh skelqh[2] +#define skel_int16_qh skelqh[3] +#define skel_int32_qh skelqh[4] +#define skel_int64_qh skelqh[5] +#define skel_int128_qh skelqh[6] +#define skel_int256_qh skelqh[7] + +#define skel_control_qh skelqh[8] + +#define skel_bulk_qh skelqh[9] + +/* + * This describes the full uhci information. + * + * Note how the "proper" USB information is just + * a subset of what the full implementation needs. + */ +struct uhci { + int irq; + unsigned int io_addr; + unsigned int io_size; + + int control_pid; + int control_running; + int control_continue; + + struct list_head uhci_list; + + struct usb_bus *bus; + + struct uhci_qh skelqh[UHCI_NUM_SKELQH]; /* Skeleton QH's */ + + struct uhci_framelist *fl; /* Frame list */ + struct list_head interrupt_list; /* List of interrupt-active TD's for this uhci */ + + struct uhci_td *ticktd; +}; + +/* needed for the debugging code */ +struct uhci_td *uhci_link_to_td(unsigned int element); + +/* Debugging code */ +void uhci_show_td(struct uhci_td *td); +void uhci_show_status(struct uhci *uhci); +void uhci_show_queue(struct uhci_qh *qh); +void uhci_show_queues(struct uhci *uhci); + +#endif + diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/uhci.c linux.ac/drivers/usb/uhci.c --- linux.vanilla/drivers/usb/uhci.c Sat Sep 11 00:54:11 1999 +++ linux.ac/drivers/usb/uhci.c Mon Sep 20 16:58:18 1999 @@ -1035,7 +1035,7 @@ } /* td points to the last td in the list, which interrupts on completion */ -static int uhci_run_control(struct uhci_device *dev, struct uhci_td *first, struct uhci_td *last) +static int uhci_run_control(struct uhci_device *dev, struct uhci_td *first, struct uhci_td *last, int timeout) { DECLARE_WAITQUEUE(wait, current); struct uhci_qh *qh = uhci_qh_alloc(dev); @@ -1053,7 +1053,8 @@ /* Add it into the skeleton */ uhci_insert_qh(&dev->uhci->skel_control_qh, qh); - schedule_timeout(HZ * 5); /* 5 seconds */ + /* wait a user specified reasonable amount of time */ + schedule_timeout(timeout); remove_wait_queue(&qh->wakeup, &wait); @@ -1094,7 +1095,7 @@ * there is no restriction on length of transfers * anymore */ -static int uhci_control_msg(struct usb_device *usb_dev, unsigned int pipe, devrequest *cmd, void *data, int len) +static int uhci_control_msg(struct usb_device *usb_dev, unsigned int pipe, devrequest *cmd, void *data, int len, int timeout) { struct uhci_device *dev = usb_to_uhci(usb_dev); struct uhci_td *first, *td, *prevtd; @@ -1184,7 +1185,7 @@ td->link = UHCI_PTR_TERM; /* Terminate */ /* Start it up.. */ - ret = uhci_run_control(dev, first, td); + ret = uhci_run_control(dev, first, td, timeout); count = 1000; td = first; @@ -1231,7 +1232,7 @@ */ /* td points to the last td in the list, which interrupts on completion */ -static int uhci_run_bulk(struct uhci_device *dev, struct uhci_td *first, struct uhci_td *last, unsigned long *rval) +static int uhci_run_bulk(struct uhci_device *dev, struct uhci_td *first, struct uhci_td *last, unsigned long *rval, int timeout) { DECLARE_WAITQUEUE(wait, current); struct uhci_qh *qh = uhci_qh_alloc(dev); @@ -1249,7 +1250,8 @@ /* Add it into the skeleton */ uhci_insert_qh(&dev->uhci->skel_bulk_qh, qh); - schedule_timeout(HZ * 5); /* 5 seconds */ + /* wait a user specified reasonable amount of time */ + schedule_timeout(timeout); remove_wait_queue(&qh->wakeup, &wait); @@ -1272,7 +1274,7 @@ * A bulk message is only built up from * the data phase */ -static int uhci_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, unsigned long *rval) +static int uhci_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, unsigned long *rval, int timeout) { struct uhci_device *dev = usb_to_uhci(usb_dev); struct uhci_td *first, *td, *prevtd; @@ -1334,7 +1336,7 @@ /* CHANGE DIRECTION HERE! SAVE IT SOMEWHERE IN THE ENDPOINT!!! */ /* Start it up.. */ - ret = uhci_run_bulk(dev, first, td, rval); + ret = uhci_run_bulk(dev, first, td, rval, timeout); { int count = 100; @@ -1570,6 +1572,7 @@ } while (nr < maxchild); } +#if 0 static int fixup_isoc_desc (struct uhci_td *td) { struct usb_isoc_desc *isocdesc = td->dev_id; @@ -1621,6 +1624,7 @@ return 0; } +#endif /* 0 */ static void uhci_interrupt_notify(struct uhci *uhci) { @@ -2097,7 +2101,7 @@ for (i = 0; i < 6; i++) { unsigned int io_addr = dev->resource[i].start; unsigned int io_size = - dev->resource[i].end - dev->resource[i].start; + dev->resource[i].end - dev->resource[i].start + 1; /* IO address? */ if (!(dev->resource[i].flags & 1)) diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/usb-core.c linux.ac/drivers/usb/usb-core.c --- linux.vanilla/drivers/usb/usb-core.c Tue Sep 7 22:07:06 1999 +++ linux.ac/drivers/usb/usb-core.c Thu Sep 16 16:15:45 1999 @@ -31,6 +31,9 @@ int usb_init(void) { +#ifdef CONFIG_USB_PROC + proc_usb_init (); +#endif #ifndef CONFIG_USB_MODULE # ifdef CONFIG_USB_UHCI uhci_init(); @@ -68,9 +71,6 @@ # ifdef CONFIG_USB_SCSI usb_scsi_init(); # endif -#endif -#ifdef CONFIG_USB_PROC - proc_usb_init (); #endif return 0; } diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/usb.c linux.ac/drivers/usb/usb.c --- linux.vanilla/drivers/usb/usb.c Sat Sep 11 00:54:11 1999 +++ linux.ac/drivers/usb/usb.c Sat Sep 18 01:50:54 1999 @@ -22,6 +22,11 @@ #include "usb.h" +static int usb_find_driver(struct usb_device *); +static void usb_check_support(struct usb_device *); +static void usb_driver_purge(struct usb_driver *, struct usb_device *); + + /* * We have a per-interface "registered driver" list. */ @@ -179,7 +184,8 @@ new_alloc = old_alloc + bustime; /* what new total allocated bus time would be */ - PRINTD ("usb-bandwidth-alloc: was: %ld, new: %ld, bustime = %ld us, Pipe allowed: %s", + PRINTD ("usb-bandwidth-alloc: was: %u, new: %u, " + "bustime = %ld us, Pipe allowed: %s", old_alloc, new_alloc, bustime, (new_alloc <= FRAME_TIME_MAX_USECS_ALLOC) ? "yes" : "no"); @@ -318,7 +324,6 @@ { if (atomic_dec_and_test(&dev->refcnt)) { usb_destroy_configuration(dev); - dev->bus->op->deallocate(dev); kfree(dev); } @@ -681,7 +686,7 @@ dr.index = 0; dr.length = 0; - return dev->bus->op->control_msg(dev, usb_snddefctrl(dev), &dr, NULL, 0); + return dev->bus->op->control_msg(dev, usb_snddefctrl(dev), &dr, NULL, 0, HZ); } int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size) @@ -697,7 +702,7 @@ dr.length = size; while (i--) { - if (!(result = dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, buf, size)) + if (!(result = dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, buf, size, HZ)) || result == USB_ST_STALL) break; } @@ -714,7 +719,7 @@ dr.index = langid; dr.length = size; - return dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, buf, size); + return dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, buf, size, HZ); } int usb_get_device_descriptor(struct usb_device *dev) @@ -740,7 +745,7 @@ dr.index = target; dr.length = 2; - return dev->bus->op->control_msg (dev, usb_rcvctrlpipe (dev,0), &dr, data, 2); + return dev->bus->op->control_msg (dev, usb_rcvctrlpipe (dev,0), &dr, data, 2, HZ); } int usb_get_protocol(struct usb_device *dev) @@ -754,7 +759,7 @@ dr.index = 1; dr.length = 1; - if (dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev, 0), &dr, buf, 1)) + if (dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev, 0), &dr, buf, 1, HZ)) return -1; return buf[0]; @@ -770,7 +775,7 @@ dr.index = 1; dr.length = 0; - if (dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev, 0), &dr, NULL, 0)) + if (dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev, 0), &dr, NULL, 0, HZ)) return -1; return 0; @@ -788,7 +793,7 @@ dr.index = 1; dr.length = 0; - if (dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev, 0), &dr, NULL, 0)) + if (dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev, 0), &dr, NULL, 0, HZ)) return -1; return 0; @@ -838,7 +843,7 @@ dr.index = endp; dr.length = 0; - result = dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); + result = dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0, HZ); /* don't clear if failed */ if (result) @@ -850,7 +855,7 @@ dr.length = 2; status = 0xffff; - result = dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, &status, 2); + result = dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, &status, 2, HZ); if (result) return result; @@ -876,7 +881,7 @@ dr.index = interface; dr.length = 0; - if (dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev, 0), &dr, NULL, 0)) + if (dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev, 0), &dr, NULL, 0, HZ)) return -1; dev->ifnum = interface; @@ -907,7 +912,7 @@ printk(KERN_INFO "usb: selecting invalid configuration %d\n", configuration); return -1; } - if (dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev, 0), &dr, NULL, 0)) + if (dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev, 0), &dr, NULL, 0, HZ)) return -1; dev->actconfig = cp; @@ -927,7 +932,7 @@ dr.index = index; dr.length = size; - if (dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev, 0), &dr, buf, size)) + if (dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev, 0), &dr, buf, size, HZ)) return -1; return 0; @@ -962,9 +967,9 @@ /* We grab the first 8 bytes so we know how long the whole */ /* configuration is */ result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 8); - if (result) + if (result < 0) return -1; - + /* Get the full buffer */ le16_to_cpus(&desc->wTotalLength); @@ -1115,7 +1120,7 @@ return 0; } -int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void *data, __u16 size) +int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void *data, __u16 size, int timeout) { devrequest dr; @@ -1125,7 +1130,7 @@ dr.index = cpu_to_le16p(&index); dr.length = cpu_to_le16p(&size); - return dev->bus->op->control_msg(dev, pipe, &dr, data, size); + return dev->bus->op->control_msg(dev, pipe, &dr, data, size, timeout); } int usb_request_irq(struct usb_device *dev, unsigned int pipe, usb_device_irq handler, int period, void *dev_id, void **handle) diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/usb.h linux.ac/drivers/usb/usb.h --- linux.vanilla/drivers/usb/usb.h Sat Sep 11 00:54:11 1999 +++ linux.ac/drivers/usb/usb.h Mon Sep 20 15:52:49 1999 @@ -117,29 +117,44 @@ __u16 value; __u16 index; __u16 length; - /* pointer to data */ + __u32 timeout; /* in milliseconds */ void *data; }; -#define USB_PROC_CONTROL _IOWR('U', 0, struct usb_proc_ctrltransfer) - struct usb_proc_bulktransfer { unsigned int ep; unsigned int len; + unsigned int timeout; /* in milliseconds */ void *data; }; -#define USB_PROC_BULK _IOWR('U', 2, struct usb_proc_bulktransfer) +struct usb_proc_old_ctrltransfer { + __u8 requesttype; + __u8 request; + __u16 value; + __u16 index; + __u16 length; + /* pointer to data */ + void *data; +}; -#define USB_PROC_RESETEP _IOR('U', 3, unsigned int) +struct usb_proc_old_bulktransfer { + unsigned int ep; + unsigned int len; + void *data; +}; struct usb_proc_setinterface { unsigned int interface; unsigned int altsetting; }; +#define USB_PROC_CONTROL _IOWR('U', 0, struct usb_proc_ctrltransfer) +#define USB_PROC_BULK _IOWR('U', 2, struct usb_proc_bulktransfer) +#define USB_PROC_OLD_CONTROL _IOWR('U', 0, struct usb_proc_old_ctrltransfer) +#define USB_PROC_OLD_BULK _IOWR('U', 2, struct usb_proc_old_bulktransfer) +#define USB_PROC_RESETEP _IOR('U', 3, unsigned int) #define USB_PROC_SETINTERFACE _IOR('U', 4, struct usb_proc_setinterface) - #define USB_PROC_SETCONFIGURATION _IOR('U', 5, unsigned int) @@ -429,8 +444,8 @@ struct usb_operations { int (*allocate)(struct usb_device *); int (*deallocate)(struct usb_device *); - int (*control_msg)(struct usb_device *, unsigned int, devrequest *, void *, int); - int (*bulk_msg)(struct usb_device *, unsigned int, void *, int,unsigned long *); + int (*control_msg)(struct usb_device *, unsigned int, devrequest *, void *, int, int); + int (*bulk_msg)(struct usb_device *, unsigned int, void *, int, unsigned long *, int); int (*request_irq)(struct usb_device *, unsigned int, usb_device_irq, int, void *, void **); int (*release_irq)(struct usb_device *, void *); void *(*request_bulk)(struct usb_device *, unsigned int, usb_device_irq, @@ -496,7 +511,7 @@ void *hcpriv; /* Host Controller private data */ void *private; /* Upper layer private data */ - + void *audiopriv; /* May be both audio and HID */ /* procfs entry */ struct proc_dir_entry *proc_entry; @@ -515,10 +530,6 @@ extern int usb_register(struct usb_driver *); extern void usb_deregister(struct usb_driver *); -int usb_find_driver(struct usb_device *); -void usb_check_support(struct usb_device *); -void usb_driver_purge(struct usb_driver *, struct usb_device *); - extern struct usb_bus *usb_alloc_bus(struct usb_operations *); extern void usb_free_bus(struct usb_bus *); extern void usb_register_bus(struct usb_bus *); @@ -529,7 +540,7 @@ extern void usb_inc_dev_use(struct usb_device *); #define usb_dec_dev_use usb_free_dev -extern int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void *data, __u16 size); +extern int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void *data, __u16 size, int timeout); extern int usb_request_irq(struct usb_device *, unsigned int, usb_device_irq, int, void *, void **); extern int usb_release_irq(struct usb_device *dev, void *handle, unsigned int pipe); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/usb_scsi.c linux.ac/drivers/usb/usb_scsi.c --- linux.vanilla/drivers/usb/usb_scsi.c Sat Sep 11 00:54:11 1999 +++ linux.ac/drivers/usb/usb_scsi.c Mon Sep 20 16:58:45 1999 @@ -142,7 +142,7 @@ do { /*US_DEBUGP("Bulk xfer %x(%d)\n", (unsigned int)buf, this_xfer);*/ result = us->pusb_dev->bus->op->bulk_msg(us->pusb_dev, pipe, buf, - this_xfer, &partial); + this_xfer, &partial, HZ*5); if (result != 0 || partial != this_xfer) US_DEBUGP("bulk_msg returned %d xferred %lu/%d\n", @@ -263,7 +263,6 @@ { unsigned char cmd[12]; devrequest dr; - int result; US_DEBUGP("pop_CB_reset\n"); dr.requesttype = USB_TYPE_CLASS | USB_RT_INTERFACE; @@ -276,7 +275,7 @@ cmd[1] = 4; us->pusb_dev->bus->op->control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), - &dr, cmd, 12); + &dr, cmd, 12, HZ); /* long wait for reset */ @@ -338,7 +337,7 @@ } result = us->pusb_dev->bus->op->control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), - &dr, cmd, us->fixedlength); + &dr, cmd, us->fixedlength, HZ); if (!done_start && (us->subclass == US_SC_UFI /*|| us->subclass == US_SC_8070*/) && cmd[0] == TEST_UNIT_READY && result) { /* as per spec try a start command, wait and retry */ @@ -349,7 +348,7 @@ cmd[4] = 1; /* start */ result = us->pusb_dev->bus->op->control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), - &dr, cmd, us->fixedlength); + &dr, cmd, us->fixedlength, HZ); wait_ms(100); retry++; continue; @@ -357,7 +356,7 @@ } else result = us->pusb_dev->bus->op->control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), - &dr, srb->cmnd, srb->cmd_len); + &dr, srb->cmnd, srb->cmd_len, HZ); if (/*result != USB_ST_STALL &&*/ result != USB_ST_TIMEOUT) return result; } @@ -389,7 +388,7 @@ dr.length = 2; result = us->pusb_dev->bus->op->control_msg(us->pusb_dev, usb_rcvctrlpipe(us->pusb_dev,0), - &dr, status, sizeof(status)); + &dr, status, sizeof(status), HZ); if (result != USB_ST_TIMEOUT) break; } @@ -452,7 +451,6 @@ static int pop_CBI(Scsi_Cmnd *srb) { - struct us_data *us = (struct us_data *)srb->host_scribble; int result; /* run the command */ @@ -500,7 +498,7 @@ dr.index = 0; dr.length = 0; - result = us->pusb_dev->bus->op->control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), &dr, NULL, 0); + result = us->pusb_dev->bus->op->control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), &dr, NULL, 0, HZ); if (result) US_DEBUGP("Bulk hard reset failed %d\n", result); usb_clear_halt(us->pusb_dev, us->ep_in | 0x80); @@ -546,7 +544,7 @@ bcb.Tag, bcb.DataTransferLength, bcb.Flags, bcb.Length); result = us->pusb_dev->bus->op->bulk_msg(us->pusb_dev, usb_sndbulkpipe(us->pusb_dev, us->ep_out), &bcb, - US_BULK_CB_WRAP_LEN, &partial); + US_BULK_CB_WRAP_LEN, &partial, HZ*5); if (result) { US_DEBUGP("Bulk command result %x\n", result); return DID_ABORT << 16; @@ -570,7 +568,7 @@ do { result = us->pusb_dev->bus->op->bulk_msg(us->pusb_dev, usb_rcvbulkpipe(us->pusb_dev, us->ep_in), &bcs, - US_BULK_CS_WRAP_LEN, &partial); + US_BULK_CS_WRAP_LEN, &partial, HZ*5); if (result == USB_ST_STALL || result == USB_ST_TIMEOUT) stall++; else @@ -1296,7 +1294,7 @@ dr.index = 0; dr.value = 0; dr.length = 0; - ss->pusb_dev->bus->op->control_msg(ss->pusb_dev, usb_rcvctrlpipe(dev,0), &dr, qstat, 2); + ss->pusb_dev->bus->op->control_msg(ss->pusb_dev, usb_rcvctrlpipe(dev,0), &dr, qstat, 2, HZ); US_DEBUGP("C0 status %x %x\n", qstat[0], qstat[1]); init_waitqueue_head(&ss->ip_waitq); ss->irqpipe = usb_rcvctrlpipe(ss->pusb_dev, ss->ep_int); @@ -1413,8 +1411,6 @@ void cleanup_module(void) { - unsigned int offset; - usb_deregister(&scsi_driver); } #endif diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/usb/uss720.c linux.ac/drivers/usb/uss720.c --- linux.vanilla/drivers/usb/uss720.c Sat Sep 11 00:54:11 1999 +++ linux.ac/drivers/usb/uss720.c Mon Sep 20 15:52:49 1999 @@ -31,6 +31,7 @@ * ECP currently untested * 0.3 10.08.99 fixing merge errors * 0.4 13.08.99 Added Vendor/Product ID of Brad Hard's cable + * 0.5 20.09.99 usb_control_msg wrapper used * */ @@ -61,17 +62,11 @@ static const unsigned char regindex[9] = { 4, 0, 1, 5, 5, 0, 2, 3, 6 }; - devrequest dr; int ret; if (!usbdev) return -1; - dr.requesttype = 0xc0; - dr.request = 3; - dr.value = ((unsigned int)reg) << 8; - dr.index = 0; - dr.length = 7; - ret = usbdev->bus->op->control_msg(usbdev, usb_rcvctrlpipe(usbdev,0), &dr, priv->reg, 7); + ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev,0), 3, 0xc0, ((unsigned int)reg) << 8, 0, priv->reg, 7, HZ); if (ret) { printk(KERN_DEBUG "uss720: get_1284_register(%d) failed, status 0x%x\n", (unsigned int)reg, ret); @@ -95,17 +90,11 @@ { struct parport_uss720_private *priv = pp->private_data; struct usb_device *usbdev = priv->usbdev; - devrequest dr; int ret; if (!usbdev) return -1; - dr.requesttype = 0x40; - dr.request = 4; - dr.value = (((unsigned int)reg) << 8) | val; - dr.index = 0; - dr.length = 0; - ret = usbdev->bus->op->control_msg(usbdev, usb_sndctrlpipe(usbdev,0), &dr, NULL, 0); + ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev,0), 4, 0x40, (((unsigned int)reg) << 8) | val, 0, NULL, 0, HZ); if (ret) { printk(KERN_DEBUG "uss720: set_1284_register(%u,0x%02x) failed, status 0x%x\n", (unsigned int)reg, (unsigned int)val, ret); @@ -374,7 +363,7 @@ return 0; if (change_mode(pp, ECR_EPP)) return 0; - i = usbdev->bus->op->bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), buf, length, &rlen); + i = usbdev->bus->op->bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), buf, length, &rlen, HZ*20); if (i) printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %u rlen %lu\n", buf, length, rlen); change_mode(pp, ECR_PS2); @@ -435,7 +424,7 @@ return 0; if (change_mode(pp, ECR_ECP)) return 0; - i = usbdev->bus->op->bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), buffer, len, &rlen); + i = usbdev->bus->op->bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), buffer, len, &rlen, HZ*20); if (i) printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %u rlen %lu\n", buffer, len, rlen); change_mode(pp, ECR_PS2); @@ -453,7 +442,7 @@ return 0; if (change_mode(pp, ECR_ECP)) return 0; - i = usbdev->bus->op->bulk_msg(usbdev, usb_rcvbulkpipe(usbdev, 2), buffer, len, &rlen); + i = usbdev->bus->op->bulk_msg(usbdev, usb_rcvbulkpipe(usbdev, 2), buffer, len, &rlen, HZ*20); if (i) printk(KERN_ERR "uss720: recvbulk ep 2 buf %p len %u rlen %lu\n", buffer, len, rlen); change_mode(pp, ECR_PS2); @@ -486,7 +475,7 @@ return 0; if (change_mode(pp, ECR_PPF)) return 0; - i = usbdev->bus->op->bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), buffer, len, &rlen); + i = usbdev->bus->op->bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), buffer, len, &rlen, HZ*20); if (i) printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %u rlen %lu\n", buffer, len, rlen); change_mode(pp, ECR_PS2); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/video/Config.in linux.ac/drivers/video/Config.in --- linux.vanilla/drivers/video/Config.in Sat Sep 11 00:54:11 1999 +++ linux.ac/drivers/video/Config.in Tue Sep 14 20:48:06 1999 @@ -2,350 +2,360 @@ # Video configuration # +mainmenu_option next_comment +comment 'Frame-buffer support' + +bool 'Support for frame buffer devices (EXPERIMENTAL)' CONFIG_FB + if [ "$CONFIG_FB" = "y" ]; then - define_bool CONFIG_DUMMY_CONSOLE y - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_PCI" = "y" ]; then - tristate 'Cirrus Logic suport (experimental)' CONFIG_FB_CLGEN - tristate 'Permedia2 support (experimental)' CONFIG_FB_PM2 - if [ "$CONFIG_FB_PM2" = "y" ]; then - if [ "$CONFIG_PCI" = "y" ]; then - bool ' enable FIFO disconnect feature' CONFIG_FB_PM2_FIFO_DISCONNECT - bool ' generic Permedia2 PCI board support' CONFIG_FB_PM2_PCI - fi - if [ "$CONFIG_AMIGA" = "y" ]; then - bool ' Phase5 CVisionPPC/BVisionPPC support' CONFIG_FB_PM2_CVPPC - fi - fi - fi - fi - if [ "$CONFIG_ARCH_ACORN" = "y" ]; then - bool 'Acorn VIDC support' CONFIG_FB_ACORN - fi - if [ "$CONFIG_ARCH_NETWINDER" = "y" ]; then - tristate 'Cyber2000 support' CONFIG_FB_CYBER2000 - fi - if [ "$CONFIG_APOLLO" = "y" ]; then - define_bool CONFIG_FB_APOLLO y - fi - if [ "$CONFIG_Q40" = "y" ]; then - define_bool CONFIG_FB_Q40 y - fi - if [ "$CONFIG_AMIGA" = "y" ]; then - bool 'Amiga native chipset support' CONFIG_FB_AMIGA - if [ "$CONFIG_FB_AMIGA" != "n" ]; then - bool 'Amiga OCS chipset support' CONFIG_FB_AMIGA_OCS - bool 'Amiga ECS chipset support' CONFIG_FB_AMIGA_ECS - bool 'Amiga AGA chipset support' CONFIG_FB_AMIGA_AGA - fi - fi - if [ "$CONFIG_ZORRO" = "y" ]; then - tristate 'Amiga CyberVision support' CONFIG_FB_CYBER - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool 'Amiga CyberVision3D support (experimental)' CONFIG_FB_VIRGE - tristate 'Amiga RetinaZ3 support' CONFIG_FB_RETINAZ3 - bool 'Amiga FrameMaster II/Rainbow II support (experimental)' CONFIG_FB_FM2 - fi - fi - if [ "$CONFIG_ATARI" = "y" ]; then - bool 'Atari native chipset support' CONFIG_FB_ATARI - tristate 'ATI Mach64 display support' CONFIG_FB_ATY - fi - if [ "$CONFIG_PPC" = "y" ]; then - bool 'Open Firmware frame buffer device support' CONFIG_FB_OF - if [ "$CONFIG_FB_OF" = "y" ]; then - bool 'Apple "control" display support' CONFIG_FB_CONTROL - bool 'Apple "platinum" display support' CONFIG_FB_PLATINUM - bool 'Apple "valkyrie" display support' CONFIG_FB_VALKYRIE - tristate 'ATI Mach64 display support' CONFIG_FB_ATY - bool 'IMS Twin Turbo display support' CONFIG_FB_IMSTT - bool 'Chips 65550 display support' CONFIG_FB_CT65550 - bool 'S3 Trio display support' CONFIG_FB_S3TRIO - fi - tristate 'VGA 16-color graphics console' CONFIG_FB_VGA16 - fi - if [ "$CONFIG_MAC" = "y" ]; then - define_bool CONFIG_FB_MAC y - fi - if [ "$CONFIG_HP300" = "y" ]; then - define_bool CONFIG_FB_HP300 y - fi - if [ "$ARCH" = "alpha" ]; then - tristate 'TGA framebuffer support' CONFIG_FB_TGA - fi - if [ "$ARCH" = "i386" ]; then - bool 'VESA VGA graphics console' CONFIG_FB_VESA - tristate 'VGA 16-color graphics console' CONFIG_FB_VGA16 - define_bool CONFIG_VIDEO_SELECT y - fi - if [ "$CONFIG_VISWS" = "y" ]; then - tristate 'SGI Visual Workstation framebuffer support' CONFIG_FB_SGIVW - fi - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - if [ "$CONFIG_PCI" != "n" ]; then - tristate 'Matrox acceleration' CONFIG_FB_MATROX - if [ "$CONFIG_FB_MATROX" != "n" ]; then - bool ' Millennium I/II support' CONFIG_FB_MATROX_MILLENIUM - bool ' Mystique support' CONFIG_FB_MATROX_MYSTIQUE - bool ' G100/G200/G400 support' CONFIG_FB_MATROX_G100 - bool ' Multihead support' CONFIG_FB_MATROX_MULTIHEAD - fi - tristate 'ATI Mach64 display support' CONFIG_FB_ATY - fi - fi - if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then - bool 'SBUS and UPA framebuffers' CONFIG_FB_SBUS - if [ "$CONFIG_FB_SBUS" != "n" ]; then - if [ "$ARCH" = "sparc64" ]; then - bool ' Creator/Creator3D support' CONFIG_FB_CREATOR - fi - bool ' CGsix (GX,TurboGX) support' CONFIG_FB_CGSIX - bool ' BWtwo support' CONFIG_FB_BWTWO - bool ' CGthree support' CONFIG_FB_CGTHREE - if [ "$ARCH" = "sparc" ]; then - bool ' TCX (SS4/SS5 only) support' CONFIG_FB_TCX - bool ' CGfourteen (SX) support' CONFIG_FB_CGFOURTEEN - bool ' P9100 (Sparcbook 3 only) support' CONFIG_FB_P9100 - fi - bool ' Leo (ZX) support' CONFIG_FB_LEO - fi - fi - if [ "$ARCH" = "sparc" ]; then - if [ "$CONFIG_PCI" != "n" ]; then - bool 'PCI framebuffers' CONFIG_FB_PCI - if [ "$CONFIG_FB_PCI" != "n" ]; then - bool ' IGA 168x display support' CONFIG_FB_IGA - fi - fi - fi - if [ "$ARCH" = "sparc64" ]; then - if [ "$CONFIG_PCI" != "n" ]; then - bool 'PCI framebuffers' CONFIG_FB_PCI - if [ "$CONFIG_FB_PCI" != "n" ]; then - tristate ' ATI Mach64 display support' CONFIG_FB_ATY - fi - fi - fi - tristate 'Virtual Frame Buffer support (ONLY FOR TESTING!)' CONFIG_FB_VIRTUAL + define_bool CONFIG_DUMMY_CONSOLE y + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_PCI" = "y" ]; then + tristate ' Cirrus Logic suport (EXPERIMENTAL)' CONFIG_FB_CLGEN + tristate ' Permedia2 support (EXPERIMENTAL)' CONFIG_FB_PM2 + if [ "$CONFIG_FB_PM2" = "y" ]; then + if [ "$CONFIG_PCI" = "y" ]; then + bool ' enable FIFO disconnect feature' CONFIG_FB_PM2_FIFO_DISCONNECT + bool ' generic Permedia2 PCI board support' CONFIG_FB_PM2_PCI + fi + if [ "$CONFIG_AMIGA" = "y" ]; then + bool ' Phase5 CVisionPPC/BVisionPPC support' CONFIG_FB_PM2_CVPPC + fi + fi + fi + fi + if [ "$CONFIG_ARCH_ACORN" = "y" ]; then + bool ' Acorn VIDC support' CONFIG_FB_ACORN + fi + if [ "$CONFIG_ARCH_NETWINDER" = "y" ]; then + tristate ' Cyber2000 support' CONFIG_FB_CYBER2000 + fi + if [ "$CONFIG_APOLLO" = "y" ]; then + define_bool CONFIG_FB_APOLLO y + fi + if [ "$CONFIG_Q40" = "y" ]; then + define_bool CONFIG_FB_Q40 y + fi + if [ "$CONFIG_AMIGA" = "y" ]; then + bool ' Amiga native chipset support' CONFIG_FB_AMIGA + if [ "$CONFIG_FB_AMIGA" != "n" ]; then + bool ' Amiga OCS chipset support' CONFIG_FB_AMIGA_OCS + bool ' Amiga ECS chipset support' CONFIG_FB_AMIGA_ECS + bool ' Amiga AGA chipset support' CONFIG_FB_AMIGA_AGA + fi + fi + if [ "$CONFIG_ZORRO" = "y" ]; then + tristate ' Amiga CyberVision support' CONFIG_FB_CYBER + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool ' Amiga CyberVision3D support (EXPERIMENTAL)' CONFIG_FB_VIRGE + tristate ' Amiga RetinaZ3 support (EXPERIMENTAL)' CONFIG_FB_RETINAZ3 + bool ' Amiga FrameMaster II/Rainbow II support (EXPERIMENTAL)' CONFIG_FB_FM2 + fi + fi + if [ "$CONFIG_ATARI" = "y" ]; then + bool ' Atari native chipset support' CONFIG_FB_ATARI + tristate ' ATI Mach64 display support' CONFIG_FB_ATY + fi + if [ "$CONFIG_PPC" = "y" ]; then + bool ' Open Firmware frame buffer device support' CONFIG_FB_OF + if [ "$CONFIG_FB_OF" = "y" ]; then + bool ' Apple "control" display support' CONFIG_FB_CONTROL + bool ' Apple "platinum" display support' CONFIG_FB_PLATINUM + bool ' Apple "valkyrie" display support' CONFIG_FB_VALKYRIE + tristate ' ATI Mach64 display support' CONFIG_FB_ATY + bool ' IMS Twin Turbo display support' CONFIG_FB_IMSTT + bool ' Chips 65550 display support' CONFIG_FB_CT65550 + bool ' S3 Trio display support' CONFIG_FB_S3TRIO + fi + tristate ' VGA 16-color graphics console' CONFIG_FB_VGA16 + fi + if [ "$CONFIG_MAC" = "y" ]; then + define_bool CONFIG_FB_MAC y + fi + if [ "$CONFIG_HP300" = "y" ]; then + define_bool CONFIG_FB_HP300 y + fi + if [ "$ARCH" = "alpha" ]; then + tristate ' TGA framebuffer support' CONFIG_FB_TGA + fi + if [ "$ARCH" = "i386" ]; then + bool ' VESA VGA graphics console' CONFIG_FB_VESA + tristate ' VGA 16-color graphics console' CONFIG_FB_VGA16 + define_bool CONFIG_VIDEO_SELECT y + fi + if [ "$CONFIG_VISWS" = "y" ]; then + tristate ' SGI Visual Workstation framebuffer support' CONFIG_FB_SGIVW + define_bool CONFIG_BUS_I2C y + fi + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + if [ "$CONFIG_PCI" != "n" ]; then + tristate ' Matrox acceleration (EXPERIMENTAL)' CONFIG_FB_MATROX + if [ "$CONFIG_FB_MATROX" != "n" ]; then + bool ' Millennium I/II support' CONFIG_FB_MATROX_MILLENIUM + bool ' Mystique support' CONFIG_FB_MATROX_MYSTIQUE + bool ' G100/G200/G400 support' CONFIG_FB_MATROX_G100 + bool ' Multihead support' CONFIG_FB_MATROX_MULTIHEAD + fi + tristate ' ATI Mach64 display support (EXPERIMENTAL)' CONFIG_FB_ATY + fi + fi + if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then + bool ' SBUS and UPA framebuffers' CONFIG_FB_SBUS + if [ "$CONFIG_FB_SBUS" != "n" ]; then + if [ "$ARCH" = "sparc64" ]; then + bool ' Creator/Creator3D support' CONFIG_FB_CREATOR + fi + bool ' CGsix (GX,TurboGX) support' CONFIG_FB_CGSIX + bool ' BWtwo support' CONFIG_FB_BWTWO + bool ' CGthree support' CONFIG_FB_CGTHREE + if [ "$ARCH" = "sparc" ]; then + bool ' TCX (SS4/SS5 only) support' CONFIG_FB_TCX + bool ' CGfourteen (SX) support' CONFIG_FB_CGFOURTEEN + bool ' P9100 (Sparcbook 3 only) support' CONFIG_FB_P9100 + fi + bool ' Leo (ZX) support' CONFIG_FB_LEO + fi + fi + if [ "$ARCH" = "sparc" ]; then + if [ "$CONFIG_PCI" != "n" ]; then + bool ' PCI framebuffers' CONFIG_FB_PCI + if [ "$CONFIG_FB_PCI" != "n" ]; then + bool ' IGA 168x display support' CONFIG_FB_IGA + fi + fi + fi + if [ "$ARCH" = "sparc64" ]; then + if [ "$CONFIG_PCI" != "n" ]; then + bool ' PCI framebuffers' CONFIG_FB_PCI + if [ "$CONFIG_FB_PCI" != "n" ]; then + tristate ' ATI Mach64 display support' CONFIG_FB_ATY + fi + fi + fi + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate ' Virtual Frame Buffer support (ONLY FOR TESTING!)' CONFIG_FB_VIRTUAL + fi - bool 'Advanced low level driver options' CONFIG_FBCON_ADVANCED - if [ "$CONFIG_FBCON_ADVANCED" = "y" ]; then - tristate 'Monochrome support' CONFIG_FBCON_MFB - tristate '2 bpp packed pixels support' CONFIG_FBCON_CFB2 - tristate '4 bpp packed pixels support' CONFIG_FBCON_CFB4 - tristate '8 bpp packed pixels support' CONFIG_FBCON_CFB8 - tristate '16 bpp packed pixels support' CONFIG_FBCON_CFB16 - tristate '24 bpp packed pixels support' CONFIG_FBCON_CFB24 - tristate '32 bpp packed pixels support' CONFIG_FBCON_CFB32 - tristate 'Amiga bitplanes support' CONFIG_FBCON_AFB - tristate 'Amiga interleaved bitplanes support' CONFIG_FBCON_ILBM - tristate 'Atari interleaved bitplanes (2 planes) support' CONFIG_FBCON_IPLAN2P2 - tristate 'Atari interleaved bitplanes (4 planes) support' CONFIG_FBCON_IPLAN2P4 - tristate 'Atari interleaved bitplanes (8 planes) support' CONFIG_FBCON_IPLAN2P8 -# tristate 'Atari interleaved bitplanes (16 planes) support' CONFIG_FBCON_IPLAN2P16 - tristate 'Mac variable bpp packed pixels support' CONFIG_FBCON_MAC - tristate 'VGA 16-color planar support' CONFIG_FBCON_VGA_PLANES - tristate 'VGA characters/attributes support' CONFIG_FBCON_VGA - else - # Guess what we need - if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_AMIGA" = "y" -o \ - "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \ - "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_RETINAZ3" = "y" -o \ - "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \ - "$CONFIG_FB_BWTWO" = "y" -o "$CONFIG_FB_CLGEN" = "y" ]; then - define_bool CONFIG_FBCON_MFB y - else - if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_AMIGA" = "m" -o \ - "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \ - "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_RETINAZ3" = "m" -o \ - "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \ - "$CONFIG_FB_BWTWO" = "m" -o "$CONFIG_FB_CLGEN" = "m" ]; then - define_bool CONFIG_FBCON_MFB m - fi - fi - if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_MAC" = "y" -o \ - "$CONFIG_FB_VIRTUAL" = "y" ]; then - define_bool CONFIG_FBCON_CFB2 y - define_bool CONFIG_FBCON_CFB4 y - else - if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_MAC" = "m" -o \ - "$CONFIG_FB_VIRTUAL" = "m" ]; then - define_bool CONFIG_FBCON_CFB2 m - define_bool CONFIG_FBCON_CFB4 m - fi - fi - if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_ATARI" = "y" -o \ - "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_MAC" = "y" -o \ - "$CONFIG_FB_OF" = "y" -o "$CONFIG_FB_TGA" = "y" -o \ - "$CONFIG_FB_VESA" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \ - "$CONFIG_FB_TCX" = "y" -o "$CONFIG_FB_CGTHREE" = "y" -o \ - "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \ - "$CONFIG_FB_CGFOURTEEN" = "y" -o "$CONFIG_FB_G364" = "y" -o \ - "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \ - "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ - "$CONFIG_FB_IGA" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \ - "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_PM2" = "y" -o \ - "$CONFIG_FB_P9100" = "y" -o \ - "$CONFIG_FB_SGIVW" = "y" -o "$CONFIG_FB_CYBER2000" = "y" ]; then - define_bool CONFIG_FBCON_CFB8 y - else - if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \ - "$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_MAC" = "m" -o \ - "$CONFIG_FB_OF" = "m" -o "$CONFIG_FB_TGA" = "m" -o \ - "$CONFIG_FB_VESA" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \ - "$CONFIG_FB_TCX" = "m" -o "$CONFIG_FB_CGTHREE" = "m" -o \ - "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \ - "$CONFIG_FB_CGFOURTEEN" = "m" -o "$CONFIG_FB_G364" = "m" -o \ - "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \ - "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ - "$CONFIG_FB_IGA" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \ - "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_PM2" = "m" -o \ - "$CONFIG_FB_P9100" = "m" -o \ - "$CONFIG_FB_SGIVW" = "m" -o "$CONFIG_FB_CYBER2000" = "m" ]; then - define_bool CONFIG_FBCON_CFB8 m - fi - fi - if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \ - "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_VESA" = "y" -o \ - "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_TBOX" = "y" -o \ - "$CONFIG_FB_Q40" = "y" -o \ - "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \ - "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \ - "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ - "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \ - "$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \ - "$CONFIG_FB_CYBER2000" = "y" ]; then - define_bool CONFIG_FBCON_CFB16 y - else - if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \ - "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_VESA" = "m" -o \ - "$CONFIG_FB_VIRTUAL" = "m" -o "$CONFIG_FB_TBOX" = "m" -o \ - "$CONFIG_FB_Q40" = "m" -o \ - "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \ - "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \ - "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ - "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \ - "$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_SGIVW" = "m" -o \ - "$CONFIG_FB_CYBER2000" = "m" ]; then - define_bool CONFIG_FBCON_CFB16 m - fi - fi - if [ "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \ - "$CONFIG_FB_CLGEN" = "y" -o "$CONFIG_FB_VESA" = "y" -o \ - "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \ - "$CONFIG_FB_CYBER2000" = "y" ]; then - define_bool CONFIG_FBCON_CFB24 y - else - if [ "$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \ - "$CONFIG_FB_CLGEN" = "m" -o "$CONFIG_FB_VESA" = "m" -o \ - "$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \ - "$CONFIG_FB_CYBER2000" = "m" ]; then - define_bool CONFIG_FBCON_CFB24 m - fi - fi - if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \ - "$CONFIG_FB_VESA" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \ - "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \ - "$CONFIG_FB_TGA" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ - "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \ - "$CONFIG_FB_FM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" ]; then - define_bool CONFIG_FBCON_CFB32 y - else - if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \ - "$CONFIG_FB_VESA" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \ - "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \ - "$CONFIG_FB_TGA" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ - "$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \ - "$CONFIG_FB_SGIVW" = "m" ]; then - define_bool CONFIG_FBCON_CFB32 m - fi - fi - if [ "$CONFIG_FB_AMIGA" = "y" ]; then - define_bool CONFIG_FBCON_AFB y - define_bool CONFIG_FBCON_ILBM y - else - if [ "$CONFIG_FB_AMIGA" = "m" ]; then - define_bool CONFIG_FBCON_AFB m - define_bool CONFIG_FBCON_ILBM m - fi - fi - if [ "$CONFIG_FB_ATARI" = "y" ]; then - define_bool CONFIG_FBCON_IPLAN2P2 y - define_bool CONFIG_FBCON_IPLAN2P4 y - define_bool CONFIG_FBCON_IPLAN2P8 y -# define_bool CONFIG_FBCON_IPLAN2P16 y - else - if [ "$CONFIG_FB_ATARI" = "m" ]; then - define_bool CONFIG_FBCON_IPLAN2P2 m - define_bool CONFIG_FBCON_IPLAN2P4 m - define_bool CONFIG_FBCON_IPLAN2P8 m -# define_bool CONFIG_FBCON_IPLAN2P16 m - fi - fi - if [ "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" ]; then - define_bool CONFIG_FBCON_MAC y - else - if [ "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then - define_bool CONFIG_FBCON_MAC m - fi - fi - if [ "$CONFIG_FB_VGA16" = "y" ]; then - define_bool CONFIG_FBCON_VGA_PLANES y - else - if [ "$CONFIG_FB_VGA16" = "m" ]; then - define_bool CONFIG_FBCON_VGA_PLANES m - fi - fi - if [ "$CONFIG_FB_MDA" = "y" -o "$CONFIG_FB_VGA" = "y" ]; then - define_bool CONFIG_FBCON_VGA y - else - if [ "$CONFIG_FB_MDA" = "m" -o "$CONFIG_FB_VGA" = "m" ]; then - define_bool CONFIG_FBCON_VGA m - fi - fi - fi - bool 'Support only 8 pixels wide fonts' CONFIG_FBCON_FONTWIDTH8_ONLY - if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then - bool 'Sparc console 8x16 font' CONFIG_FONT_SUN8x16 - if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then - bool 'Sparc console 12x22 font (not supported by all drivers)' CONFIG_FONT_SUN12x22 - fi - bool 'Select other fonts' CONFIG_FBCON_FONTS - if [ "$CONFIG_FBCON_FONTS" = "y" ]; then - bool ' VGA 8x8 font' CONFIG_FONT_8x8 - bool ' VGA 8x16 font' CONFIG_FONT_8x16 - if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then - bool ' Mac console 6x11 font (not supported by all drivers)' CONFIG_FONT_6x11 - fi - bool ' Pearl (old m68k) console 8x8 font' CONFIG_FONT_PEARL_8x8 - bool ' Acorn console 8x8 font' CONFIG_FONT_ACORN_8x8 - fi - else - bool 'Select compiled-in fonts' CONFIG_FBCON_FONTS - if [ "$CONFIG_FBCON_FONTS" = "y" ]; then - bool ' VGA 8x8 font' CONFIG_FONT_8x8 - bool ' VGA 8x16 font' CONFIG_FONT_8x16 + bool ' Advanced low level driver options' CONFIG_FBCON_ADVANCED + if [ "$CONFIG_FBCON_ADVANCED" = "y" ]; then + tristate ' Monochrome support' CONFIG_FBCON_MFB + tristate ' 2 bpp packed pixels support' CONFIG_FBCON_CFB2 + tristate ' 4 bpp packed pixels support' CONFIG_FBCON_CFB4 + tristate ' 8 bpp packed pixels support' CONFIG_FBCON_CFB8 + tristate ' 16 bpp packed pixels support' CONFIG_FBCON_CFB16 + tristate ' 24 bpp packed pixels support' CONFIG_FBCON_CFB24 + tristate ' 32 bpp packed pixels support' CONFIG_FBCON_CFB32 + tristate ' Amiga bitplanes support' CONFIG_FBCON_AFB + tristate ' Amiga interleaved bitplanes support' CONFIG_FBCON_ILBM + tristate ' Atari interleaved bitplanes (2 planes) support' CONFIG_FBCON_IPLAN2P2 + tristate ' Atari interleaved bitplanes (4 planes) support' CONFIG_FBCON_IPLAN2P4 + tristate ' Atari interleaved bitplanes (8 planes) support' CONFIG_FBCON_IPLAN2P8 +# tristate ' Atari interleaved bitplanes (16 planes) support' CONFIG_FBCON_IPLAN2P16 + tristate ' Mac variable bpp packed pixels support' CONFIG_FBCON_MAC + tristate ' VGA 16-color planar support' CONFIG_FBCON_VGA_PLANES + tristate ' VGA characters/attributes support' CONFIG_FBCON_VGA + else + # Guess what we need + if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_AMIGA" = "y" -o \ + "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \ + "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_RETINAZ3" = "y" -o \ + "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \ + "$CONFIG_FB_BWTWO" = "y" -o "$CONFIG_FB_CLGEN" = "y" ]; then + define_bool CONFIG_FBCON_MFB y + else + if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_AMIGA" = "m" -o \ + "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \ + "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_RETINAZ3" = "m" -o \ + "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \ + "$CONFIG_FB_BWTWO" = "m" -o "$CONFIG_FB_CLGEN" = "m" ]; then + define_bool CONFIG_FBCON_MFB m + fi + fi + if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_MAC" = "y" -o \ + "$CONFIG_FB_VIRTUAL" = "y" ]; then + define_bool CONFIG_FBCON_CFB2 y + define_bool CONFIG_FBCON_CFB4 y + else + if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_MAC" = "m" -o \ + "$CONFIG_FB_VIRTUAL" = "m" ]; then + define_bool CONFIG_FBCON_CFB2 m + define_bool CONFIG_FBCON_CFB4 m + fi + fi + if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_ATARI" = "y" -o \ + "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_MAC" = "y" -o \ + "$CONFIG_FB_OF" = "y" -o "$CONFIG_FB_TGA" = "y" -o \ + "$CONFIG_FB_VESA" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \ + "$CONFIG_FB_TCX" = "y" -o "$CONFIG_FB_CGTHREE" = "y" -o \ + "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \ + "$CONFIG_FB_CGFOURTEEN" = "y" -o "$CONFIG_FB_G364" = "y" -o \ + "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \ + "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ + "$CONFIG_FB_IGA" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \ + "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_PM2" = "y" -o \ + "$CONFIG_FB_P9100" = "y" -o \ + "$CONFIG_FB_SGIVW" = "y" -o "$CONFIG_FB_CYBER2000" = "y" ]; then + define_bool CONFIG_FBCON_CFB8 y + else + if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \ + "$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_MAC" = "m" -o \ + "$CONFIG_FB_OF" = "m" -o "$CONFIG_FB_TGA" = "m" -o \ + "$CONFIG_FB_VESA" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \ + "$CONFIG_FB_TCX" = "m" -o "$CONFIG_FB_CGTHREE" = "m" -o \ + "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \ + "$CONFIG_FB_CGFOURTEEN" = "m" -o "$CONFIG_FB_G364" = "m" -o \ + "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \ + "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ + "$CONFIG_FB_IGA" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \ + "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_PM2" = "m" -o \ + "$CONFIG_FB_P9100" = "m" -o \ + "$CONFIG_FB_SGIVW" = "m" -o "$CONFIG_FB_CYBER2000" = "m" ]; then + define_bool CONFIG_FBCON_CFB8 m + fi + fi + if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \ + "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_VESA" = "y" -o \ + "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_TBOX" = "y" -o \ + "$CONFIG_FB_Q40" = "y" -o \ + "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \ + "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \ + "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ + "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \ + "$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \ + "$CONFIG_FB_CYBER2000" = "y" ]; then + define_bool CONFIG_FBCON_CFB16 y + else + if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \ + "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_VESA" = "m" -o \ + "$CONFIG_FB_VIRTUAL" = "m" -o "$CONFIG_FB_TBOX" = "m" -o \ + "$CONFIG_FB_Q40" = "m" -o \ + "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \ + "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \ + "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ + "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \ + "$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_SGIVW" = "m" -o \ + "$CONFIG_FB_CYBER2000" = "m" ]; then + define_bool CONFIG_FBCON_CFB16 m + fi + fi + if [ "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \ + "$CONFIG_FB_CLGEN" = "y" -o "$CONFIG_FB_VESA" = "y" -o \ + "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \ + "$CONFIG_FB_CYBER2000" = "y" ]; then + define_bool CONFIG_FBCON_CFB24 y + else + if [ "$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \ + "$CONFIG_FB_CLGEN" = "m" -o "$CONFIG_FB_VESA" = "m" -o \ + "$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \ + "$CONFIG_FB_CYBER2000" = "m" ]; then + define_bool CONFIG_FBCON_CFB24 m + fi + fi + if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \ + "$CONFIG_FB_VESA" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \ + "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \ + "$CONFIG_FB_TGA" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ + "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \ + "$CONFIG_FB_FM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" ]; then + define_bool CONFIG_FBCON_CFB32 y + else + if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \ + "$CONFIG_FB_VESA" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \ + "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \ + "$CONFIG_FB_TGA" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ + "$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \ + "$CONFIG_FB_SGIVW" = "m" ]; then + define_bool CONFIG_FBCON_CFB32 m + fi + fi + if [ "$CONFIG_FB_AMIGA" = "y" ]; then + define_bool CONFIG_FBCON_AFB y + define_bool CONFIG_FBCON_ILBM y + else + if [ "$CONFIG_FB_AMIGA" = "m" ]; then + define_bool CONFIG_FBCON_AFB m + define_bool CONFIG_FBCON_ILBM m + fi + fi + if [ "$CONFIG_FB_ATARI" = "y" ]; then + define_bool CONFIG_FBCON_IPLAN2P2 y + define_bool CONFIG_FBCON_IPLAN2P4 y + define_bool CONFIG_FBCON_IPLAN2P8 y +# define_bool CONFIG_FBCON_IPLAN2P16 y + else + if [ "$CONFIG_FB_ATARI" = "m" ]; then + define_bool CONFIG_FBCON_IPLAN2P2 m + define_bool CONFIG_FBCON_IPLAN2P4 m + define_bool CONFIG_FBCON_IPLAN2P8 m +# define_bool CONFIG_FBCON_IPLAN2P16 m + fi + fi + if [ "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" ]; then + define_bool CONFIG_FBCON_MAC y + else + if [ "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then + define_bool CONFIG_FBCON_MAC m + fi + fi + if [ "$CONFIG_FB_VGA16" = "y" ]; then + define_bool CONFIG_FBCON_VGA_PLANES y + else + if [ "$CONFIG_FB_VGA16" = "m" ]; then + define_bool CONFIG_FBCON_VGA_PLANES m + fi + fi + if [ "$CONFIG_FB_MDA" = "y" -o "$CONFIG_FB_VGA" = "y" ]; then + define_bool CONFIG_FBCON_VGA y + else + if [ "$CONFIG_FB_MDA" = "m" -o "$CONFIG_FB_VGA" = "m" ]; then + define_bool CONFIG_FBCON_VGA m + fi + fi + fi + bool ' Support only 8 pixels wide fonts' CONFIG_FBCON_FONTWIDTH8_ONLY + if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then bool ' Sparc console 8x16 font' CONFIG_FONT_SUN8x16 if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then - bool ' Sparc console 12x22 font (not supported by all drivers)' CONFIG_FONT_SUN12x22 - bool ' Mac console 6x11 font (not supported by all drivers)' CONFIG_FONT_6x11 + bool ' Sparc console 12x22 font (not supported by all drivers)' CONFIG_FONT_SUN12x22 fi - bool ' Pearl (old m68k) console 8x8 font' CONFIG_FONT_PEARL_8x8 - bool ' Acorn console 8x8 font' CONFIG_FONT_ACORN_8x8 - else - define_bool CONFIG_FONT_8x8 y - define_bool CONFIG_FONT_8x16 y - if [ "$CONFIG_MAC" = "y" ]; then - if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then - define_bool CONFIG_FONT_6x11 y - fi + bool ' Select other fonts' CONFIG_FBCON_FONTS + if [ "$CONFIG_FBCON_FONTS" = "y" ]; then + bool ' VGA 8x8 font' CONFIG_FONT_8x8 + bool ' VGA 8x16 font' CONFIG_FONT_8x16 + if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then + bool ' Mac console 6x11 font (not supported by all drivers)' CONFIG_FONT_6x11 + fi + bool ' Pearl (old m68k) console 8x8 font' CONFIG_FONT_PEARL_8x8 + bool ' Acorn console 8x8 font' CONFIG_FONT_ACORN_8x8 + fi + else + bool ' Select compiled-in fonts' CONFIG_FBCON_FONTS + if [ "$CONFIG_FBCON_FONTS" = "y" ]; then + bool ' VGA 8x8 font' CONFIG_FONT_8x8 + bool ' VGA 8x16 font' CONFIG_FONT_8x16 + bool ' Sparc console 8x16 font' CONFIG_FONT_SUN8x16 + if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then + bool ' Sparc console 12x22 font (not supported by all drivers)' CONFIG_FONT_SUN12x22 + bool ' Mac console 6x11 font (not supported by all drivers)' CONFIG_FONT_6x11 + fi + bool ' Pearl (old m68k) console 8x8 font' CONFIG_FONT_PEARL_8x8 + bool ' Acorn console 8x8 font' CONFIG_FONT_ACORN_8x8 + else + define_bool CONFIG_FONT_8x8 y + define_bool CONFIG_FONT_8x16 y + if [ "$CONFIG_MAC" = "y" ]; then + if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then + define_bool CONFIG_FONT_6x11 y + fi + fi + if [ "$CONFIG_AMIGA" = "y" ]; then + define_bool CONFIG_FONT_PEARL_8x8 y + fi + if [ "$CONFIG_ARM" = "y" -a "$CONFIG_ARCH_ACORN" = "y" ]; then + define_bool CONFIG_FONT_ACORN_8x8 y + fi fi - if [ "$CONFIG_AMIGA" = "y" ]; then - define_bool CONFIG_FONT_PEARL_8x8 y - fi - if [ "$CONFIG_ARM" = "y" -a "$CONFIG_ARCH_ACORN" = "y" ]; then - define_bool CONFIG_FONT_ACORN_8x8 y - fi - fi - fi + fi fi + +endmenu diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/video/Makefile linux.ac/drivers/video/Makefile --- linux.vanilla/drivers/video/Makefile Sat Sep 11 00:54:11 1999 +++ linux.ac/drivers/video/Makefile Fri Sep 10 17:55:10 1999 @@ -150,10 +150,10 @@ endif ifeq ($(CONFIG_FB_SGIVW),y) -L_OBJS += sgivwfb.o +LX_OBJS += sgivwfb.o else ifeq ($(CONFIG_FB_SGIVW),m) - M_OBJS += sgivwfb.o + MX_OBJS += sgivwfb.o endif endif diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/video/p9100fb.c linux.ac/drivers/video/p9100fb.c --- linux.vanilla/drivers/video/p9100fb.c Sat Sep 11 00:54:12 1999 +++ linux.ac/drivers/video/p9100fb.c Mon Sep 13 23:44:29 1999 @@ -106,7 +106,7 @@ static char idstring[60] __initdata = { 0 }; -__initfunc(char *p9100fb_init(struct fb_info_sbusfb *fb)) +char * __init p9100fb_init(struct fb_info_sbusfb *fb) { struct fb_fix_screeninfo *fix = &fb->fix; struct display *disp = &fb->disp; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/fs/Config.in linux.ac/fs/Config.in --- linux.vanilla/fs/Config.in Tue Sep 7 22:07:06 1999 +++ linux.ac/fs/Config.in Mon Sep 13 00:22:42 1999 @@ -4,15 +4,15 @@ mainmenu_option next_comment comment 'Filesystems' -bool 'Quota support' CONFIG_QUOTA +bool 'Quota support' CONFIG_QUOTA tristate 'Kernel automounter support' CONFIG_AUTOFS_FS if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'ADFS filesystem support (read only) (EXPERIMENTAL)' CONFIG_ADFS_FS + tristate 'ADFS filesystem support (read only) (EXPERIMENTAL)' CONFIG_ADFS_FS fi tristate 'Amiga FFS filesystem support' CONFIG_AFFS_FS -tristate 'Apple Macintosh filesystem support (experimental)' CONFIG_HFS_FS +tristate 'Apple Macintosh filesystem support (EXPERIMENTAL)' CONFIG_HFS_FS # msdos filesystems tristate 'DOS FAT fs support' CONFIG_FAT_FS dep_tristate ' MSDOS fs support' CONFIG_MSDOS_FS $CONFIG_FAT_FS @@ -20,48 +20,48 @@ dep_tristate ' VFAT (Windows-95) fs support' CONFIG_VFAT_FS $CONFIG_FAT_FS if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'EFS filesystem support (read only) (experimental)' CONFIG_EFS_FS + tristate 'EFS filesystem support (read only) (EXPERIMENTAL)' CONFIG_EFS_FS fi tristate 'ISO 9660 CDROM filesystem support' CONFIG_ISO9660_FS if [ "$CONFIG_ISO9660_FS" != "n" ]; then - bool 'Microsoft Joliet CDROM extensions' CONFIG_JOLIET + bool ' Microsoft Joliet CDROM extensions' CONFIG_JOLIET else - # needed by nls/Config.in - define_bool CONFIG_JOLIET n + # needed by nls/Config.in + define_bool CONFIG_JOLIET n fi -tristate 'UDF filesystem support' CONFIG_UDF_FS +tristate 'UDF filesystem support (read only)' CONFIG_UDF_FS if [ "$CONFIG_UDF_FS" != "n" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool ' UDF read-write support (EXPERIMENTAL)' CONFIG_UDF_RW + bool ' UDF write support (DANGEROUS)' CONFIG_UDF_RW fi tristate 'Minix fs support' CONFIG_MINIX_FS tristate 'NTFS filesystem support (read only)' CONFIG_NTFS_FS if [ "$CONFIG_NTFS_FS" != "n" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool ' NTFS read-write support (DANGEROUS)' CONFIG_NTFS_RW + bool ' NTFS write support (DANGEROUS)' CONFIG_NTFS_RW fi -tristate 'OS/2 HPFS filesystem support (read/write) (NEW)' CONFIG_HPFS_FS +tristate 'OS/2 HPFS filesystem support' CONFIG_HPFS_FS bool '/proc filesystem support' CONFIG_PROC_FS if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then - # It compiles as a module for testing only. It should not be used - # as a module in general. If we make this "tristate", a bunch of people - # who don't know what they are doing turn it on and complain when it - # breaks. - bool '/dev/pts filesystem for Unix98 PTYs' CONFIG_DEVPTS_FS + # It compiles as a module for testing only. It should not be used + # as a module in general. If we make this "tristate", a bunch of people + # who don't know what they are doing turn it on and complain when it + # breaks. + bool '/dev/pts filesystem for Unix98 PTYs' CONFIG_DEVPTS_FS fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'QNX filesystem support (EXPERIMENTAL)' CONFIG_QNX4FS_FS - if [ "$CONFIG_QNX4FS_FS" != "n" ]; then - bool ' QNXFS read-write support (FOR TESTING ONLY)' CONFIG_QNX4FS_RW - fi + tristate 'QNX filesystem support (read only) (EXPERIMENTAL)' CONFIG_QNX4FS_FS + if [ "$CONFIG_QNX4FS_FS" != "n" ]; then + bool ' QNXFS write support (DANGEROUS)' CONFIG_QNX4FS_RW + fi fi tristate 'ROM filesystem support' CONFIG_ROMFS_FS tristate 'Second extended fs support' CONFIG_EXT2_FS tristate 'System V and Coherent filesystem support' CONFIG_SYSV_FS -tristate 'UFS filesystem support' CONFIG_UFS_FS -if [ "$CONFIG_UFS_FS" != "n" ]; then - bool ' UFS filesystem write support (experimental)' CONFIG_UFS_FS_WRITE +tristate 'UFS filesystem support (read only)' CONFIG_UFS_FS +if [ "$CONFIG_UFS_FS" != "n" -a "$CONFIG_EXPERIMENTAL" ]; then + bool ' UFS filesystem write support (DANGEROUS)' CONFIG_UFS_FS_WRITE fi @@ -71,35 +71,36 @@ comment 'Network File Systems' if [ "$CONFIG_INET" = "y" ]; then - tristate 'Coda filesystem support (advanced network fs)' CONFIG_CODA_FS - tristate 'NFS filesystem support' CONFIG_NFS_FS - if [ "$CONFIG_NFS_FS" = "y" -a "$CONFIG_IP_PNP" = "y" ]; then - bool ' Root file system on NFS' CONFIG_ROOT_NFS - fi - # considering that RedHat-6.0 ships with this on, I guess it's not really experimental - tristate 'NFS server support' CONFIG_NFSD - if [ "$CONFIG_NFSD" != "n" ]; then - bool ' Emulate SUN NFS server' CONFIG_NFSD_SUN - fi - if [ "$CONFIG_NFS_FS" = "y" -o "$CONFIG_NFSD" = "y" ]; then - define_bool CONFIG_SUNRPC y - define_bool CONFIG_LOCKD y - else - if [ "$CONFIG_NFS_FS" = "m" -o "$CONFIG_NFSD" = "m" ]; then - define_bool CONFIG_SUNRPC m - define_bool CONFIG_LOCKD m - else - define_bool CONFIG_SUNRPC n - define_bool CONFIG_LOCKD n - fi - fi - tristate 'SMB filesystem support (to mount WfW shares etc.)' CONFIG_SMB_FS + tristate 'Coda filesystem support (advanced network fs)' CONFIG_CODA_FS + tristate 'NFS filesystem support' CONFIG_NFS_FS + if [ "$CONFIG_NFS_FS" = "y" -a "$CONFIG_IP_PNP" = "y" ]; then + bool ' Root file system on NFS' CONFIG_ROOT_NFS + fi + if [ "$CONFIG_EXPERIMENTAL" ]; then + tristate 'NFS server support (EXPERIMENTAL)' CONFIG_NFSD + if [ "$CONFIG_NFSD" != "n" ]; then + bool ' Emulate SUN NFS server' CONFIG_NFSD_SUN + fi + fi + if [ "$CONFIG_NFS_FS" = "y" -o "$CONFIG_NFSD" = "y" ]; then + define_bool CONFIG_SUNRPC y + define_bool CONFIG_LOCKD y + else + if [ "$CONFIG_NFS_FS" = "m" -o "$CONFIG_NFSD" = "m" ]; then + define_bool CONFIG_SUNRPC m + define_bool CONFIG_LOCKD m + else + define_bool CONFIG_SUNRPC n + define_bool CONFIG_LOCKD n + fi + fi + tristate 'SMB filesystem support (to mount WfW shares etc.)' CONFIG_SMB_FS fi if [ "$CONFIG_IPX" != "n" -o "$CONFIG_INET" != "n" ]; then - tristate 'NCP filesystem support (to mount NetWare volumes)' CONFIG_NCP_FS - if [ "$CONFIG_NCP_FS" != "n" ]; then - source fs/ncpfs/Config.in - fi + tristate 'NCP filesystem support (to mount NetWare volumes)' CONFIG_NCP_FS + if [ "$CONFIG_NCP_FS" != "n" ]; then + source fs/ncpfs/Config.in + fi fi endmenu diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/fs/binfmt_aout.c linux.ac/fs/binfmt_aout.c --- linux.vanilla/fs/binfmt_aout.c Thu Sep 2 00:48:38 1999 +++ linux.ac/fs/binfmt_aout.c Tue Sep 14 21:24:56 1999 @@ -270,6 +270,7 @@ unsigned long fd_offset; unsigned long rlim; int retval; + static unsigned long error_time=0; ex = *((struct exec *) bprm->buf); /* exec-header */ if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && @@ -283,7 +284,11 @@ #ifdef __i386__ if (N_MAGIC(ex) == ZMAGIC && fd_offset != BLOCK_SIZE) { - printk(KERN_NOTICE "N_TXTOFF != BLOCK_SIZE. See a.out.h.\n"); + if((jiffies-error_time) >5) + { + printk(KERN_NOTICE "N_TXTOFF != BLOCK_SIZE. See a.out.h.\n"); + error_time=jiffies; + } return -ENOEXEC; } @@ -291,7 +296,11 @@ bprm->dentry->d_inode->i_op && bprm->dentry->d_inode->i_op->get_block && (fd_offset < bprm->dentry->d_inode->i_sb->s_blocksize)) { - printk(KERN_NOTICE "N_TXTOFF < BLOCK_SIZE. Please convert binary.\n"); + if((jiffies-error_time) >5) + { + printk(KERN_NOTICE "N_TXTOFF < BLOCK_SIZE. Please convert binary.\n"); + error_time=jiffies; + } return -ENOEXEC; } #endif diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/fs/buffer.c linux.ac/fs/buffer.c --- linux.vanilla/fs/buffer.c Tue Sep 7 22:07:06 1999 +++ linux.ac/fs/buffer.c Sat Sep 18 01:36:51 1999 @@ -114,18 +114,18 @@ each time we call refill */ int nref_dirt; /* Dirty buffer threshold for activating bdflush when trying to refill buffers. */ - int dummy1; /* unused */ + int interval; /* jiffies delay between kupdate flushes */ int age_buffer; /* Time for normal buffer to age before we flush it */ int age_super; /* Time for superblock to age before we flush it */ int dummy2; /* unused */ int dummy3; /* unused */ } b_un; unsigned int data[N_PARAM]; -} bdf_prm = {{40, 500, 64, 256, 15, 30*HZ, 5*HZ, 1884, 2}}; +} bdf_prm = {{40, 500, 64, 256, 5*HZ, 30*HZ, 5*HZ, 1884, 2}}; /* These are the min and max parameter values that we will allow to be assigned */ int bdflush_min[N_PARAM] = { 0, 10, 5, 25, 0, 1*HZ, 1*HZ, 1, 1}; -int bdflush_max[N_PARAM] = {100,50000, 20000, 20000,1000, 6000*HZ, 6000*HZ, 2047, 5}; +int bdflush_max[N_PARAM] = {100,50000, 20000, 20000,600*HZ, 6000*HZ, 6000*HZ, 2047, 5}; void wakeup_bdflush(int); @@ -1158,7 +1158,7 @@ goto try_again; } -static int create_page_buffers(int rw, struct page *page, kdev_t dev, int b[], int size, int bmap) +static int create_page_buffers(int rw, struct page *page, kdev_t dev, int b[], int size) { struct buffer_head *head, *bh, *tail; int block; @@ -1186,17 +1186,6 @@ bh->b_dev = dev; bh->b_blocknr = block; - /* - * When we use bmap, we define block zero to represent - * a hole. ll_rw_page, however, may legitimately - * access block zero, and we need to distinguish the - * two cases. - */ - if (bmap && !block) { - memset(bh->b_data, 0, size); - set_bit(BH_Uptodate, &bh->b_state); - continue; - } set_bit(BH_Mapped, &bh->b_state); } tail->b_this_page = head; @@ -1236,7 +1225,6 @@ mark_buffer_clean(bh); wait_on_buffer(bh); clear_bit(BH_Uptodate, &bh->b_state); - clear_bit(BH_Mapped, &bh->b_state); clear_bit(BH_Req, &bh->b_state); bh->b_blocknr = 0; } @@ -1247,7 +1235,7 @@ /* * subtle. We release buffer-heads only if this is - * the 'final' flushpage. We have invalidated the bmap + * the 'final' flushpage. We have invalidated the get_block * cached value unconditionally, so real IO is not * possible anymore. * @@ -1750,7 +1738,7 @@ */ int brw_kiovec(int rw, int nr, struct kiobuf *iovec[], - kdev_t dev, unsigned long b[], int size, int bmap) + kdev_t dev, unsigned long b[], int size) { int err; int length; @@ -1873,7 +1861,7 @@ return err; error: - /* We got an error allocation the bh'es. Just free the current + /* We got an error allocating the bh'es. Just free the current buffer_heads and exit. */ spin_lock(&unused_list_lock); for (i = bhind; --i >= 0; ) { @@ -1895,7 +1883,7 @@ * FIXME: we need a swapper_inode->get_block function to remove * some of the bmap kludges and interface ugliness here. */ -int brw_page(int rw, struct page *page, kdev_t dev, int b[], int size, int bmap) +int brw_page(int rw, struct page *page, kdev_t dev, int b[], int size) { struct buffer_head *head, *bh, *arr[MAX_BUF_PER_PAGE]; int nr, fresh /* temporary debugging flag */, block; @@ -1909,7 +1897,7 @@ */ fresh = 0; if (!page->buffers) { - create_page_buffers(rw, page, dev, b, size, bmap); + create_page_buffers(rw, page, dev, b, size); fresh = 1; } if (!page->buffers) @@ -1927,16 +1915,9 @@ if (rw == READ) { if (!fresh) BUG(); - if (bmap && !block) { - if (block) - BUG(); - } else { - if (bmap && !block) - BUG(); - if (!buffer_uptodate(bh)) { - arr[nr++] = bh; - atomic_inc(&bh->b_count); - } + if (!buffer_uptodate(bh)) { + arr[nr++] = bh; + atomic_inc(&bh->b_count); } } else { /* WRITE */ if (!bh->b_blocknr) { @@ -1974,7 +1955,7 @@ /* * Generic "read page" function for block devices that have the normal - * bmap functionality. This is most of the block device filesystems. + * get_block functionality. This is most of the block device filesystems. * Reads the page asynchronously --- the unlock_buffer() and * mark_buffer_uptodate() functions propagate buffer state into the * page struct once IO has completed. @@ -2326,6 +2307,10 @@ return -EPERM; if (func == 1) { + /* do_exit directly and let kupdate to do its work alone. */ + do_exit(0); +#if 0 /* left here as it's the only example of lazy-mm-stuff used from + a syscall that doesn't care about the current mm context. */ int error; struct mm_struct *user_mm; @@ -2339,6 +2324,7 @@ error = sync_old_buffers(); end_lazy_tlb(user_mm); return error; +#endif } /* Basically func 1 means read param 1, 2 means write param 1, etc */ @@ -2457,9 +2443,70 @@ } } +/* + * This is the kernel update daemon. It used to live in userspace + * but since it is needed in order to run safely we don't want it to + * be killable by mistake. + * You don't need to change your userspace configuration since + * the userspace `update` will do_exit(0) at the first sys_bdflush(). + */ + +int kupdate(void * unused) +{ + struct task_struct * tsk = current; + int interval; + + tsk->session = 1; + tsk->pgrp = 1; + strcpy(tsk->comm, "kupdate"); + + /* sigstop and sigcont will stop and wakeup kupdate */ + spin_lock_irq(&tsk->sigmask_lock); + sigfillset(&tsk->blocked); + siginitsetinv(¤t->blocked, sigmask(SIGCONT) | sigmask(SIGSTOP)); + recalc_sigpending(tsk); + spin_unlock_irq(&tsk->sigmask_lock); + + for (;;) { + /* update interval */ + interval = bdf_prm.b_un.interval; + if (interval) + { + tsk->state = TASK_INTERRUPTIBLE; + schedule_timeout(interval); + } + else + { + stop_kupdate: + tsk->state = TASK_STOPPED; + schedule(); /* wait for SIGCONT */ + } + /* check for sigstop */ + if (signal_pending(tsk)) + { + int stopped = 0; + spin_lock_irq(&tsk->sigmask_lock); + if (sigismember(&tsk->signal, SIGSTOP)) + { + sigdelset(&tsk->signal, SIGSTOP); + stopped = 1; + } + recalc_sigpending(tsk); + spin_unlock_irq(&tsk->sigmask_lock); + if (stopped) + goto stop_kupdate; + } +#ifdef DEBUG + printk("kupdate() activated...\n"); +#endif + sync_old_buffers(); + } +} + static int __init bdflush_init(void) { kernel_thread(bdflush, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); + kernel_thread(kupdate, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); return 0; } diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/fs/exec.c linux.ac/fs/exec.c --- linux.vanilla/fs/exec.c Tue Sep 7 22:07:06 1999 +++ linux.ac/fs/exec.c Thu Sep 16 16:42:35 1999 @@ -169,7 +169,7 @@ /* * count() counts the number of arguments/envelopes */ -static int count(char ** argv) +static int count(char ** argv, int max) { int i = 0; @@ -184,7 +184,8 @@ if (!p) break; argv++; - i++; + if(++i > max) + return -E2BIG; } } return i; @@ -202,7 +203,7 @@ int len; unsigned long pos; - if (get_user(str, argv+argc) || !str || !(len = strlen_user(str))) + if (get_user(str, argv+argc) || !str || !(len = strnlen_user(str, bprm->p))) return -EFAULT; if (bprm->p < len) return -E2BIG; @@ -211,7 +212,7 @@ /* XXX: add architecture specific overflow check here. */ pos = bprm->p; - while (len) { + while (len>0) { char *pag; int offset, bytes_to_copy; @@ -274,7 +275,7 @@ mpnt->vm_ops = NULL; mpnt->vm_offset = 0; mpnt->vm_file = NULL; - mpnt->vm_private_data = NULL; + mpnt->vm_private_data = (void *) 0; insert_vm_struct(current->mm, mpnt); current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; } @@ -753,12 +754,12 @@ bprm.sh_bang = 0; bprm.loader = 0; bprm.exec = 0; - if ((bprm.argc = count(argv)) < 0) { + if ((bprm.argc = count(argv, bprm.p / sizeof(void *))) < 0) { dput(dentry); return bprm.argc; } - if ((bprm.envc = count(envp)) < 0) { + if ((bprm.envc = count(envp, bprm.p / sizeof(void *))) < 0) { dput(dentry); return bprm.envc; } diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/fs/fcntl.c linux.ac/fs/fcntl.c --- linux.vanilla/fs/fcntl.c Thu Sep 2 00:48:39 1999 +++ linux.ac/fs/fcntl.c Wed Sep 15 23:56:18 1999 @@ -8,6 +8,8 @@ #include #include +#include +#include #include extern int sock_fcntl (struct file *, unsigned int cmd, unsigned long arg); @@ -255,8 +257,22 @@ return err; } +/* Table to convert sigio signal codes into poll band bitmaps */ + +static int band_table[NSIGPOLL+1] = { + ~0, + POLLIN | POLLRDNORM, /* POLL_IN */ + POLLOUT | POLLWRNORM | POLLWRBAND, /* POLL_OUT */ + POLLIN | POLLRDNORM | POLLMSG, /* POLL_MSG */ + POLLERR, /* POLL_ERR */ + POLLPRI | POLLRDBAND, /* POLL_PRI */ + POLLHUP | POLLERR /* POLL_HUP */ +}; + static void send_sigio_to_task(struct task_struct *p, - struct fown_struct *fown, struct fasync_struct *fa) + struct fown_struct *fown, + struct fasync_struct *fa, + int reason) { if ((fown->euid != 0) && (fown->euid ^ p->suid) && (fown->euid ^ p->uid) && @@ -273,9 +289,11 @@ back to SIGIO in that case. --sct */ si.si_signo = fown->signum; si.si_errno = 0; - si.si_code = SI_SIGIO; - si.si_pid = fown->pid; - si.si_uid = fown->uid; + si.si_code = reason; + if (reason < 0 || reason > NSIGPOLL) + si.si_band = ~0; + else + si.si_band = band_table[reason]; si.si_fd = fa->fa_fd; if (!send_sig_info(fown->signum, &si, p)) break; @@ -285,14 +303,15 @@ } } -static void send_sigio(struct fown_struct *fown, struct fasync_struct *fa) +static void send_sigio(struct fown_struct *fown, struct fasync_struct *fa, + int band) { struct task_struct * p; int pid = fown->pid; read_lock(&tasklist_lock); if ( (pid > 0) && (p = find_task_by_pid(pid)) ) { - send_sigio_to_task(p, fown, fa); + send_sigio_to_task(p, fown, fa, band); goto out; } for_each_task(p) { @@ -301,13 +320,13 @@ match = -p->pgrp; if (pid != match) continue; - send_sigio_to_task(p, fown, fa); + send_sigio_to_task(p, fown, fa, band); } out: read_unlock(&tasklist_lock); } -void kill_fasync(struct fasync_struct *fa, int sig) +void kill_fasync(struct fasync_struct *fa, int sig, int band) { while (fa) { struct fown_struct * fown; @@ -317,8 +336,11 @@ return; } fown = &fa->fa_file->f_owner; - if (fown->pid) - send_sigio(fown, fa); + /* Don't send SIGURG to processes which have not set a + queued signum: SIGURG has its own default signalling + mechanism. */ + if (fown->pid && !(sig == SIGURG && fown->signum == 0)) + send_sigio(fown, fa, band); fa = fa->fa_next; } } diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/fs/isofs/inode.c linux.ac/fs/isofs/inode.c --- linux.vanilla/fs/isofs/inode.c Thu Sep 2 00:48:39 1999 +++ linux.ac/fs/isofs/inode.c Wed Sep 15 23:53:22 1999 @@ -446,6 +446,14 @@ inode_fake.i_rdev=dev; init_waitqueue_head(&inode_fake.i_wait); ms_info.addr_format=CDROM_LBA; + /* If a minor device was explicitly opened, set session to the + * minor number. For instance, if /dev/hdc1 is mounted, session + * 1 on the CD-ROM is selected. CD_PART_MAX gives access to + * a max of 64 sessions on IDE. SCSI drives must still use + * the session option to mount. + */ + if ((MINOR(dev) % CD_PART_MAX) && (MAJOR(dev) != SCSI_CDROM_MAJOR)) + session = MINOR(dev) % CD_PART_MAX; set_fs(KERNEL_DS); if(session >= 0 && session <= 99) { struct cdrom_tocentry Te; @@ -1042,6 +1050,7 @@ struct buffer_head * bh = NULL; int block = 0; int i = 0; + int more_entries = 0; void *cpnt; struct iso_directory_record * raw_inode; @@ -1062,7 +1071,6 @@ goto out_noread; } pnt = ((unsigned char *) bh->b_data + offset); - raw_inode = ((struct iso_directory_record *) pnt); /* * Note: this is invariant even if the record * spans buffers and must be copied ... @@ -1074,6 +1082,7 @@ ino = (ino & ~(ISOFS_BLOCK_SIZE - 1)) + ISOFS_BLOCK_SIZE; continue; } + raw_inode = ((struct iso_directory_record *) pnt); /* Check whether the raw inode spans the buffer ... */ if (offset + reclen > bufsize){ @@ -1095,13 +1104,15 @@ inode->i_size += isonum_733 (raw_inode->size); if(i == 1) inode->u.isofs_i.i_next_section_ino = ino; + more_entries = raw_inode->flags[-high_sierra] & 0x80; + ino += reclen; if (cpnt) kfree (cpnt); i++; if(i > 100) goto out_toomany; - } while(raw_inode->flags[-high_sierra] & 0x80); + } while(more_entries); out: brelse(bh); return 0; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/fs/namei.c linux.ac/fs/namei.c --- linux.vanilla/fs/namei.c Thu Aug 26 14:42:18 1999 +++ linux.ac/fs/namei.c Thu Sep 2 16:51:04 1999 @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -548,83 +549,6 @@ return -EEXIST; return permission(dir,MAY_WRITE | MAY_EXEC); } - -static inline struct dentry *get_parent(struct dentry *dentry) -{ - return dget(dentry->d_parent); -} - -static inline void unlock_dir(struct dentry *dir) -{ - up(&dir->d_inode->i_sem); - dput(dir); -} - -/* - * We need to do a check-parent every time - * after we have locked the parent - to verify - * that the parent is still our parent and - * that we are still hashed onto it.. - * - * This is requied in case two processes race - * on removing (or moving) the same entry: the - * parent lock will serialize them, but the - * other process will be too late.. - */ -#define check_parent(dir, dentry) \ - ((dir) == (dentry)->d_parent && !list_empty(&dentry->d_hash)) - -/* - * Locking the parent is needed to: - * - serialize directory operations - * - make sure the parent doesn't change from - * under us in the middle of an operation. - * - * NOTE! Right now we'd rather use a "struct inode" - * for this, but as I expect things to move toward - * using dentries instead for most things it is - * probably better to start with the conceptually - * better interface of relying on a path of dentries. - */ -static inline struct dentry *lock_parent(struct dentry *dentry) -{ - struct dentry *dir = dget(dentry->d_parent); - - down(&dir->d_inode->i_sem); - return dir; -} - -/* - * Whee.. Deadlock country. Happily there are only two VFS - * operations that do this.. - */ -static inline void double_lock(struct dentry *d1, struct dentry *d2) -{ - struct semaphore *s1 = &d1->d_inode->i_sem; - struct semaphore *s2 = &d2->d_inode->i_sem; - - if (s1 != s2) { - if ((unsigned long) s1 < (unsigned long) s2) { - struct semaphore *tmp = s2; - s2 = s1; s1 = tmp; - } - down(s1); - } - down(s2); -} - -static inline void double_unlock(struct dentry *d1, struct dentry *d2) -{ - struct semaphore *s1 = &d1->d_inode->i_sem; - struct semaphore *s2 = &d2->d_inode->i_sem; - - up(s1); - if (s1 != s2) - up(s2); - dput(d1); - dput(d2); -} - /* * Special case: O_CREAT|O_EXCL implies O_NOFOLLOW for security diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/fs/ncpfs/Config.in linux.ac/fs/ncpfs/Config.in --- linux.vanilla/fs/ncpfs/Config.in Tue Apr 20 23:17:20 1999 +++ linux.ac/fs/ncpfs/Config.in Mon Sep 13 00:22:42 1999 @@ -1,15 +1,15 @@ # # NCP Filesystem configuration # -bool ' Packet signatures' CONFIG_NCPFS_PACKET_SIGNING -bool ' Proprietary file locking' CONFIG_NCPFS_IOCTL_LOCKING -bool ' Clear remove/delete inhibit when needed' CONFIG_NCPFS_STRONG -bool ' Use NFS namespace if available' CONFIG_NCPFS_NFS_NS -bool ' Use LONG (OS/2) namespace if available' CONFIG_NCPFS_OS2_NS +bool ' Packet signatures' CONFIG_NCPFS_PACKET_SIGNING +bool ' Proprietary file locking' CONFIG_NCPFS_IOCTL_LOCKING +bool ' Clear remove/delete inhibit when needed' CONFIG_NCPFS_STRONG +bool ' Use NFS namespace if available' CONFIG_NCPFS_NFS_NS +bool ' Use LONG (OS/2) namespace if available' CONFIG_NCPFS_OS2_NS if [ "$CONFIG_NCPFS_OS2_NS" = "y" ]; then - bool ' Lowercase DOS filenames' CONFIG_NCPFS_SMALLDOS + bool ' Lowercase DOS filenames' CONFIG_NCPFS_SMALLDOS fi -bool ' Allow mounting of volume subdirectories' CONFIG_NCPFS_MOUNT_SUBDIR -# bool ' NDS interserver authentication support' CONFIG_NCPFS_NDS_DOMAINS -bool ' Use Native Language Support' CONFIG_NCPFS_NLS -bool ' Enable symbolic links and execute flags' CONFIG_NCPFS_EXTRAS +bool ' Allow mounting of volume subdirectories' CONFIG_NCPFS_MOUNT_SUBDIR +# bool ' NDS interserver authentication support' CONFIG_NCPFS_NDS_DOMAINS +bool ' Use Native Language Support' CONFIG_NCPFS_NLS +bool ' Enable symbolic links and execute flags' CONFIG_NCPFS_EXTRAS diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/fs/nfs/file.c linux.ac/fs/nfs/file.c --- linux.vanilla/fs/nfs/file.c Mon Jul 5 22:33:52 1999 +++ linux.ac/fs/nfs/file.c Sat Sep 18 18:29:10 1999 @@ -222,7 +222,7 @@ nfs_lock(struct file *filp, int cmd, struct file_lock *fl) { struct inode * inode = filp->f_dentry->d_inode; - int status; + int status = 0; dprintk("NFS: nfs_lock(f=%4x/%ld, t=%x, fl=%x, r=%ld:%ld)\n", inode->i_dev, inode->i_ino, @@ -237,8 +237,11 @@ return -ENOLCK; /* Fake OK code if mounted without NLM support */ - if (NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM) - return 0; + if (NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM) { + if (cmd == F_GETLK) + status = LOCK_USE_CLNT; + goto out_ok; + } /* * No BSD flocks over NFS allowed. @@ -260,11 +263,14 @@ if ((status = nlmclnt_proc(inode, cmd, fl)) < 0) return status; + else + status = 0; /* * Make sure we re-validate anything we've got cached. * This makes locking act as a cache coherency point. */ + out_ok: NFS_CACHEINV(inode); - return 0; + return status; } diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/fs/nfs/inode.c linux.ac/fs/nfs/inode.c --- linux.vanilla/fs/nfs/inode.c Mon Jul 5 22:33:38 1999 +++ linux.ac/fs/nfs/inode.c Tue Sep 14 21:27:07 1999 @@ -412,6 +412,8 @@ unhashed = 0; while ((tmp = tmp->next) != head) { struct dentry *dentry = list_entry(tmp, struct dentry, d_alias); + if (!list_empty(&dentry->d_subdirs)) + shrink_dcache_parent(dentry); dprintk("nfs_free_dentries: found %s/%s, d_count=%d, hashed=%d\n", dentry->d_parent->d_name.name, dentry->d_name.name, dentry->d_count, !list_empty(&dentry->d_hash)); @@ -421,7 +423,7 @@ dput(dentry); goto restart; } - if (!list_empty(&dentry->d_hash)) + if (list_empty(&dentry->d_hash)) unhashed++; } return unhashed; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/fs/open.c linux.ac/fs/open.c --- linux.vanilla/fs/open.c Thu Aug 26 14:42:18 1999 +++ linux.ac/fs/open.c Tue Sep 14 21:27:17 1999 @@ -526,10 +526,13 @@ * non-root user, remove the setuid bit. * 19981026 David C Niemi * + * Changed this to apply to all users, including root, to avoid + * some races. This is the behavior we had in 2.0. The check for + * non-root was definitely wrong for 2.2 anyway, as it should + * have been using CAP_FSETID rather than fsuid -- 19990830 SD. */ if ((inode->i_mode & S_ISUID) == S_ISUID && - !S_ISDIR(inode->i_mode) - && current->fsuid) + !S_ISDIR(inode->i_mode)) { newattrs.ia_mode &= ~S_ISUID; newattrs.ia_valid |= ATTR_MODE; @@ -539,9 +542,11 @@ * by a non-root user, remove the setgid bit UNLESS there is no group * execute bit (this would be a file marked for mandatory locking). * 19981026 David C Niemi + * + * Removed the fsuid check (see the comment above) -- 19990830 SD. */ if (((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) - && !S_ISDIR(inode->i_mode) && current->fsuid) + && !S_ISDIR(inode->i_mode)) { newattrs.ia_mode &= ~S_ISGID; newattrs.ia_valid |= ATTR_MODE; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/fs/partitions/Config.in linux.ac/fs/partitions/Config.in --- linux.vanilla/fs/partitions/Config.in Tue Sep 7 22:07:06 1999 +++ linux.ac/fs/partitions/Config.in Thu Sep 16 16:26:18 1999 @@ -3,60 +3,54 @@ # bool 'Advanced partition selection' CONFIG_PARTITION_ADVANCED if [ "$CONFIG_PARTITION_ADVANCED" = "y" ]; then - bool 'Alpha OSF partition support' CONFIG_OSF_PARTITION - bool 'Macintosh partition map support' CONFIG_MAC_PARTITION - bool 'PC BIOS (MSDOS partition tables) support' CONFIG_MSDOS_PARTITION + bool ' Alpha OSF partition support' CONFIG_OSF_PARTITION + bool ' Macintosh partition map support' CONFIG_MAC_PARTITION + bool ' PC BIOS (MSDOS partition tables) support' CONFIG_MSDOS_PARTITION + bool ' SGI partition support' CONFIG_SGI_PARTITION + bool ' Sun partition tables support' CONFIG_SUN_PARTITION + bool ' Amiga partition table support' CONFIG_AMIGA_PARTITION + bool ' Atari partition table support' CONFIG_ATARI_PARTITION + bool ' Acorn partition support' CONFIG_ACORN_PARTITION + if [ "$CONFIG_ACORN_PARTITION" != "n" ]; then + bool ' Native filecore partition support' CONFIG_ACORN_PARTITION_ADFS +# bool ' Cumana partition support' CONFIG_ACORN_PARTITION_CUMANA + bool ' ICS partition support' CONFIG_ACORN_PARTITION_ICS + bool ' PowerTec partition support' CONFIG_ACORN_PARTITION_POWERTEC + bool ' RISCiX partition support' CONFIG_ACORN_PARTITION_RISCIX + fi else - if [ "$ARCH" = "alpha" ]; then - define_bool CONFIG_OSF_PARTITION y - fi - if [ "$ARCH" = "ppc" -o "$CONFIG_MAC" = "y" ]; then - define_bool CONFIG_MAC_PARTITION y - fi - if [ "$CONFIG_AMIGA" != "y" -a "$CONFIG_ATARI" != "y" -a \ - "$CONFIG_MAC" != "y" ]; then - define_bool CONFIG_MSDOS_PARTITION y - fi + if [ "$ARCH" = "alpha" ]; then + define_bool CONFIG_OSF_PARTITION y + fi + if [ "$ARCH" = "ppc" -o "$CONFIG_MAC" = "y" ]; then + define_bool CONFIG_MAC_PARTITION y + fi + if [ "$CONFIG_X86" = "y" ]; then + define_bool CONFIG_MSDOS_PARTITION y + fi + if [ "$CONFIG_SGI" = "y" ]; then + define_bool CONFIG_SGI_PARTITION y + fi + if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then + define_bool CONFIG_SUN_PARTITION y + fi + if [ "$CONFIG_AMIGA" = "y" ]; then + define_bool CONFIG_AMIGA_PARTITION y + fi + if [ "$CONFIG_ARCH_ACORN" = "y" ]; then + define_bool CONFIG_ACORN_PARTITION y + define_bool CONFIG_ACORN_PARTITION_ADFS y +# define_bool CONFIG_ACORN_PARTITION_CUMANA y + define_bool CONFIG_ACORN_PARTITION_ICS y + define_bool CONFIG_ACORN_PARTITION_POWERTEC y + define_bool CONFIG_ACORN_PARTITION_RISCIX y + fi + if [ "$CONFIG_ATARI" = "y" ]; then + define_bool CONFIG_ATARI_PARTITION y + fi fi if [ "$CONFIG_MSDOS_PARTITION" = "y" ]; then - bool ' BSD disklabel (FreeBSD partition tables) support' CONFIG_BSD_DISKLABEL - bool ' Solaris (x86) partition table support' CONFIG_SOLARIS_X86_PARTITION - bool ' Unixware slices support' CONFIG_UNIXWARE_DISKLABEL -fi -if [ "$CONFIG_SGI" != "y" ]; then - bool 'SGI partition support' CONFIG_SGI_PARTITION -else - define_bool CONFIG_SGI_PARTITION y -fi -if [ "$ARCH" != "sparc" -a "$ARCH" != "sparc64" ]; then - bool 'Sun partition tables support' CONFIG_SUN_PARTITION -else - define_bool CONFIG_SUN_PARTITION y -fi -if [ "$CONFIG_PARTITION_ADVANCED" = "y" ]; then - bool 'Amiga partition table support' CONFIG_AMIGA_PARTITION - bool 'Atari partition table support' CONFIG_ATARI_PARTITION - bool 'Acorn partition support' CONFIG_ACORN_PARTITION - if [ "$CONFIG_ACORN_PARTITION" != "n" ]; then - bool ' Native filecore partition support' CONFIG_ACORN_PARTITION_ADFS -# bool ' Cumana partition support' CONFIG_ACORN_PARTITION_CUMANA - bool ' ICS partition support' CONFIG_ACORN_PARTITION_ICS - bool ' PowerTec partition support' CONFIG_ACORN_PARTITION_POWERTEC - bool ' RISCiX partition support' CONFIG_ACORN_PARTITION_RISCIX - fi -else - if [ "$CONFIG_AMIGA" = "y" ]; then - define_bool CONFIG_AMIGA_PARTITION y - fi - if [ "$CONFIG_ARCH_ACORN" = "y" ]; then - define_bool CONFIG_ACORN_PARTITION y - define_bool CONFIG_ACORN_PARTITION_ADFS y -# define_bool CONFIG_ACORN_PARTITION_CUMANA y - define_bool CONFIG_ACORN_PARTITION_ICS y - define_bool CONFIG_ACORN_PARTITION_POWERTEC y - define_bool CONFIG_ACORN_PARTITION_RISCIX y - fi -fi -if [ "$CONFIG_ATARI" = "y" ]; then - define_bool CONFIG_ATARI_PARTITION y + bool 'BSD disklabel (FreeBSD partition tables) support' CONFIG_BSD_DISKLABEL + bool 'Solaris (x86) partition table support' CONFIG_SOLARIS_X86_PARTITION + bool 'Unixware slices support' CONFIG_UNIXWARE_DISKLABEL fi diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/fs/proc/array.c linux.ac/fs/proc/array.c --- linux.vanilla/fs/proc/array.c Thu Sep 2 00:48:39 1999 +++ linux.ac/fs/proc/array.c Mon Sep 20 20:42:43 1999 @@ -38,7 +38,6 @@ * * aeb@cwi.nl : /proc/partitions * - * * Alan Cox : security fixes. * * @@ -46,6 +45,9 @@ * * Gerhard Wichert : added BIGMEM support * Siemens AG + * + * Chuck Lever : safe handling of task_struct + * */ #include @@ -67,6 +69,7 @@ #include #include #include +#include #include #include @@ -469,7 +472,7 @@ return result; } } while (addr & ~PAGE_MASK); - kunmap(addr, KM_READ); + kunmap(addr-1, KM_READ); } return result; } @@ -489,7 +492,6 @@ return mm; } - static int get_env(int pid, char * buffer) { struct mm_struct *mm = get_mm(pid); @@ -842,6 +844,9 @@ return buffer; } +/* + * These next two assume that the task's sigmask_lock is held by the caller. + */ static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign, sigset_t *catch) { @@ -894,53 +899,104 @@ cap_t(p->cap_effective)); } - +/* + * This is somewhat safer than it was before. However... + * + * Embedded pointers in the task structure may reference data that + * can be changed or that is no longer valid after the tasklist + * lock is released, or that isn't even protected by the tasklist + * lock. Eg. tsk->tty, tsk->sig, and tsk->p_pptr can change after + * we make our own copy of the task structure. This doesn't matter + * unless we are trying to use the pointed-to data as an address. + * So there are still a few safety issues to be addressed here. + */ static int get_status(int pid, char * buffer) { char * orig = buffer; struct task_struct *tsk; struct mm_struct *mm = NULL; + /* + * We lock the whole kernel here because p->files is still + * protected by the global kernel lock. + */ + lock_kernel(); + read_lock(&tasklist_lock); tsk = find_task_by_pid(pid); - if (tsk) + if (tsk) { mm = tsk->mm; - if (mm) - atomic_inc(&mm->mm_users); - read_unlock(&tasklist_lock); /* FIXME!! This should be done after the last use */ - if (!tsk) - return 0; - buffer = task_name(tsk, buffer); - buffer = task_state(tsk, buffer); - if (mm) + if (mm) + atomic_inc(&mm->mm_users); + + buffer = task_name(tsk, buffer); + buffer = task_state(tsk, buffer); + + spin_lock_irq(&tsk->sigmask_lock); + buffer = task_sig(tsk, buffer); + spin_unlock_irq(&tsk->sigmask_lock); + + buffer = task_cap(tsk, buffer); + } + read_unlock(&tasklist_lock); + + unlock_kernel(); + + /* + * We can't hold the tasklist_lock and jiggle the mmap_sem -- + * that can result in a deadlock. + */ + if (mm) { buffer = task_mem(mm, buffer); - buffer = task_sig(tsk, buffer); - buffer = task_cap(tsk, buffer); - if (mm) mmput(mm); + } + + /* + * (buffer - orig) will be zero on an error exit. + */ return buffer - orig; } static int get_stat(int pid, char * buffer) { - struct task_struct *tsk; + struct task_struct *tsk, *p; struct mm_struct *mm = NULL; unsigned long vsize, eip, esp, wchan; long priority, nice; - int tty_pgrp; + pid_t ppid = 0; sigset_t sigign, sigcatch; char state; - int res; + int res = 0; - read_lock(&tasklist_lock); - tsk = find_task_by_pid(pid); - if (tsk) - mm = tsk->mm; - if (mm) - atomic_inc(&mm->mm_users); - read_unlock(&tasklist_lock); /* FIXME!! This should be done after the last use */ + tsk = kmalloc(sizeof(struct task_struct), GFP_KERNEL); if (!tsk) - return 0; + goto out; + + /* + * Hold the tasklist_lock and extract address information + * we may need after the lock is released. We can't hold + * the tasklist_lock and jiggle the mmap_sem -- that can + * result in a deadlock. + */ + read_lock(&tasklist_lock); + p = find_task_by_pid(pid); + if (p) { + memcpy(tsk, p, sizeof(struct task_struct)); + + mm = p->mm; + if (mm) + atomic_inc(&mm->mm_users); + + ppid = p->p_pptr->pid; + + spin_lock_irq(&p->sigmask_lock); + collect_sigign_sigcatch(p, &sigign, &sigcatch); + spin_unlock_irq(&p->sigmask_lock); + } + read_unlock(&tasklist_lock); + if (!p) + goto free_out; + state = *get_task_state(tsk); vsize = eip = esp = 0; if (mm) { @@ -951,19 +1007,12 @@ vsize += vma->vm_end - vma->vm_start; vma = vma->vm_next; } - eip = KSTK_EIP(tsk); - esp = KSTK_ESP(tsk); + eip = KSTK_EIP(p); + esp = KSTK_ESP(p); up(&mm->mmap_sem); } - wchan = get_wchan(tsk); - - collect_sigign_sigcatch(tsk, &sigign, &sigcatch); - - if (tsk->tty) - tty_pgrp = tsk->tty->pgrp; - else - tty_pgrp = -1; + wchan = get_wchan(p); /* scale priority and nice values from timeslices to -20..20 */ /* to make it look like a "normal" Unix priority/nice value */ @@ -978,11 +1027,11 @@ pid, tsk->comm, state, - tsk->p_pptr->pid, + ppid, tsk->pgrp, tsk->session, tsk->tty ? kdev_t_to_nr(tsk->tty->device) : 0, - tty_pgrp, + tsk->tty ? tsk->tty->pgrp : -1, tsk->flags, tsk->min_flt, tsk->cmin_flt, @@ -1018,6 +1067,10 @@ tsk->cnswap, tsk->exit_signal, tsk->processor); + +free_out: + kfree(tsk); +out: if (mm) mmput(mm); return res; @@ -1168,11 +1221,12 @@ size_t count, loff_t *ppos) { struct task_struct *p; + struct mm_struct *mm = NULL; struct vm_area_struct * map, * next; char * destptr = buf, * buffer; loff_t lineno; ssize_t column, i; - int volatile_task; + int volatile_task = 0; long retval; /* @@ -1186,22 +1240,30 @@ retval = -EINVAL; read_lock(&tasklist_lock); p = find_task_by_pid(pid); - read_unlock(&tasklist_lock); /* FIXME!! This should be done after the last use */ + if (p) { + mm = p->mm; + if (mm) { + atomic_inc(&mm->mm_users); + + /* Check whether the mmaps could change if we sleep */ + volatile_task = (p != current || + atomic_read(&mm->mm_users) > 2); + } + } + read_unlock(&tasklist_lock); if (!p) goto freepage_out; - if (!p->mm || count == 0) + /* nothing to map */ + if (!mm || count == 0) goto getlen_out; - /* Check whether the mmaps could change if we sleep */ - volatile_task = (p != current || atomic_read(&p->mm->mm_users) > 1); - /* decode f_pos */ lineno = *ppos >> MAPS_LINE_SHIFT; column = *ppos & (MAPS_LINE_LENGTH-1); - /* quickly go to line lineno */ - for (map = p->mm->mmap, i = 0; map && (i < lineno); map = map->vm_next, i++) + /* quickly go to line "lineno" */ + for (map = mm->mmap, i = 0; map && (i < lineno); map = map->vm_next, i++) continue; for ( ; map ; map = next ) { @@ -1283,6 +1345,7 @@ /* encode f_pos */ *ppos = (lineno << MAPS_LINE_SHIFT) + column; + mmput(mm); getlen_out: retval = destptr - buf; @@ -1295,28 +1358,28 @@ #ifdef __SMP__ static int get_pidcpu(int pid, char * buffer) { - struct task_struct * tsk = current ; - int i, len; + struct task_struct * tsk; + int i, len = 0; + /* + * Hold the tasklist_lock to guarantee that the task_struct + * address will remain valid while we examine its contents. + */ read_lock(&tasklist_lock); - if (pid != tsk->pid) - tsk = find_task_by_pid(pid); - read_unlock(&tasklist_lock); /* FIXME!! This should be done after the last use */ - - if (tsk == NULL) - return 0; - - len = sprintf(buffer, - "cpu %lu %lu\n", - tsk->times.tms_utime, - tsk->times.tms_stime); + tsk = find_task_by_pid(pid); + if (tsk) { + len = sprintf(buffer, + "cpu %lu %lu\n", + tsk->times.tms_utime, + tsk->times.tms_stime); - for (i = 0 ; i < smp_num_cpus; i++) - len += sprintf(buffer + len, "cpu%d %lu %lu\n", - i, - tsk->per_cpu_utime[cpu_logical_map(i)], - tsk->per_cpu_stime[cpu_logical_map(i)]); - + for (i = 0 ; i < smp_num_cpus; i++) + len += sprintf(buffer + len, "cpu%d %lu %lu\n", + i, + tsk->per_cpu_utime[cpu_logical_map(i)], + tsk->per_cpu_stime[cpu_logical_map(i)]); + } + read_unlock(&tasklist_lock); return len; } #endif @@ -1453,12 +1516,6 @@ int ok = 0; read_lock(&tasklist_lock); - - /* - * Grab the lock, find the task, save the uid and - * check it has an mm still (ie its not dead) - */ - p = find_task_by_pid(pid); if (p) { euid=p->euid; @@ -1466,9 +1523,7 @@ if(!cap_issubset(p->cap_permitted, current->cap_permitted)) ok=0; } - read_unlock(&tasklist_lock); - if (!p) return 1; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/fs/proc/fd.c linux.ac/fs/proc/fd.c --- linux.vanilla/fs/proc/fd.c Thu Aug 5 20:21:50 1999 +++ linux.ac/fs/proc/fd.c Tue Sep 14 21:27:25 1999 @@ -90,6 +90,7 @@ fd = 0; len = dentry->d_name.len; name = dentry->d_name.name; + if (len > 1 && *name == '0') goto out; while (len-- > 0) { c = *name - '0'; name++; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/fs/proc/root.c linux.ac/fs/proc/root.c --- linux.vanilla/fs/proc/root.c Sat Sep 11 00:54:15 1999 +++ linux.ac/fs/proc/root.c Tue Sep 14 21:27:25 1999 @@ -676,6 +676,13 @@ 0, &proc_array_inode_operations }; #endif +#ifdef CONFIG_SGI_DS1286 +static struct proc_dir_entry proc_root_ds1286 = { + PROC_RTC, 3, "rtc", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_array_inode_operations +}; +#endif static struct proc_dir_entry proc_root_locks = { PROC_LOCKS, 5, "locks", S_IFREG | S_IRUGO, 1, 0, 0, @@ -758,6 +765,9 @@ #ifdef CONFIG_RTC proc_register(&proc_root, &proc_root_rtc); #endif +#ifdef CONFIG_SGI_DS1286 + proc_register(&proc_root, &proc_root_ds1286); +#endif proc_register(&proc_root, &proc_root_locks); proc_register(&proc_root, &proc_root_mounts); @@ -898,6 +908,7 @@ } pid *= 10; pid += c; + if (!pid) break; if (pid & 0xffff0000) { pid = 0; break; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/fs/qnx4/inode.c linux.ac/fs/qnx4/inode.c --- linux.vanilla/fs/qnx4/inode.c Thu Sep 2 00:48:40 1999 +++ linux.ac/fs/qnx4/inode.c Tue Sep 14 22:54:51 1999 @@ -27,7 +27,6 @@ #define QNX4_VERSION 4 #define QNX4_BMNAME ".bitmap" -#define CHECK_BOOT_SIGNATURE 0 static struct super_operations qnx4_sops; @@ -257,9 +256,6 @@ int i, j; int found = 0; - if (s == NULL) { - return "no qnx4 filesystem (null superblock)."; - } if (*(s->u.qnx4_sb.sb->RootDir.di_fname) != '/') { return "no qnx4 filesystem (no root dir)."; } else { @@ -282,6 +278,8 @@ } } } + /* WAIT! s->u.qnx4_sb.BitMap points into bh->b_data + and now we release bh?? */ brelse(bh); if (found != 0) { break; @@ -299,9 +297,8 @@ { struct buffer_head *bh; kdev_t dev = s->s_dev; -#if CHECK_BOOT_SIGNATURE + struct inode *root; char *tmpc; -#endif const char *errmsg; MOD_INC_USE_COUNT; @@ -311,7 +308,9 @@ s->s_blocksize_bits = 9; s->s_dev = dev; -#if CHECK_BOOT_SIGNATURE + /* Check the boot signature. Since the qnx4 code is + dangerous, we should leave as quickly as possible + if we don't belong here... */ bh = bread(dev, 0, QNX4_BLOCK_SIZE); if (!bh) { printk("qnx4: unable to read the boot sector\n"); @@ -320,11 +319,12 @@ tmpc = (char *) bh->b_data; if (tmpc[4] != 'Q' || tmpc[5] != 'N' || tmpc[6] != 'X' || tmpc[7] != '4' || tmpc[8] != 'F' || tmpc[9] != 'S') { - printk("qnx4: wrong fsid in boot sector.\n"); + if (!silent) + printk("qnx4: wrong fsid in boot sector.\n"); goto out; } brelse(bh); -#endif + bh = bread(dev, 1, QNX4_BLOCK_SIZE); if (!bh) { printk("qnx4: unable to read the superblock\n"); @@ -337,23 +337,35 @@ #endif s->u.qnx4_sb.sb_buf = bh; s->u.qnx4_sb.sb = (struct qnx4_super_block *) bh->b_data; - s->s_root = - d_alloc_root(iget(s, QNX4_ROOT_INO * QNX4_INODES_PER_BLOCK)); - if (s->s_root == NULL) { - printk("qnx4: get inode failed\n"); - goto out; - } + + + /* check before allocating dentries, inodes, .. */ errmsg = qnx4_checkroot(s); if (errmsg != NULL) { - printk("qnx4: %s\n", errmsg); + if (!silent) + printk("qnx4: %s\n", errmsg); goto out; } + + /* does root not have inode number QNX4_ROOT_INO ?? */ + root = iget(s, QNX4_ROOT_INO * QNX4_INODES_PER_BLOCK); + if (!root) { + printk("qnx4: get inode failed\n"); + goto out; + } + + s->s_root = d_alloc_root(root); + if (s->s_root == NULL) + goto outi; + brelse(bh); unlock_super(s); s->s_dirt = 1; return s; + outi: + iput(root); out: brelse(bh); outnobh: diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-alpha/keyboard.h linux.ac/include/asm-alpha/keyboard.h --- linux.vanilla/include/asm-alpha/keyboard.h Mon Apr 26 18:54:25 1999 +++ linux.ac/include/asm-alpha/keyboard.h Thu Sep 16 00:13:33 1999 @@ -37,6 +37,31 @@ #define SYSRQ_KEY 0x54 +/* resource allocation */ +#define kbd_request_region() +#define kbd_request_irq(handler) request_irq(KEYBOARD_IRQ, handler, 0, \ + "keyboard", NULL) + +/* How to access the keyboard macros on this platform. */ +#define kbd_read_input() inb(KBD_DATA_REG) +#define kbd_read_status() inb(KBD_STATUS_REG) +#define kbd_write_output(val) outb(val, KBD_DATA_REG) +#define kbd_write_command(val) outb(val, KBD_CNTL_REG) + +/* Some stoneage hardware needs delays after some operations. */ +#define kbd_pause() do { } while(0) + +/* + * Machine specific bits for the PS/2 driver + */ + +#define AUX_IRQ 12 + +#define aux_request_irq(hand, dev_id) \ + request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS/2 Mouse", dev_id) + +#define aux_free_irq(dev_id) free_irq(AUX_IRQ, dev_id) + #endif /* __KERNEL__ */ #endif /* __ASMalpha_KEYBOARD_H */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-alpha/pgtable.h linux.ac/include/asm-alpha/pgtable.h --- linux.vanilla/include/asm-alpha/pgtable.h Sat Sep 11 00:54:15 1999 +++ linux.ac/include/asm-alpha/pgtable.h Thu Sep 16 00:14:22 1999 @@ -622,6 +622,6 @@ #define kern_addr_valid(addr) (1) #define io_remap_page_range(start, busaddr, size, prot) \ - remap_page_range(start, virt_to_phys(ioremap(busaddr)), size, prot) + remap_page_range(start, virt_to_phys(__ioremap(busaddr)), size, prot) #endif /* _ALPHA_PGTABLE_H */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-alpha/processor.h linux.ac/include/asm-alpha/processor.h --- linux.vanilla/include/asm-alpha/processor.h Tue Aug 17 17:27:39 1999 +++ linux.ac/include/asm-alpha/processor.h Thu Sep 16 00:13:33 1999 @@ -114,6 +114,8 @@ /* Do necessary setup to start up a newly executed thread. */ extern void start_thread(struct pt_regs *, unsigned long, unsigned long); +struct task_struct; + /* Free all resources held by a thread. */ extern void release_thread(struct task_struct *); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-alpha/socket.h linux.ac/include/asm-alpha/socket.h --- linux.vanilla/include/asm-alpha/socket.h Mon Dec 22 01:41:24 1997 +++ linux.ac/include/asm-alpha/socket.h Thu Sep 16 00:13:33 1999 @@ -48,4 +48,18 @@ #define SO_SECURITY_ENCRYPTION_TRANSPORT 20 #define SO_SECURITY_ENCRYPTION_NETWORK 21 +#ifdef __KERNEL__ +/* Socket types. */ +#define SOCK_STREAM 1 /* stream (connection) socket */ +#define SOCK_DGRAM 2 /* datagram (conn.less) socket */ +#define SOCK_RAW 3 /* raw socket */ +#define SOCK_RDM 4 /* reliably-delivered message */ +#define SOCK_SEQPACKET 5 /* sequential packet socket */ +#define SOCK_PACKET 10 /* linux specific way of */ + /* getting packets at the dev */ + /* level. For writing rarp and */ + /* other similar things on the */ + /* user level. */ +#endif + #endif /* _ASM_SOCKET_H */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-alpha/termios.h linux.ac/include/asm-alpha/termios.h --- linux.vanilla/include/asm-alpha/termios.h Wed Mar 24 19:46:00 1999 +++ linux.ac/include/asm-alpha/termios.h Mon Sep 6 16:58:03 1999 @@ -77,7 +77,7 @@ #define N_MASC 8 /* Reserved for Mobitex module */ #define N_R3964 9 /* Reserved for Simatic R3964 module */ #define N_PROFIBUS_FDL 10 /* Reserved for Profibus */ -#define N_IRDA 11 /* Linux IrDa - http://www.cs.uit.no/~dagb/irda/irda.html */ +#define N_IRDA 11 /* Reserved for IrDA async (SIR) mode */ #define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ #define N_HDLC 13 /* synchronous HDLC */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-arm/termios.h linux.ac/include/asm-arm/termios.h --- linux.vanilla/include/asm-arm/termios.h Thu Sep 2 00:48:41 1999 +++ linux.ac/include/asm-arm/termios.h Mon Sep 6 16:58:03 1999 @@ -60,7 +60,7 @@ #define N_MASC 8 /* Reserved for Mobitex module */ #define N_R3964 9 /* Reserved for Simatic R3964 module */ #define N_PROFIBUS_FDL 10 /* Reserved for Profibus */ -#define N_IRDA 11 /* Linux IrDa - http://www.cs.uit.no/~dagb/irda/irda.html */ +#define N_IRDA 11 /* Reserved for IrDA async (SIR) mode */ #define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ #define N_HDLC 13 /* synchronous HDLC */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-i386/dma.h linux.ac/include/asm-i386/dma.h --- linux.vanilla/include/asm-i386/dma.h Sat Sep 11 00:54:15 1999 +++ linux.ac/include/asm-i386/dma.h Sat Sep 18 02:08:11 1999 @@ -290,6 +290,7 @@ /* From PCI */ #ifdef CONFIG_PCI +#define HAS_BRIDGE_BUGGY_FUNC extern int isa_dma_bridge_buggy; #else #define isa_dma_bridge_buggy (0) diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-i386/e820.h linux.ac/include/asm-i386/e820.h --- linux.vanilla/include/asm-i386/e820.h Thu Sep 2 00:48:41 1999 +++ linux.ac/include/asm-i386/e820.h Sat Sep 11 19:48:47 1999 @@ -16,6 +16,11 @@ #define E820MAX 32 /* number of entries in E820MAP */ #define E820NR 0x1e8 /* # entries in E820MAP */ +/* for e820map.map[].type */ +#define E820_RAM 1 +#define E820_RESERVED 2 +#define E820_ACPI 3 + #define HIGH_MEMORY (1024*1024) #ifndef __ASSEMBLY__ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-i386/elf.h linux.ac/include/asm-i386/elf.h --- linux.vanilla/include/asm-i386/elf.h Tue Jan 26 23:21:02 1999 +++ linux.ac/include/asm-i386/elf.h Sat Sep 11 01:48:33 1999 @@ -51,7 +51,9 @@ the loader. We need to make sure that it is out of the way of the program that it will "exec", and that there is sufficient room for the brk. */ -#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) +#define ELF_ET_DYN_BASE ((TASK_SIZE & 0x80000000) \ + ? TASK_SIZE / 3 * 2 \ + : 2 * TASK_SIZE / 3) /* Wow, the "main" arch needs arch dependent functions too.. :) */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-i386/keyboard.h linux.ac/include/asm-i386/keyboard.h --- linux.vanilla/include/asm-i386/keyboard.h Mon Apr 26 18:54:03 1999 +++ linux.ac/include/asm-i386/keyboard.h Thu Sep 16 16:58:53 1999 @@ -13,6 +13,10 @@ #ifdef __KERNEL__ +#include +#include +#include + #define KEYBOARD_IRQ 1 #define DISABLE_KBD_DURING_INTERRUPTS 0 @@ -35,6 +39,30 @@ #define SYSRQ_KEY 0x54 -#endif /* __KERNEL__ */ +/* resource allocation */ +#define kbd_request_region() +#define kbd_request_irq(handler) request_irq(KEYBOARD_IRQ, handler, 0, \ + "keyboard", NULL) + +/* How to access the keyboard macros on this platform. */ +#define kbd_read_input() inb(KBD_DATA_REG) +#define kbd_read_status() inb(KBD_STATUS_REG) +#define kbd_write_output(val) outb(val, KBD_DATA_REG) +#define kbd_write_command(val) outb(val, KBD_CNTL_REG) + +/* Some stoneage hardware needs delays after some operations. */ +#define kbd_pause() do { } while(0) + +/* + * Machine specific bits for the PS/2 driver + */ -#endif /* __ASMi386_KEYBOARD_H */ +#define AUX_IRQ 12 + +#define aux_request_irq(hand, dev_id) \ + request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS/2 Mouse", dev_id) + +#define aux_free_irq(dev_id) free_irq(AUX_IRQ, dev_id) + +#endif /* __KERNEL__ */ +#endif /* _I386_KEYBOARD_H */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-i386/mmx.h linux.ac/include/asm-i386/mmx.h --- linux.vanilla/include/asm-i386/mmx.h Thu Jan 1 01:00:00 1970 +++ linux.ac/include/asm-i386/mmx.h Thu Sep 2 16:56:44 1999 @@ -0,0 +1,14 @@ +#ifndef _ASM_MMX_H +#define _ASM_MMX_H + +/* + * MMX 3Dnow! helper operations + */ + +#include + +extern void *_mmx_memcpy(void *to, const void *from, size_t size); +extern void mmx_clear_page(long page); +extern void mmx_copy_page(long to, long from); + +#endif diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-i386/page.h linux.ac/include/asm-i386/page.h --- linux.vanilla/include/asm-i386/page.h Thu Sep 2 00:48:41 1999 +++ linux.ac/include/asm-i386/page.h Sat Sep 11 01:34:25 1999 @@ -11,8 +11,26 @@ #define STRICT_MM_TYPECHECKS +#include + +#ifdef CONFIG_X86_USE_3DNOW + +#include + +#define clear_page(page) mmx_clear_page(page) +#define copy_page(to,from) mmx_copy_page(to,from) + +#else + +/* + * On older X86 processors its not a win to use MMX here it seems. + * Maybe the K6-III ? + */ + #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) #define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE) + +#endif #ifdef STRICT_MM_TYPECHECKS /* diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-i386/pgtable.h linux.ac/include/asm-i386/pgtable.h --- linux.vanilla/include/asm-i386/pgtable.h Thu Aug 26 14:42:18 1999 +++ linux.ac/include/asm-i386/pgtable.h Thu Sep 16 16:16:11 1999 @@ -44,7 +44,7 @@ do { unsigned long tmpreg; __asm__ __volatile__("movl %%cr3,%0\n\tmovl %0,%%cr3":"=r" (tmpreg) : :"memory"); } while (0) #ifndef CONFIG_X86_INVLPG -#define __flush_tlb_one(addr) flush_tlb() +#define __flush_tlb_one(addr) __flush_tlb() #else #define __flush_tlb_one(addr) \ __asm__ __volatile__("invlpg %0": :"m" (*(char *) addr)) diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-i386/socket.h linux.ac/include/asm-i386/socket.h --- linux.vanilla/include/asm-i386/socket.h Mon Dec 22 01:41:24 1997 +++ linux.ac/include/asm-i386/socket.h Thu Sep 2 16:51:06 1999 @@ -39,4 +39,18 @@ #define SO_ATTACH_FILTER 26 #define SO_DETACH_FILTER 27 +#ifdef __KERNEL__ +/* Socket types. */ +#define SOCK_STREAM 1 /* stream (connection) socket */ +#define SOCK_DGRAM 2 /* datagram (conn.less) socket */ +#define SOCK_RAW 3 /* raw socket */ +#define SOCK_RDM 4 /* reliably-delivered message */ +#define SOCK_SEQPACKET 5 /* sequential packet socket */ +#define SOCK_PACKET 10 /* linux specific way of */ + /* getting packets at the dev */ + /* level. For writing rarp and */ + /* other similar things on the */ + /* user level. */ +#endif + #endif /* _ASM_SOCKET_H */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-i386/softirq.h linux.ac/include/asm-i386/softirq.h --- linux.vanilla/include/asm-i386/softirq.h Thu Sep 2 00:48:41 1999 +++ linux.ac/include/asm-i386/softirq.h Tue Sep 14 21:58:56 1999 @@ -3,6 +3,11 @@ #include #include +#include + +#ifndef NULL +#define NULL ((void *) 0) +#endif extern unsigned int local_bh_count[NR_CPUS]; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-i386/string-486.h linux.ac/include/asm-i386/string-486.h --- linux.vanilla/include/asm-i386/string-486.h Thu Feb 27 18:57:31 1997 +++ linux.ac/include/asm-i386/string-486.h Thu Sep 16 16:12:36 1999 @@ -14,6 +14,8 @@ * 1994/03/15 by Alberto Vignani/Davide Parodi @crf.it * * Split into 2 CPU specific files by Alan Cox to keep #ifdef noise down. + * + * 99/9/15 Proper reg args for newer gcc/egcs - Petkan (petkan@spct.net) */ #define __HAVE_ARCH_STRCPY @@ -180,6 +182,7 @@ #define __HAVE_ARCH_STRRCHR extern inline char * strrchr(const char * s, int c) { +int d0, d1; register char * __res; __asm__ __volatile__( "cld\n\t" @@ -190,17 +193,19 @@ "leal -1(%%esi),%0\n" "2:\ttestb %%al,%%al\n\t" "jne 1b" - :"=d" (__res):"0" (0),"S" (s),"a" (c):"ax","si"); + :"=d" (__res), "=&S" (d0), "=&a" (d1) + :"0" (0), "1" (s), "2" (c)); return __res; } #define __HAVE_ARCH_STRSPN extern inline size_t strspn(const char * cs, const char * ct) { +int d0, d1; register char * __res; __asm__ __volatile__( "cld\n\t" - "movl %4,%%edi\n\t" + "movl %6,%%edi\n\t" "repne\n\t" "scasb\n\t" "notl %%ecx\n\t" @@ -209,24 +214,26 @@ "1:\tlodsb\n\t" "testb %%al,%%al\n\t" "je 2f\n\t" - "movl %4,%%edi\n\t" + "movl %6,%%edi\n\t" "movl %%edx,%%ecx\n\t" "repne\n\t" "scasb\n\t" "je 1b\n" "2:\tdecl %0" - :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct) - :"ax","cx","dx","di"); + :"=S" (__res), "=&a" (d0), "=&c" (d1) + :"0" (cs), "1" (0), "2" (0xffffffff), "g" (ct) + :"dx", "di"); return __res-cs; } #define __HAVE_ARCH_STRCSPN extern inline size_t strcspn(const char * cs, const char * ct) { +int d0, d1; register char * __res; __asm__ __volatile__( "cld\n\t" - "movl %4,%%edi\n\t" + "movl %6,%%edi\n\t" "repne\n\t" "scasb\n\t" "notl %%ecx\n\t" @@ -235,20 +242,22 @@ "1:\tlodsb\n\t" "testb %%al,%%al\n\t" "je 2f\n\t" - "movl %4,%%edi\n\t" + "movl %6,%%edi\n\t" "movl %%edx,%%ecx\n\t" "repne\n\t" "scasb\n\t" "jne 1b\n" "2:\tdecl %0" - :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct) - :"ax","cx","dx","di"); + :"=S" (__res), "=&a" (d0), "=&c" (d1) + :"0" (cs), "1" (0), "2" (0xffffffff), "g" (ct) + :"dx", "di"); return __res-cs; } #define __HAVE_ARCH_STRPBRK extern inline char * strpbrk(const char * cs,const char * ct) { +int d0, d1; register char * __res; __asm__ __volatile__( "cld\n\t" @@ -270,14 +279,16 @@ "jmp 3f\n" "2:\txorl %0,%0\n" "3:" - :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct) - :"ax","cx","dx","di"); + :"=S" (__res), "=&a" (d0), "=&c" (d1) + :"0" (cs), "1" (0), "2" (0xffffffff), "g" (ct) + :"dx", "di"); return __res; } #define __HAVE_ARCH_STRSTR extern inline char * strstr(const char * cs,const char * ct) { +int d0, d1; register char * __res; __asm__ __volatile__( "cld\n\t" \ @@ -299,8 +310,9 @@ "jne 1b\n\t" "xorl %%eax,%%eax\n\t" "2:" - :"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct) - :"cx","dx","di","si"); + :"=a" (__res), "=&c" (d0), "=&S" (d1) + :"0" (0), "1" (0xffffffff), "2" (cs), "g" (ct) + :"dx", "di"); return __res; } @@ -328,6 +340,7 @@ #define __HAVE_ARCH_STRNLEN extern inline size_t strnlen(const char * s, size_t count) { +int d0; register int __res; __asm__ __volatile__( "movl %1,%0\n\t" @@ -339,9 +352,8 @@ "cmpl $-1,%2\n\t" "jne 1b\n" "3:\tsubl %1,%0" - :"=a" (__res) - :"c" (s),"d" (count) - :"dx"); + :"=a" (__res), "=&d" (d0) + :"1" (count), "c" (s)); return __res; } /* end of additional stuff */ @@ -464,6 +476,7 @@ extern inline void * __memcpy_g(void * to, const void * from, size_t n) { +int d0, d1, d2; register void *tmp = (void *)to; __asm__ __volatile__ ( "cld\n\t" @@ -475,9 +488,9 @@ "movsw\n" "2:\trep\n\t" "movsl" - : /* no output */ - :"c" (n),"D" ((long) tmp),"S" ((long) from) - :"cx","di","si","memory"); + :"=&c" (d0), "=&D" (d1), "=&S" (d2) + :"0" (n), "1" ((long) tmp), "2" ((long) from) + :"memory"); return (to); } @@ -485,29 +498,31 @@ #define __HAVE_ARCH_MEMMOVE extern inline void * memmove(void * dest,const void * src, size_t n) { +int d0, d1, d2; register void *tmp = (void *)dest; if (dest + +#ifdef CONFIG_X86_USE_3DNOW + +#include +#include +#include +#include +#include +#include +#include + +/* + * This CPU favours 3DNow strongly (eg AMD Athlon) + */ + +extern inline void * __constant_memcpy3d(void * to, const void * from, size_t len) +{ + if(len<512 || in_interrupt()) + return __constant_memcpy(to, from, len); + return _mmx_memcpy(to, from, len); +} + +extern __inline__ void *__memcpy3d(void *to, const void *from, size_t len) +{ + if(len<512 || in_interrupt()) + return __memcpy(to, from, len); + return _mmx_memcpy(to, from, len); +} + +#define memcpy(t, f, n) \ +(__builtin_constant_p(n) ? \ + __constant_memcpy3d((t),(f),(n)) : \ + __memcpy3d((t),(f),(n))) + +#else + +/* + * No 3D Now! + */ + #define memcpy(t, f, n) \ (__builtin_constant_p(n) ? \ __constant_memcpy((t),(f),(n)) : \ __memcpy((t),(f),(n))) + +#endif #define __HAVE_ARCH_MEMMOVE extern inline void * memmove(void * dest,const void * src, size_t n) diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-i386/termios.h linux.ac/include/asm-i386/termios.h --- linux.vanilla/include/asm-i386/termios.h Wed Mar 24 19:45:59 1999 +++ linux.ac/include/asm-i386/termios.h Mon Sep 6 16:58:03 1999 @@ -50,7 +50,7 @@ #define N_MASC 8 /* Reserved for Mobitex module */ #define N_R3964 9 /* Reserved for Simatic R3964 module */ #define N_PROFIBUS_FDL 10 /* Reserved for Profibus */ -#define N_IRDA 11 /* Linux IR - http://www.cs.uit.no/~dagb/irda/irda.html */ +#define N_IRDA 11 /* Reserved for IrDA async (SIR) mode */ #define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ #define N_HDLC 13 /* synchronous HDLC */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-i386/uaccess.h linux.ac/include/asm-i386/uaccess.h --- linux.vanilla/include/asm-i386/uaccess.h Thu Sep 2 00:48:41 1999 +++ linux.ac/include/asm-i386/uaccess.h Thu Sep 16 16:56:50 1999 @@ -597,7 +597,8 @@ long strncpy_from_user(char *dst, const char *src, long count); long __strncpy_from_user(char *dst, const char *src, long count); -long strlen_user(const char *str); +#define strlen_user(str) strnlen_user(str, ~0UL >> 1) +long strnlen_user(const char *str, long n); unsigned long clear_user(void *mem, unsigned long len); unsigned long __clear_user(void *mem, unsigned long len); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-i386/unistd.h linux.ac/include/asm-i386/unistd.h --- linux.vanilla/include/asm-i386/unistd.h Tue Aug 17 17:27:39 1999 +++ linux.ac/include/asm-i386/unistd.h Mon Sep 13 00:03:39 1999 @@ -196,7 +196,7 @@ #define __NR_putpmsg 189 /* some people actually want streams */ #define __NR_vfork 190 -/* user-visible error numbers are in the range -1 - -122: see */ +/* user-visible error numbers are in the range -1 - -124: see */ #define __syscall_return(type, res) \ do { \ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-m68k/socket.h linux.ac/include/asm-m68k/socket.h --- linux.vanilla/include/asm-m68k/socket.h Fri Feb 13 00:30:13 1998 +++ linux.ac/include/asm-m68k/socket.h Thu Sep 2 16:51:07 1999 @@ -39,4 +39,16 @@ #define SO_ATTACH_FILTER 26 #define SO_DETACH_FILTER 27 +/* Socket types. */ +#define SOCK_STREAM 1 /* stream (connection) socket */ +#define SOCK_DGRAM 2 /* datagram (conn.less) socket */ +#define SOCK_RAW 3 /* raw socket */ +#define SOCK_RDM 4 /* reliably-delivered message */ +#define SOCK_SEQPACKET 5 /* sequential packet socket */ +#define SOCK_PACKET 10 /* linux specific way of */ + /* getting packets at the dev */ + /* level. For writing rarp and */ + /* other similar things on the */ + /* user level. */ + #endif /* _ASM_SOCKET_H */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-m68k/termios.h linux.ac/include/asm-m68k/termios.h --- linux.vanilla/include/asm-m68k/termios.h Wed Mar 24 19:46:00 1999 +++ linux.ac/include/asm-m68k/termios.h Mon Sep 6 16:58:03 1999 @@ -58,7 +58,7 @@ #define N_MASC 8 /* Reserved for Mobitex module */ #define N_R3964 9 /* Reserved for Simatic R3964 module */ #define N_PROFIBUS_FDL 10 /* Reserved for Profibus */ -#define N_IRDA 11 /* Linux IrDa - http://www.cs.uit.no/~dagb/irda/irda.html */ +#define N_IRDA 11 /* Reserved for IrDA async (SIR) mode */ #define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ #define N_HDLC 13 /* synchronous HDLC */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-mips/floppy.h linux.ac/include/asm-mips/floppy.h --- linux.vanilla/include/asm-mips/floppy.h Mon Oct 26 17:57:56 1998 +++ linux.ac/include/asm-mips/floppy.h Thu Sep 2 16:51:06 1999 @@ -1,4 +1,4 @@ -/* $Id: floppy.h,v 1.4 1998/05/07 18:38:41 ralf Exp $ +/* $Id: floppy.h,v 1.6.2.1 1999/06/23 22:28:38 ralf Exp $ * * Architecture specific parts of the Floppy driver * @@ -42,30 +42,30 @@ extern struct fd_ops *fd_ops; -#define fd_inb(port) fd_ops->fd_inb(port) -#define fd_outb(value,port) fd_ops->fd_outb(value,port) +#define fd_inb(port) fd_ops->fd_inb(port) +#define fd_outb(value,port) fd_ops->fd_outb(value,port) -#define fd_enable_dma(channel) fd_ops->fd_enable_dma(channel) -#define fd_disable_dma(channel) fd_ops->fd_disable_dma(channel) -#define fd_request_dma(channel) fd_ops->fd_request_dma(channel) -#define fd_free_dma(channel) fd_ops->fd_free_dma(channel) -#define fd_clear_dma_ff(channel) fd_ops->fd_clear_dma_ff(channel) -#define fd_set_dma_mode(channel, mode) fd_ops->fd_set_dma_mode(channel, mode) -#define fd_set_dma_addr(channel, addr) fd_ops->fd_set_dma_addr(channel, \ - virt_to_bus(addr)) -#define fd_set_dma_count(channel,count) fd_ops->fd_set_dma_count(channel,count) -#define fd_get_dma_residue(channel) fd_ops->fd_get_dma_residue(channel) - -#define fd_enable_irq(irq) fd_ops->fd_enable_irq(irq) -#define fd_disable_irq(irq) fd_ops->fd_disable_irq(irq) -#define fd_request_irq(irq) request_irq(irq, floppy_interrupt, \ - SA_INTERRUPT \ - | SA_SAMPLE_RANDOM, \ - "floppy", NULL) -#define fd_free_irq(irq) free_irq(irq, NULL); -#define fd_dma_mem_alloc(size) fd_ops->fd_dma_mem_alloc(size) +#define fd_enable_dma() fd_ops->fd_enable_dma(FLOPPY_DMA) +#define fd_disable_dma() fd_ops->fd_disable_dma(FLOPPY_DMA) +#define fd_request_dma() fd_ops->fd_request_dma(FLOPPY_DMA) +#define fd_free_dma() fd_ops->fd_free_dma(FLOPPY_DMA) +#define fd_clear_dma_ff() fd_ops->fd_clear_dma_ff(FLOPPY_DMA) +#define fd_set_dma_mode(mode) fd_ops->fd_set_dma_mode(FLOPPY_DMA, mode) +#define fd_set_dma_addr(addr) fd_ops->fd_set_dma_addr(FLOPPY_DMA, \ + virt_to_bus(addr)) +#define fd_set_dma_count(count) fd_ops->fd_set_dma_count(FLOPPY_DMA,count) +#define fd_get_dma_residue() fd_ops->fd_get_dma_residue(FLOPPY_DMA) + +#define fd_enable_irq() fd_ops->fd_enable_irq(FLOPPY_IRQ) +#define fd_disable_irq() fd_ops->fd_disable_irq(FLOPPY_IRQ) +#define fd_request_irq() request_irq(FLOPPY_IRQ, floppy_interrupt, \ + SA_INTERRUPT | SA_SAMPLE_RANDOM, \ + "floppy", NULL) +#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL); +#define fd_dma_mem_alloc(size) fd_ops->fd_dma_mem_alloc(size) #define fd_dma_mem_free(mem,size) fd_ops->fd_dma_mem_free(mem,size) -#define fd_drive_type(n) fd_ops->fd_drive_type(n) +#define fd_drive_type(n) fd_ops->fd_drive_type(n) +#define fd_cacheflush(addr,size) dma_cache_wback_inv(addr,size) #define MAX_BUFFER_SECTORS 24 diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-mips/semaphore.h linux.ac/include/asm-mips/semaphore.h --- linux.vanilla/include/asm-mips/semaphore.h Sat Sep 11 00:54:16 1999 +++ linux.ac/include/asm-mips/semaphore.h Fri Sep 10 17:55:35 1999 @@ -102,6 +102,94 @@ { long ret, tmp, tmp2, sub; +#ifdef __MIPSEB__ + __asm__ __volatile__(" + .set mips3 + 0: lld %1, %4 + dli %3, 0x0000000100000000 + sltu %0, %1, $0 + + bltz %1, 1f + move %3, $0 + 1: + + sltu %2, %1, $0 + and %0, %0, %2 + bnez %0, 2f + + subu %0, %3 + scd %1, %4 + + beqz %1, 0b + 2: + + .set mips0" + : "=&r"(ret), "=&r"(tmp), "=&r"(tmp2), "=&r"(sub) + : "m"(*sem) + : "memory"); +#endif + +#ifdef __MIPSEL__ +#error "FIXME: down_trylock doesn't support little endian machines yet." +#endif + + return ret; +} + +/* + * down_trylock returns 0 on success, 1 if we failed to get the lock. + * + * We must manipulate count and waking simultaneously and atomically. + * Do this by using ll/sc on the pair of 32-bit words. + */ +extern inline int down_trylock(struct semaphore * sem) +{ + long ret, tmp, tmp2, sub; + +#ifdef __MIPSEB__ + __asm__ __volatile__(" + .set mips3 + 0: lld %1, %4 + dli %3, 0x0000000100000000 + sltu %0, %1, $0 + + bltz %1, 1f + move %3, $0 + 1: + + sltu %2, %1, $0 + and %0, %0, %2 + bnez %0, 2f + + subu %0, %3 + scd %1, %4 + + beqz %1, 0b + 2: + + .set mips0" + : "=&r"(ret), "=&r"(tmp), "=&r"(tmp2), "=&r"(sub) + : "m"(*sem) + : "memory"); +#endif + +#ifdef __MIPSEL__ +#error "FIXME: down_trylock doesn't support little endian machines yet." +#endif + + return ret; +} + +/* + * down_trylock returns 0 on success, 1 if we failed to get the lock. + * + * We must manipulate count and waking simultaneously and atomically. + * Do this by using ll/sc on the pair of 32-bit words. + */ +extern inline int down_trylock(struct semaphore * sem) +{ + long ret, tmp, tmp2, sub; + #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-mips/socket.h linux.ac/include/asm-mips/socket.h --- linux.vanilla/include/asm-mips/socket.h Tue Oct 20 21:52:54 1998 +++ linux.ac/include/asm-mips/socket.h Thu Sep 2 16:51:06 1999 @@ -1,5 +1,5 @@ /* - * $Id: socket.h,v 1.5 1998/03/15 09:52:54 ralf Exp $ + * $Id: socket.h,v 1.5 1998/03/17 22:16:17 ralf Exp $ */ #ifndef __ASM_MIPS_SOCKET_H #define __ASM_MIPS_SOCKET_H @@ -13,6 +13,7 @@ */ #define SOL_SOCKET 0xffff + #define SO_DEBUG 0x0001 /* Record debugging information. */ #define SO_REUSEADDR 0x0004 /* Allow reuse of local addresses. */ #define SO_KEEPALIVE 0x0008 /* Keep connections alive and send @@ -56,17 +57,20 @@ #define SO_ATTACH_FILTER 26 #define SO_DETACH_FILTER 27 -/* Types of sockets. */ -#define SOCK_DGRAM 1 /* Connectionless, unreliable datagrams - of fixed maximum length. */ -#define SOCK_STREAM 2 /* Sequenced, reliable, connection-based - byte streams. */ -#define SOCK_RAW 3 /* Raw protocol interface. */ -#define SOCK_RDM 4 /* Reliably-delivered messages. */ -#define SOCK_SEQPACKET 5 /* Sequenced, reliable, connection-based, - datagrams of fixed maximum length. */ -#define SOCK_PACKET 10 /* Linux specific way of getting packets at - the dev level. For writing rarp and - other similar things on the user level. */ +/* Socket types. */ + +#ifdef __KERNEL__ +#define SOCK_DGRAM 1 /* datagram (conn.less) socket */ +#define SOCK_STREAM 2 /* stream (connection) socket */ +#define SOCK_RAW 3 /* raw socket */ +#define SOCK_RDM 4 /* reliably-delivered message */ +#define SOCK_SEQPACKET 5 /* sequential packet socket */ +#define SOCK_PACKET 10 /* linux specific way of */ + /* getting packets at the dev */ + /* level. For writing rarp and */ + /* other similar things on the */ + /* user level. */ + +#endif #endif /* __ASM_MIPS_SOCKET_H */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-mips/termios.h linux.ac/include/asm-mips/termios.h --- linux.vanilla/include/asm-mips/termios.h Wed Mar 24 19:45:59 1999 +++ linux.ac/include/asm-mips/termios.h Mon Sep 6 16:58:03 1999 @@ -96,7 +96,7 @@ #define N_MASC 8 /* Reserved fo Mobitex module */ #define N_R3964 9 /* Reserved for Simatic R3964 module */ #define N_PROFIBUS_FDL 10 /* Reserved for Profibus */ -#define N_IRDA 11 /* Linux IrDa - http://www.cs.uit.no/~dagb/irda/irda.html */ +#define N_IRDA 11 /* Reserved for IrDA async (SIR) mode */ #define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ #define N_HDLC 13 /* synchronous HDLC */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/adb.h linux.ac/include/asm-ppc/adb.h --- linux.vanilla/include/asm-ppc/adb.h Thu Apr 29 20:39:01 1999 +++ linux.ac/include/asm-ppc/adb.h Thu Jan 1 01:00:00 1970 @@ -1,100 +0,0 @@ -/* - * Definitions for ADB (Apple Desktop Bus) support. - */ -#ifndef __PPC_ADB_H -#define __PPC_ADB_H - -/* ADB commands */ -#define ADB_BUSRESET 0 -#define ADB_FLUSH(id) (1 + ((id) << 4)) -#define ADB_WRITEREG(id, reg) (8 + (reg) + ((id) << 4)) -#define ADB_READREG(id, reg) (0xc + (reg) + ((id) << 4)) - -/* ADB default device IDs (upper 4 bits of ADB command byte) */ -#define ADB_DONGLE 1 /* "software execution control" devices */ -#define ADB_KEYBOARD 2 -#define ADB_MOUSE 3 -#define ADB_TABLET 4 -#define ADB_MODEM 5 -#define ADB_MISC 7 /* maybe a monitor */ - -#define ADB_RET_OK 0 -#define ADB_RET_TIMEOUT 3 - -/* The kind of ADB request. The controller may emulate some - of all of those CUDA/PMU packet kinds */ -#define ADB_PACKET 0 -#define CUDA_PACKET 1 -#define ERROR_PACKET 2 -#define TIMER_PACKET 3 -#define POWER_PACKET 4 -#define MACIIC_PACKET 5 -#define PMU_PACKET 6 - -#ifdef __KERNEL__ - -struct adb_request { - unsigned char data[32]; - int nbytes; - unsigned char reply[32]; - int reply_len; - unsigned char reply_expected; - unsigned char sent; - unsigned char complete; - void (*done)(struct adb_request *); - void *arg; - struct adb_request *next; -}; - -struct adb_ids { - int nids; - unsigned char id[16]; -}; - -/* Messages sent thru the client_list notifier. You should NOT stop - the operation, at least not with this version */ -enum adb_message { - ADB_MSG_POWERDOWN, /* Currently called before sleep only */ - ADB_MSG_PRE_RESET, /* Called before resetting the bus */ - ADB_MSG_POST_RESET /* Called after resetting the bus (re-do init & register) */ -}; -extern struct notifier_block *adb_client_list; - -/* Kind of ADB controller */ -enum adb_hw { - ADB_NONE, ADB_VIACUDA, ADB_VIAPMU, ADB_MACIO, ADB_UNKNOWN -}; - -/* Definition of a controller */ -extern struct adb_controller { - enum adb_hw kind; - - int (*send_request)(struct adb_request *req, int sync); - int (*autopoll)(int devs); - int (*reset_bus)(void); - void (*poll)(void); -} *adb_controller; -extern enum adb_hw adb_hardware; - -/* Values for adb_request flags */ -#define ADBREQ_REPLY 1 /* expect reply */ -#define ADBREQ_SYNC 2 /* poll until done */ - -void adb_init(void); - -int adb_request(struct adb_request *req, void (*done)(struct adb_request *), - int flags, int nbytes, ...); -int adb_register(int default_id,int handler_id,struct adb_ids *ids, - void (*handler)(unsigned char *, int, struct pt_regs *, int)); -void adb_input(unsigned char *, int, struct pt_regs *, int); - -int adb_try_handler_change(int address, int new_id); -int adb_get_infos(int address, int *original_address, int *handler_id); - -int adb_reset_bus(void); - -void adb_poll(void); - -#endif /* __KERNEL__ */ - -#endif /* __PPC_ADB_H */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/adb_mouse.h linux.ac/include/asm-ppc/adb_mouse.h --- linux.vanilla/include/asm-ppc/adb_mouse.h Sat May 15 23:05:37 1999 +++ linux.ac/include/asm-ppc/adb_mouse.h Thu Jan 1 01:00:00 1970 @@ -1,23 +0,0 @@ -#ifndef _LINUX_ADB_MOUSE_H -#define _LINUX_ADB_MOUSE_H - -/* - * linux/include/linux/mac_mouse.h - * header file for Macintosh ADB mouse driver - * 27-10-97 Michael Schmitz - * copied from: - * header file for Atari Mouse driver - * by Robert de Vries (robert@and.nl) on 19Jul93 - */ - -struct mouse_status { - char buttons; - short dx; - short dy; - int ready; - int active; - wait_queue_head_t wait; - struct fasync_struct *fasyncptr; -}; - -#endif diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/amigappc.h linux.ac/include/asm-ppc/amigappc.h --- linux.vanilla/include/asm-ppc/amigappc.h Mon Dec 21 16:37:24 1998 +++ linux.ac/include/asm-ppc/amigappc.h Sat Sep 18 01:31:40 1999 @@ -16,30 +16,24 @@ #ifndef __ASSEMBLY__ -#ifndef iobarrier_rw /* Don't include io.h - avoid circular dependency */ -#define iobarrier_rw() eieio() -#endif +/* #include */ +#define mb() __asm__ __volatile__ ("sync" : : : "memory") #define APUS_WRITE(_a_, _v_) \ do { \ (*((volatile unsigned char *)(_a_)) = (_v_)); \ - iobarrier_rw (); \ + mb(); \ } while (0) -#define APUS_READ(_a_, _v_) \ +#define APUS_READ(_a_, _v_) \ do { \ (_v_) = (*((volatile unsigned char *)(_a_))); \ - iobarrier_rw (); \ + mb(); \ } while (0) #endif /* ndef __ASSEMBLY__ */ /* Maybe add a [#ifdef WANT_ZTWOBASE] condition to amigahw.h? */ #define zTwoBase (0x80000000) - -/* At CYBERBASEp we find the following sum: - * -KERNELBASE+CyberStormMemoryBase - */ -#define CYBERBASEp (0xfff00000) #define APUS_IPL_BASE (zTwoBase + 0x00f60000) #define APUS_REG_RESET (APUS_IPL_BASE + 0x00) diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/amigayle.h linux.ac/include/asm-ppc/amigayle.h --- linux.vanilla/include/asm-ppc/amigayle.h Wed Sep 30 18:14:33 1998 +++ linux.ac/include/asm-ppc/amigayle.h Sat Sep 18 01:31:40 1999 @@ -1 +1 @@ -#include "../asm-m68k/amigayle.h" +#include diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/amipcmcia.h linux.ac/include/asm-ppc/amipcmcia.h --- linux.vanilla/include/asm-ppc/amipcmcia.h Wed Sep 30 18:14:33 1998 +++ linux.ac/include/asm-ppc/amipcmcia.h Sat Sep 18 01:31:40 1999 @@ -1 +1 @@ -#include "../asm-m68k/amipcmcia.h" +#include diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/bootx.h linux.ac/include/asm-ppc/bootx.h --- linux.vanilla/include/asm-ppc/bootx.h Thu Mar 11 05:30:32 1999 +++ linux.ac/include/asm-ppc/bootx.h Sat Sep 18 01:31:40 1999 @@ -11,6 +11,7 @@ #ifdef macintosh #include +#include "linux_type_defs.h" #endif #ifdef macintosh @@ -18,66 +19,118 @@ #pragma options align=power #endif -/* On boostrap entry: +/* On kernel entry: * - * r3 = 0x426f6f58 ('BooX') + * r3 = 0x426f6f58 ('BooX') * r4 = pointer to boot_infos * r5 = NULL + * + * Data and instruction translation disabled, interrupts + * disabled, kernel loaded at physical 0x00000000 on PCI + * machines (will be different on NuBus). + */ + +#define BOOT_INFO_VERSION 5 +#define BOOT_INFO_COMPATIBLE_VERSION 1 + +/* Bit in the architecture flag mask. More to be defined in + future versions. Note that either BOOT_ARCH_PCI or + BOOT_ARCH_NUBUS is set. The other BOOT_ARCH_NUBUS_xxx are + set additionally when BOOT_ARCH_NUBUS is set. */ +#define BOOT_ARCH_PCI 0x00000001UL +#define BOOT_ARCH_NUBUS 0x00000002UL +#define BOOT_ARCH_NUBUS_PDM 0x00000010UL +#define BOOT_ARCH_NUBUS_PERFORMA 0x00000020UL +#define BOOT_ARCH_NUBUS_POWERBOOK 0x00000040UL + +/* Maximum number of ranges in phys memory map */ +#define MAX_MEM_MAP_SIZE 26 + +/* This is the format of an element in the physical memory map. Note that + the map is optional and current BootX will only build it for pre-PCI + machines */ +typedef struct boot_info_map_entry +{ + __u32 physAddr; /* Physical starting address */ + __u32 size; /* Size in bytes */ +} boot_info_map_entry_t; -#define BOOT_INFO_VERSION 2 -#define BOOT_INFO_COMPATIBLE_VERSION 1 /* Here are the boot informations that are passed to the bootstrap * Note that the kernel arguments and the device tree are appended * at the end of this structure. */ typedef struct boot_infos { - /* Version of this structure */ - unsigned long version; - /* backward compatible down to version: */ - unsigned long compatible_version; - - /* NEW (vers. 2) this holds the current _logical_ base addr of - the frame buffer (for use by early boot message) */ - unsigned char* logicalDisplayBase; - - /* Set to 0 by current BootX */ - unsigned long unused[2]; - - /* The device tree (internal addresses relative to the beginning of the tree, - * device tree offset relative to the beginning of this structure). */ - unsigned long deviceTreeOffset; /* Device tree offset */ - unsigned long deviceTreeSize; /* Size of the device tree */ - - /* Some infos about the current MacOS display */ - unsigned long dispDeviceRect[4]; /* left,top,right,bottom */ - unsigned long dispDeviceDepth; /* (8, 16 or 32) */ - unsigned char* dispDeviceBase; /* base address (physical) */ - unsigned long dispDeviceRowBytes; /* rowbytes (in bytes) */ - unsigned long dispDeviceColorsOffset; /* Colormap (8 bits only) or 0 (*) */ - /* Optional offset in the registry to the current - * MacOS display. (Can be 0 when not detected) */ - unsigned long dispDeviceRegEntryOffset; - - /* Optional pointer to boot ramdisk (offset from this structure) */ - unsigned long ramDisk; - unsigned long ramDiskSize; /* size of ramdisk image */ - - /* Kernel command line arguments (offset from this structure) */ - unsigned long kernelParamsOffset; - + /* Version of this structure */ + __u32 version; + /* backward compatible down to version: */ + __u32 compatible_version; + + /* NEW (vers. 2) this holds the current _logical_ base addr of + the frame buffer (for use by early boot message) */ + __u8* logicalDisplayBase; + + /* NEW (vers. 4) Apple's machine identification */ + __u32 machineID; + + /* NEW (vers. 4) Detected hw architecture */ + __u32 architecture; + + /* The device tree (internal addresses relative to the beginning of the tree, + * device tree offset relative to the beginning of this structure). + * On pre-PCI macintosh (BOOT_ARCH_PCI bit set to 0 in architecture), this + * field is 0. + */ + __u32 deviceTreeOffset; /* Device tree offset */ + __u32 deviceTreeSize; /* Size of the device tree */ + + /* Some infos about the current MacOS display */ + __u32 dispDeviceRect[4]; /* left,top,right,bottom */ + __u32 dispDeviceDepth; /* (8, 16 or 32) */ + __u8* dispDeviceBase; /* base address (physical) */ + __u32 dispDeviceRowBytes; /* rowbytes (in bytes) */ + __u32 dispDeviceColorsOffset; /* Colormap (8 bits only) or 0 (*) */ + /* Optional offset in the registry to the current + * MacOS display. (Can be 0 when not detected) */ + __u32 dispDeviceRegEntryOffset; + + /* Optional pointer to boot ramdisk (offset from this structure) */ + __u32 ramDisk; + __u32 ramDiskSize; /* size of ramdisk image */ + + /* Kernel command line arguments (offset from this structure) */ + __u32 kernelParamsOffset; + + /* ALL BELOW NEW (vers. 4) */ + + /* This defines the physical memory. Valid with BOOT_ARCH_NUBUS flag + (non-PCI) only. On PCI, memory is contiguous and it's size is in the + device-tree. */ + boot_info_map_entry_t + physMemoryMap[MAX_MEM_MAP_SIZE]; /* Where the phys memory is */ + __u32 physMemoryMapSize; /* How many entries in map */ + + + /* The framebuffer size (optional, currently 0) */ + __u32 frameBufferSize; /* Represents a max size, can be 0. */ + + /* NEW (vers. 5) */ + + /* Total params size (args + colormap + device tree + ramdisk) */ + __u32 totalParamsSize; + } boot_infos_t; /* (*) The format of the colormap is 256 * 3 * 2 bytes. Each color index is represented * by 3 short words containing a 16 bits (unsigned) color component. * Later versions may contain the gamma table for direct-color devices here. */ -#define BOOTX_COLORTABLE_SIZE (256UL*3UL*2UL) +#define BOOTX_COLORTABLE_SIZE (256UL*3UL*2UL) #ifdef macintosh #pragma options align=reset #endif #endif - + \ No newline at end of file diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/bseip.h linux.ac/include/asm-ppc/bseip.h --- linux.vanilla/include/asm-ppc/bseip.h Thu Jan 1 01:00:00 1970 +++ linux.ac/include/asm-ppc/bseip.h Sat Sep 18 01:31:40 1999 @@ -0,0 +1,41 @@ + +/* + * A collection of structures, addresses, and values associated with + * the Bright Star Engineering ip-Engine board. Copied from the MBX stuff. + * + * Copyright (c) 1998 Dan Malek (dmalek@jlc.net) + */ +#ifndef __MACH_BSEIP_DEFS +#define __MACH_BSEIP_DEFS + +/* A Board Information structure that is given to a program when + * prom starts it up. + */ +typedef struct bd_info { + unsigned int bi_memstart; /* Memory start address */ + unsigned int bi_memsize; /* Memory (end) size in bytes */ + unsigned int bi_intfreq; /* Internal Freq, in Hz */ + unsigned int bi_busfreq; /* Bus Freq, in Hz */ + unsigned char bi_enetaddr[6]; + unsigned int bi_baudrate; +} bd_t; + +extern bd_t m8xx_board_info; + +/* Memory map is configured by the PROM startup. + * All we need to get started is the IMMR. + */ +#define IMAP_ADDR ((uint)0xff000000) +#define IMAP_SIZE ((uint)(64 * 1024)) +#define PCMCIA_MEM_ADDR ((uint)0x04000000) +#define PCMCIA_MEM_SIZE ((uint)(64 * 1024)) + +/* We don't use the 8259. +*/ +#define NR_8259_INTS 0 + +/* Machine type +*/ +#define _MACH_8xx (_MACH_bseip) + +#endif diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/cuda.h linux.ac/include/asm-ppc/cuda.h --- linux.vanilla/include/asm-ppc/cuda.h Thu Apr 29 20:39:01 1999 +++ linux.ac/include/asm-ppc/cuda.h Thu Jan 1 01:00:00 1970 @@ -1,38 +0,0 @@ -/* - * Definitions for talking to the CUDA. The CUDA is a microcontroller - * which controls the ADB, system power, RTC, and various other things. - * - * Copyright (C) 1996 Paul Mackerras. - */ - -/* CUDA commands (2nd byte) */ -#define CUDA_WARM_START 0 -#define CUDA_AUTOPOLL 1 -#define CUDA_GET_6805_ADDR 2 -#define CUDA_GET_TIME 3 -#define CUDA_GET_PRAM 7 -#define CUDA_SET_6805_ADDR 8 -#define CUDA_SET_TIME 9 -#define CUDA_POWERDOWN 0xa -#define CUDA_POWERUP_TIME 0xb -#define CUDA_SET_PRAM 0xc -#define CUDA_MS_RESET 0xd -#define CUDA_SEND_DFAC 0xe -#define CUDA_RESET_SYSTEM 0x11 -#define CUDA_SET_IPL 0x12 -#define CUDA_SET_AUTO_RATE 0x14 -#define CUDA_GET_AUTO_RATE 0x16 -#define CUDA_SET_DEVICE_LIST 0x19 -#define CUDA_GET_DEVICE_LIST 0x1a -#define CUDA_GET_SET_IIC 0x22 - -#ifdef __KERNEL__ - -void find_via_cuda(void); -void via_cuda_init(void); -int cuda_request(struct adb_request *req, - void (*done)(struct adb_request *), int nbytes, ...); -void cuda_poll(void); -int cuda_present(void); - -#endif /* __KERNEL */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/feature.h linux.ac/include/asm-ppc/feature.h --- linux.vanilla/include/asm-ppc/feature.h Thu Mar 11 05:30:32 1999 +++ linux.ac/include/asm-ppc/feature.h Sat Sep 18 01:31:40 1999 @@ -36,6 +36,8 @@ FEATURE_BMac_reset, FEATURE_BMac_IO_enable, FEATURE_Modem_Reset, + FEATURE_IDE_DiskPower, + FEATURE_IDE_Reset, FEATURE_last, }; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/init.h linux.ac/include/asm-ppc/init.h --- linux.vanilla/include/asm-ppc/init.h Sat Sep 11 00:54:16 1999 +++ linux.ac/include/asm-ppc/init.h Sat Sep 18 01:31:40 1999 @@ -11,7 +11,7 @@ __argpmac #define __prep __attribute__ ((__section__ (".text.prep"))) -#define __prepdata /* __attribute__ ((__section__ (".data.prep")))*/ +#define __prepdata __attribute__ ((__section__ (".data.prep"))) #define __prepfunc(__argprep) \ __argprep __prep; \ __argprep diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/io.h linux.ac/include/asm-ppc/io.h --- linux.vanilla/include/asm-ppc/io.h Thu Sep 2 00:48:41 1999 +++ linux.ac/include/asm-ppc/io.h Sat Sep 18 01:31:40 1999 @@ -19,11 +19,9 @@ #define PREP_ISA_MEM_BASE 0xc0000000 #define PREP_PCI_DRAM_OFFSET 0x80000000 -#ifdef CONFIG_MBX -#define _IO_BASE 0x80000000 -#define _ISA_MEM_BASE 0 -#define PCI_DRAM_OFFSET 0x80000000 -#else /* CONFIG_MBX8xx */ +#ifdef CONFIG_8xx +#include +#else #ifdef CONFIG_APUS #define _IO_BASE 0 #define _ISA_MEM_BASE 0 @@ -36,7 +34,7 @@ #define _ISA_MEM_BASE isa_mem_base #define PCI_DRAM_OFFSET pci_dram_offset #endif /* CONFIG_APUS */ -#endif /* CONFIG_MBX8xx */ +#endif /* CONFIG_8xx */ #define readb(addr) in_8((volatile unsigned char *)(addr)) #define writeb(b,addr) out_8((volatile unsigned char *)(addr), (b)) diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/irq.h linux.ac/include/asm-ppc/irq.h --- linux.vanilla/include/asm-ppc/irq.h Thu Sep 2 00:48:41 1999 +++ linux.ac/include/asm-ppc/irq.h Sat Sep 18 01:31:40 1999 @@ -59,27 +59,42 @@ * from such devices as CPM, PCMCIA, RTC, PIT, TimeBase and Decrementer. * There are eight external interrupts (IRQs) that can be configured * as either level or edge sensitive. - * On the MBX implementation, there is also the possibility of an 8259 + * + * The 82xx can have up to 64 interrupts on the internal controller. + * + * On some implementations, there is also the possibility of an 8259 * through the PCI and PCI-ISA bridges. */ -#define NR_IRQS (16+16) /* 8259 has 16, too -- Cort */ +#ifdef CONFIG_82xx +#define NR_SIU_INTS 64 +#else +#define NR_SIU_INTS 16 +#endif + +#define NR_IRQS (NR_SIU_INTS + NR_8259_INTS) -#define SIU_IRQ0 (0+16) /* Highest priority */ -#define SIU_LEVEL0 (1+16) -#define SIU_IRQ1 (2+16) -#define SIU_LEVEL1 (3+16) -#define SIU_IRQ2 (4+16) -#define SIU_LEVEL2 (5+16) -#define SIU_IRQ3 (6+16) -#define SIU_LEVEL3 (7+16) -#define SIU_IRQ4 (8+16) -#define SIU_LEVEL4 (9+16) -#define SIU_IRQ5 (10+16) -#define SIU_LEVEL5 (11+16) -#define SIU_IRQ6 (12+16) -#define SIU_LEVEL6 (13+16) -#define SIU_IRQ7 (14+16) -#define SIU_LEVEL7 (15+16) +/* These values must be zero-based and map 1:1 with the SIU configuration. + * They are used throughout the 8xx/82xx I/O subsystem to generate + * interrupt masks, flags, and other control patterns. This is why the + * current kernel assumption of the 8259 as the base controller is such + * a pain in the butt. + */ +#define SIU_IRQ0 (0) /* Highest priority */ +#define SIU_LEVEL0 (1) +#define SIU_IRQ1 (2) +#define SIU_LEVEL1 (3) +#define SIU_IRQ2 (4) +#define SIU_LEVEL2 (5) +#define SIU_IRQ3 (6) +#define SIU_LEVEL3 (7) +#define SIU_IRQ4 (8) +#define SIU_LEVEL4 (9) +#define SIU_IRQ5 (10) +#define SIU_LEVEL5 (11) +#define SIU_IRQ6 (12) +#define SIU_LEVEL6 (13) +#define SIU_IRQ7 (14) +#define SIU_LEVEL7 (15) /* The internal interrupts we can configure as we see fit. * My personal preference is CPM at level 2, which puts it above the @@ -95,21 +110,11 @@ */ #define mk_int_int_mask(IL) (1 << (7 - (IL/2))) -#ifdef CONFIG_MBX -/* These are defined (and fixed) by the MBX hardware implementation.*/ -#define POWER_FAIL_INT SIU_IRQ0 /* Power fail */ -#define TEMP_HILO_INT SIU_IRQ1 /* Temperature sensor */ -#define QSPAN_INT SIU_IRQ2 /* PCI Bridge (DMA CTLR?) */ -#define ISA_BRIDGE_INT SIU_IRQ3 /* All those PC things */ -#define COMM_L_INT SIU_IRQ6 /* MBX Comm expansion connector pin */ -#define STOP_ABRT_INT SIU_IRQ7 /* Stop/Abort header pin */ -#endif /* CONFIG_MBX */ - -#ifdef CONFIG_FADS -#define FEC_INTERRUPT SIU_LEVEL1 /* FEC interrupt */ -#endif +/* Now include the board configuration specific associations. +*/ +#include -/* always the same on MBX -- Cort */ +/* always the same on 8xx -- Cort */ static __inline__ int irq_cannonicalize(int irq) { return irq; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/irq_control.h linux.ac/include/asm-ppc/irq_control.h --- linux.vanilla/include/asm-ppc/irq_control.h Thu Sep 2 00:48:41 1999 +++ linux.ac/include/asm-ppc/irq_control.h Sat Sep 18 01:31:40 1999 @@ -1,5 +1,5 @@ /* - * $Id: irq_control.h,v 1.2 1999/07/17 20:23:58 cort Exp $ + * $Id: irq_control.h,v 1.8 1999/09/15 23:58:48 cort Exp $ * * Copyright (C) 1999 Cort Dougan */ @@ -11,74 +11,52 @@ #include #include -extern void do_lost_interrupts(unsigned long); -extern atomic_t ppc_n_lost_interrupts; +/* Structure describing interrupts */ +struct hw_interrupt_type { + const char * typename; + void (*startup)(unsigned int irq); + void (*shutdown)(unsigned int irq); + void (*enable)(unsigned int irq); + void (*disable)(unsigned int irq); + void (*mask_and_ack)(unsigned int irq); + int irq_offset; +}; + +struct irqdesc { + struct irqaction *action; + struct hw_interrupt_type *ctl; +}; -#define __no_use_save_flags(flags) \ - ({__asm__ __volatile__ ("mfmsr %0" : "=r" ((flags)) : : "memory"); }) - -extern __inline__ void __no_use_restore_flags(unsigned long flags) -{ - if ((flags & MSR_EE) && atomic_read(&ppc_n_lost_interrupts) != 0) { - do_lost_interrupts(flags); - } else { - __asm__ __volatile__ ("sync; mtmsr %0; isync" - : : "r" (flags) : "memory"); - } -} +extern struct irqdesc irq_desc[NR_IRQS]; -extern __inline__ void __no_use_sti(void) +struct int_control_struct { - unsigned long flags; + void (*int_cli)(void); + void (*int_sti)(void); + void (*int_restore_flags)(unsigned long); + void (*int_save_flags)(unsigned long *); +}; +extern struct int_control_struct int_control; +extern unsigned long timer_interrupt_intercept; +extern unsigned long do_IRQ_intercept; +void timer_interrupt(struct pt_regs *); + +extern void __no_use_sti(void); +extern void __no_use_cli(void); +extern void __no_use_restore_flags(unsigned long); +extern void __no_use_save_flags(unsigned long *); + +#define __cli() int_control.int_cli() +#define __sti() int_control.int_sti() +#define __save_flags(flags) int_control.int_save_flags(&flags) +#define __restore_flags(flags) int_control.int_restore_flags(flags) +#define __save_and_cli(flags) ({__save_flags(flags);__cli();}) - __asm__ __volatile__ ("mfmsr %0": "=r" (flags)); - flags |= MSR_EE; - if ( atomic_read(&ppc_n_lost_interrupts) ) - do_lost_interrupts(flags); - __asm__ __volatile__ ("sync; mtmsr %0; isync":: "r" (flags)); -} - -extern __inline__ void __no_use_cli(void) -{ - unsigned long flags; - __asm__ __volatile__ ("mfmsr %0": "=r" (flags)); - flags &= ~MSR_EE; - __asm__ __volatile__ ("sync; mtmsr %0; isync":: "r" (flags)); -} - -#define __no_use_mask_irq(irq) ({if (irq_desc[irq].ctl && irq_desc[irq].ctl->disable) irq_desc[irq].ctl->disable(irq);}) -#define __no_use_unmask_irq(irq) ({if (irq_desc[irq].ctl && irq_desc[irq].ctl->enable) irq_desc[irq].ctl->enable(irq);}) -#define __no_use_mask_and_ack_irq(irq) ({if (irq_desc[irq].ctl && irq_desc[irq].ctl->mask_and_ack) irq_desc[irq].ctl->mask_and_ack(irq);}) - -#ifdef CONFIG_RTL - -/* the rtl system provides these -- Cort */ -extern void __sti(void); -extern void __cli(void); -extern void __restore_flags(unsigned int); -extern unsigned int __return_flags(void); -#define __save_flags(flags) (flags = __return_flags()) - -#define rtl_hard_cli __no_use_cli -#define rtl_hard_sti __no_use_sti -#define rtl_hard_save_flags(flags) __no_use_save_flags(flags) -#define rtl_hard_restore_flags(flags) __no_use_restore_flags(flags) - -#define rtl_hard_mask_irq(irq) __no_use_mask_irq(irq) -#define rtl_hard_unmask_irq(irq) __no_use_unmask_irq(irq) -#define rtl_hard_mask_and_ack_irq(irq) __no_use_mask_and_ack_irq(irq) - -#else /* CONFIG_RTL */ - -#define __cli __no_use_cli -#define __sti __no_use_sti -#define __save_flags(flags) __no_use_save_flags(flags) -#define __restore_flags(flags) __no_use_restore_flags(flags) - -#define mask_irq(irq) __no_use_mask_irq(irq) -#define unmask_irq(irq) __no_use_unmask_irq(irq) -#define mask_and_ack_irq(irq) __no_use_mask_and_ack_irq(irq) +extern void do_lost_interrupts(unsigned long); +extern atomic_t ppc_n_lost_interrupts; -#endif /* CONFIG_RTL */ +#define mask_irq(irq) ({if (irq_desc[irq].ctl && irq_desc[irq].ctl->disable) irq_desc[irq].ctl->disable(irq);}) +#define unmask_irq(irq) ({if (irq_desc[irq].ctl && irq_desc[irq].ctl->enable) irq_desc[irq].ctl->enable(irq);}) +#define mask_and_ack_irq(irq) ({if (irq_desc[irq].ctl && irq_desc[irq].ctl->mask_and_ack) irq_desc[irq].ctl->mask_and_ack(irq);}) #endif /* _PPC_IRQ_CONTROL_H */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/keyboard.h linux.ac/include/asm-ppc/keyboard.h --- linux.vanilla/include/asm-ppc/keyboard.h Sat Sep 11 00:54:16 1999 +++ linux.ac/include/asm-ppc/keyboard.h Sat Sep 18 01:31:40 1999 @@ -16,7 +16,7 @@ #ifdef __KERNEL__ #include -#include +#include #include #ifdef CONFIG_APUS #include diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/linux_logo.h linux.ac/include/asm-ppc/linux_logo.h --- linux.vanilla/include/asm-ppc/linux_logo.h Wed Sep 30 18:14:33 1998 +++ linux.ac/include/asm-ppc/linux_logo.h Sat Sep 18 01:31:40 1999 @@ -12,14 +12,6 @@ */ #include -#ifdef CONFIG_APUS -#include - -#undef linux_logo_banner -#define linux_logo_banner "Linux/PPC version " UTS_RELEASE - -#else - #include #define linux_logo_banner "Linux/PPC version " UTS_RELEASE @@ -48,4 +40,3 @@ extern unsigned char linux_logo16[]; #endif -#endif /* CONFIG_APUS */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/machdep.h linux.ac/include/asm-ppc/machdep.h --- linux.vanilla/include/asm-ppc/machdep.h Sat Sep 11 00:54:16 1999 +++ linux.ac/include/asm-ppc/machdep.h Sat Sep 18 01:31:40 1999 @@ -9,6 +9,7 @@ #endif struct pt_regs; +struct pci_bus; struct machdep_calls { void (*setup_arch)(unsigned long * memory_start_p, @@ -20,8 +21,9 @@ /* Optional, may be NULL. */ unsigned int (*irq_cannonicalize)(unsigned int irq); void (*init_IRQ)(void); - void (*do_IRQ)(struct pt_regs *regs, int cpu, int isfake); - + int (*get_irq)(struct pt_regs *); + void (*post_irq)( int ); + /* A general init function, called by ppc_init in init/main.c. May be NULL. */ void (*init)(void); @@ -72,8 +74,9 @@ int (*pcibios_write_config_dword)(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned int val); void (*pcibios_fixup)(void); -struct pci_bus; void (*pcibios_fixup_bus)(struct pci_bus *); + /* this is for modules, since _machine can be a define -- Cort */ + int ppc_machine; }; extern struct machdep_calls ppc_md; @@ -89,7 +92,7 @@ unsigned long magic_start; char cmd_line[256]; char boot_loader[128]; - int _machine; + int _machine_type; unsigned long initrd_start, initrd_size; unsigned long systemmap_start, systemmap_size; unsigned long prom_entry; @@ -97,4 +100,14 @@ unsigned long magic_end; }; struct boot_info *binfo; + +/* + * Power macintoshes have either a CUDA or a PMU controlling + * system reset, power, NVRAM, RTC. + */ +enum sys_ctrler_kind { + SYS_CTRLER_CUDA = 1, + SYS_CTRLER_PMU = 2, +} sys_ctrler; + #endif /* _PPC_MACHDEP_H */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/mbx.h linux.ac/include/asm-ppc/mbx.h --- linux.vanilla/include/asm-ppc/mbx.h Wed Sep 30 18:14:33 1998 +++ linux.ac/include/asm-ppc/mbx.h Sat Sep 18 01:31:40 1999 @@ -39,9 +39,10 @@ * NVRAM, Status/Control registers, CPM Dual Port RAM, and the PCI * Bridge CSRs 1:1 into the kernel address space. */ -#define PCI_ISA_IO_ADDR ((uint)0x80000000) +#define PCI_ISA_IO_ADDR ((unsigned)0x80000000) #define PCI_ISA_IO_SIZE ((uint)(512 * 1024 * 1024)) -#define PCI_ISA_MEM_ADDR ((uint)0xc0000000) +#define PCI_IDE_ADDR ((unsigned)0x81000000) +#define PCI_ISA_MEM_ADDR ((unsigned)0xc0000000) #define PCI_ISA_MEM_SIZE ((uint)(512 * 1024 * 1024)) #define PCMCIA_MEM_ADDR ((uint)0xe0000000) #define PCMCIA_MEM_SIZE ((uint)(64 * 1024 * 1024)) @@ -59,4 +60,29 @@ #define IMAP_SIZE ((uint)(64 * 1024)) #define PCI_CSR_ADDR ((uint)0xfa210000) #define PCI_CSR_SIZE ((uint)(64 * 1024)) + +/* Map additional physical space into well known virtual addresses. Due + * to virtual address mapping, these physical addresses are not accessible + * in a 1:1 virtual to physical mapping. + */ +#define ISA_IO_VIRT_ADDR ((uint)0xfa220000) +#define ISA_IO_VIRT_SIZE ((uint)64 * 1024) + +/* Interrupt assignments. + * These are defined (and fixed) by the MBX hardware implementation. + */ +#define POWER_FAIL_INT SIU_IRQ0 /* Power fail */ +#define TEMP_HILO_INT SIU_IRQ1 /* Temperature sensor */ +#define QSPAN_INT SIU_IRQ2 /* PCI Bridge (DMA CTLR?) */ +#define ISA_BRIDGE_INT SIU_IRQ3 /* All those PC things */ +#define COMM_L_INT SIU_IRQ6 /* MBX Comm expansion connector pin */ +#define STOP_ABRT_INT SIU_IRQ7 /* Stop/Abort header pin */ + +/* The MBX uses the 8259. +*/ +#define NR_8259_INTS 16 + +/* Generic 8xx type +*/ +#define _MACH_8xx (_MACH_mbx) #endif diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/mpc8xx.h linux.ac/include/asm-ppc/mpc8xx.h --- linux.vanilla/include/asm-ppc/mpc8xx.h Thu Jan 1 01:00:00 1970 +++ linux.ac/include/asm-ppc/mpc8xx.h Sat Sep 18 01:31:40 1999 @@ -0,0 +1,66 @@ + +/* This is the single file included by all MPC8xx build options. + * Since there are many different boards and no standard configuration, + * we have a unique include file for each. Rather than change every + * file that has to include MPC8xx configuration, they all include + * this one and the configuration switching is done here. + */ +#ifndef __CONFIG_8xx_DEFS +#define __CONFIG_8xx_DEFS + +#ifdef CONFIG_8xx + +#ifdef CONFIG_MBX +#include +#endif + +#ifdef CONFIG_FADS +#include +#endif + +#ifdef CONFIG_RPXLITE +#include +#endif + +#ifdef CONFIG_BSEIP +#include +#endif + +#ifdef CONFIG_RPXCLASSIC +#include +#endif + +/* I need this to get pt_regs....... +*/ +#include + +/* Currently, all 8xx boards that support a processor to PCI/ISA bridge + * use the same memory map. + */ +#if 0 +#if defined(CONFIG_PCI) && defined(PCI_ISA_IO_ADDR) +#define _IO_BASE PCI_ISA_IO_ADDR +#define _ISA_MEM_BASE PCI_ISA_MEM_ADDR +#define PCI_DRAM_OFFSET 0x80000000 +#else +#define _IO_BASE 0 +#define _ISA_MEM_BASE 0 +#define PCI_DRAM_OFFSET 0 +#endif +#else +#define _IO_BASE 0 +#define _ISA_MEM_BASE 0 +#define PCI_DRAM_OFFSET 0 +#endif + +extern unsigned long isa_io_base; +extern unsigned long isa_mem_base; +extern unsigned long pci_dram_offset; + +extern int request_8xxirq(unsigned int irq, + void (*handler)(int, void *, struct pt_regs *), + unsigned long flags, + const char *device, + void *dev_id); +#endif /* CONFIG_8xx */ +#endif diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/ohare.h linux.ac/include/asm-ppc/ohare.h --- linux.vanilla/include/asm-ppc/ohare.h Thu Mar 11 05:30:32 1999 +++ linux.ac/include/asm-ppc/ohare.h Sat Sep 18 01:31:40 1999 @@ -18,7 +18,9 @@ #define OH_BAY_IDE_ENABLE 8 #define OH_BAY_FLOPPY_ENABLE 0x10 #define OH_IDE_ENABLE 0x20 +#define OH_IDE_POWER 0x40 /* a guess */ #define OH_BAY_ENABLE 0x80 +#define OH_IDE_RESET 0x100 /* 0-based, a guess */ #define OH_SCC_ENABLE 0x200 #define OH_MESH_ENABLE 0x400 #define OH_FLOPPY_ENABLE 0x800 diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/pgtable.h linux.ac/include/asm-ppc/pgtable.h --- linux.vanilla/include/asm-ppc/pgtable.h Thu Sep 2 00:48:41 1999 +++ linux.ac/include/asm-ppc/pgtable.h Sat Sep 18 01:31:40 1999 @@ -9,11 +9,28 @@ #include #include +#ifndef CONFIG_8xx extern void local_flush_tlb_all(void); extern void local_flush_tlb_mm(struct mm_struct *mm); extern void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr); extern void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end); +#else /* CONFIG_8xx */ +#define __tlbia() asm volatile ("tlbia" : : ) + +extern inline void local_flush_tlb_all(void) + { __tlbia(); } +extern inline void local_flush_tlb_mm(struct mm_struct *mm) + { __tlbia(); } +extern inline void local_flush_tlb_page(struct vm_area_struct *vma, + unsigned long vmaddr) + { __tlbia(); } +extern inline void local_flush_tlb_range(struct mm_struct *mm, + unsigned long start, unsigned long end) + { __tlbia(); } +extern inline void flush_hash_page(unsigned context, unsigned long va) + { } +#endif #define flush_tlb_all local_flush_tlb_all #define flush_tlb_mm local_flush_tlb_mm @@ -636,22 +653,6 @@ #define io_remap_page_range remap_page_range -#ifdef CONFIG_8xx -#define __tlbia() asm volatile ("tlbia" : : ) - -extern inline void local_flush_tlb_all(void) - { __tlbia(); } -extern inline void local_flush_tlb_mm(struct mm_struct *mm) - { __tlbia(); } -extern inline void local_flush_tlb_page(struct vm_area_struct *vma, - unsigned long vmaddr) - { __tlbia(); } -extern inline void local_flush_tlb_range(struct mm_struct *mm, - unsigned long start, unsigned long end) - { __tlbia(); } -extern inline void flush_hash_page(unsigned context, unsigned long va) - { } -#endif #endif __ASSEMBLY__ #endif /* _PPC_PGTABLE_H */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/pmu.h linux.ac/include/asm-ppc/pmu.h --- linux.vanilla/include/asm-ppc/pmu.h Tue Sep 7 22:07:08 1999 +++ linux.ac/include/asm-ppc/pmu.h Thu Jan 1 01:00:00 1970 @@ -1,97 +0,0 @@ -/* - * Definitions for talking to the PMU. The PMU is a microcontroller - * which controls battery charging and system power on PowerBook 3400 - * and 2400 models as well as the RTC and various other things. - * - * Copyright (C) 1998 Paul Mackerras. - */ - -/* - * PMU commands - */ -#define PMU_POWER_CTRL 0x11 /* control power of some devices */ -#define PMU_ADB_CMD 0x20 /* send ADB packet */ -#define PMU_ADB_POLL_OFF 0x21 /* disable ADB auto-poll */ -#define PMU_WRITE_NVRAM 0x33 /* write non-volatile RAM */ -#define PMU_READ_NVRAM 0x3b /* read non-volatile RAM */ -#define PMU_SET_RTC 0x30 /* set real-time clock */ -#define PMU_READ_RTC 0x38 /* read real-time clock */ -#define PMU_SET_VOLBUTTON 0x40 /* set volume up/down position */ -#define PMU_BACKLIGHT_BRIGHT 0x41 /* set backlight brightness */ -#define PMU_GET_VOLBUTTON 0x48 /* get volume up/down position */ -#define PMU_PCEJECT 0x4c /* eject PC-card from slot */ -#define PMU_BATTERY_STATE 0x6b /* report battery state etc. */ -#define PMU_SET_INTR_MASK 0x70 /* set PMU interrupt mask */ -#define PMU_INT_ACK 0x78 /* read interrupt bits */ -#define PMU_SHUTDOWN 0x7e /* turn power off */ -#define PMU_SLEEP 0x7f /* put CPU to sleep */ -#define PMU_RESET 0xd0 /* reset CPU */ -#define PMU_GET_BRIGHTBUTTON 0xd9 /* report brightness up/down pos */ -#define PMU_GET_COVER 0xdc /* report cover open/closed */ - -/* Bits to use with the PMU_POWER_CTRL command */ -#define PMU_POW_ON 0x80 /* OR this to power ON the device */ -#define PMU_POW_OFF 0x00 /* leave bit 7 to 0 to power it OFF */ -#define PMU_POW_BACKLIGHT 0x01 /* backlight power */ -#define PMU_POW_IRLED 0x04 /* IR led power (on wallstreet) ??? */ - -/* Bits in PMU interrupt and interrupt mask bytes */ -#define PMU_INT_ADB_AUTO 0x04 /* ADB autopoll, when PMU_INT_ADB */ -#define PMU_INT_PCEJECT 0x04 /* PC-card eject buttons */ -#define PMU_INT_SNDBRT 0x08 /* sound/brightness up/down buttons */ -#define PMU_INT_ADB 0x10 /* ADB autopoll or reply data */ -#define PMU_INT_TICK 0x80 /* 1-second tick interrupt */ - -/* Kind of PMU (model) */ -enum { - PMU_UNKNOWN, - PMU_OHARE_BASED, - PMU_HEATHROW_BASED -}; - -/* - * Ioctl commands for the /dev/pmu device - */ -#include - -/* no param */ -#define PMU_IOC_SLEEP _IO('B', 0) -/* out param: u32* backlight value: 0 to 31 */ -#define PMU_IOC_GET_BACKLIGHT _IOR('B', 1, sizeof(__u32*)) -/* in param: u32 backlight value: 0 to 31 */ -#define PMU_IOC_SET_BACKLIGHT _IOW('B', 2, sizeof(__u32)) -/* out param: u32* backlight value: 0 to 31 */ -#define PMU_IOC_GET_MODEL _IOR('B', 3, sizeof(__u32*)) - -#ifdef __KERNEL__ - -void find_via_pmu(void); -void via_pmu_init(void); - -int pmu_request(struct adb_request *req, - void (*done)(struct adb_request *), int nbytes, ...); -void pmu_poll(void); - -void pmu_enable_backlight(int on); -void pmu_set_brightness(int level); - -void pmu_enable_irled(int on); - -void pmu_restart(void); -void pmu_shutdown(void); - -int pmu_present(void); -int pmu_get_model(void); - -/* - * Stuff for putting the powerbook to sleep and waking it again. - */ -#include - -extern struct notifier_block *sleep_notifier_list; - -/* code values for calling sleep/wakeup handlers */ -#define PBOOK_SLEEP 1 -#define PBOOK_WAKE 2 - -#endif /* __KERNEL */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/processor.h linux.ac/include/asm-ppc/processor.h --- linux.vanilla/include/asm-ppc/processor.h Thu Sep 2 00:48:42 1999 +++ linux.ac/include/asm-ppc/processor.h Sat Sep 18 01:31:40 1999 @@ -34,7 +34,7 @@ #define MSR_RI (1<<1) /* Recoverable Exception */ #define MSR_LE (1<<0) /* Little-Endian enable */ -#ifdef CONFIG_APUS +#ifdef CONFIG_APUS_FAST_EXCEPT #define MSR_ MSR_ME|MSR_IP|MSR_RI #else #define MSR_ MSR_ME|MSR_RI @@ -104,6 +104,7 @@ #define _MACH_bseip 128 /* Bright Star Engineering ip-Engine */ #define _MACH_yk 256 /* Motorola Yellowknife */ #define _MACH_gemini 512 /* Synergy Microsystems gemini board */ +#define _MACH_classic 1024 /* RPCG RPX-Classic 8xx board */ /* see residual.h for these */ #define _PREP_Motorola 0x01 /* motorola prep */ @@ -212,13 +213,12 @@ #define SR15 15 #ifndef __ASSEMBLY__ +#ifndef CONFIG_MACH_SPECIFIC extern int _machine; - -/* Temporary hacks until we can clean things up better - Corey */ extern int have_of; -extern int is_prep; extern int is_chrp; extern int is_powerplus; +#endif /* CONFIG_MACH_SPECIFIC */ /* what kind of prep workstation we are */ extern int _prep_type; @@ -331,5 +331,28 @@ #endif /* ndef ASSEMBLY*/ - +#ifdef CONFIG_MACH_SPECIFIC +#if defined(CONFIG_PREP) +#define _machine _MACH_prep +#define have_of 0 +#elif defined(CONFIG_CHRP) +#define _machine _MACH_chrp +#define have_of 1 +#elif defined(CONFIG_PMAC) +#define _machine _MACH_Pmac +#define have_of 1 +#elif defined(CONFIG_8xx) +#define _machine _MACH_8xx +#define have_of 0 +#elif defined(CONFIG_APUS) +#define _machine _MACH_apus +#define have_of 0 +#elif defined(CONFIG_GEMINI) +#define _machine _MACH_gemini +#define have_of 0 +#else +#error "Machine not defined correctly" +#endif +#endif /* CONFIG_MACH_SPECIFIC */ + #endif /* __ASM_PPC_PROCESSOR_H */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/prom.h linux.ac/include/asm-ppc/prom.h --- linux.vanilla/include/asm-ppc/prom.h Sun Nov 15 18:51:50 1998 +++ linux.ac/include/asm-ppc/prom.h Sat Sep 18 01:31:40 1999 @@ -65,6 +65,7 @@ extern void abort(void); extern void prom_init(int, int, prom_entry); extern void prom_print(const char *msg); +extern void relocate_nodes(void); extern void finish_device_tree(void); extern struct device_node *find_devices(const char *name); extern struct device_node *find_type_devices(const char *type); @@ -72,7 +73,8 @@ extern struct device_node *find_compatible_devices(const char *type, const char *compat); extern struct device_node *find_phandle(phandle); -extern int device_is_compatible(struct device_node *device, const char* compat); +extern int device_is_compatible(struct device_node *device, const char *); +extern int machine_is_compatible(const char *compat); extern unsigned char *get_property(struct device_node *node, const char *name, int *lenp); extern void print_properties(struct device_node *node); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/rpxclassic.h linux.ac/include/asm-ppc/rpxclassic.h --- linux.vanilla/include/asm-ppc/rpxclassic.h Thu Jan 1 01:00:00 1970 +++ linux.ac/include/asm-ppc/rpxclassic.h Sat Sep 18 01:31:40 1999 @@ -0,0 +1,67 @@ + +/* + * A collection of structures, addresses, and values associated with + * the RPCG RPX-Classic board. Copied from the RPX-Lite stuff. + * + * Copyright (c) 1998 Dan Malek (dmalek@jlc.net) + */ +#ifndef __MACH_RPX_DEFS +#define __MACH_RPX_DEFS + +/* A Board Information structure that is given to a program when + * prom starts it up. + */ +typedef struct bd_info { + unsigned int bi_memstart; /* Memory start address */ + unsigned int bi_memsize; /* Memory (end) size in bytes */ + unsigned int bi_intfreq; /* Internal Freq, in Hz */ + unsigned int bi_busfreq; /* Bus Freq, in Hz */ + unsigned char bi_enetaddr[6]; + unsigned int bi_baudrate; +} bd_t; + +extern bd_t m8xx_board_info; + +/* Memory map is configured by the PROM startup. + * We just map a few things we need. The CSR is actually 4 byte-wide + * registers that can be accessed as 8-, 16-, or 32-bit values. + */ +#define PCMCIA_MEM_ADDR ((uint)0x04000000) +#define PCMCIA_MEM_SIZE ((uint)(64 * 1024)) +#define PCI_ISA_IO_ADDR ((unsigned)0x80000000) +#define PCI_ISA_IO_SIZE ((uint)(512 * 1024 * 1024)) +#define PCI_ISA_MEM_ADDR ((unsigned)0xc0000000) +#define PCI_ISA_MEM_SIZE ((uint)(512 * 1024 * 1024)) +#define RPX_CSR_ADDR ((uint)0xfa400000) +#define RPX_CSR_SIZE ((uint)(4 * 1024)) +#define IMAP_ADDR ((uint)0xfa200000) +#define IMAP_SIZE ((uint)(64 * 1024)) +#define PCI_CSR_ADDR ((uint)0x80000000) +#define PCI_CSR_SIZE ((uint)(64 * 1024)) + +/* Things of interest in the CSR. +*/ +#define BCSR0_ETHEN ((uint)0x80000000) +#define BCSR0_ETHLPBK ((uint)0x40000000) +#define BCSR0_COLTESTDIS ((uint)0x20000000) +#define BCSR0_FULLDPLXDIS ((uint)0x10000000) +#define BCSR0_ENFLSHSEL ((uint)0x04000000) +#define BCSR0_FLASH_SEL ((uint)0x02000000) +#define BCSR0_ENMONXCVR ((uint)0x01000000) + +#define BCSR2_EN232XCVR ((uint)0x00008000) +#define BCSR2_QSPACESEL ((uint)0x00004000) + +/* Interrupt level assignments. +*/ +#define FEC_INTERRUPT SIU_LEVEL1 /* FEC interrupt */ + +/* We don't use the 8259. +*/ +#define NR_8259_INTS 0 + +/* Machine type +*/ +#define _MACH_8xx (_MACH_rpxclassic) + +#endif diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/rpxlite.h linux.ac/include/asm-ppc/rpxlite.h --- linux.vanilla/include/asm-ppc/rpxlite.h Thu Jan 1 01:00:00 1970 +++ linux.ac/include/asm-ppc/rpxlite.h Sat Sep 18 01:31:40 1999 @@ -0,0 +1,67 @@ + +/* + * A collection of structures, addresses, and values associated with + * the RPCG RPX-Lite board. Copied from the MBX stuff. + * + * Copyright (c) 1998 Dan Malek (dmalek@jlc.net) + */ +#ifndef __MACH_RPX_DEFS +#define __MACH_RPX_DEFS + +/* A Board Information structure that is given to a program when + * prom starts it up. + */ +typedef struct bd_info { + unsigned int bi_memstart; /* Memory start address */ + unsigned int bi_memsize; /* Memory (end) size in bytes */ + unsigned int bi_intfreq; /* Internal Freq, in Hz */ + unsigned int bi_busfreq; /* Bus Freq, in Hz */ + unsigned char bi_enetaddr[6]; + unsigned int bi_baudrate; +} bd_t; + +extern bd_t m8xx_board_info; + +/* Memory map is configured by the PROM startup. + * We just map a few things we need. The CSR is actually 4 byte-wide + * registers that can be accessed as 8-, 16-, or 32-bit values. + */ +#define RPX_CSR_ADDR ((uint)0xfa400000) +#define RPX_CSR_SIZE ((uint)(4 * 1024)) +#define IMAP_ADDR ((uint)0xfa200000) +#define IMAP_SIZE ((uint)(64 * 1024)) +#define HIOX_CSR_ADDR ((uint)0xfac00000) +#define HIOX_CSR_SIZE ((uint)(4 * 1024)) +#define PCMCIA_MEM_ADDR ((uint)0x04000000) +#define PCMCIA_MEM_SIZE ((uint)(64 * 1024)) +#define PCMCIA_IO_ADDR ((uint)0x04400000) +#define PCMCIA_IO_SIZE ((uint)(4 * 1024)) + +/* Things of interest in the CSR. +*/ +#define BCSR0_ETHEN ((uint)0x80000000) +#define BCSR0_ETHLPBK ((uint)0x40000000) +#define BCSR0_COLTESTDIS ((uint)0x20000000) +#define BCSR0_FULLDPLXDIS ((uint)0x10000000) +#define BCSR0_LEDOFF ((uint)0x08000000) +#define BCSR0_USBDISABLE ((uint)0x04000000) +#define BCSR0_USBHISPEED ((uint)0x02000000) +#define BCSR0_USBPWREN ((uint)0x01000000) +#define BCSR0_PCMCIAVOLT ((uint)0x000f0000) +#define BCSR0_PCMCIA3VOLT ((uint)0x000a0000) +#define BCSR0_PCMCIA5VOLT ((uint)0x00060000) + +/* HIO Expansion card. +*/ +#define HIOX_CSR_ENAUDIO ((uint)0x00000200) +#define HIOX_CSR_RSTAUDIO ((uint)0x00000100) /* 0 == reset */ + +/* We don't use the 8259. +*/ +#define NR_8259_INTS 0 + +/* Machine type +*/ +#define _MACH_8xx (_MACH_rpxlite) + +#endif diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/serial.h linux.ac/include/asm-ppc/serial.h --- linux.vanilla/include/asm-ppc/serial.h Sat Sep 11 00:54:16 1999 +++ linux.ac/include/asm-ppc/serial.h Sat Sep 18 01:31:40 1999 @@ -20,20 +20,18 @@ */ #define BASE_BAUD ( 1843200 / 16 ) -#ifdef CONFIG_PMAC -/* - * Auto-probing will cause machine checks on powermacs. - */ -#define SERIAL_PORT_DFNS - #ifdef CONFIG_SERIAL_MANY_PORTS #define RS_TABLE_SIZE 64 #else #define RS_TABLE_SIZE 4 #endif -#else +#ifdef CONFIG_PMAC +/* + * Auto-probing will cause machine checks on powermacs. + */ #define SERIAL_PORT_DFNS +#else /* * PReP, CHRP, etc. */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/shmparam.h linux.ac/include/asm-ppc/shmparam.h --- linux.vanilla/include/asm-ppc/shmparam.h Sat Nov 25 17:49:06 1995 +++ linux.ac/include/asm-ppc/shmparam.h Sat Sep 18 01:31:40 1999 @@ -33,7 +33,7 @@ * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS). */ -#define SHMMAX 0x3fa000 /* max shared seg size (bytes) */ +#define SHMMAX 0x2000000 /* max shared seg size (bytes) */ #define SHMMIN 1 /* really PAGE_SIZE */ /* min shared seg size (bytes) */ #define SHMMNI (1<<_SHM_ID_BITS) /* max num of segs system wide */ #define SHMALL /* max shm system wide (pages) */ \ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/smp.h linux.ac/include/asm-ppc/smp.h --- linux.vanilla/include/asm-ppc/smp.h Thu Sep 2 00:48:42 1999 +++ linux.ac/include/asm-ppc/smp.h Sat Sep 18 01:31:40 1999 @@ -21,7 +21,6 @@ }; extern struct cpuinfo_PPC cpu_data[NR_CPUS]; -extern int first_cpu_booted; extern unsigned long smp_proc_in_lock[NR_CPUS]; extern void smp_message_pass(int target, int msg, unsigned long data, int wait); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/spinlock.h linux.ac/include/asm-ppc/spinlock.h --- linux.vanilla/include/asm-ppc/spinlock.h Sat Sep 11 00:54:16 1999 +++ linux.ac/include/asm-ppc/spinlock.h Sat Sep 18 01:31:40 1999 @@ -1,10 +1,8 @@ #ifndef __ASM_SPINLOCK_H #define __ASM_SPINLOCK_H -/* Simple spin lock operations. There are two variants, one clears IRQ's - * on the local processor, one does not. - * - * We make no fairness assumptions. They have a cost. +/* + * Simple spin lock operations. */ typedef struct { @@ -23,19 +21,6 @@ #define spin_lock(lp) _spin_lock(lp) #define spin_unlock(lp) _spin_unlock(lp) - -#define spin_lock_irq(lock) \ - do { __cli(); spin_lock(lock); } while (0) -#define spin_lock_bh(___lk) do { local_bh_disable(); spin_lock(___lk); } while(0) - -#define spin_unlock_irq(lock) \ - do { spin_unlock(lock); __sti(); } while (0) -#define spin_unlock_bh(___lk) do { spin_unlock(___lk); local_bh_enable(); } while(0) - -#define spin_lock_irqsave(lock, flags) \ - do { __save_flags(flags); __cli(); spin_lock(lock); } while (0) -#define spin_unlock_irqrestore(lock, flags) \ - do { spin_unlock(lock); __restore_flags(flags); } while (0) extern unsigned long __spin_trylock(volatile unsigned long *lock); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-ppc/system.h linux.ac/include/asm-ppc/system.h --- linux.vanilla/include/asm-ppc/system.h Sat Sep 11 00:54:16 1999 +++ linux.ac/include/asm-ppc/system.h Sat Sep 18 01:31:40 1999 @@ -1,5 +1,5 @@ /* - * $Id: system.h,v 1.48 1999/09/05 11:56:40 paulus Exp $ + * $Id: system.h,v 1.49 1999/09/11 18:37:54 cort Exp $ * * Copyright (C) 1999 Cort Dougan */ @@ -103,6 +103,11 @@ #define restore_flags(x) __global_restore_flags(x) #endif /* !__SMP__ */ + +#define local_irq_disable() __cli() +#define local_irq_enable() __sti() +#define local_irq_save(flags) __save_and_cli(flags) +#define local_irq_restore(flags) __restore_flags(flags) #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-sparc/keyboard.h linux.ac/include/asm-sparc/keyboard.h --- linux.vanilla/include/asm-sparc/keyboard.h Wed Apr 28 16:47:39 1999 +++ linux.ac/include/asm-sparc/keyboard.h Thu Sep 2 16:51:08 1999 @@ -13,6 +13,9 @@ #ifdef __KERNEL__ +#include +#include + #define KEYBOARD_IRQ 13 #define DISABLE_KBD_DURING_INTERRUPTS 0 @@ -44,6 +47,31 @@ /* #define SYSRQ_KEY 0x54 */ /* sparc64 */ #define SYSRQ_KEY 0x63 /* sparc */ + +/* resource allocation */ +#define kbd_request_region() request_region(0x60, 16, "keyboard") +#define kbd_request_irq(handler) request_irq(KEYBOARD_IRQ, handler, 0, \ + "keyboard", NULL) + +/* How to access the keyboard macros on this platform. */ +#define kbd_read_input() inb(KBD_DATA_REG) +#define kbd_read_status() inb(KBD_STATUS_REG) +#define kbd_write_output(val) outb(val, KBD_DATA_REG) +#define kbd_write_command(val) outb(val, KBD_CNTL_REG) + +/* Some stoneage hardware needs delays after some operations. */ +#define kbd_pause() do { } while(0) + +/* + * Machine specific bits for the PS/2 driver + */ + +#define AUX_IRQ 12 + +#define aux_request_irq(hand, dev_id) \ + request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS/2 Mouse", dev_id) + +#define aux_free_irq(dev_id) free_irq(AUX_IRQ, dev_id) #endif /* __KERNEL__ */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-sparc/socket.h linux.ac/include/asm-sparc/socket.h --- linux.vanilla/include/asm-sparc/socket.h Wed Aug 5 00:03:35 1998 +++ linux.ac/include/asm-sparc/socket.h Thu Sep 2 16:51:07 1999 @@ -45,4 +45,18 @@ #define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002 #define SO_SECURITY_ENCRYPTION_NETWORK 0x5004 +/* Socket types. */ +#ifdef __KERNEL__ +#define SOCK_STREAM 1 /* stream (connection) socket */ +#define SOCK_DGRAM 2 /* datagram (conn.less) socket */ +#define SOCK_RAW 3 /* raw socket */ +#define SOCK_RDM 4 /* reliably-delivered message */ +#define SOCK_SEQPACKET 5 /* sequential packet socket */ +#define SOCK_PACKET 10 /* linux specific way of */ + /* getting packets at the dev */ + /* level. For writing rarp and */ + /* other similar things on the */ + /* user level. */ +#endif + #endif /* _ASM_SOCKET_H */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-sparc/termios.h linux.ac/include/asm-sparc/termios.h --- linux.vanilla/include/asm-sparc/termios.h Thu Mar 25 17:23:34 1999 +++ linux.ac/include/asm-sparc/termios.h Mon Sep 6 16:58:03 1999 @@ -66,7 +66,7 @@ #define N_MASC 8 /* Reserved for Mobitex module */ #define N_R3964 9 /* Reserved for Simatic R3964 module */ #define N_PROFIBUS_FDL 10 /* Reserved for Profibus */ -#define N_IRDA 11 /* Linux IrDa - http://www.cs.uit.no/~dagb/irda/irda.html */ +#define N_IRDA 11 /* Reserved for IrDA async (SIR) mode */ #define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ #define N_HDLC 13 /* synchronous HDLC */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-sparc64/socket.h linux.ac/include/asm-sparc64/socket.h --- linux.vanilla/include/asm-sparc64/socket.h Wed Aug 5 00:03:35 1998 +++ linux.ac/include/asm-sparc64/socket.h Thu Sep 2 16:51:08 1999 @@ -45,4 +45,16 @@ #define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002 #define SO_SECURITY_ENCRYPTION_NETWORK 0x5004 +/* Socket types. */ +#define SOCK_STREAM 1 /* stream (connection) socket */ +#define SOCK_DGRAM 2 /* datagram (conn.less) socket */ +#define SOCK_RAW 3 /* raw socket */ +#define SOCK_RDM 4 /* reliably-delivered message */ +#define SOCK_SEQPACKET 5 /* sequential packet socket */ +#define SOCK_PACKET 10 /* linux specific way of */ + /* getting packets at the dev */ + /* level. For writing rarp and */ + /* other similar things on the */ + /* user level. */ + #endif /* _ASM_SOCKET_H */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/asm-sparc64/termios.h linux.ac/include/asm-sparc64/termios.h --- linux.vanilla/include/asm-sparc64/termios.h Thu Mar 25 17:23:34 1999 +++ linux.ac/include/asm-sparc64/termios.h Mon Sep 6 16:58:03 1999 @@ -66,7 +66,7 @@ #define N_MASC 8 /* Reserved for Mobitex module */ #define N_R3964 9 /* Reserved for Simatic R3964 module */ #define N_PROFIBUS_FDL 10 /* Reserved for Profibus */ -#define N_IRDA 11 /* Linux IrDa - http://www.cs.uit.no/~dagb/irda/irda.html */ +#define N_IRDA 11 /* Reserved for IrDA async (SIR) mode */ #define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ #define N_HDLC 13 /* synchronous HDLC */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/blk.h linux.ac/include/linux/blk.h --- linux.vanilla/include/linux/blk.h Sat Sep 11 00:54:17 1999 +++ linux.ac/include/linux/blk.h Thu Sep 16 16:56:44 1999 @@ -346,6 +346,15 @@ #define DEVICE_ON(device) #define DEVICE_OFF(device) +#elif (MAJOR_NR == MFM_ACORN_MAJOR) + +#define DEVICE_NAME "mfm disk" +#define DEVICE_INTR do_mfm +#define DEVICE_REQUEST do_mfm_request +#define DEVICE_NR(device) (MINOR(device) >> 6) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) + #elif (MAJOR_NR == NBD_MAJOR) #define DEVICE_NAME "nbd" diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/cdrom.h linux.ac/include/linux/cdrom.h --- linux.vanilla/include/linux/cdrom.h Thu Sep 2 00:48:46 1999 +++ linux.ac/include/linux/cdrom.h Wed Sep 15 23:53:22 1999 @@ -147,9 +147,9 @@ /* Address in MSF format */ struct cdrom_msf0 { - u_char minute; - u_char second; - u_char frame; + __u8 minute; + __u8 second; + __u8 frame; }; /* Address in either MSF or logical format */ @@ -162,48 +162,48 @@ /* This struct is used by the CDROMPLAYMSF ioctl */ struct cdrom_msf { - u_char cdmsf_min0; /* start minute */ - u_char cdmsf_sec0; /* start second */ - u_char cdmsf_frame0; /* start frame */ - u_char cdmsf_min1; /* end minute */ - u_char cdmsf_sec1; /* end second */ - u_char cdmsf_frame1; /* end frame */ + __u8 cdmsf_min0; /* start minute */ + __u8 cdmsf_sec0; /* start second */ + __u8 cdmsf_frame0; /* start frame */ + __u8 cdmsf_min1; /* end minute */ + __u8 cdmsf_sec1; /* end second */ + __u8 cdmsf_frame1; /* end frame */ }; /* This struct is used by the CDROMPLAYTRKIND ioctl */ struct cdrom_ti { - u_char cdti_trk0; /* start track */ - u_char cdti_ind0; /* start index */ - u_char cdti_trk1; /* end track */ - u_char cdti_ind1; /* end index */ + __u8 cdti_trk0; /* start track */ + __u8 cdti_ind0; /* start index */ + __u8 cdti_trk1; /* end track */ + __u8 cdti_ind1; /* end index */ }; /* This struct is used by the CDROMREADTOCHDR ioctl */ struct cdrom_tochdr { - u_char cdth_trk0; /* start track */ - u_char cdth_trk1; /* end track */ + __u8 cdth_trk0; /* start track */ + __u8 cdth_trk1; /* end track */ }; /* This struct is used by the CDROMVOLCTRL and CDROMVOLREAD ioctls */ struct cdrom_volctrl { - u_char channel0; - u_char channel1; - u_char channel2; - u_char channel3; + __u8 channel0; + __u8 channel1; + __u8 channel2; + __u8 channel3; }; /* This struct is used by the CDROMSUBCHNL ioctl */ struct cdrom_subchnl { - u_char cdsc_format; - u_char cdsc_audiostatus; - u_char cdsc_adr: 4; - u_char cdsc_ctrl: 4; - u_char cdsc_trk; - u_char cdsc_ind; + __u8 cdsc_format; + __u8 cdsc_audiostatus; + __u8 cdsc_adr: 4; + __u8 cdsc_ctrl: 4; + __u8 cdsc_trk; + __u8 cdsc_ind; union cdrom_addr cdsc_absaddr; union cdrom_addr cdsc_reladdr; }; @@ -212,12 +212,12 @@ /* This struct is used by the CDROMREADTOCENTRY ioctl */ struct cdrom_tocentry { - u_char cdte_track; - u_char cdte_adr :4; - u_char cdte_ctrl :4; - u_char cdte_format; + __u8 cdte_track; + __u8 cdte_adr :4; + __u8 cdte_ctrl :4; + __u8 cdte_format; union cdrom_addr cdte_addr; - u_char cdte_datamode; + __u8 cdte_datamode; }; /* This struct is used by the CDROMREADMODE1, and CDROMREADMODE2 ioctls */ @@ -232,9 +232,9 @@ struct cdrom_read_audio { union cdrom_addr addr; /* frame address */ - u_char addr_format; /* CDROM_LBA or CDROM_MSF */ + __u8 addr_format; /* CDROM_LBA or CDROM_MSF */ int nframes; /* number of 2352-byte-frames to read at once */ - u_char *buf; /* frame buffer (size: nframes*2352 bytes) */ + __u8 *buf; /* frame buffer (size: nframes*2352 bytes) */ }; /* This struct is used with the CDROMMULTISESSION ioctl */ @@ -243,8 +243,8 @@ union cdrom_addr addr; /* frame address: start-of-last-session (not the new "frame 16"!). Only valid if the "xa_flag" is true. */ - u_char xa_flag; /* 1: "is XA disk" */ - u_char addr_format; /* CDROM_LBA or CDROM_MSF */ + __u8 xa_flag; /* 1: "is XA disk" */ + __u8 addr_format; /* CDROM_LBA or CDROM_MSF */ }; /* This struct is used with the CDROM_GET_MCN ioctl. @@ -254,7 +254,7 @@ */ struct cdrom_mcn { - u_char medium_catalog_number[14]; /* 13 ASCII digits, null-terminated */ + __u8 medium_catalog_number[14]; /* 13 ASCII digits, null-terminated */ }; /* This is used by the CDROMPLAYBLK ioctl */ @@ -400,6 +400,14 @@ #define CDSL_NONE ((int) (~0U>>1)-1) #define CDSL_CURRENT ((int) (~0U>>1)) +/* For partition based multisession access. IDE can handle 64 partitions + * per drive - SCSI CD-ROM's use minors to differentiate between the + * various drives, so we can't do multisessions the same way there. + * Use the -o session=x option to mount on them. + */ +#define CD_PART_MAX 64 +#define CD_PART_MASK (CD_PART_MAX - 1) + /********************************************************************* * Generic Packet commands, MMC commands, and such *********************************************************************/ @@ -495,59 +503,59 @@ #define DVD_STRUCT_MANUFACT 0x04 struct dvd_layer { - u_char book_version : 4; - u_char book_type : 4; - u_char min_rate : 4; - u_char disc_size : 4; - u_char layer_type : 4; - u_char track_path : 1; - u_char nlayers : 2; - u_char track_density : 4; - u_char linear_density : 4; - u_char bca : 1; - u_char start_sector; - u_char end_sector; - u_char end_sector_l0; + __u8 book_version : 4; + __u8 book_type : 4; + __u8 min_rate : 4; + __u8 disc_size : 4; + __u8 layer_type : 4; + __u8 track_path : 1; + __u8 nlayers : 2; + __u8 track_density : 4; + __u8 linear_density : 4; + __u8 bca : 1; + __u8 start_sector; + __u8 end_sector; + __u8 end_sector_l0; }; struct dvd_physical { - u_char type; - u_char layer_num; + __u8 type; + __u8 layer_num; struct dvd_layer layer[4]; }; struct dvd_copyright { - u_char type; + __u8 type; - u_char layer_num; - u_char cpst; - u_char rmi; + __u8 layer_num; + __u8 cpst; + __u8 rmi; }; struct dvd_disckey { - u_char type; + __u8 type; unsigned agid : 2; - u_char value[2048]; + __u8 value[2048]; }; struct dvd_bca { - u_char type; + __u8 type; int len; - u_char value[188]; + __u8 value[188]; }; struct dvd_manufact { - u_char type; + __u8 type; - u_char layer_num; + __u8 layer_num; int len; - u_char value[2048]; + __u8 value[2048]; }; typedef union { - u_char type; + __u8 type; struct dvd_physical physical; struct dvd_copyright copyright; @@ -577,30 +585,30 @@ #define DVD_INVALIDATE_AGID 9 /* State data */ -typedef u_char dvd_key[5]; /* 40-bit value, MSB is first elem. */ -typedef u_char dvd_challenge[10]; /* 80-bit value, MSB is first elem. */ +typedef __u8 dvd_key[5]; /* 40-bit value, MSB is first elem. */ +typedef __u8 dvd_challenge[10]; /* 80-bit value, MSB is first elem. */ struct dvd_lu_send_agid { - u_char type; + __u8 type; unsigned agid : 2; }; struct dvd_host_send_challenge { - u_char type; + __u8 type; unsigned agid : 2; dvd_challenge chal; }; struct dvd_send_key { - u_char type; + __u8 type; unsigned agid : 2; dvd_key key; }; struct dvd_lu_send_challenge { - u_char type; + __u8 type; unsigned agid : 2; dvd_challenge chal; @@ -617,7 +625,7 @@ #define DVD_CGMS_RESTRICTED 3 struct dvd_lu_send_title_key { - u_char type; + __u8 type; unsigned agid : 2; dvd_key title_key; @@ -628,14 +636,14 @@ }; struct dvd_lu_send_asf { - u_char type; + __u8 type; unsigned agid : 2; unsigned asf : 1; }; typedef union { - u_char type; + __u8 type; struct dvd_lu_send_agid lsa; struct dvd_host_send_challenge hsc; @@ -658,11 +666,13 @@ int speed; /* maximum speed for reading data */ int capacity; /* number of discs in jukebox */ /* device-related storage */ - int options : 30; /* options flags */ - unsigned mc_flags : 2; /* media change buffer flags */ + int options : 30; /* options flags */ + unsigned mc_flags : 2; /* media change buffer flags */ int use_count; /* number of times device opened */ char name[20]; /* name of the device type */ - +/* per-device flags */ + __u8 sanyo_slot : 2; /* Sanyo 3 CD changer support */ + __u8 reserved : 6; /* not used yet */ }; struct cdrom_device_ops { @@ -699,6 +709,7 @@ extern int register_cdrom(struct cdrom_device_info *cdi); extern int unregister_cdrom(struct cdrom_device_info *cdi); + typedef struct { int data; int audio; @@ -706,9 +717,19 @@ int xa; long error; } tracktype; + extern void cdrom_count_tracks(struct cdrom_device_info *cdi,tracktype* tracks); extern int cdrom_get_next_writable(kdev_t dev, long *next_writable); extern int cdrom_get_last_written(kdev_t dev, long *last_written); +extern int cdrom_number_of_slots(struct cdrom_device_info *cdi); +extern int cdrom_select_disc(struct cdrom_device_info *cdi, int slot); +extern int cdrom_mode_select(struct cdrom_device_info *cdi, + struct cdrom_generic_command *cgc); +extern int cdrom_mode_sense(struct cdrom_device_info *cdi, + struct cdrom_generic_command *cgc, + int page_code, int page_control); +extern void init_cdrom_command(struct cdrom_generic_command *cgc, + void *buffer, int len); typedef struct { __u16 disc_information_length; @@ -795,6 +816,61 @@ __u32 track_size; __u32 last_rec_address; } track_information; + +/* The SCSI spec says there could be 256 slots. */ +#define CDROM_MAX_SLOTS 256 + +struct cdrom_mechstat_header { +#if defined(__BIG_ENDIAN_BITFIELD) + __u8 fault : 1; + __u8 changer_state : 2; + __u8 curslot : 5; + __u8 mech_state : 3; + __u8 door_open : 1; + __u8 reserved1 : 4; +#elif defined(__LITTLE_ENDIAN_BITFIELD) + __u8 curslot : 5; + __u8 changer_state : 2; + __u8 fault : 1; + __u8 reserved1 : 4; + __u8 door_open : 1; + __u8 mech_state : 3; +#else +#error "Please fix " +#endif + __u8 curlba[3]; + __u8 nslots; + __u8 short slot_tablelen; +}; + + +struct cdrom_slot { +#if defined(__BIG_ENDIAN_BITFIELD) + __u8 disc_present : 1; + __u8 reserved1 : 6; + __u8 change : 1; +#elif defined(__LITTLE_ENDIAN_BITFIELD) + __u8 change : 1; + __u8 reserved1 : 6; + __u8 disc_present : 1; +#else +#error "Please fix " +#endif + __u8 reserved2[3]; +}; + +struct cdrom_changer_info { + struct cdrom_mechstat_header hdr; + struct cdrom_slot slots[CDROM_MAX_SLOTS]; +}; + +typedef enum { + mechtype_caddy = 0, + mechtype_tray = 1, + mechtype_popup = 2, + mechtype_individual_changer = 4, + mechtype_cartridge_changer = 5 +} mechtype_t; #endif /* End of kernel only stuff */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/console.h linux.ac/include/linux/console.h --- linux.vanilla/include/linux/console.h Thu Feb 25 18:02:12 1999 +++ linux.ac/include/linux/console.h Thu Sep 2 16:51:05 1999 @@ -51,6 +51,7 @@ extern struct consw dummy_con; /* dummy console buffer */ extern struct consw fb_con; /* frame buffer based console */ extern struct consw vga_con; /* VGA text console */ +extern struct consw newport_con; /* SGI Newport console */ extern struct consw prom_con; /* SPARC PROM console */ void take_over_console(struct consw *sw, int first, int last, int deflt); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/dcache_func.h linux.ac/include/linux/dcache_func.h --- linux.vanilla/include/linux/dcache_func.h Thu Jan 1 01:00:00 1970 +++ linux.ac/include/linux/dcache_func.h Tue Sep 14 22:01:41 1999 @@ -0,0 +1,91 @@ +#ifndef __LINUX_DCACHE_FUNC_H +#define __LINUX_DCACHE_FUNC_H + +/* + * Common dentry functions for inclusion in the VFS + * or in other stackable file systems. Some of these + * functions were in linux/fs/ C (VFS) files. + */ +#ifdef __KERNEL__ +#include +#include + +/* + * We need to do a check-parent every time + * after we have locked the parent - to verify + * that the parent is still our parent and + * that we are still hashed onto it.. + * + * This is required in case two processes race + * on removing (or moving) the same entry: the + * parent lock will serialize them, but the + * other process will be too late.. + */ +#define check_parent(dir, dentry) \ + ((dir) == (dentry)->d_parent && !list_empty(&dentry->d_hash)) + +/* + * Locking the parent is needed to: + * - serialize directory operations + * - make sure the parent doesn't change from + * under us in the middle of an operation. + * + * NOTE! Right now we'd rather use a "struct inode" + * for this, but as I expect things to move toward + * using dentries instead for most things it is + * probably better to start with the conceptually + * better interface of relying on a path of dentries. + */ +static inline struct dentry *lock_parent(struct dentry *dentry) +{ + struct dentry *dir = dget(dentry->d_parent); + + down(&dir->d_inode->i_sem); + return dir; +} + +static inline struct dentry *get_parent(struct dentry *dentry) +{ + return dget(dentry->d_parent); +} + +static inline void unlock_dir(struct dentry *dir) +{ + up(&dir->d_inode->i_sem); + dput(dir); +} + +/* + * Whee.. Deadlock country. Happily there are only two VFS + * operations that does this.. + */ +static inline void double_lock(struct dentry *d1, struct dentry *d2) +{ + struct semaphore *s1 = &d1->d_inode->i_sem; + struct semaphore *s2 = &d2->d_inode->i_sem; + + if (s1 != s2) { + if ((unsigned long) s1 < (unsigned long) s2) { + struct semaphore *tmp = s2; + s2 = s1; s1 = tmp; + } + down(s1); + } + down(s2); +} + +static inline void double_unlock(struct dentry *d1, struct dentry *d2) +{ + struct semaphore *s1 = &d1->d_inode->i_sem; + struct semaphore *s2 = &d2->d_inode->i_sem; + + up(s1); + if (s1 != s2) + up(s2); + dput(d1); + dput(d2); +} + +#endif /* __KERNEL__ */ + +#endif /* __LINUX_DCACHE_FUNC_H */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/dmaram.h linux.ac/include/linux/dmaram.h --- linux.vanilla/include/linux/dmaram.h Thu Jan 1 01:00:00 1970 +++ linux.ac/include/linux/dmaram.h Thu Sep 2 16:51:06 1999 @@ -0,0 +1,13 @@ +#ifndef __LINUX_DMARAM_H +#define __LINUX_DMARAM_H + +struct dma_info +{ + unsigned long size; + unsigned long phys; +}; + +#define DMAIOCSET _IOR('D',1,long) +#define DMAIOCGET _IOW('D',2,struct dma_info) + +#endif \ No newline at end of file diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/elf.h linux.ac/include/linux/elf.h --- linux.vanilla/include/linux/elf.h Thu Sep 2 00:48:46 1999 +++ linux.ac/include/linux/elf.h Sat Sep 11 01:48:33 1999 @@ -29,6 +29,13 @@ #define PT_PHDR 6 #define PT_LOPROC 0x70000000 #define PT_HIPROC 0x7fffffff +#define PT_MIPS_REGINFO 0x70000000 + +/* Flags in the e_flags field of the header */ +#define EF_MIPS_NOREORDER 0x00000001 +#define EF_MIPS_PIC 0x00000002 +#define EF_MIPS_CPIC 0x00000004 +#define EF_MIPS_ARCH 0xf0000000 /* These constants define the different elf file types */ #define ET_NONE 0 @@ -36,8 +43,8 @@ #define ET_EXEC 2 #define ET_DYN 3 #define ET_CORE 4 -#define ET_LOPROC 5 -#define ET_HIPROC 6 +#define ET_LOPROC 0xff00 +#define ET_HIPROC 0xffff /* These constants define the various ELF target machines */ #define EM_NONE 0 @@ -99,6 +106,25 @@ #define DT_JMPREL 23 #define DT_LOPROC 0x70000000 #define DT_HIPROC 0x7fffffff +#define DT_MIPS_RLD_VERSION 0x70000001 +#define DT_MIPS_TIME_STAMP 0x70000002 +#define DT_MIPS_ICHECKSUM 0x70000003 +#define DT_MIPS_IVERSION 0x70000004 +#define DT_MIPS_FLAGS 0x70000005 + #define RHF_NONE 0 + #define RHF_HARDWAY 1 + #define RHF_NOTPOT 2 +#define DT_MIPS_BASE_ADDRESS 0x70000006 +#define DT_MIPS_CONFLICT 0x70000008 +#define DT_MIPS_LIBLIST 0x70000009 +#define DT_MIPS_LOCAL_GOTNO 0x7000000a +#define DT_MIPS_CONFLICTNO 0x7000000b +#define DT_MIPS_LIBLISTNO 0x70000010 +#define DT_MIPS_SYMTABNO 0x70000011 +#define DT_MIPS_UNREFEXTNO 0x70000012 +#define DT_MIPS_GOTSYM 0x70000013 +#define DT_MIPS_HIPAGENO 0x70000014 +#define DT_MIPS_RLD_MAP 0x70000016 /* This info is needed when parsing the symbol table */ #define STB_LOCAL 0 @@ -167,6 +193,55 @@ #define R_386_GOTPC 10 #define R_386_NUM 11 +#define R_MIPS_NONE 0 +#define R_MIPS_16 1 +#define R_MIPS_32 2 +#define R_MIPS_REL32 3 +#define R_MIPS_26 4 +#define R_MIPS_HI16 5 +#define R_MIPS_LO16 6 +#define R_MIPS_GPREL16 7 +#define R_MIPS_LITERAL 8 +#define R_MIPS_GOT16 9 +#define R_MIPS_PC16 10 +#define R_MIPS_CALL16 11 +#define R_MIPS_GPREL32 12 +/* The remaining relocs are defined on Irix, although they are not + in the MIPS ELF ABI. */ +#define R_MIPS_UNUSED1 13 +#define R_MIPS_UNUSED2 14 +#define R_MIPS_UNUSED3 15 +#define R_MIPS_SHIFT5 16 +#define R_MIPS_SHIFT6 17 +#define R_MIPS_64 18 +#define R_MIPS_GOT_DISP 19 +#define R_MIPS_GOT_PAGE 20 +#define R_MIPS_GOT_OFST 21 +/* + * The following two relocation types are specified in the the MIPS ABI + * conformance guide version 1.2 but not yet in the psABI. + */ +#define R_MIPS_GOTHI16 22 +#define R_MIPS_GOTLO16 23 +#define R_MIPS_SUB 24 +#define R_MIPS_INSERT_A 25 +#define R_MIPS_INSERT_B 26 +#define R_MIPS_DELETE 27 +#define R_MIPS_HIGHER 28 +#define R_MIPS_HIGHEST 29 +/* + * The following two relocation types are specified in the the MIPS ABI + * conformance guide version 1.2 but not yet in the psABI. + */ +#define R_MIPS_CALLHI16 30 +#define R_MIPS_CALLLO16 31 +/* + * This range is reserved for vendor specific relocations. + */ +#define R_MIPS_LOVENDOR 100 +#define R_MIPS_HIVENDOR 127 + + /* * Sparc ELF relocation types */ @@ -404,12 +479,17 @@ #define SHT_HIPROC 0x7fffffff #define SHT_LOUSER 0x80000000 #define SHT_HIUSER 0xffffffff +#define SHT_MIPS_LIST 0x70000000 +#define SHT_MIPS_CONFLICT 0x70000002 +#define SHT_MIPS_GPTAB 0x70000003 +#define SHT_MIPS_UCODE 0x70000004 /* sh_flags */ #define SHF_WRITE 0x1 #define SHF_ALLOC 0x2 #define SHF_EXECINSTR 0x4 #define SHF_MASKPROC 0xf0000000 +#define SHF_MIPS_GPREL 0x10000000 /* special section indexes */ #define SHN_UNDEF 0 @@ -419,6 +499,7 @@ #define SHN_ABS 0xfff1 #define SHN_COMMON 0xfff2 #define SHN_HIRESERVE 0xffff +#define SHN_MIPS_ACCOMON 0xff00 typedef struct { Elf32_Word sh_name; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/fs.h linux.ac/include/linux/fs.h --- linux.vanilla/include/linux/fs.h Tue Sep 7 22:07:13 1999 +++ linux.ac/include/linux/fs.h Tue Sep 14 21:58:56 1999 @@ -724,7 +724,7 @@ #define __getname() ((char *) __get_free_page(GFP_KERNEL)) #define putname(name) free_page((unsigned long)(name)) -extern void kill_fasync(struct fasync_struct *, int); +extern void kill_fasync(struct fasync_struct *, int, int); extern int register_blkdev(unsigned int, const char *, struct file_operations *); extern int unregister_blkdev(unsigned int, const char *); extern int blkdev_open(struct inode *, struct file *); @@ -913,7 +913,7 @@ extern struct buffer_head * bread(kdev_t, int, int); extern struct buffer_head * breada(kdev_t, int, int, unsigned int, unsigned int); -extern int brw_page(int, struct page *, kdev_t, int [], int, int); +extern int brw_page(int, struct page *, kdev_t, int [], int); typedef int (*writepage_t)(struct file *, struct page *, unsigned long, unsigned long, const char *); @@ -928,6 +928,7 @@ extern ssize_t generic_file_read(struct file *, char *, size_t, loff_t *); extern ssize_t generic_file_write(struct file *, const char *, size_t, loff_t *, writepage_t); extern void do_generic_file_read(struct file * filp, loff_t *ppos, read_descriptor_t * desc, read_actor_t actor); +extern loff_t default_llseek(struct file *file, loff_t offset, int origin); extern struct super_block *get_super(kdev_t); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/genhd.h linux.ac/include/linux/genhd.h --- linux.vanilla/include/linux/genhd.h Mon Aug 23 15:12:17 1999 +++ linux.ac/include/linux/genhd.h Mon Sep 13 00:42:42 1999 @@ -11,6 +11,7 @@ #include #include +#include /* These three have identical behaviour; use the second one if DOS fdisk gets confused about extended/logical partitions starting past cylinder 1023. */ @@ -18,7 +19,9 @@ #define LINUX_EXTENDED_PARTITION 0x85 #define WIN98_EXTENDED_PARTITION 0x0f -#define LINUX_SWAP_PARTITION 0x82 +#define LINUX_SWAP_PARTITION 0x82 +#define LINUX_RAID_PARTITION 0xfd /* autodetect RAID partition */ +#define LINUX_OLD_RAID_PARTITION 0x86 #ifdef CONFIG_SOLARIS_X86_PARTITION #define SOLARIS_X86_PARTITION LINUX_SWAP_PARTITION @@ -29,6 +32,7 @@ #define DM6_AUX1PARTITION 0x51 /* no DDO: use xlated geom */ #define DM6_AUX3PARTITION 0x53 /* no DDO: use xlated geom */ + struct partition { unsigned char boot_ind; /* 0x80 - active */ unsigned char head; /* starting head */ @@ -45,7 +49,31 @@ struct hd_struct { long start_sect; long nr_sects; + int type; /* RAID or normal */ }; + +/* + * partition types Linux cares about. + * + * currently there are 'normal' and RAID types. + */ + +static inline unsigned int ptype (unsigned char raw_type) +{ + switch (raw_type) { + case LINUX_OLD_RAID_PARTITION: + return LINUX_OLD_RAID_PARTITION; + case LINUX_RAID_PARTITION: + return LINUX_RAID_PARTITION; + default: + } + return 0; +} + +/* + * the maximum length a given partition name can take (eg. "scd11") + */ +#define MAX_DISKNAME_LEN 32 struct gendisk { int major; /* major number of driver */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/i2c.h linux.ac/include/linux/i2c.h --- linux.vanilla/include/linux/i2c.h Thu Aug 5 19:11:40 1999 +++ linux.ac/include/linux/i2c.h Mon Sep 20 20:53:47 1999 @@ -41,6 +41,8 @@ #define I2C_BUSID_BT848 1 /* I2C bus on a BT848 */ #define I2C_BUSID_PARPORT 2 /* Bit banging on a parallel port */ #define I2C_BUSID_BUZ 3 +#define I2C_BUSID_ZORAN 4 + /* * struct for a driver for a i2c chip (tuner, soundprocessor, * videotext, ... ). diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/iobuf.h linux.ac/include/linux/iobuf.h --- linux.vanilla/include/linux/iobuf.h Thu Aug 5 20:30:24 1999 +++ linux.ac/include/linux/iobuf.h Sat Sep 18 01:36:52 1999 @@ -75,6 +75,6 @@ /* fs/buffer.c */ int brw_kiovec(int rw, int nr, struct kiobuf *iovec[], - kdev_t dev, unsigned long b[], int size, int bmap); + kdev_t dev, unsigned long b[], int size); #endif /* __LINUX_IOBUF_H */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/lp.h linux.ac/include/linux/lp.h --- linux.vanilla/include/linux/lp.h Thu Aug 5 19:11:40 1999 +++ linux.ac/include/linux/lp.h Sat Sep 18 01:44:16 1999 @@ -5,6 +5,7 @@ * usr/include/linux/lp.h c.1991-1992 James Wiegand * many modifications copyright (C) 1992 Michael K. Johnson * Interrupt support added 1993 Nigel Gamble + * Removed 8255 status defines from inside __KERNEL__ Marcelo Tosatti */ /* @@ -28,6 +29,17 @@ #define LP_HAVE_PORT_BIT 12 /* (0x1000) Port is claimed. */ #define LP_PORT_BUSY (1<<13) /* Reading or writing. */ +/* + * bit defines for 8255 status port + * base + 1 + * accessed with LP_S(minor), which gets the byte... + */ +#define LP_PBUSY 0x80 /* inverted input, active high */ +#define LP_PACK 0x40 /* unchanged input, active low */ +#define LP_POUTPA 0x20 /* unchanged input, active high */ +#define LP_PSELECD 0x10 /* unchanged input, active high */ +#define LP_PERRORP 0x08 /* unchanged input, active low */ + /* timeout for each character. This is relative to bus cycles -- it * is the count in a busy loop. THIS IS THE VALUE TO CHANGE if you * have extremely slow printing, or if the machine seems to slow down @@ -143,16 +155,6 @@ * gets inverted, but it is also active low. */ -/* - * bit defines for 8255 status port - * base + 1 - * accessed with LP_S(minor), which gets the byte... - */ -#define LP_PBUSY 0x80 /* inverted input, active high */ -#define LP_PACK 0x40 /* unchanged input, active low */ -#define LP_POUTPA 0x20 /* unchanged input, active high */ -#define LP_PSELECD 0x10 /* unchanged input, active high */ -#define LP_PERRORP 0x08 /* unchanged input, active low */ /* * defines for 8255 control port diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/mm.h linux.ac/include/linux/mm.h --- linux.vanilla/include/linux/mm.h Tue Sep 7 22:07:13 1999 +++ linux.ac/include/linux/mm.h Thu Sep 16 16:56:44 1999 @@ -349,6 +349,14 @@ extern void truncate_inode_pages(struct inode *, unsigned long); extern unsigned long get_cached_page(struct inode *, unsigned long, int); extern void put_cached_page(unsigned long); +/* generic vm_area_ops exported for stackable file systems */ +extern int filemap_swapout(struct vm_area_struct * vma, struct page * page); +extern pte_t filemap_swapin(struct vm_area_struct * vma, + unsigned long offset, unsigned long entry); +extern int filemap_sync(struct vm_area_struct * vma, unsigned long address, + size_t size, unsigned int flags); +extern unsigned long filemap_nopage(struct vm_area_struct * area, + unsigned long address, int no_share); /* * GFP bitmasks.. @@ -393,10 +401,11 @@ address &= PAGE_MASK; grow = vma->vm_start - address; - if (vma->vm_end - address - > (unsigned long) current->rlim[RLIMIT_STACK].rlim_cur || - (vma->vm_mm->total_vm << PAGE_SHIFT) + grow - > (unsigned long) current->rlim[RLIMIT_AS].rlim_cur) + if ((vma->vm_end - address + > current->rlim[RLIMIT_STACK].rlim_cur) || + ((current->rlim[RLIMIT_AS].rlim_cur < RLIM_INFINITY) && + ((vma->vm_mm->total_vm << PAGE_SHIFT) + grow + > current->rlim[RLIMIT_AS].rlim_cur))) return -ENOMEM; vma->vm_start = address; vma->vm_offset -= grow; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/module.h linux.ac/include/linux/module.h --- linux.vanilla/include/linux/module.h Tue Aug 17 17:27:42 1999 +++ linux.ac/include/linux/module.h Mon Sep 20 20:53:07 1999 @@ -8,6 +8,7 @@ #define _LINUX_MODULE_H #include +#include #ifdef __GENKSYMS__ # define _set_ver(sym) sym @@ -207,11 +208,17 @@ #endif #else /* MODULE */ - +extern int parse_parameters(void *var, char *type, char *str); #define MODULE_AUTHOR(name) #define MODULE_DESCRIPTION(desc) #define MODULE_SUPPORTED_DEVICE(name) -#define MODULE_PARM(var,type) +#define MODULE_PARM(var,type) \ +static char *modparm##var##_setup_type __initdata = type;\ +static int __init modparm##var##_setup(char *str)\ +{\ + return parse_parameters((void *)&var, modparm##var##_setup_type, str);\ +}\ +__setup(MODULE_NAME #var "=", modparm##var##_setup); #define MODULE_PARM_DESC(var,desc) #ifndef __GENKSYMS__ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/net.h linux.ac/include/linux/net.h --- linux.vanilla/include/linux/net.h Thu Aug 26 14:42:19 1999 +++ linux.ac/include/linux/net.h Tue Sep 14 21:58:56 1999 @@ -126,7 +126,7 @@ void (*init_func)(struct net_proto *); /* Bootstrap */ }; -extern int sock_wake_async(struct socket *sk, int how); +extern int sock_wake_async(struct socket *sk, int how, int band); extern int sock_register(struct net_proto_family *fam); extern int sock_unregister(int family); extern struct socket *sock_alloc(void); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/pagemap.h linux.ac/include/linux/pagemap.h --- linux.vanilla/include/linux/pagemap.h Tue Sep 7 22:07:13 1999 +++ linux.ac/include/linux/pagemap.h Thu Sep 16 16:56:44 1999 @@ -103,7 +103,6 @@ static inline void wait_on_page(struct page * page) { - if (PageLocked(page)) ___wait_on_page(page); } diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/pc_keyb.h linux.ac/include/linux/pc_keyb.h --- linux.vanilla/include/linux/pc_keyb.h Thu Jan 1 01:00:00 1970 +++ linux.ac/include/linux/pc_keyb.h Thu Sep 2 16:51:06 1999 @@ -0,0 +1,130 @@ +/* + * include/linux/pc_keyb.h + * + * PC Keyboard And Keyboard Controller + * + * (c) 1997 Martin Mares + */ + +/* + * Configuration Switches + */ + +#undef KBD_REPORT_ERR /* Report keyboard errors */ +#define KBD_REPORT_UNKN /* Report unknown scan codes */ +#define KBD_REPORT_TIMEOUTS /* Report keyboard timeouts */ +#undef KBD_IS_FOCUS_9000 /* We have the brain-damaged FOCUS-9000 keyboard */ +#undef INITIALIZE_MOUSE /* Define if your PS/2 mouse needs initialization. */ + + + +#define KBD_INIT_TIMEOUT 1000 /* Timeout in ms for initializing the keyboard */ +#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */ +#define KBD_TIMEOUT 1000 /* Timeout in ms for keyboard command acknowledge */ + +/* + * Internal variables of the driver + */ + +extern unsigned char pckbd_read_mask; +extern unsigned char aux_device_present; + +/* + * Keyboard Controller Registers on normal PCs. + */ + +#define KBD_STATUS_REG 0x64 /* Status register (R) */ +#define KBD_CNTL_REG 0x64 /* Controller command register (W) */ +#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */ + +/* + * Keyboard Controller Commands + */ + +#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */ +#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */ +#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */ +#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */ +#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */ +#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */ +#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */ +#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */ +#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */ +#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */ +#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if + initiated by the auxiliary device */ +#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */ + +/* + * Keyboard Commands + */ + +#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */ +#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */ +#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */ +#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */ +#define KBD_CMD_RESET 0xFF /* Reset */ + +/* + * Keyboard Replies + */ + +#define KBD_REPLY_POR 0xAA /* Power on reset */ +#define KBD_REPLY_ACK 0xFA /* Command ACK */ +#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */ + +/* + * Status Register Bits + */ + +#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */ +#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */ +#define KBD_STAT_SELFTEST 0x04 /* Self test successful */ +#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */ +#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */ +#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */ +#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */ +#define KBD_STAT_PERR 0x80 /* Parity error */ + +#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF) + +/* + * Controller Mode Register Bits + */ + +#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */ +#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */ +#define KBD_MODE_SYS 0x04 /* The system flag (?) */ +#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */ +#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */ +#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */ +#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */ +#define KBD_MODE_RFU 0x80 + +/* + * Mouse Commands + */ + +#define AUX_SET_RES 0xE8 /* Set resolution */ +#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */ +#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */ +#define AUX_GET_SCALE 0xE9 /* Get scaling factor */ +#define AUX_SET_STREAM 0xEA /* Set stream mode */ +#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */ +#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */ +#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */ +#define AUX_RESET 0xFF /* Reset aux device */ +#define AUX_ACK 0xFA /* Command byte ACK. */ + +#define AUX_BUF_SIZE 2048 /* This might be better divisible by + three to make overruns stay in sync + but then the read function would need + a lock etc - ick */ + +struct aux_queue { + unsigned long head; + unsigned long tail; + wait_queue_head_t proc_list; + struct fasync_struct *fasync; + unsigned char buf[AUX_BUF_SIZE]; +}; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/pci.h linux.ac/include/linux/pci.h --- linux.vanilla/include/linux/pci.h Sat Sep 11 00:54:17 1999 +++ linux.ac/include/linux/pci.h Tue Sep 14 21:30:53 1999 @@ -1179,8 +1179,8 @@ #define PCI_VENDOR_ID_LAVA 0x1407 #define PCI_DEVICE_ID_LAVA_PARALLEL 0x8000 -#define PCI_DEVICE_ID_LAVA_DUAL_PAR_A 0x8001 /* The Lava Dual Parallel is */ -#define PCI_DEVICE_ID_LAVA_DUAL_PAR_B 0x8002 /* two PCI devices on a card */ +#define PCI_DEVICE_ID_LAVA_DUAL_PAR_A 0x8002 /* The Lava Dual Parallel is */ +#define PCI_DEVICE_ID_LAVA_DUAL_PAR_B 0x8003 /* two PCI devices on a card */ #define PCI_VENDOR_ID_PANACOM 0x14d4 #define PCI_DEVICE_ID_PANACOM_QUADMODEM 0x0400 diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/pci_scan.h linux.ac/include/linux/pci_scan.h --- linux.vanilla/include/linux/pci_scan.h Thu Jan 1 01:00:00 1970 +++ linux.ac/include/linux/pci_scan.h Mon Sep 20 17:04:56 1999 @@ -0,0 +1,100 @@ +#ifndef __PCI_SCAN_H__ +#define __PCI_SCAN_H__ + +#include + + + +/* + version 0.04 $Date: 1999/08/31 16:05:30 $ + Copyright 1999 Donald Becker / Scyld Computing Corporation + This software is part of the Linux kernel. It may be used and + distributed according to the terms of the GNU Public License, + incorporated herein by reference. +*/ + +/* + These are the structures in the table that drives the PCI probe routines. + Note the matching code uses a bitmask: more specific table entries should + be placed before "catch-all" entries. + + The table must be zero terminated. +*/ +enum pci_id_flags_bits { + /* Set PCI command register bits before calling probe1(). */ + PCI_USES_IO = PCI_COMMAND_IO, + PCI_USES_MEM = PCI_COMMAND_MEMORY, + PCI_USES_MASTER = PCI_COMMAND_MASTER, + + /* Read and map the single following PCI BAR. */ + PCI_ADDR0 = 0<<4, + PCI_ADDR1 = 1<<4, + PCI_ADDR2 = 2<<4, + PCI_ADDR3 = 3<<4, + PCI_ADDR_64BITS = 0x100, + PCI_NO_ACPI_WAKE = 0x200, + PCI_NO_MIN_LATENCY = 0x400, +}; + +struct pci_id_info { + const char *name; + struct match_info { + int pci, pci_mask, subsystem, subsystem_mask; + int revision, revision_mask; /* Only 8 bits. */ + } id; + enum pci_id_flags_bits pci_flags; + int io_size; /* Needed for I/O region check or ioremap(). */ + int drv_flags; /* Driver use, intended as capability flags. */ +}; + +enum drv_id_flags { + PCI_HOTSWAP=1, /* Leave module loaded for Cardbus-like chips. */ +}; +enum drv_pwr_action { + DRV_NOOP, DRV_SUSPEND, DRV_RESUME, DRV_DETACH, DRV_PWRDOWN }; + +struct drv_id_info { + const char *name; /* Single-word driver name. */ + int flags; + int pci_class; /* Typically PCI_CLASS_NETWORK_ETHERNET<<8. */ + struct pci_id_info *pci_dev_tbl; + void *(*probe1)(struct pci_dev *pdev, void *dev_ptr, + long ioaddr, int irq, int table_idx, int fnd_cnt); + /* Optional, called for suspend, resume and detach. */ + int (*pwr_event)(void *dev, int event); +#if 0 + /* Internal values. */ + struct drv_id_info *next; + void *cb_ops; +#endif +}; + +/* PCI scan and activate. + Scan PCI-like hardware, calling probe1(..,dev,..) on devices that match. + Returns -ENODEV, a negative number, if no cards are found. */ + +extern int pci_drv_register(struct drv_id_info *drv_id, void *initial_device); +extern void pci_drv_unregister(struct drv_id_info *drv_id); + + +/* ACPI routines. + Wake (change to ACPI D0 state) or set the ACPI power level of a sleeping + ACPI device. Returns the old power state. */ + +extern int acpi_wake(struct pci_dev *pdev); +enum acpi_pwr_state {ACPI_D0, ACPI_D1, ACPI_D2, ACPI_D3}; +extern int acpi_set_pwr_state(struct pci_dev *pdev, enum acpi_pwr_state state); + +extern int (*register_cb_hook)(struct drv_id_info *did); +extern void (*unregister_cb_hook)(struct drv_id_info *did); + + +/* + * Local variables: + * c-indent-level: 4 + * c-basic-offset: 4 + * tab-width: 4 + * End: + */ +#endif /* __PCI_SCAN_H__ */ + diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/prctl.h linux.ac/include/linux/prctl.h --- linux.vanilla/include/linux/prctl.h Thu Aug 26 14:42:19 1999 +++ linux.ac/include/linux/prctl.h Thu Sep 2 16:51:06 1999 @@ -6,5 +6,8 @@ #define PR_SET_PDEATHSIG 1 /* Second arg is a signal */ #define PR_GET_PDEATHSIG 2 /* Second arg is a ptr to return the signal */ +/* Get/set current->dumpable */ +#define PR_GET_DUMPABLE 3 +#define PR_SET_DUMPABLE 4 #endif /* _LINUX_PRCTL_H */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/resource.h linux.ac/include/linux/resource.h --- linux.vanilla/include/linux/resource.h Mon Dec 28 06:18:28 1998 +++ linux.ac/include/linux/resource.h Mon Sep 6 16:57:05 1999 @@ -38,10 +38,14 @@ }; #define RLIM_INFINITY ((long)(~0UL>>1)) +#define RLIM_SAVED_CUR RLIM_INFINITY +#define RLIM_SAVED_MAX RLIM_INFINITY + +typedef unsigned long rlim_t; struct rlimit { - long rlim_cur; - long rlim_max; + rlim_t rlim_cur; + rlim_t rlim_max; }; #define PRIO_MIN (-20) diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/sched.h linux.ac/include/linux/sched.h --- linux.vanilla/include/linux/sched.h Sat Sep 11 00:54:17 1999 +++ linux.ac/include/linux/sched.h Thu Sep 16 16:56:44 1999 @@ -646,6 +646,10 @@ /* Remove the current tasks stale references to the old mm_struct */ extern void mm_release(void); +/* flush all the user space tied resources of a thread */ + +extern void daemonize(void); + /* * Routines for handling the fd arrays */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/socket.h linux.ac/include/linux/socket.h --- linux.vanilla/include/linux/socket.h Sat Sep 11 00:54:17 1999 +++ linux.ac/include/linux/socket.h Fri Sep 10 17:56:17 1999 @@ -128,18 +128,6 @@ __u32 gid; }; -/* Socket types. */ - -#define SOCK_STREAM 1 /* stream (connection) socket */ -#define SOCK_DGRAM 2 /* datagram (conn.less) socket */ -#define SOCK_RAW 3 /* raw socket */ -#define SOCK_RDM 4 /* reliably-delivered message */ -#define SOCK_SEQPACKET 5 /* sequential packet socket */ -#define SOCK_PACKET 10 /* linux specific way of */ - /* getting packets at the dev */ - /* level. For writing rarp and */ - /* other similar things on the */ - /* user level. */ /* Supported address families. */ #define AF_UNSPEC 0 diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/synclink.h linux.ac/include/linux/synclink.h --- linux.vanilla/include/linux/synclink.h Mon Jul 5 22:33:39 1999 +++ linux.ac/include/linux/synclink.h Tue Sep 14 20:50:01 1999 @@ -1,7 +1,7 @@ /* * SyncLink Multiprotocol Serial Adapter Driver * - * ==FILEDATE 19990523== + * ==FILEDATE 19990810== * * Copyright (C) 1998 by Microgate Corporation * @@ -50,8 +50,9 @@ #define BIT31 0x80000000 -#define HDLC_MAX_FRAME_SIZE 4096 +#define HDLC_MAX_FRAME_SIZE 65535 #define MAX_ASYNC_TRANSMIT 4096 +#define MAX_ASYNC_BUFFER_SIZE 4096 #define ASYNC_PARITY_NONE 0 #define ASYNC_PARITY_EVEN 1 @@ -68,12 +69,12 @@ #define HDLC_FLAG_AUTO_RTS 0x0080 #define HDLC_FLAG_RXC_DPLL 0x0100 #define HDLC_FLAG_RXC_BRG 0x0200 -#define HDLC_FLAG_RXC_TXCPIN 0x8000 -#define HDLC_FLAG_RXC_RXCPIN 0x0000 +#define HDLC_FLAG_RXC_TXCPIN 0x8000 +#define HDLC_FLAG_RXC_RXCPIN 0x0000 #define HDLC_FLAG_TXC_DPLL 0x0400 #define HDLC_FLAG_TXC_BRG 0x0800 -#define HDLC_FLAG_TXC_TXCPIN 0x0000 -#define HDLC_FLAG_TXC_RXCPIN 0x0008 +#define HDLC_FLAG_TXC_TXCPIN 0x0000 +#define HDLC_FLAG_TXC_RXCPIN 0x0008 #define HDLC_FLAG_DPLL_DIV8 0x1000 #define HDLC_FLAG_DPLL_DIV16 0x2000 #define HDLC_FLAG_DPLL_DIV32 0x0000 @@ -81,6 +82,7 @@ #define HDLC_CRC_NONE 0 #define HDLC_CRC_16_CCITT 1 +#define HDLC_CRC_32_CCITT 2 #define HDLC_TXIDLE_FLAGS 0 #define HDLC_TXIDLE_ALT_ZEROS_ONES 1 @@ -132,7 +134,7 @@ unsigned char encoding; /* NRZ, NRZI, etc. */ unsigned long clock_speed; /* external clock speed in bits per second */ unsigned char addr_filter; /* receive HDLC address filter, 0xFF = disable */ - unsigned short crc_type; /* None, CRC16 or CRC16-CCITT */ + unsigned short crc_type; /* None, CRC16-CCITT, or CRC32-CCITT */ unsigned char preamble_length; unsigned char preamble; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/sysctl.h linux.ac/include/linux/sysctl.h --- linux.vanilla/include/linux/sysctl.h Sat Sep 11 00:54:17 1999 +++ linux.ac/include/linux/sysctl.h Thu Sep 16 00:05:37 1999 @@ -103,7 +103,8 @@ KERN_MSGPOOL=37, /* int: Maximum system message pool size */ KERN_SYSRQ=38, /* int: Sysreq enable */ KERN_MAX_THREADS=39, /* int: Maximum nr of threads in the system */ - KERN_RANDOM=40 /* Random driver */ + KERN_RANDOM=40, /* Random driver */ + KERN_SHMALL=41 /* int: Maximum size of shared memory */ }; @@ -629,7 +630,7 @@ int ctl_name; /* Binary ID */ const char *procname; /* Text ID for /proc/sys, or zero */ void *data; - int maxlen; + size_t maxlen; mode_t mode; ctl_table *child; proc_handler *proc_handler; /* Callback for text formatting */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/tty.h linux.ac/include/linux/tty.h --- linux.vanilla/include/linux/tty.h Tue Sep 7 22:07:13 1999 +++ linux.ac/include/linux/tty.h Tue Sep 14 21:58:56 1999 @@ -118,6 +118,9 @@ #define VIDEO_TYPE_PMAC 0x60 /* PowerMacintosh frame buffer. */ +#define VIDEO_TYPE_SGI 0x70 /* Various SGI graphics hardware */ +#define VIDEO_TYPE_MIPS_G364 0x71 /* MIPS Magnum 4000 G364 video */ + /* * This character is the same as _POSIX_VDISABLE: it cannot be used as * a c_cc[] character, but indicates that a particular special character @@ -326,6 +329,7 @@ #define TTY_HW_COOK_OUT 14 #define TTY_HW_COOK_IN 15 #define TTY_PTY_LOCK 16 +#define TTY_NO_WRITE_SPLIT 17 #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/linux/videodev.h linux.ac/include/linux/videodev.h --- linux.vanilla/include/linux/videodev.h Thu Aug 5 19:11:40 1999 +++ linux.ac/include/linux/videodev.h Mon Sep 20 20:53:47 1999 @@ -278,8 +278,9 @@ #define VID_HARDWARE_TYPHOON 19 #define VID_HARDWARE_VINO 20 /* Reserved for SGI Indy Vino */ #define VID_HARDWARE_CADET 21 /* Cadet radio */ -#define VID_HARDWARE_CPIA 22 +#define VID_HARDWARE_TRUST 22 /* Trust FM Radio */ #define VID_HARDWARE_TERRATEC 23 /* TerraTec ActiveRadio */ +#define VID_HARDWARE_CPIA 24 /* * Initialiser list diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/net/ip.h linux.ac/include/net/ip.h --- linux.vanilla/include/net/ip.h Thu Aug 26 14:42:20 1999 +++ linux.ac/include/net/ip.h Mon Sep 20 20:10:52 1999 @@ -137,6 +137,7 @@ extern int sysctl_local_port_range[2]; +#ifdef CONFIG_INET extern __inline__ int ip_send(struct sk_buff *skb) { if (skb->len > skb->dst->pmtu) @@ -181,6 +182,7 @@ buf[3]=addr&0x7F; } +#endif extern int ip_call_ra_chain(struct sk_buff *skb); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/net/irda/ircomm_tty.h linux.ac/include/net/irda/ircomm_tty.h --- linux.vanilla/include/net/irda/ircomm_tty.h Thu Sep 2 00:48:46 1999 +++ linux.ac/include/net/irda/ircomm_tty.h Sat Sep 18 01:41:42 1999 @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli * Created at: Sun Jun 6 23:24:22 1999 - * Modified at: Fri Aug 13 07:31:35 1999 + * Modified at: Tue Aug 31 10:22:02 1999 * Modified by: Dag Brattli * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -83,8 +83,12 @@ struct termios callout_termios; wait_queue_head_t open_wait; + wait_queue_head_t close_wait; struct timer_list watchdog_timer; struct tq_struct tqueue; + + unsigned short close_delay; + unsigned short closing_wait; /* time to wait before closing */ long pgrp; /* pgrp of opening process */ int open_count; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/net/irda/ircomm_tty_attach.h linux.ac/include/net/irda/ircomm_tty_attach.h --- linux.vanilla/include/net/irda/ircomm_tty_attach.h Thu Sep 2 00:48:46 1999 +++ linux.ac/include/net/irda/ircomm_tty_attach.h Sat Sep 18 01:41:42 1999 @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli * Created at: Wed Jun 9 15:55:18 1999 - * Modified at: Mon Jul 5 12:56:56 1999 + * Modified at: Thu Sep 2 10:29:30 1999 * Modified by: Dag Brattli * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -52,6 +52,8 @@ IRCOMM_TTY_DISCOVERY_INDICATION, IRCOMM_TTY_CONNECT_CONFIRM, IRCOMM_TTY_CONNECT_INDICATION, + IRCOMM_TTY_DISCONNECT_REQUEST, + IRCOMM_TTY_DISCONNECT_INDICATION, IRCOMM_TTY_WD_TIMER_EXPIRED, IRCOMM_TTY_GOT_PARAMETERS, IRCOMM_TTY_GOT_LSAPSEL, @@ -66,6 +68,7 @@ extern char *ircomm_state[]; extern char *ircomm_event[]; +extern char *ircomm_tty_state[]; int ircomm_tty_do_event(struct ircomm_tty_cb *self, IRCOMM_TTY_EVENT event, struct sk_buff *skb, struct ircomm_tty_info *info); @@ -79,6 +82,9 @@ __u32 max_sdu_size, __u8 max_header_size, struct sk_buff *skb); +void ircomm_tty_disconnect_indication(void *instance, void *sap, + LM_REASON reason, + struct sk_buff *skb); void ircomm_tty_connect_indication(void *instance, void *sap, struct qos_info *qos, __u32 max_sdu_size, diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/net/irda/irlpt_cli.h linux.ac/include/net/irda/irlpt_cli.h --- linux.vanilla/include/net/irda/irlpt_cli.h Mon Aug 23 15:12:18 1999 +++ linux.ac/include/net/irda/irlpt_cli.h Thu Jan 1 01:00:00 1970 @@ -1,49 +0,0 @@ -/********************************************************************* - * - * Filename: irlpt_cli.h - * Version: 0.1 - * Description: - * Status: Experimental. - * Author: Dag Brattli - * Created at: Sat Feb 21 18:54:38 1998 - * Modified at: Wed Apr 21 16:46:26 1999 - * Modified by: Dag Brattli - * - * Copyright (c) 1998, Thomas Davis, - * Copyright (c) 1998, Dag Brattli, - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * I, Thomas Davis, provide no warranty for any of this software. This - * material is provided "AS-IS" and at no charge. - * - ********************************************************************/ - -#ifndef IRLPT_CLIENT_H -#define IRLPT_CLIENT_H - -/* Debug function */ - -/* int client_init( struct net_device *dev); */ - -/* - * if it's static, it doesn't go in here. - */ - -void irlpt_client_get_value_confirm(int result, __u16 obj_id, - struct ias_value *value, - void *priv); -void irlpt_client_connect_indication( void *instance, - void *sap, - struct qos_info *qos, - int max_seg_size, - struct sk_buff *skb); -void irlpt_client_connect_request( struct irlpt_cb *self); - -extern hashbin_t *irlpt_clients; - -#endif diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/net/irda/irlpt_cli_fsm.h linux.ac/include/net/irda/irlpt_cli_fsm.h --- linux.vanilla/include/net/irda/irlpt_cli_fsm.h Sun Mar 7 23:26:43 1999 +++ linux.ac/include/net/irda/irlpt_cli_fsm.h Thu Jan 1 01:00:00 1970 @@ -1,36 +0,0 @@ -/********************************************************************* - * - * Filename: irlpt_cli_fsm.h - * Version: 0.1 - * Sources: irlan_event.h - * - * Copyright (c) 1997 Dag Brattli , - * All Rights Reserved. - * Copyright (c) 1998, Thomas Davis, , - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * I, Thomas Davis, provide no warranty for any of this software. - * This material is provided "AS-IS" and at no charge. - * - ********************************************************************/ - -#ifndef IRLPT_EVENT_H -#define IRLPT_EVENT_H - -#include -#include - -extern void irlpt_client_do_event( struct irlpt_cb *self, - IRLPT_EVENT event, - struct sk_buff *skb, - struct irlpt_info *info); -extern void irlpt_client_next_state( struct irlpt_cb *self, - IRLPT_CLIENT_STATE state); - -#endif - diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/net/irda/irlpt_common.h linux.ac/include/net/irda/irlpt_common.h --- linux.vanilla/include/net/irda/irlpt_common.h Sun May 30 18:27:04 1999 +++ linux.ac/include/net/irda/irlpt_common.h Thu Jan 1 01:00:00 1970 @@ -1,190 +0,0 @@ -/********************************************************************* - * - * Filename: irlpt_common.h - * Version: - * Description: - * Status: Experimental. - * Author: Thomas Davis, - * Created at: Sat Feb 21 18:54:38 1998 - * Modified at: Sun Mar 8 23:44:19 1998 - * Modified by: Dag Brattli - * Sources: irlan.c - * - * Copyright (c) 1998, Thomas Davis, , - * Dag Brattli, - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * I, Thomas Davis, provide no warranty for any of this software. - * This material is provided "AS-IS" and at no charge. - * - ********************************************************************/ - -#ifndef IRLPT_COMMON_H -#define IRLPT_COMMON_H - -#include -#include - -#include -#include -#include -#include -#include - -#include - -extern char *irlpt_service_type[]; -extern char *irlpt_port_type[]; -extern char *irlpt_connected[]; -extern char *irlpt_reasons[]; -extern char *irlpt_client_fsm_state[]; -extern char *irlpt_server_fsm_state[]; -extern char *irlpt_fsm_event[]; - -extern wait_queue_head_t lpt_wait; - -extern struct irlpt_cb *irlpt_find_handle(unsigned int minor); -extern void irlpt_flow_control(struct sk_buff *skb); - -extern ssize_t irlpt_read( struct file *file, char *buffer, - size_t count, loff_t *noidea); -extern ssize_t irlpt_write(struct file *file, const char *buffer, - size_t count, loff_t *noidea); -extern loff_t irlpt_seek(struct file *, loff_t, int); -extern int irlpt_open(struct inode * inode, struct file *file); -extern int irlpt_close(struct inode *inode, struct file *file); -extern u_int irlpt_poll(struct file *file, poll_table *wait); - -/* FSM definitions */ - -typedef enum { - IRLPT_CLIENT_IDLE, - IRLPT_CLIENT_QUERY, - IRLPT_CLIENT_READY, - IRLPT_CLIENT_WAITI, - IRLPT_CLIENT_CONN, -} IRLPT_CLIENT_STATE; - -typedef enum { - IRLPT_SERVER_IDLE, - IRLPT_SERVER_CONN, -} IRLPT_SERVER_STATE; - -/* IrLPT Events */ - -typedef enum { - QUERY_REMOTE_IAS, - IAS_PROVIDER_AVAIL, - IAS_PROVIDER_NOT_AVAIL, - LAP_DISCONNECT, - LMP_CONNECT, - LMP_DISCONNECT, - LMP_CONNECT_INDICATION, - LMP_DISCONNECT_INDICATION, - IRLPT_DISCOVERY_INDICATION, - IRLPT_CONNECT_REQUEST, - IRLPT_DISCONNECT_REQUEST, - CLIENT_DATA_INDICATION, -} IRLPT_EVENT; - -struct irlpt_info { - struct lsap_cb *lsap; - __u8 dlsap_sel; - __u32 daddr; - __u32 saddr; -}; - -/* Command packet types */ - -#define IRLPT_MAX_PACKET 1024 -#define IRLPT_MAX_HEADER LMP_MAX_HEADER -#define IRLPT_MAX_DEVICES 3 -#define IRLPT_MAGIC 0x0755 - -typedef enum { - IRLPT_DISCONNECTED, - IRLPT_WAITING, - IRLPT_CONNECTED, - IRLPT_FLUSHED, -} IRLPT_SERVER_STATUS; - -#define IRLPT_LSAP 0x09 - -#define PI_SERVICE_TYPE 0x00 - -#define IRLPT_UNKNOWN 0x00 /* not defined yet. */ -#define IRLPT_THREE_WIRE_RAW 0x01 /* bit 0 */ -#define IRLPT_THREE_WIRE 0x02 /* bit 1 */ -#define IRLPT_NINE_WIRE 0x04 /* bit 2 */ -#define IRLPT_CENTRONICS 0x08 /* bit 3 */ -#define IRLPT_SERVER_MODE 0xFF /* our own flag */ - -#define PI_PORT_TYPE 0x01 - -#define IRLPT_SERIAL 0x01 /* bit 0 */ -#define IRLPT_PARALLEL 0x02 /* bit 1 */ - -#define PI_PORT_NAME 0x02 - -#define PI_CRITICAL 0x80 - -struct irlpt_cb { - QUEUE queue; /* must be first. */ - - int magic; /* magic used to detect corruption of - the struct */ - __u32 daddr; /* address of remote printer */ - __u32 saddr; /* my local address. */ - - struct timer_list retry_timer; - - int volatile state; /* Current state of IrCOMM layer */ - int open_retries; - int in_use; /* flag to prevent re-use */ - char ifname[16]; /* name of the allocated instance, - and registered device. */ - struct lsap_cb *lsap; /* lmp handle */ - - __u8 dlsap_sel; /* remote LSAP selector address */ - __u8 slsap_sel; /* local LSAP selectoraddress */ - __u8 servicetype; /* Type of remote service, ie THREE_WIRE_RAW */ - __u8 porttype; /* type of remote port. */ - - struct miscdevice ir_dev; /* used to register the misc device. */ - - int count; /* open count */ - int max_data_size; /* max frame size we can send */ - int max_header_size; /* how much header space is needed */ - int pkt_count; /* how many packets are queued up */ - - wait_queue_head_t read_wait; /* wait queues */ - wait_queue_head_t write_wait; - wait_queue_head_t ex_wait; - - /* this is used to remove the printer when it's gone */ - struct timer_list lpt_timer; - void (*timeout) (unsigned long data); - - void (*do_event) (struct irlpt_cb *self, IRLPT_EVENT event, - struct sk_buff *skb, - struct irlpt_info *info); - - /* this is used by the server side of the system */ - - IRLPT_SERVER_STATE connected; - - int eof; - int service_LSAP; - - struct sk_buff_head rx_queue; /* read buffer queue */ -}; - -/* Debug function */ -void irlpt_dump_buffer(struct sk_buff *); - -#endif diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/net/irda/irlpt_server.h linux.ac/include/net/irda/irlpt_server.h --- linux.vanilla/include/net/irda/irlpt_server.h Mon Aug 23 15:12:18 1999 +++ linux.ac/include/net/irda/irlpt_server.h Thu Jan 1 01:00:00 1970 @@ -1,42 +0,0 @@ -/********************************************************************* - * - * Filename: irlpt_server.h - * Version: 0.1 - * Description: - * Status: Experimental. - * Author: Dag Brattli - * Created at: Sat Feb 21 18:54:38 1998 - * Modified at: Tue Sep 22 11:41:42 1998 - * Modified by: Dag Brattli - * - * Copyright (c) 1998, Thomas Davis, - * Copyright (c) 1998, Dag Brattli, - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * I, Thomas Davis, provide no warranty for any of this software. This - * material is provided "AS-IS" and at no charge. - * - ********************************************************************/ - -#ifndef IRLPT_SERVER_H -#define IRLPT_SERVER_H - -#include "qos.h" -#include "irmod.h" - -#include -#include -#include -#include -#include - -/* int server_init( struct net_device *dev); */ - -extern struct irlpt_cb *irlpt_server; - -#endif diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/net/irda/irlpt_server_fsm.h linux.ac/include/net/irda/irlpt_server_fsm.h --- linux.vanilla/include/net/irda/irlpt_server_fsm.h Sun Mar 7 23:26:43 1999 +++ linux.ac/include/net/irda/irlpt_server_fsm.h Thu Jan 1 01:00:00 1970 @@ -1,35 +0,0 @@ -/********************************************************************* - * - * Filename: server_server_fsm.h - * Version: 0.1 - * Sources: irlan_event.h - * - * Copyright (c) 1997 Dag Brattli , - * All Rights Reserved. - * Copyright (c) 1998, Thomas Davis, , - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * I, Thomas Davis, provide no warranty for any of this software. - * This material is provided "AS-IS" and at no charge. - * - ********************************************************************/ - -#ifndef IRLPT_EVENT_H -#define IRLPT_EVENT_H - -#include -#include - -void irlpt_server_do_event( struct irlpt_cb *self, - IRLPT_EVENT event, - struct sk_buff *skb, - struct irlpt_info *info); -void irlpt_server_next_state( struct irlpt_cb *self, - IRLPT_SERVER_STATE state); - -#endif diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/net/irda/irvtd.h linux.ac/include/net/irda/irvtd.h --- linux.vanilla/include/net/irda/irvtd.h Thu Jun 10 12:57:41 1999 +++ linux.ac/include/net/irda/irvtd.h Thu Jan 1 01:00:00 1970 @@ -1,95 +0,0 @@ -/********************************************************************* - * - * Filename: irvtd.h - * Version: 0.1 - * Sources: irlpt.h - * - * Copyright (c) 1998, Takahide Higuchi , - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * I, Takahide Higuchi, provide no warranty for any of this software. - * This material is provided "AS-IS" and at no charge. - * - ********************************************************************/ - -#ifndef IRVTD_H -#define IRVTD_H - -#include -#include -#include -#include - -#include -#include -#include - - -#define IRVTD_MAGIC 0xff545943 /* random */ -#define COMM_MAX_TTY 1 -#define IRVTD_RX_QUEUE_HIGH 10 -#define IRVTD_RX_QUEUE_LOW 2 - -#define IRCOMM_MAJOR 60; /* Zero means automatic allocation - 60,61,62,and 63 is reserved for experiment */ -#define IRVTD_MINOR 64 - - - -struct irvtd_cb { - - int magic; /* magic used to detect corruption of the struct */ - - /* if daddr is NULL, remote device have not been discovered yet */ - - int tx_disable; - int rx_disable; - struct sk_buff *txbuff; - struct sk_buff_head rxbuff; - struct ircomm_cb *comm; /* ircomm instance */ - - __u32 tx_max_sdu_size; - __u32 max_header_size; - /* - * These members are used for compatibility with usual serial device. - * See linux/serial.h - */ - - int flags; - struct tty_struct *tty; - - int line; - int count; /* open count */ - int blocked_open; - wait_queue_head_t open_wait; - wait_queue_head_t close_wait; - wait_queue_head_t delta_msr_wait; - wait_queue_head_t tx_wait; - - struct timer_list tx_timer; - struct timer_list rx_timer; - - long pgrp; - long session; - unsigned short closing_wait; /* time to wait before closing */ - unsigned short close_delay; - - int custom_divisor; - int mcr; - int msr; - int cts_stoptx; - int ttp_stoptx; - int ttp_stoprx; - int disconnect_pend; - struct serial_icounter_struct icount; - int read_status_mask; - int ignore_status_mask; -}; - - -#endif diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/net/irda/toshoboe.h linux.ac/include/net/irda/toshoboe.h --- linux.vanilla/include/net/irda/toshoboe.h Sun May 30 18:27:04 1999 +++ linux.ac/include/net/irda/toshoboe.h Mon Sep 6 16:57:45 1999 @@ -25,6 +25,12 @@ /* * $Log: toshoboe.h,v $ + * Revision 1.4 1999/06/29 13:46:42 root + * ls + * + * Revision 1.3 1999/06/29 12:31:03 root + * *** empty log message *** + * * Revision 1.2 1999/05/09 01:43:08 root * *** empty log message *** * @@ -157,6 +163,8 @@ struct OboeTaskFile *taskfile; /*The taskfile */ void *xmit_bufs[TX_SLOTS]; /*The buffers */ void *recv_bufs[RX_SLOTS]; + int open; + int stopped; /*Stopped by some or other APM stuff*/ }; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/pcmcia/bus_ops.h linux.ac/include/pcmcia/bus_ops.h --- linux.vanilla/include/pcmcia/bus_ops.h Tue Sep 7 22:07:13 1999 +++ linux.ac/include/pcmcia/bus_ops.h Wed Sep 15 23:57:59 1999 @@ -1,5 +1,5 @@ /* - * bus_ops.h 1.6 1999/08/28 04:12:33 + * bus_ops.h 1.7 1999/09/10 06:22:33 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -30,6 +30,8 @@ #ifndef _LINUX_BUS_OPS_H #define _LINUX_BUS_OPS_H +#ifdef CONFIG_VIRTUAL_BUS + typedef struct bus_operations { void *priv; u32 (*b_in)(void *bus, u32 port, s32 sz); @@ -51,8 +53,6 @@ void *dev_id); void (*b_free_irq)(void *bus, u_int irq, void *dev_id); } bus_operations; - -#ifdef CONFIG_VIRTUAL_BUS #define bus_inb(b,p) (b)->b_in((b),(p),0) #define bus_inw(b,p) (b)->b_in((b),(p),1) diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/pcmcia/mem_op.h linux.ac/include/pcmcia/mem_op.h --- linux.vanilla/include/pcmcia/mem_op.h Tue Sep 7 22:07:13 1999 +++ linux.ac/include/pcmcia/mem_op.h Wed Sep 15 23:57:59 1999 @@ -1,5 +1,5 @@ /* - * mem_op.h 1.10 1999/08/28 04:12:33 + * mem_op.h 1.11 1999/09/15 07:14:03 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -49,7 +49,7 @@ size_t odd = (n & 3); n -= odd; while (n) { - put_user(readl_ns(from), (int *)to); + put_user(__raw_readl(from), (int *)to); (char *)from += 4; (char *)to += 4; n -= 4; } while (odd--) @@ -64,7 +64,7 @@ n -= odd; while (n) { get_user(l, (int *)from); - writel_ns(l, to); + __raw_writel(l, to); (char *)to += 4; (char *)from += 4; n -= 4; } while (odd--) { diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/include/scsi/sg.h linux.ac/include/scsi/sg.h --- linux.vanilla/include/scsi/sg.h Thu Jun 10 12:57:41 1999 +++ linux.ac/include/scsi/sg.h Sat Sep 11 01:12:19 1999 @@ -12,10 +12,16 @@ * Copyright (C) 1998, 1999 Douglas Gilbert - Version: 2.1.34 (990603) - This version for later 2.1.x and 2.2.x series kernels - D. P. Gilbert (dgilbert@interlog.com, dougg@triode.net.au) - + Version: 2.3.35 (990708) + This version for 2.3 series kernels. It only differs from sg version + 2.1.35 used in the 2.2 series kernels by changes to wait_queue. This + in an internal kernel interface and should not effect users. + D. P. Gilbert (dgilbert@interlog.com, dougg@triode.net.au) + + Changes since 2.1.34 (990603) + - add queuing info into struct sg_scsi_id + - block negative timeout values + - add back write() wait on previous read() when no cmd queuing Changes since 2.1.33 (990521) - implement SG_SET_RESERVED_SIZE and associated memory re-org. - add SG_NEXT_CMD_LEN to override SCSI command lengths @@ -144,9 +150,10 @@ int scsi_id; /* scsi id of target device */ int lun; int scsi_type; /* TYPE_... defined in scsi/scsi.h */ + short h_cmd_per_lun;/* host (adapter) maximum commands per lun */ + short d_queue_depth;/* device (or adapter) maximum queue length */ int unused1; /* probably find a good use, set 0 for now */ int unused2; /* ditto */ - int unused3; } Sg_scsi_id; /* IOCTLs: ( _GET_s yield result via 'int *' 3rd argument unless @@ -204,6 +211,10 @@ #define SG_GET_VERSION_NUM 0x2282 /* Example: version 2.1.34 yields 20134 */ #define SG_NEXT_CMD_LEN 0x2283 /* override SCSI command length with given number on the next write() on this file descriptor */ + +/* Returns -EBUSY if occupied else takes as input: 0 -> do nothing, + 1 -> device reset or 2 -> bus reset (may not be activated yet) */ +#define SG_SCSI_RESET 0x2284 #define SG_SCATTER_SZ (8 * 4096) /* PAGE_SIZE not available to user */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/init/main.c linux.ac/init/main.c --- linux.vanilla/init/main.c Tue Sep 7 22:07:13 1999 +++ linux.ac/init/main.c Wed Sep 15 23:57:59 1999 @@ -84,7 +84,7 @@ extern void sysctl_init(void); extern void filescache_init(void); extern void signals_init(void); -extern int pcmcia_init(void); +extern int init_pcmcia_ds(void); extern void free_initmem(void); extern void filesystem_setup(void); @@ -659,7 +659,7 @@ irda_device_init(); /* Must be done after protocol initialization */ #endif #ifdef CONFIG_PCMCIA - pcmcia_init(); /* Do this last */ + init_pcmcia_ds(); /* Do this last */ #endif /* Mount the root filesystem.. */ mount_root(); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/kernel/exit.c linux.ac/kernel/exit.c --- linux.vanilla/kernel/exit.c Thu Aug 26 14:42:20 1999 +++ linux.ac/kernel/exit.c Thu Sep 16 16:58:25 1999 @@ -288,7 +288,7 @@ */ static void exit_notify(void) { - struct task_struct * p; + struct task_struct * p, *t; forget_original_parent(current); /* @@ -300,15 +300,30 @@ * and we were the only connection outside, so our pgrp * is about to become orphaned. */ - if ((current->p_pptr->pgrp != current->pgrp) && - (current->p_pptr->session == current->session) && + + t = current->p_pptr; + + if ((t->pgrp != current->pgrp) && + (t->session == current->session) && will_become_orphaned_pgrp(current->pgrp, current) && has_stopped_jobs(current->pgrp)) { kill_pg(current->pgrp,SIGHUP,1); kill_pg(current->pgrp,SIGCONT,1); } - /* Let father know we died */ + /* Let father know we died + * + * Thread signals are configurable, but you aren't going to use + * that to send signals to arbitary processes. + * That stops right now. + */ + + if(current->exit_signal != SIGCHLD && + (current->euid ^ t->suid) && (current->euid ^ t->uid) + && (current->uid ^ t->suid) && (current->uid ^ t->uid) + && !capable(CAP_KILL)) + current->exit_signal = SIGCHLD; + notify_parent(current, current->exit_signal); /* diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/kernel/fork.c linux.ac/kernel/fork.c --- linux.vanilla/kernel/fork.c Tue Aug 17 17:27:43 1999 +++ linux.ac/kernel/fork.c Tue Sep 14 21:33:27 1999 @@ -592,6 +592,13 @@ struct task_struct *p; DECLARE_MUTEX_LOCKED(sem); + if(clone_flags & CLONE_PID) + { + /* This is only allowed from the boot up thread */ + if(current->pid) + return -EPERM; + } + current->vfork_sem = &sem; p = alloc_task_struct(); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/kernel/ksyms.c linux.ac/kernel/ksyms.c --- linux.vanilla/kernel/ksyms.c Tue Sep 7 22:07:13 1999 +++ linux.ac/kernel/ksyms.c Sat Sep 11 19:39:06 1999 @@ -201,7 +201,17 @@ EXPORT_SYMBOL(add_to_page_cache_unique); EXPORT_SYMBOL(__find_get_page); EXPORT_SYMBOL(__find_lock_page); - + +/* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */ +EXPORT_SYMBOL(___wait_on_page); +EXPORT_SYMBOL(add_to_page_cache); +EXPORT_SYMBOL(default_llseek); +EXPORT_SYMBOL(filemap_nopage); +EXPORT_SYMBOL(filemap_swapout); +EXPORT_SYMBOL(filemap_sync); +EXPORT_SYMBOL(remove_inode_page); +EXPORT_SYMBOL(swap_free); + #if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE) EXPORT_SYMBOL(do_nfsservctl); #endif @@ -364,6 +374,7 @@ EXPORT_SYMBOL(get_random_bytes); EXPORT_SYMBOL(securebits); EXPORT_SYMBOL(cap_bset); +EXPORT_SYMBOL(daemonize); /* Program loader interfaces */ EXPORT_SYMBOL(setup_arg_pages); @@ -423,3 +434,6 @@ /* library functions */ EXPORT_SYMBOL(strnicmp); + +/* init task, for moving kthread roots - ought to export a function ?? */ +EXPORT_SYMBOL(init_task_union); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/kernel/ptrace.c linux.ac/kernel/ptrace.c --- linux.vanilla/kernel/ptrace.c Thu Sep 2 00:48:48 1999 +++ linux.ac/kernel/ptrace.c Thu Sep 16 00:06:42 1999 @@ -89,7 +89,7 @@ copied = 0; for (;;) { unsigned long offset = addr & ~PAGE_MASK; - int this_len = PAGE_SIZE - offset; + size_t this_len = PAGE_SIZE - offset; int retval; if (this_len > len) diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/kernel/sched.c linux.ac/kernel/sched.c --- linux.vanilla/kernel/sched.c Thu Aug 26 14:42:20 1999 +++ linux.ac/kernel/sched.c Thu Sep 16 00:07:27 1999 @@ -1181,7 +1181,7 @@ static inline void do_process_times(struct task_struct *p, unsigned long user, unsigned long system) { - long psecs; + unsigned long psecs; psecs = (p->times.tms_utime += user); psecs += (p->times.tms_stime += system); @@ -1806,6 +1806,35 @@ for_each_task(p) show_task(p); read_unlock(&tasklist_lock); +} + +/* + * Put all the gunge required to become a kernel thread without + * attached user resources in one place where it belongs. + */ + +void daemonize(void) +{ + struct fs_struct *fs; + + + /* + * If we were started as result of loading a module, close all of the + * user space pages. We don't need them, and if we didn't close them + * they would be locked into memory. + */ + exit_mm(current); + + current->session = 1; + current->pgrp = 1; + + /* Become as one with the init task */ + + exit_fs(current); /* current->fs->count--; */ + fs = init_task.fs; + current->fs = fs; + atomic_inc(&fs->count); + } void __init init_idle(void) diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/kernel/signal.c linux.ac/kernel/signal.c --- linux.vanilla/kernel/signal.c Thu Aug 26 14:42:20 1999 +++ linux.ac/kernel/signal.c Wed Sep 15 23:56:18 1999 @@ -353,13 +353,9 @@ break; } } else { - /* If this was sent by a rt mechanism, try again. */ - if (info->si_code < 0) { - ret = -EAGAIN; - goto out; - } - /* Otherwise, mention that the signal is pending, - but don't queue the info. */ + /* Queue overflow, we have to abort. */ + ret = -EAGAIN; + goto out; } } @@ -792,6 +788,8 @@ { struct siginfo info; + memset(&info, 0, sizeof(info)); + info.si_signo = sig; info.si_errno = 0; info.si_code = SI_USER; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/kernel/sys.c linux.ac/kernel/sys.c --- linux.vanilla/kernel/sys.c Tue Sep 7 22:07:13 1999 +++ linux.ac/kernel/sys.c Tue Sep 7 23:43:18 1999 @@ -997,6 +997,17 @@ case PR_GET_PDEATHSIG: error = put_user(current->pdeath_signal, (int *)arg2); break; + case PR_GET_DUMPABLE: + if (current->dumpable) + error = 1; + break; + case PR_SET_DUMPABLE: + if (arg2 != 0 && arg2 != 1) { + error = -EINVAL; + break; + } + current->dumpable = arg2; + break; default: error = -EINVAL; break; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/kernel/sysctl.c linux.ac/kernel/sysctl.c --- linux.vanilla/kernel/sysctl.c Thu Sep 2 00:48:48 1999 +++ linux.ac/kernel/sysctl.c Thu Sep 16 00:10:25 1999 @@ -635,7 +635,7 @@ int proc_dostring(ctl_table *table, int write, struct file *filp, void *buffer, size_t *lenp) { - int len; + size_t len; char *p, c; if (!table->data || !table->maxlen || !*lenp || @@ -1185,7 +1185,7 @@ void *newval, size_t newlen, void **context) { if (oldval) { - size_t olen; + int olen; if (oldlenp) { if (get_user(olen, oldlenp)) return -EFAULT; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/lib/Makefile linux.ac/lib/Makefile --- linux.vanilla/lib/Makefile Mon Nov 27 13:54:00 1995 +++ linux.ac/lib/Makefile Mon Sep 13 00:04:31 1999 @@ -7,6 +7,6 @@ # L_TARGET := lib.a -L_OBJS := errno.o ctype.o string.o vsprintf.o +L_OBJS := errno.o ctype.o string.o vsprintf.o parse.o include $(TOPDIR)/Rules.make diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/lib/parse.c linux.ac/lib/parse.c --- linux.vanilla/lib/parse.c Thu Jan 1 01:00:00 1970 +++ linux.ac/lib/parse.c Mon Sep 13 01:57:36 1999 @@ -0,0 +1,119 @@ +/* + * linux/lib/parse.c + * + * (C) Richard Guenther + * + * Heavily based on parts of modutil's insmod.c which is + * + * Copyright 1996, 1997 Linux International. + * + * New implementation contributed by Richard Henderson + * Based on original work by Bjorn Eckwall + * + * This file is part of the Linux modutils. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You 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. + * + * Fixes: + * Alan Cox Make it get non arrays right. + */ + +#include +#include +#include + +/* parse module parameters like insmod */ +int parse_parameters(void *var, char *type, char *str) +{ + char *p, t; + long min, max, val, cnt; + int array = 0; + + p = type; + if (isdigit(*p)) { + min = simple_strtoul(p, &p, 0); + if (*p == '-') + { + max = simple_strtoul(p+1, &p, 0); + array=1; + } + else + max = min; + } else + min = max = 1; + t = *p; + + /* + * We are passed a pointer to the object. Now the object + * could be an array, in which case we have a pointer to + * a pointer. It might be a direct value in which case + * we have a pointer the value to write. + * + * For an array we want to the array base, for a non array + * pass, we want the value + * + * Alan. + */ + + if(array) + var=*(void **)var; + + p = str; + cnt = 0; + do { + if (*p == ',') { + p++; + cnt++; + continue; + } + switch (t) { + case 'b': + val = simple_strtol(p, &p, 0); + ((char *)var)[cnt] = (char)val; + break; + case 'h': + val = simple_strtol(p, &p, 0); + ((short *)var)[cnt] = (short)val; + break; + case 'i': + val = simple_strtol(p, &p, 0); + ((int *)var)[cnt] = (int)val; + break; + case 'l': + val = simple_strtol(p, &p, 0); + ((long *)var)[cnt] = (long)val; + break; + case 's': + /* complex quoting is not possible, as parse_options() + * just searches for ' ', so we can safely just leech + * the whole string (multiple strings are impossible, too) + * - where do we check for overflows?? */ + strcpy((char *)(var), p); + break; + default: + printk(KERN_INFO "error in parsing arguments \"%s\" using format %s\n", str, type); + return 0; + } + if (*p == ',') + p++; + cnt++; + } while (*p && cnt < max); + + return 1; +} + + + + diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/mm/filemap.c linux.ac/mm/filemap.c --- linux.vanilla/mm/filemap.c Tue Sep 7 22:07:13 1999 +++ linux.ac/mm/filemap.c Mon Sep 20 20:42:30 1999 @@ -530,7 +530,7 @@ * This adds the requested page to the page cache if it isn't already there, * and schedules an I/O to read in its contents from disk. */ -static inline void page_cache_read(struct file * file, unsigned long offset) +static inline int page_cache_read(struct file * file, unsigned long offset) { unsigned long new_page; struct inode *inode = file->f_dentry->d_inode; @@ -541,17 +541,20 @@ page = __find_page_nolock(inode, offset, *hash); spin_unlock(&pagecache_lock); if (page) - return; + return 0; new_page = page_cache_alloc(); if (!new_page) - return; + return -ENOMEM; page = page_cache_entry(new_page); if (!add_to_page_cache_unique(page, inode, offset, hash)) { - inode->i_op->readpage(file, page); + int error; + + error = inode->i_op->readpage(file, page); + page_cache_release(page); - return; + return error; } /* @@ -559,26 +562,34 @@ * raced with us and added our page to the cache first. */ page_cache_free(new_page); - return; + return 0; } /* * Read in an entire cluster at once. A cluster is usually a 64k- * aligned block that includes the address requested in "offset." */ -static void read_cluster_nonblocking(struct file * file, +static int read_cluster_nonblocking(struct file * file, unsigned long offset) { + int error = 0; off_t filesize = file->f_dentry->d_inode->i_size; + unsigned long pg_offset = CLUSTER_OFFSET(offset); unsigned long pages = CLUSTER_PAGES; - offset = CLUSTER_OFFSET(offset); - while ((pages-- > 0) && (offset < filesize)) { - page_cache_read(file, offset); - offset += PAGE_CACHE_SIZE; + while ((pages-- > 0) && (pg_offset < filesize)) { + error = page_cache_read(file, pg_offset); + if (!error) { + pg_offset += PAGE_CACHE_SIZE; + continue; + } + + if (pg_offset > offset) + error = 0; + break; } - return; + return error; } /* @@ -912,7 +923,8 @@ ahead = 0; while (ahead < max_ahead) { ahead += PAGE_CACHE_SIZE; - page_cache_read(filp, raend + ahead); + if (page_cache_read(filp, raend + ahead) < 0) + break; } /* * If we tried to read ahead some pages, @@ -1292,13 +1304,12 @@ * The goto's are kind of ugly, but this streamlines the normal case of having * it in the page cache, and handles the special cases reasonably without * having a lot of duplicated code. - * - * XXX - at some point, this should return unique values to indicate to - * the caller whether this is EIO, OOM, or SIGBUS. */ -static unsigned long filemap_nopage(struct vm_area_struct * area, + +unsigned long filemap_nopage(struct vm_area_struct * area, unsigned long address, int no_share) { + int error; struct file * file = area->vm_file; struct dentry * dentry = file->f_dentry; struct inode * inode = dentry->d_inode; @@ -1345,7 +1356,9 @@ if (new_page) { copy_page(new_page, old_page); flush_page_to_ram(new_page); - } + } else + new_page = -1; + page_cache_release(page); return new_page; } @@ -1362,16 +1375,26 @@ * so we need to map a zero page. */ if (offset < inode->i_size) - read_cluster_nonblocking(file, offset); + error = read_cluster_nonblocking(file, offset); else - page_cache_read(file, offset); + error = page_cache_read(file, offset); /* * The page we want has now been added to the page cache. * In the unlikely event that someone removed it in the * meantime, we'll just come back here and read it again. */ - goto retry_find; + if (!error) + goto retry_find; + + /* + * An error return from page_cache_read can result if the + * system is low on memory, or a problem occurs while trying + * to schedule I/O. + */ + if (error == -ENOMEM) + return -1; + return 0; page_not_uptodate: lock_page(page); @@ -1584,7 +1607,7 @@ return error; } -static int filemap_sync(struct vm_area_struct * vma, unsigned long address, +int filemap_sync(struct vm_area_struct * vma, unsigned long address, size_t size, unsigned int flags) { pgd_t * dir; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/mm/mlock.c linux.ac/mm/mlock.c --- linux.vanilla/mm/mlock.c Thu Aug 26 14:42:20 1999 +++ linux.ac/mm/mlock.c Thu Sep 2 16:51:05 1999 @@ -186,11 +186,13 @@ locked += current->mm->locked_vm; lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur; - lock_limit >>= PAGE_SHIFT; + if (lock_limit < RLIM_INFINITY) { + lock_limit >>= PAGE_SHIFT; - /* check against resource limits */ - if (locked > lock_limit) - goto out; + /* check against resource limits */ + if (locked > lock_limit) + goto out; + } /* we may lock at most half of physical memory... */ /* (this check is pretty bogus, but doesn't hurt) */ @@ -253,12 +255,14 @@ if (!flags || (flags & ~(MCL_CURRENT | MCL_FUTURE))) goto out; + ret = -ENOMEM; lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur; - lock_limit >>= PAGE_SHIFT; + if (lock_limit < RLIM_INFINITY) { + lock_limit >>= PAGE_SHIFT; - ret = -ENOMEM; - if (current->mm->total_vm > lock_limit) - goto out; + if (current->mm->total_vm > lock_limit) + goto out; + } /* we may lock at most half of physical memory... */ /* (this check is pretty bogus, but doesn't hurt) */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/mm/mremap.c linux.ac/mm/mremap.c --- linux.vanilla/mm/mremap.c Thu Aug 5 20:21:52 1999 +++ linux.ac/mm/mremap.c Thu Sep 2 16:51:05 1999 @@ -198,12 +198,14 @@ unsigned long locked = current->mm->locked_vm << PAGE_SHIFT; locked += new_len - old_len; ret = -EAGAIN; - if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur) + if ((current->rlim[RLIMIT_MEMLOCK].rlim_cur < RLIM_INFINITY) && + (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)) goto out; } ret = -ENOMEM; - if ((current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len) - > current->rlim[RLIMIT_AS].rlim_cur) + if ((current->rlim[RLIMIT_AS].rlim_cur < RLIM_INFINITY) && + ((current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len) + > current->rlim[RLIMIT_AS].rlim_cur)) goto out; /* Private writable mapping? Check memory availability.. */ if ((vma->vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE && diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/mm/page_io.c linux.ac/mm/page_io.c --- linux.vanilla/mm/page_io.c Thu Sep 2 00:48:48 1999 +++ linux.ac/mm/page_io.c Thu Sep 2 16:51:05 1999 @@ -118,7 +118,7 @@ } /* block_size == PAGE_SIZE/zones_used */ - brw_page(rw, page, dev, zones, block_size, 0); + brw_page(rw, page, dev, zones, block_size); /* Note! For consistency we do all of the logic, * decrementing the page count, and unlocking the page in the diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/mm/swap_state.c linux.ac/mm/swap_state.c --- linux.vanilla/mm/swap_state.c Thu Sep 2 00:48:48 1999 +++ linux.ac/mm/swap_state.c Sat Sep 18 19:28:22 1999 @@ -13,6 +13,7 @@ #include #include #include +#include #include @@ -234,7 +235,9 @@ page_address(page), page_count(page), entry); #endif remove_from_swap_cache (page); + lock_kernel(); swap_free (entry); + unlock_kernel(); } static void delete_from_swap_cache_nolock(struct page *page) diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/Config.in linux.ac/net/Config.in --- linux.vanilla/net/Config.in Sat Sep 11 00:54:17 1999 +++ linux.ac/net/Config.in Mon Sep 13 00:22:42 1999 @@ -5,85 +5,84 @@ comment 'Networking options' tristate 'Packet socket' CONFIG_PACKET if [ "$CONFIG_PACKET" != "n" ]; then - bool 'Packet socket: mmapped IO' CONFIG_PACKET_MMAP + bool ' Packet socket: mmapped IO' CONFIG_PACKET_MMAP fi bool 'Kernel/User netlink socket' CONFIG_NETLINK if [ "$CONFIG_NETLINK" = "y" ]; then - bool 'Routing messages' CONFIG_RTNETLINK - tristate 'Netlink device emulation' CONFIG_NETLINK_DEV + bool ' Routing messages' CONFIG_RTNETLINK + tristate ' Netlink device emulation' CONFIG_NETLINK_DEV fi bool 'Network packet filtering (replaces ipchains)' CONFIG_NETFILTER if [ "$CONFIG_NETFILTER" = "y" ]; then - bool 'Network packet filtering debugging' CONFIG_NETFILTER_DEBUG + bool ' Network packet filtering debugging' CONFIG_NETFILTER_DEBUG fi bool 'Socket Filtering' CONFIG_FILTER tristate 'Unix domain sockets' CONFIG_UNIX bool 'TCP/IP networking' CONFIG_INET if [ "$CONFIG_INET" = "y" ]; then - source net/ipv4/Config.in - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then -# Sorry, but IPv6 as module is still invalid. - tristate 'The IPv6 protocol (EXPERIMENTAL)' CONFIG_IPV6 -# bool 'The IPv6 protocol (EXPERIMENTAL)' CONFIG_IPV6 - if [ "$CONFIG_IPV6" != "n" ]; then - source net/ipv6/Config.in - fi - fi - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - source net/khttpd/Config.in - fi + source net/ipv4/Config.in + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then +# IPv6 as module will cause a CRASH if you try to unload it + tristate ' The IPv6 protocol (EXPERIMENTAL)' CONFIG_IPV6 + if [ "$CONFIG_IPV6" != "n" ]; then + source net/ipv6/Config.in + fi + fi + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + source net/khttpd/Config.in + fi fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool 'Asynchronous Transfer Mode (ATM, EXPERIMENTAL)' CONFIG_ATM y - if [ "$CONFIG_ATM" = "y" ]; then - if [ "$CONFIG_INET" = "y" ]; then - bool ' Classical IP over ATM' CONFIG_ATM_CLIP y - if [ "$CONFIG_ATM_CLIP" = "y" ]; then - bool ' Do NOT send ICMP if no neighbour' CONFIG_ATM_CLIP_NO_ICMP n + bool 'Asynchronous Transfer Mode (ATM) (EXPERIMENTAL)' CONFIG_ATM y + if [ "$CONFIG_ATM" = "y" ]; then + if [ "$CONFIG_INET" = "y" ]; then + bool ' Classical IP over ATM' CONFIG_ATM_CLIP y + if [ "$CONFIG_ATM_CLIP" = "y" ]; then + bool ' Do NOT send ICMP if no neighbour' CONFIG_ATM_CLIP_NO_ICMP n + fi + fi + tristate ' LAN Emulation (LANE) support' CONFIG_ATM_LANE y + if [ "$CONFIG_INET" = "y" -a "$CONFIG_ATM_LANE" != "n" ]; then + tristate ' Multi-Protocol Over ATM (MPOA) support' CONFIG_ATM_MPOA y fi - fi - tristate ' LAN Emulation (LANE) support' CONFIG_ATM_LANE y - if [ "$CONFIG_INET" = "y" -a "$CONFIG_ATM_LANE" != "n" ]; then - tristate ' Multi-Protocol Over ATM (MPOA) support' CONFIG_ATM_MPOA y - fi - fi + fi fi comment ' ' tristate 'The IPX protocol' CONFIG_IPX if [ "$CONFIG_IPX" != "n" ]; then - source net/ipx/Config.in + source net/ipx/Config.in fi tristate 'Appletalk DDP' CONFIG_ATALK if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'DECnet Support (EXPERIMENTAL)' CONFIG_DECNET - if [ "$CONFIG_DECNET" != "n" ]; then - source net/decnet/Config.in - fi - tristate 'CCITT X.25 Packet Layer (EXPERIMENTAL)' CONFIG_X25 - tristate 'LAPB Data Link Driver (EXPERIMENTAL)' CONFIG_LAPB - bool 'Bridging (EXPERIMENTAL)' CONFIG_BRIDGE - bool '802.2 LLC (EXPERIMENTAL)' CONFIG_LLC -# if [ "$CONFIG_LLC" = "y" ]; then -# bool 'Netbeui (EXPERIMENTAL)' CONFIG_NETBEUI -# fi - tristate 'Acorn Econet/AUN protocols (EXPERIMENTAL)' CONFIG_ECONET - if [ "$CONFIG_ECONET" != "n" ]; then - bool ' AUN over UDP' CONFIG_ECONET_AUNUDP - bool ' Native Econet' CONFIG_ECONET_NATIVE - fi - tristate 'WAN router' CONFIG_WAN_ROUTER - bool 'Fast switching (read help!)' CONFIG_NET_FASTROUTE - bool 'Forwarding between high speed interfaces' CONFIG_NET_HW_FLOWCONTROL - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - mainmenu_option next_comment - comment 'QoS and/or fair queueing' - bool 'QoS and/or fair queueing' CONFIG_NET_SCHED - if [ "$CONFIG_NET_SCHED" = "y" ]; then - source net/sched/Config.in - fi -# bool 'Network code profiler' CONFIG_NET_PROFILE - endmenu - fi + tristate 'DECnet Support (EXPERIMENTAL)' CONFIG_DECNET + if [ "$CONFIG_DECNET" != "n" ]; then + source net/decnet/Config.in + fi + tristate 'CCITT X.25 Packet Layer (EXPERIMENTAL)' CONFIG_X25 + tristate 'LAPB Data Link Driver (EXPERIMENTAL)' CONFIG_LAPB + bool 'Bridging (EXPERIMENTAL)' CONFIG_BRIDGE + bool '802.2 LLC (EXPERIMENTAL)' CONFIG_LLC +# if [ "$CONFIG_LLC" = "y" ]; then +# bool ' Netbeui (EXPERIMENTAL)' CONFIG_NETBEUI +# fi + tristate 'Acorn Econet/AUN protocols (EXPERIMENTAL)' CONFIG_ECONET + if [ "$CONFIG_ECONET" != "n" ]; then + bool ' AUN over UDP' CONFIG_ECONET_AUNUDP + bool ' Native Econet' CONFIG_ECONET_NATIVE + fi + tristate 'WAN router' CONFIG_WAN_ROUTER + bool 'Fast switching (read help!)' CONFIG_NET_FASTROUTE + bool 'Forwarding between high speed interfaces' CONFIG_NET_HW_FLOWCONTROL + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + mainmenu_option next_comment + comment 'QoS and/or fair queueing' + bool 'QoS and/or fair queueing (EXPERIMENTAL)' CONFIG_NET_SCHED + if [ "$CONFIG_NET_SCHED" = "y" ]; then + source net/sched/Config.in + fi +# bool 'Network code profiler' CONFIG_NET_PROFILE + endmenu + fi fi endmenu diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/ax25/Config.in linux.ac/net/ax25/Config.in --- linux.vanilla/net/ax25/Config.in Tue Aug 17 17:27:43 1999 +++ linux.ac/net/ax25/Config.in Mon Sep 13 00:22:42 1999 @@ -10,21 +10,26 @@ comment 'Amateur Radio support' bool 'Amateur Radio support' CONFIG_HAMRADIO -if [ "$CONFIG_HAMRADIO" != "n" ] ; then - if [ "$CONFIG_NET" != "n" ] ; then - comment 'Packet Radio protocols' - tristate 'Amateur Radio AX.25 Level 2 protocol' CONFIG_AX25 - if [ "$CONFIG_AX25" != "n" ]; then - bool ' AX.25 DAMA Slave support' CONFIG_AX25_DAMA_SLAVE -# bool ' AX.25 DAMA Master support' CONFIG_AX25_DAMA_MASTER - dep_tristate ' Amateur Radio NET/ROM protocol' CONFIG_NETROM $CONFIG_AX25 - dep_tristate ' Amateur Radio X.25 PLP (Rose)' CONFIG_ROSE $CONFIG_AX25 - fi +if [ "$CONFIG_HAMRADIO" != "n" ]; then + if [ "$CONFIG_NET" != "n" ]; then + comment 'Packet Radio protocols' + tristate ' Amateur Radio AX.25 Level 2 protocol' CONFIG_AX25 + if [ "$CONFIG_AX25" != "n" ]; then + bool ' AX.25 DAMA Slave support' CONFIG_AX25_DAMA_SLAVE +# bool ' AX.25 DAMA Master support' CONFIG_AX25_DAMA_MASTER + dep_tristate ' Amateur Radio NET/ROM protocol' CONFIG_NETROM $CONFIG_AX25 + dep_tristate ' Amateur Radio X.25 PLP (Rose)' CONFIG_ROSE $CONFIG_AX25 + fi - if [ "$CONFIG_AX25" != "n" ]; then - source drivers/net/hamradio/Config.in - fi - fi + if [ "$CONFIG_AX25" != "n" ]; then + mainmenu_option next_comment + comment 'AX.25 network device drivers' + + source drivers/net/hamradio/Config.in + + endmenu + fi + fi fi diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/core/datagram.c linux.ac/net/core/datagram.c --- linux.vanilla/net/core/datagram.c Thu Sep 2 00:48:49 1999 +++ linux.ac/net/core/datagram.c Thu Sep 16 00:13:33 1999 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/core/dev.c linux.ac/net/core/dev.c --- linux.vanilla/net/core/dev.c Thu Sep 2 00:48:49 1999 +++ linux.ac/net/core/dev.c Mon Sep 13 00:00:36 1999 @@ -1327,7 +1327,7 @@ stats->qual.level, stats->qual.updated & 2 ? '.' : ' ', stats->qual.noise, - stats->qual.updated & 3 ? '.' : ' ', + stats->qual.updated & 4 ? '.' : ' ', stats->discard.nwid, stats->discard.code, stats->discard.misc); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/core/sock.c linux.ac/net/core/sock.c --- linux.vanilla/net/core/sock.c Sat Sep 11 00:54:18 1999 +++ linux.ac/net/core/sock.c Fri Sep 10 17:56:44 1999 @@ -1013,7 +1013,7 @@ read_lock(&sk->callback_lock); if (!sk->dead) { wake_up_interruptible(sk->sleep); - sock_wake_async(sk->socket,0); + sock_wake_async(sk->socket,0,POLL_ERR); } read_unlock(&sk->callback_lock); } @@ -1023,7 +1023,7 @@ read_lock(&sk->callback_lock); if(!sk->dead) { wake_up_interruptible(sk->sleep); - sock_wake_async(sk->socket,1); + sock_wake_async(sk->socket,1,POLL_IN); } read_unlock(&sk->callback_lock); } @@ -1041,7 +1041,7 @@ /* Should agree with poll, otherwise some programs break */ if (sock_writeable(sk)) - sock_wake_async(sk->socket, 2); + sock_wake_async(sk->socket, 2, POLL_OUT); } read_unlock(&sk->callback_lock); } diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/decnet/Config.in linux.ac/net/decnet/Config.in --- linux.vanilla/net/decnet/Config.in Thu Aug 26 14:42:27 1999 +++ linux.ac/net/decnet/Config.in Mon Sep 13 00:22:42 1999 @@ -1,6 +1,8 @@ # # DECnet configuration # -bool 'DECnet: SIOCGIFCONF support' CONFIG_DECNET_SIOCGIFCONF -bool 'DECnet: router support (VERY VERY EXPERIMENTAL)' CONFIG_DECNET_ROUTER -bool 'DECnet: raw socket support' CONFIG_DECNET_RAW +bool ' DECnet: SIOCGIFCONF support' CONFIG_DECNET_SIOCGIFCONF +if [ "$CONFIG_EXPERIMENTAL" ]; then + bool ' DECnet: router support (EXPERIMENTAL)' CONFIG_DECNET_ROUTER +fi +bool ' DECnet: raw socket support' CONFIG_DECNET_RAW diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/decnet/dn_nsp_in.c linux.ac/net/decnet/dn_nsp_in.c --- linux.vanilla/net/decnet/dn_nsp_in.c Thu Sep 2 00:48:49 1999 +++ linux.ac/net/decnet/dn_nsp_in.c Wed Sep 15 23:56:18 1999 @@ -431,7 +431,8 @@ struct socket *sock = sk->socket; wake_up_interruptible(sk->sleep); if (!(sock->flags & SO_WAITDATA) && sock->fasync_list) - kill_fasync(sock->fasync_list, sig); + kill_fasync(sock->fasync_list, sig, + (sig == SIGURG) ? POLL_PRI : POLL_IN); } read_unlock_irqrestore(&sk->callback_lock, flags); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/ipv4/Config.in linux.ac/net/ipv4/Config.in --- linux.vanilla/net/ipv4/Config.in Thu Aug 26 14:42:27 1999 +++ linux.ac/net/ipv4/Config.in Thu Sep 16 16:25:26 1999 @@ -1,56 +1,55 @@ # # IP configuration # -bool 'IP: multicasting' CONFIG_IP_MULTICAST -bool 'IP: advanced router' CONFIG_IP_ADVANCED_ROUTER +bool ' IP: multicasting' CONFIG_IP_MULTICAST +bool ' IP: advanced router' CONFIG_IP_ADVANCED_ROUTER if [ "$CONFIG_IP_ADVANCED_ROUTER" = "y" ]; then - define_bool CONFIG_RTNETLINK y - define_bool CONFIG_NETLINK y - bool 'IP: policy routing' CONFIG_IP_MULTIPLE_TABLES - bool 'IP: equal cost multipath' CONFIG_IP_ROUTE_MULTIPATH - bool 'IP: use TOS value as routing key' CONFIG_IP_ROUTE_TOS - bool 'IP: verbose route monitoring' CONFIG_IP_ROUTE_VERBOSE - bool 'IP: large routing tables' CONFIG_IP_ROUTE_LARGE_TABLES - if [ "$CONFIG_IP_MULTIPLE_TABLES" = "y" ]; then - bool 'IP: fast network address translation' CONFIG_IP_ROUTE_NAT - fi + define_bool CONFIG_RTNETLINK y + define_bool CONFIG_NETLINK y + bool ' IP: policy routing' CONFIG_IP_MULTIPLE_TABLES + if [ "$CONFIG_IP_MULTIPLE_TABLES" = "y" ]; then + bool ' IP: use FWMARK value as routing key' CONFIG_IP_ROUTE_FWMARK + fi + bool ' IP: equal cost multipath' CONFIG_IP_ROUTE_MULTIPATH + bool ' IP: use TOS value as routing key' CONFIG_IP_ROUTE_TOS + bool ' IP: verbose route monitoring' CONFIG_IP_ROUTE_VERBOSE + bool ' IP: large routing tables' CONFIG_IP_ROUTE_LARGE_TABLES + if [ "$CONFIG_IP_MULTIPLE_TABLES" = "y" ]; then + bool ' IP: fast network address translation' CONFIG_IP_ROUTE_NAT + fi fi -if [ "$CONFIG_IP_MULTIPLE_TABLES" = "y" ]; then - bool 'IP: use FWMARK value as routing key' CONFIG_IP_ROUTE_FWMARK -fi -bool 'IP: kernel level autoconfiguration' CONFIG_IP_PNP +bool ' IP: kernel level autoconfiguration' CONFIG_IP_PNP if [ "$CONFIG_IP_PNP" = "y" ]; then - bool ' BOOTP support' CONFIG_IP_PNP_BOOTP - bool ' RARP support' CONFIG_IP_PNP_RARP + bool ' BOOTP support' CONFIG_IP_PNP_BOOTP + bool ' RARP support' CONFIG_IP_PNP_RARP # not yet ready.. -# bool ' ARP support' CONFIG_IP_PNP_ARP +# bool ' ARP support' CONFIG_IP_PNP_ARP fi -bool 'IP: optimize as router not host' CONFIG_IP_ROUTER -tristate 'IP: tunneling' CONFIG_NET_IPIP -tristate 'IP: GRE tunnels over IP' CONFIG_NET_IPGRE +bool ' IP: optimize as router not host' CONFIG_IP_ROUTER +tristate ' IP: tunneling' CONFIG_NET_IPIP +tristate ' IP: GRE tunnels over IP' CONFIG_NET_IPGRE if [ "$CONFIG_IP_MULTICAST" = "y" ]; then - if [ "$CONFIG_NET_IPGRE" != "n" ]; then - bool 'IP: broadcast GRE over IP' CONFIG_NET_IPGRE_BROADCAST - fi - bool 'IP: multicast routing' CONFIG_IP_MROUTE - if [ "$CONFIG_IP_MROUTE" = "y" ]; then - bool 'IP: PIM-SM version 1 support' CONFIG_IP_PIMSM_V1 - bool 'IP: PIM-SM version 2 support' CONFIG_IP_PIMSM_V2 - fi + if [ "$CONFIG_NET_IPGRE" != "n" ]; then + bool ' IP: broadcast GRE over IP' CONFIG_NET_IPGRE_BROADCAST + fi + bool ' IP: multicast routing' CONFIG_IP_MROUTE + if [ "$CONFIG_IP_MROUTE" = "y" ]; then + bool ' IP: PIM-SM version 1 support' CONFIG_IP_PIMSM_V1 + bool ' IP: PIM-SM version 2 support' CONFIG_IP_PIMSM_V2 + fi fi -bool 'IP: aliasing support' CONFIG_IP_ALIAS +bool ' IP: aliasing support' CONFIG_IP_ALIAS if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - if [ "$CONFIG_RTNETLINK" = "y" ]; then - bool 'IP: ARP daemon support (EXPERIMENTAL)' CONFIG_ARPD - fi + if [ "$CONFIG_RTNETLINK" = "y" ]; then + bool ' IP: ARP daemon support (EXPERIMENTAL)' CONFIG_ARPD + fi fi -bool 'IP: TCP syncookie support (not enabled per default)' CONFIG_SYN_COOKIES +bool ' IP: TCP syncookie support (disabled per default)' CONFIG_SYN_COOKIES comment '(it is safe to leave these untouched)' -#bool 'IP: PC/TCP compatibility mode' CONFIG_INET_PCTCP -#bool 'IP: Path MTU Discovery (normally enabled)' CONFIG_PATH_MTU_DISCOVERY -#bool 'IP: Disable NAGLE algorithm (normally enabled)' CONFIG_TCP_NAGLE_OFF -bool 'IP: Allow large windows (not recommended if <16Mb of memory)' CONFIG_SKB_LARGE +#bool ' IP: PC/TCP compatibility mode' CONFIG_INET_PCTCP +#bool ' IP: Path MTU Discovery (normally enabled)' CONFIG_PATH_MTU_DISCOVERY +#bool ' IP: Disable NAGLE algorithm (normally enabled)' CONFIG_TCP_NAGLE_OFF +bool ' IP: Allow large windows (not recommended if <16Mb of memory)' CONFIG_SKB_LARGE #if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then -#bool 'IP: support experimental checksum copy to user for UDP' CONFIG_UDP_DELAY_CSUM +# bool ' IP: support checksum copy to user for UDP (EXPERIMENTAL)' CONFIG_UDP_DELAY_CSUM #fi - diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/ipv4/tcp.c linux.ac/net/ipv4/tcp.c --- linux.vanilla/net/ipv4/tcp.c Sat Sep 11 00:54:18 1999 +++ linux.ac/net/ipv4/tcp.c Fri Sep 10 17:56:45 1999 @@ -626,7 +626,7 @@ wake_up_interruptible(sk->sleep); if (sock_wspace(sk) >= tcp_min_write_space(sk)) - sock_wake_async(sk->socket, 2); + sock_wake_async(sk->socket, 2, POLL_OUT); } read_unlock(&sk->callback_lock); } diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/ipv4/tcp_input.c linux.ac/net/ipv4/tcp_input.c --- linux.vanilla/net/ipv4/tcp_input.c Sat Sep 11 00:54:18 1999 +++ linux.ac/net/ipv4/tcp_input.c Wed Sep 15 23:56:18 1999 @@ -1403,7 +1403,7 @@ if (!sk->dead) { wake_up_interruptible(sk->sleep); - sock_wake_async(sk->socket, 1); + sock_wake_async(sk->socket, 1, POLL_HUP); } switch(sk->state) { @@ -1806,7 +1806,7 @@ */ if (!sk->dead) { wake_up_interruptible(sk->sleep); - sock_wake_async(sk->socket,1); + sock_wake_async(sk->socket,1, POLL_IN); } return(1); } @@ -1965,6 +1965,7 @@ kill_proc(sk->proc, SIGURG, 1); else kill_pg(-sk->proc, SIGURG, 1); + sock_wake_async(sk->socket, 3, POLL_PRI); } /* We may be adding urgent data when the last byte read was @@ -2201,7 +2202,7 @@ * this frame, the pred_flags won't match up. -DaveM */ wake_up_interruptible(sk->sleep); - sock_wake_async(sk->socket,1); + sock_wake_async(sk->socket,1, POLL_IN); tcp_delack_estimator(tp); tcp_remember_ack(tp, th, skb); @@ -2760,7 +2761,7 @@ if(!sk->dead) { wake_up_interruptible(sk->sleep); - sock_wake_async(sk->socket, 0); + sock_wake_async(sk->socket, 0, POLL_IN); } return -1; } @@ -3017,7 +3018,7 @@ */ if (!sk->dead && sk->sleep) { wake_up_interruptible(sk->sleep); - sock_wake_async(sk->socket, 1); + sock_wake_async(sk->socket,0,POLL_OUT); } tp->snd_una = TCP_SKB_CB(skb)->ack_seq; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/ipv6/Config.in linux.ac/net/ipv6/Config.in --- linux.vanilla/net/ipv6/Config.in Thu Feb 19 22:46:16 1998 +++ linux.ac/net/ipv6/Config.in Mon Sep 13 00:22:42 1999 @@ -1,14 +1,14 @@ # # IPv6 configuration # -bool 'IPv6: enable EUI-64 token format' CONFIG_IPV6_EUI64 +bool ' IPv6: enable EUI-64 token format' CONFIG_IPV6_EUI64 if [ "$CONFIG_IPV6_EUI64" = "y" ]; then - bool 'IPv6: disable provider based addresses' CONFIG_IPV6_NO_PB + bool ' IPv6: disable provider based addresses' CONFIG_IPV6_NO_PB fi if [ "$CONFIG_NETLINK" = "y" ]; then - if [ "$CONFIG_RTNETLINK" = "n" ]; then - bool 'IPv6: routing messages via old netlink' CONFIG_IPV6_NETLINK - fi + if [ "$CONFIG_RTNETLINK" = "n" ]; then + bool ' IPv6: routing messages via old netlink' CONFIG_IPV6_NETLINK + fi fi -#bool 'IPv6: flow policy support' CONFIG_RT6_POLICY -#bool 'IPv6: firewall support' CONFIG_IPV6_FIREWALL +#bool ' IPv6: flow policy support' CONFIG_RT6_POLICY +#bool ' IPv6: firewall support' CONFIG_IPV6_FIREWALL diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/ipx/Config.in linux.ac/net/ipx/Config.in --- linux.vanilla/net/ipx/Config.in Sun Apr 12 01:18:16 1998 +++ linux.ac/net/ipx/Config.in Mon Sep 13 00:22:42 1999 @@ -2,7 +2,7 @@ # IPX configuration # -bool 'IPX: Full internal IPX network' CONFIG_IPX_INTERN +bool ' IPX: Full internal IPX network' CONFIG_IPX_INTERN if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - dep_tristate 'IPX: SPX networking (EXPERIMENTAL)' CONFIG_SPX $CONFIG_IPX + dep_tristate ' IPX: SPX networking (EXPERIMENTAL)' CONFIG_SPX $CONFIG_IPX fi diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/irda/Config.in linux.ac/net/irda/Config.in --- linux.vanilla/net/irda/Config.in Thu Sep 2 00:48:51 1999 +++ linux.ac/net/irda/Config.in Mon Sep 13 00:22:42 1999 @@ -2,30 +2,30 @@ # IrDA protocol configuration # -if [ "$CONFIG_NET" != "n" ] ; then +if [ "$CONFIG_NET" != "n" ]; then - mainmenu_option next_comment - comment 'IrDA (infrared) support' - dep_tristate 'IrDA subsystem support' CONFIG_IRDA $CONFIG_NET + mainmenu_option next_comment + comment 'IrDA (infrared) support' + dep_tristate 'IrDA subsystem support' CONFIG_IRDA $CONFIG_NET - if [ "$CONFIG_IRDA" != "n" ] ; then - comment 'IrDA protocols' - source net/irda/irlan/Config.in - source net/irda/ircomm/Config.in + if [ "$CONFIG_IRDA" != "n" ]; then + comment 'IrDA protocols' + source net/irda/irlan/Config.in + source net/irda/ircomm/Config.in - bool 'IrDA protocol options' CONFIG_IRDA_OPTIONS - if [ "$CONFIG_IRDA_OPTIONS" != "n" ] ; then - comment ' IrDA options' - bool ' Cache last LSAP' CONFIG_IRDA_CACHE_LAST_LSAP - bool ' Fast RRs' CONFIG_IRDA_FAST_RR - bool ' Debug information' CONFIG_IRDA_DEBUG - fi - fi + bool ' IrDA protocol options' CONFIG_IRDA_OPTIONS + if [ "$CONFIG_IRDA_OPTIONS" != "n" ]; then + comment ' IrDA options' + bool ' Cache last LSAP' CONFIG_IRDA_CACHE_LAST_LSAP + bool ' Fast RRs' CONFIG_IRDA_FAST_RR + bool ' Debug information' CONFIG_IRDA_DEBUG + fi + fi - if [ "$CONFIG_IRDA" != "n" ] ; then - source net/irda/compressors/Config.in - source drivers/net/irda/Config.in - fi - endmenu + if [ "$CONFIG_IRDA" != "n" ]; then + source net/irda/compressors/Config.in + source drivers/net/irda/Config.in + fi + endmenu fi diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/irda/af_irda.c linux.ac/net/irda/af_irda.c --- linux.vanilla/net/irda/af_irda.c Thu Sep 2 00:48:51 1999 +++ linux.ac/net/irda/af_irda.c Sat Sep 18 01:41:43 1999 @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli * Created at: Sun May 31 10:12:43 1998 - * Modified at: Mon Aug 23 09:44:37 1999 + * Modified at: Wed Sep 8 09:01:34 1999 * Modified by: Dag Brattli * Sources: af_netroom.c, af_ax25.c, af_rose.c, af_x25.c etc. * @@ -47,6 +47,8 @@ extern int irlap_driver_rcv(struct sk_buff *, struct net_device *, struct packet_type *); +static int irda_create(struct socket *sock, int protocol); + static struct proto_ops irda_stream_ops; static struct proto_ops irda_dgram_ops; static hashbin_t *cachelog = NULL; @@ -66,8 +68,6 @@ struct sock *sk; int err; - DEBUG(1, __FUNCTION__ "()\n"); - self = (struct irda_sock *) instance; ASSERT(self != NULL, return -1;); @@ -428,8 +428,6 @@ { struct sock *sk = sock->sk; - DEBUG(1, __FUNCTION__ "()\n"); - if (sk->type == SOCK_STREAM && sk->state != TCP_LISTEN) { sk->max_ack_backlog = backlog; sk->state = TCP_LISTEN; @@ -1171,8 +1169,7 @@ case SIOCSIFNETMASK: case SIOCGIFMETRIC: case SIOCSIFMETRIC: - return -EINVAL; - + return -EINVAL; default: DEBUG(1, __FUNCTION__ "(), doing device ioctl!\n"); return dev_ioctl(cmd, (void *) arg); @@ -1212,7 +1209,7 @@ DEBUG(0, __FUNCTION__ "(), sorry not impl. yet!\n"); return 0; case IRTTP_MAX_SDU_SIZE: - DEBUG(0, __FUNCTION__ "(), setting max_sdu_size = %d\n", opt); + DEBUG(2, __FUNCTION__ "(), setting max_sdu_size = %d\n", opt); self->max_sdu_size_rx = opt; break; default: @@ -1290,7 +1287,7 @@ len = sizeof(struct irda_device_list) + sizeof(struct irda_device_info) * i; - DEBUG(1, __FUNCTION__ "(), len=%d, i=%d\n", len, i); + DEBUG(2, __FUNCTION__ "(), len=%d, i=%d\n", len, i); if (put_user(len, optlen)) return -EFAULT; @@ -1300,7 +1297,7 @@ break; case IRTTP_MAX_SDU_SIZE: val = self->max_data_size; - DEBUG(0, __FUNCTION__ "(), getting max_sdu_size = %d\n", val); + DEBUG(2, __FUNCTION__ "(), getting max_sdu_size = %d\n", val); len = sizeof(int); if (put_user(len, optlen)) return -EFAULT; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/irda/compressors/Config.in linux.ac/net/irda/compressors/Config.in --- linux.vanilla/net/irda/compressors/Config.in Thu Dec 17 17:01:03 1998 +++ linux.ac/net/irda/compressors/Config.in Mon Sep 13 00:22:42 1999 @@ -1,9 +1,11 @@ -bool 'IrLAP compression' CONFIG_IRDA_COMPRESSION +bool ' IrLAP compression' CONFIG_IRDA_COMPRESSION -if [ "$CONFIG_IRDA_COMPRESSION" != "n" ] ; then - comment ' IrDA compressors' - dep_tristate ' Deflate compression (experimental)' CONFIG_IRDA_DEFLATE $CONFIG_IRDA -# tristate ' BZIP2 compression' CONFIG_IRDA_BZIP2 -# tristate ' BSD compression' CONFIG_IRDA_BSD +if [ "$CONFIG_IRDA_COMPRESSION" != "n" ]; then + comment ' IrDA compressors' + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate ' Deflate compression (EXPERIMENTAL)' CONFIG_IRDA_DEFLATE $CONFIG_IRDA + fi +# tristate ' BZIP2 compression' CONFIG_IRDA_BZIP2 +# tristate ' BSD compression' CONFIG_IRDA_BSD fi diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/irda/ircomm/Config.in linux.ac/net/irda/ircomm/Config.in --- linux.vanilla/net/irda/ircomm/Config.in Thu Dec 17 17:01:03 1998 +++ linux.ac/net/irda/ircomm/Config.in Mon Sep 13 00:22:42 1999 @@ -1,3 +1,3 @@ -dep_tristate 'IrCOMM protocol' CONFIG_IRCOMM $CONFIG_IRDA +dep_tristate ' IrCOMM protocol' CONFIG_IRCOMM $CONFIG_IRDA diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/irda/ircomm/Makefile linux.ac/net/irda/ircomm/Makefile --- linux.vanilla/net/irda/ircomm/Makefile Thu Sep 2 00:48:51 1999 +++ linux.ac/net/irda/ircomm/Makefile Sat Sep 18 01:41:43 1999 @@ -8,7 +8,7 @@ # Note 2! The CFLAGS definition is now in the main makefile... O_TARGET := ircomm_and_tty.o -O_OBJS := ircomm_param.o ircomm_core.o ircomm_event.o ircomm_lmp.o ircomm_ttp.o ircomm_tty.o ircomm_tty_attach.o ircomm_tty_ioctl.c +O_OBJS := ircomm_param.o ircomm_core.o ircomm_event.o ircomm_lmp.o ircomm_ttp.o ircomm_tty.o ircomm_tty_attach.o ircomm_tty_ioctl.o M_OBJS := ircomm.o ircomm-tty.o MI_OBJS := ircomm_param.o ircomm_core.o ircomm_event.o ircomm_lmp.o ircomm_ttp.o ircomm_tty.o ircomm_tty_attach.o ircomm_tty_ioctl.o diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/irda/ircomm/ircomm_event.c linux.ac/net/irda/ircomm/ircomm_event.c --- linux.vanilla/net/irda/ircomm/ircomm_event.c Thu Sep 2 00:48:51 1999 +++ linux.ac/net/irda/ircomm/ircomm_event.c Sat Sep 18 01:41:43 1999 @@ -1,12 +1,12 @@ /********************************************************************* * * Filename: ircomm_event.c - * Version: - * Description: + * Version: 1.0 + * Description: IrCOMM layer state machine * Status: Experimental. * Author: Dag Brattli * Created at: Sun Jun 6 20:33:11 1999 - * Modified at: Wed Aug 25 12:58:27 1999 + * Modified at: Thu Sep 2 10:09:25 1999 * Modified by: Dag Brattli * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -161,18 +161,15 @@ ircomm_next_state(self, IRCOMM_CONN); ret = self->issue.connect_response(self, skb); break; - case IRCOMM_DISCONNECT_REQUEST: ircomm_next_state(self, IRCOMM_IDLE); ret = self->issue.disconnect_request(self, skb, info); break; - case IRCOMM_TTP_DISCONNECT_INDICATION: case IRCOMM_LMP_DISCONNECT_INDICATION: ircomm_next_state(self, IRCOMM_IDLE); ircomm_disconnect_indication(self, skb, info); break; - default: DEBUG(0, __FUNCTION__ "(), unknown event = %s\n", ircomm_event[event]); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/irda/ircomm/ircomm_param.c linux.ac/net/irda/ircomm/ircomm_param.c --- linux.vanilla/net/irda/ircomm/ircomm_param.c Thu Sep 2 00:48:51 1999 +++ linux.ac/net/irda/ircomm/ircomm_param.c Sat Sep 18 01:41:43 1999 @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli * Created at: Mon Jun 7 10:25:11 1999 - * Modified at: Wed Aug 25 13:48:14 1999 + * Modified at: Fri Sep 3 09:28:20 1999 * Modified by: Dag Brattli * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -102,6 +102,7 @@ */ int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush) { + unsigned long flags; struct sk_buff *skb; int count; @@ -119,12 +120,16 @@ if (self->service_type == IRCOMM_3_WIRE_RAW) return 0; - skb = self->ctrl_skb; - + save_flags(flags); + cli(); + + skb = self->ctrl_skb; if (!skb) { skb = dev_alloc_skb(256); - if (!skb) - return -1; + if (!skb) { + restore_flags(flags); + return -ENOMEM; + } skb_reserve(skb, self->max_header_size); @@ -136,8 +141,13 @@ */ count = irda_param_insert(self, pi, skb->tail, skb_tailroom(skb), &ircomm_param_info); - if (count > 0) - skb_put(skb, count); + if (count < 0) { + DEBUG(0, __FUNCTION__ "(), no room for parameter!\n"); + restore_flags(flags); + return -1; + } + skb_put(skb, count); + restore_flags(flags); if (flush) { ircomm_control_request(self->ircomm, skb); @@ -201,13 +211,25 @@ /* * Function ircomm_param_port_type (self, param) * - * - * + * The port type parameter tells if the devices are serial or parallel. + * Since we only advertise serial service, this parameter should only + * be equal to IRCOMM_SERIAL. */ static int ircomm_param_port_type(void *instance, param_t *param, int get) { - DEBUG(0, __FUNCTION__ "(), not impl.\n"); + struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance; + + ASSERT(self != NULL, return -1;); + ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); + + if (get) + param->pv.b = IRCOMM_SERIAL; + else { + self->session.port_type = param->pv.b; + DEBUG(0, __FUNCTION__ "(), port type=%d\n", + self->session.port_type); + } return 0; } @@ -223,11 +245,13 @@ ASSERT(self != NULL, return -1;); ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); - - if (get) + + if (get) { DEBUG(0, __FUNCTION__ "(), not imp!\n"); - else + } else { DEBUG(0, __FUNCTION__ "(), port-name=%s\n", param->pv.c); + strncpy(self->session.port_name, param->pv.c, 32); + } return 0; } @@ -273,8 +297,6 @@ else self->session.data_format = param->pv.b; - DEBUG(1, __FUNCTION__ "(), data format = 0x%02x\n", param->pv.b); - return 0; } @@ -359,9 +381,6 @@ else { dte = param->pv.b; - /* Null modem cable emulator */ - self->session.null_modem = TRUE; - if (dte & IRCOMM_DELTA_DTR) self->session.dce |= (IRCOMM_DELTA_DSR| IRCOMM_DELTA_RI | @@ -379,14 +398,9 @@ /* Take appropriate actions */ ircomm_tty_check_modem_status(self); - /* - * Send reply, and remember not to set delta values for the - * initial parameters - */ - self->session.dte = (IRCOMM_DTR| IRCOMM_RTS); - ircomm_param_request(self, IRCOMM_DTE, TRUE); + /* Null modem cable emulator */ + self->session.null_modem = TRUE; } - DEBUG(1, __FUNCTION__ "(), dte = 0x%02x\n", param->pv.b); return 0; } @@ -426,18 +440,24 @@ /* * Function ircomm_param_poll (instance, param) * - * + * Called when the peer device is polling for the line settings * */ static int ircomm_param_poll(void *instance, param_t *param, int get) { - DEBUG(0, __FUNCTION__ "(), not impl.\n"); - - return 0; -} + struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance; + ASSERT(self != NULL, return -1;); + ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); + /* Poll parameters are always of lenght 0 (just a signal) */ + if (!get) { + /* Respond with DTE line settings */ + ircomm_param_request(self, IRCOMM_DTE, TRUE); + } + return 0; +} diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/irda/ircomm/ircomm_tty.c linux.ac/net/irda/ircomm/ircomm_tty.c --- linux.vanilla/net/irda/ircomm/ircomm_tty.c Thu Sep 2 00:48:51 1999 +++ linux.ac/net/irda/ircomm/ircomm_tty.c Sat Sep 18 01:41:43 1999 @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli * Created at: Sun Jun 6 21:00:56 1999 - * Modified at: Wed Aug 25 15:12:18 1999 + * Modified at: Thu Sep 9 17:27:17 1999 * Modified by: Dag Brattli * Sources: serial.c and previous IrCOMM work by Takahide Higuchi * @@ -60,11 +60,8 @@ static void ircomm_tty_send_xchar(struct tty_struct *tty, char ch); static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout); static void ircomm_tty_hangup(struct tty_struct *tty); -static void ircomm_tty_break(struct tty_struct *tty, int break_state); static void ircomm_tty_do_softint(void *private_); -static void ircomm_tty_disconnect_indication(void *instance, void *sap, - LM_REASON reason, - struct sk_buff *skb); + static int ircomm_tty_data_indication(void *instance, void *sap, struct sk_buff *skb); static int ircomm_tty_control_indication(void *instance, void *sap, @@ -127,7 +124,6 @@ driver.stop = ircomm_tty_stop; driver.start = ircomm_tty_start; driver.hangup = ircomm_tty_hangup; - driver.break_ctl = ircomm_tty_break; driver.wait_until_sent = ircomm_tty_wait_until_sent; driver.read_proc = ircomm_tty_read_proc; @@ -170,9 +166,12 @@ notify_t notify; int ret; + ASSERT(self != NULL, return -1;); + ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); + /* Already open */ if (self->flags & ASYNC_INITIALIZED) { - DEBUG(0, __FUNCTION__ "(), already open so break out!\n"); + DEBUG(2, __FUNCTION__ "(), already open so break out!\n"); return 0; } @@ -181,10 +180,10 @@ /* These callbacks we must handle ourselves */ notify.data_indication = ircomm_tty_data_indication; notify.udata_indication = ircomm_tty_control_indication; - notify.disconnect_indication = ircomm_tty_disconnect_indication; notify.flow_indication = ircomm_tty_flow_indication; /* Use the ircomm_tty interface for these ones */ + notify.disconnect_indication = ircomm_tty_disconnect_indication; notify.connect_confirm = ircomm_tty_connect_confirm; notify.connect_indication = ircomm_tty_connect_indication; strncpy(notify.name, "ircomm_tty", NOTIFY_MAX_NAME); @@ -201,7 +200,7 @@ /* Connect IrCOMM link with remote device */ ret = ircomm_tty_attach_cable(self); if (ret < 0) { - DEBUG(0, __FUNCTION__ "(), error attaching cable!\n"); + ERROR(__FUNCTION__ "(), error attaching cable!\n"); return ret; } @@ -227,7 +226,7 @@ tty = self->tty; - DEBUG(1, __FUNCTION__ "()\n"); + DEBUG(2, __FUNCTION__ "()\n"); if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) { /* this is a callout device */ @@ -283,7 +282,7 @@ retval = 0; add_wait_queue(&self->open_wait, &wait); - DEBUG(1, "%s(%d):block_til_ready before block on %s open_count=%d\n", + DEBUG(2, "%s(%d):block_til_ready before block on %s open_count=%d\n", __FILE__,__LINE__, tty->driver.name, self->open_count ); save_flags(flags); cli(); @@ -391,16 +390,25 @@ self->tqueue.routine = ircomm_tty_do_softint; self->tqueue.data = self; self->max_header_size = 5; - self->max_data_size = 2048-self->max_header_size; + self->max_data_size = 64-self->max_header_size; + self->close_delay = 5*HZ/10; + self->closing_wait = 30*HZ; /* Init some important stuff */ init_timer(&self->watchdog_timer); init_waitqueue_head(&self->open_wait); - skb_queue_head_init(&self->tx_queue); + init_waitqueue_head(&self->close_wait); + + /* + * Force TTY into raw mode by default which is usually what + * we want for IrCOMM and IrLPT. This way applications will + * not have to twiddle with printcap etc. + */ + tty->termios->c_iflag = 0; + tty->termios->c_oflag = 0; /* Insert into hash */ hashbin_insert(ircomm_tty, (QUEUE *) self, line, NULL); - } self->open_count++; @@ -413,12 +421,28 @@ /* Not really used by us, but lets do it anyway */ self->tty->low_latency = (self->flags & ASYNC_LOW_LATENCY) ? 1 : 0; + /* + * If the port is the middle of closing, bail out now + */ + if (tty_hung_up_p(filp) || + (self->flags & ASYNC_CLOSING)) { + if (self->flags & ASYNC_CLOSING) + interruptible_sleep_on(&self->close_wait); + /* MOD_DEC_USE_COUNT; "info->tty" will cause this? */ +#ifdef SERIAL_DO_RESTART + return ((self->flags & ASYNC_HUP_NOTIFY) ? + -EAGAIN : -ERESTARTSYS); +#else + return -EAGAIN; +#endif + } + /* Check if this is a "normal" ircomm device, or an irlpt device */ if (line < 0x10) { self->service_type = IRCOMM_3_WIRE | IRCOMM_9_WIRE; - DEBUG(0, __FUNCTION__ "(), IrCOMM device\n"); + DEBUG(2, __FUNCTION__ "(), IrCOMM device\n"); } else { - DEBUG(0, __FUNCTION__ "(), IrLPT device\n"); + DEBUG(2, __FUNCTION__ "(), IrLPT device\n"); self->service_type = IRCOMM_3_WIRE_RAW; } @@ -452,7 +476,6 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp) { struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; - struct sk_buff *skb; unsigned long flags; DEBUG(2, __FUNCTION__ "()\n"); @@ -484,7 +507,7 @@ MOD_DEC_USE_COUNT; restore_flags(flags); - DEBUG(2, __FUNCTION__ "(), returning 2\n"); + DEBUG(2, __FUNCTION__ "(), open count > 0\n"); return; } self->flags |= ASYNC_CLOSING; @@ -494,6 +517,10 @@ * the line discipline to only process XON/XOFF characters. */ tty->closing = 1; + if (self->closing_wait != ASYNC_CLOSING_WAIT_NONE) + tty_wait_until_sent(tty, self->closing_wait); + + self->flags &= ~ASYNC_INITIALIZED; if (tty->driver.flush_buffer) tty->driver.flush_buffer(tty); @@ -503,35 +530,47 @@ tty->closing = 0; self->tty = 0; - wake_up_interruptible(&self->open_wait); - + if (self->blocked_open) { + if (self->close_delay) { + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(self->close_delay); + } + wake_up_interruptible(&self->open_wait); + } + self->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE| ASYNC_CLOSING); + wake_up_interruptible(&self->close_wait); MOD_DEC_USE_COUNT; - restore_flags(flags); del_timer(&self->watchdog_timer); - /* Free frames queued for transmission */ - while ((skb = skb_dequeue(&self->tx_queue)) != NULL) - dev_kfree_skb(skb); - /* Free parameter buffer */ if (self->ctrl_skb) { dev_kfree_skb(self->ctrl_skb); self->ctrl_skb = NULL; } + /* Free transmit buffer */ + if (self->tx_skb) { + dev_kfree_skb(self->tx_skb); + self->tx_skb = NULL; + } + ircomm_tty_detach_cable(self); ircomm_close(self->ircomm); - self->ircomm = NULL; + + restore_flags(flags); + +#if IRCOMM_TTY_CLOSE_WILL_DEALLOC self->magic = 0; hashbin_remove(ircomm_tty, self->line, NULL); kfree(self); +#endif } /* @@ -544,18 +583,15 @@ { struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; - DEBUG(2, __FUNCTION__ "()\n"); - ASSERT(self != NULL, return;); ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); - /* Flush transmit buffer if any */ - if ((self->tx_skb) && (!tty->hw_stopped)) { - DEBUG(0, __FUNCTION__ "(), flushing!\n"); - ircomm_tty_do_event(self, IRCOMM_TTY_DATA_REQUEST, - self->tx_skb, NULL); - self->tx_skb = NULL; - } + /* + * Let do_softint() do this to avoid race condition with + * do_softint() ;-) + */ + queue_task(&self->tqueue, &tq_immediate); + mark_bh(IMMEDIATE_BH); } /* @@ -569,28 +605,31 @@ { struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) private_; struct tty_struct *tty; + unsigned long flags; + struct sk_buff *skb; - DEBUG(2, __FUNCTION__ "()\n"); - - ASSERT(self != NULL, return;); - ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); + if (!self || self->magic != IRCOMM_TTY_MAGIC) + return; tty = self->tty; if (!tty) return; - if (tty->hw_stopped) { - DEBUG(2, __FUNCTION__ "(), hw stopped!\n"); + if (tty->hw_stopped) return; - } + + /* Unlink transmit buffer */ + save_flags(flags); + cli(); + + skb = self->tx_skb; + self->tx_skb = NULL; + + restore_flags(flags); /* Flush transmit buffer if any */ - if (self->tx_skb) { - DEBUG(1, __FUNCTION__ "(), flushing!\n"); - ircomm_tty_do_event(self, IRCOMM_TTY_DATA_REQUEST, - self->tx_skb, NULL); - self->tx_skb = NULL; - } + if (skb) + ircomm_tty_do_event(self, IRCOMM_TTY_DATA_REQUEST, skb, NULL); /* Check if user (still) wants to be waken up */ if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && @@ -625,9 +664,9 @@ ASSERT(self != NULL, return -1;); ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); -/* save_flags(flags); + save_flags(flags); cli(); -*/ + /* Fetch current transmit buffer */ skb = self->tx_skb; @@ -637,20 +676,19 @@ * max data size. The normal case however is just the opposite, and * this function may be called multiple times, and will then actually * defragment the data and send it out as one packet as soon as - * possible, but at a safer point in time + * possible, but at a safer point in time */ - while (count && !tty->hw_stopped) { + while (count) { size = count; /* Adjust data size to the max data size */ - if (size > self->max_data_size) { - DEBUG(1, __FUNCTION__ - "(), size %d to big, clipping to %d!\n", - size, self->max_data_size); + if (size > self->max_data_size) size = self->max_data_size; - } - /* Do we already have a buffer ready for transmit? */ + /* + * Do we already have a buffer ready for transmit, or do + * we need to allocate a new frame + */ if (skb) { /* * Any room for more data at the end of the current @@ -663,25 +701,18 @@ if (size > tailroom) size = tailroom; } else { - /* Current transmit frame is full */ - DEBUG(1, __FUNCTION__ "(), flushing!\n"); - ircomm_tty_do_event(self, - IRCOMM_TTY_DATA_REQUEST, - skb, NULL); - skb = self->tx_skb = NULL; + /* + * Current transmit frame is full, so break + * out, so we can send it as soon as possible + */ + break; } - } - - /* Check if we need to allocate a new frame */ - if (!skb) { - DEBUG(3, __FUNCTION__ - "(), allocating new buffer of size %d!\n", - self->max_data_size+self->max_header_size); + } else { /* Prepare a full sized frame */ skb = dev_alloc_skb(self->max_data_size+ self->max_header_size); if (!skb) { - /*restore_flags(flags);*/ + restore_flags(flags); return -ENOBUFS; } skb_reserve(skb, self->max_header_size); @@ -694,12 +725,12 @@ else memcpy(skb_put(skb,size), buf+len, size); - DEBUG(1, __FUNCTION__ "(), size=%d\n", size); - count -= size; len += size; } + restore_flags(flags); + /* * Schedule a new thread which will transmit the frame as soon * as possible, but at a safe point in time. We do this so the @@ -710,8 +741,6 @@ queue_task(&self->tqueue, &tq_immediate); mark_bh(IMMEDIATE_BH); - /*restore_flags(flags);*/ - return len; } @@ -725,6 +754,7 @@ static int ircomm_tty_write_room(struct tty_struct *tty) { struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; + unsigned long flags; int ret; ASSERT(self != NULL, return -1;); @@ -734,10 +764,13 @@ if (tty->hw_stopped) ret = 0; else { + save_flags(flags); + cli(); if (self->tx_skb) ret = self->max_data_size - self->tx_skb->len; else ret = self->max_data_size; + restore_flags(flags); } DEBUG(2, __FUNCTION__ "(), ret=%d\n", ret); @@ -753,8 +786,27 @@ static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout) { struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; + unsigned long orig_jiffies, poll_time; + + DEBUG(0, __FUNCTION__ "()\n"); - DEBUG(2, __FUNCTION__ "(), not impl\n"); + ASSERT(self != NULL, return;); + ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); + + orig_jiffies = jiffies; + + /* Set poll time to 200 ms */ + poll_time = MIN(timeout, MSECS_TO_JIFFIES(200)); + + while (self->tx_skb && self->tx_skb->len) { + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(poll_time); + if (signal_pending(current)) + break; + if (timeout && time_after(jiffies, orig_jiffies + timeout)) + break; + } + current->state = TASK_RUNNING; } /* @@ -785,7 +837,6 @@ ircomm_param_request(self, IRCOMM_DTE, TRUE); } - DEBUG(1, __FUNCTION__"(), FLOW_STOP\n"); ircomm_flow_request(self->ircomm, FLOW_STOP); } @@ -829,10 +880,21 @@ static int ircomm_tty_chars_in_buffer(struct tty_struct *tty) { struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; + unsigned long flags; + int len = 0; - DEBUG(4, __FUNCTION__ "()\n"); + ASSERT(self != NULL, return -1;); + ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); + + save_flags(flags); + cli(); + + if (self->tx_skb) + len = self->tx_skb->len; - return 0; /* We don't have any "buffer" */ + restore_flags(flags); + + return len; } /* @@ -846,7 +908,10 @@ { struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; - DEBUG(0, __FUNCTION__"()\n"); + DEBUG(2, __FUNCTION__"()\n"); + + ASSERT(self != NULL, return;); + ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); if (!tty) return; @@ -889,8 +954,6 @@ { struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; - DEBUG(2, __FUNCTION__"()\n"); - ircomm_flow_request(self->ircomm, FLOW_START); } @@ -904,25 +967,13 @@ { struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; - DEBUG(2, __FUNCTION__"()\n"); + ASSERT(self != NULL, return;); + ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); ircomm_flow_request(self->ircomm, FLOW_STOP); } /* - * Function ircomm_tty_break (tty, break_state) - * - * - * - */ -static void ircomm_tty_break(struct tty_struct *tty, int break_state) -{ - struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; - - DEBUG(0, __FUNCTION__"(), not impl\n"); -} - -/* * Function ircomm_check_modem_status (self) * * Check for any changes in the DCE's line settings. This function should @@ -934,8 +985,6 @@ struct tty_struct *tty; int status; - DEBUG(4, __FUNCTION__ "()\n"); - ASSERT(self != NULL, return;); ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); @@ -967,13 +1016,9 @@ DEBUG(2, __FUNCTION__ "(), CTS tx start...\n"); tty->hw_stopped = 0; - - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) - && tty->ldisc.write_wakeup) - { - (tty->ldisc.write_wakeup)(tty); - } - wake_up_interruptible(&tty->write_wait); + + queue_task(&self->tqueue, &tq_immediate); + mark_bh(IMMEDIATE_BH); return; } } else { @@ -1045,35 +1090,6 @@ } /* - * Function ircomm_tty_disconnect_indication (instance, sap, reason, skb) - * - * Link disconnected - * - */ -static void ircomm_tty_disconnect_indication(void *instance, void *sap, - LM_REASON reason, - struct sk_buff *skb) -{ - struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance; - - DEBUG(2, __FUNCTION__ "()\n"); - - ASSERT(self != NULL, return;); - ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); - - if (!self->tty) - return; - - /* Drop carrier */ - self->session.dce = IRCOMM_DELTA_CD; - ircomm_tty_check_modem_status(self); -#if 0 - /* Disconnect */ - tty_hangup(self->tty); -#endif -} - -/* * Function ircomm_tty_flow_indication (instance, sap, cmd) * * This function is called by IrTTP when it wants us to slow down the @@ -1093,7 +1109,7 @@ switch (cmd) { case FLOW_START: - DEBUG(1, __FUNCTION__ "(), hw start!\n"); + DEBUG(2, __FUNCTION__ "(), hw start!\n"); tty->hw_stopped = 0; if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) @@ -1104,7 +1120,7 @@ default: /* If we get here, something is very wrong, better stop */ case FLOW_STOP: - DEBUG(1, __FUNCTION__ "(), hw stopped!\n"); + DEBUG(2, __FUNCTION__ "(), hw stopped!\n"); tty->hw_stopped = 1; break; } @@ -1114,6 +1130,8 @@ { int ret=0; + ret += sprintf(buf+ret, "State: %s\n", ircomm_tty_state[self->state]); + ret += sprintf(buf+ret, "Service type: "); if (self->service_type & IRCOMM_9_WIRE) ret += sprintf(buf+ret, "9_WIRE"); @@ -1125,12 +1143,15 @@ ret += sprintf(buf+ret, "No common service type!\n"); ret += sprintf(buf+ret, "\n"); + ret += sprintf(buf+ret, "Port name: %s\n", self->session.port_name); + ret += sprintf(buf+ret, "DTE status: "); if (self->session.dte & IRCOMM_RTS) ret += sprintf(buf+ret, "RTS|"); if (self->session.dte & IRCOMM_DTR) ret += sprintf(buf+ret, "DTR|"); - ret--; /* remove the last | */ + if (self->session.dte) + ret--; /* remove the last | */ ret += sprintf(buf+ret, "\n"); ret += sprintf(buf+ret, "DCE status: "); @@ -1142,7 +1163,8 @@ ret += sprintf(buf+ret, "CD|"); if (self->session.dce & IRCOMM_RI) ret += sprintf(buf+ret, "RI|"); - ret--; /* remove the last | */ + if (self->session.dce) + ret--; /* remove the last | */ ret += sprintf(buf+ret, "\n"); ret += sprintf(buf+ret, "Configuration: "); @@ -1171,7 +1193,8 @@ ret += sprintf(buf+ret, "ENQ_ACK_IN|"); if (self->session.flow_control & IRCOMM_ENQ_ACK_OUT) ret += sprintf(buf+ret, "ENQ_ACK_OUT|"); - ret--; /* remove the last | */ + if (self->session.flow_control) + ret--; /* remove the last | */ ret += sprintf(buf+ret, "\n"); ret += sprintf(buf+ret, "Flags: "); @@ -1189,7 +1212,8 @@ ret += sprintf(buf+ret, "ASYNC_NORMAL_ACTIVE|"); if (self->flags & ASYNC_CALLOUT_ACTIVE) ret += sprintf(buf+ret, "ASYNC_CALLOUT_ACTIVE|"); - ret--; /* remove the last | */ + if (self->flags) + ret--; /* remove the last | */ ret += sprintf(buf+ret, "\n"); ret += sprintf(buf+ret, "Open count: %d\n", self->open_count); @@ -1197,7 +1221,6 @@ ret += sprintf(buf+ret, "Hardware: %s\n", self->tty->hw_stopped ? "Stopped" : "Running"); - exit: ret += sprintf(buf+ret, "\n"); return ret; } @@ -1213,7 +1236,7 @@ int *eof, void *unused) { struct ircomm_tty_cb *self; - int i, count = 0, l; + int count = 0, l; off_t begin = 0; self = (struct ircomm_tty_cb *) hashbin_get_first(ircomm_tty); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/irda/ircomm/ircomm_tty_attach.c linux.ac/net/irda/ircomm/ircomm_tty_attach.c --- linux.vanilla/net/irda/ircomm/ircomm_tty_attach.c Thu Sep 2 00:48:51 1999 +++ linux.ac/net/irda/ircomm/ircomm_tty_attach.c Sat Sep 18 01:41:43 1999 @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli * Created at: Sat Jun 5 17:42:00 1999 - * Modified at: Wed Aug 25 13:32:00 1999 + * Modified at: Wed Sep 8 11:54:27 1999 * Modified by: Dag Brattli * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -96,6 +96,8 @@ "IRCOMM_TTY_DISCOVERY_INDICATION", "IRCOMM_TTY_CONNECT_CONFIRM", "IRCOMM_TTY_CONNECT_INDICATION", + "IRCOMM_TTY_DISCONNECT_REQUEST", + "IRCOMM_TTY_DISCONNECT_INDICATION", "IRCOMM_TTY_WD_TIMER_EXPIRED", "IRCOMM_TTY_GOT_PARAMETERS", "IRCOMM_TTY_GOT_LSAPSEL", @@ -167,8 +169,10 @@ irlmp_unregister_service(self->skey); /* Remove LM-IAS object */ - if (self->obj) + if (self->obj) { irias_delete_object(self->obj); + self->obj = NULL; + } ircomm_tty_do_event(self, IRCOMM_TTY_DETACH_CABLE, NULL, NULL); @@ -204,7 +208,8 @@ irias_insert_object(self->obj); } else { hints = irlmp_service_to_hint(S_COMM); - + hints |= irlmp_service_to_hint(S_TELEPHONY); + /* Register IrCOMM with LM-IAS */ self->obj = irias_new_object("IrDA:IrCOMM", IAS_IRCOMM_ID); irias_add_integer_attrib(self->obj, "IrDA:TinyTP:LsapSel", @@ -257,8 +262,8 @@ } /* Only 9-wire service types continue here */ -#if 0 ircomm_param_request(self, IRCOMM_FLOW_CONTROL, FALSE); +#if 0 ircomm_param_request(self, IRCOMM_XON_XOFF, FALSE); ircomm_param_request(self, IRCOMM_ENQ_ACK, FALSE); #endif @@ -297,6 +302,30 @@ } /* + * Function ircomm_tty_disconnect_indication (instance, sap, reason, skb) + * + * Link disconnected + * + */ +void ircomm_tty_disconnect_indication(void *instance, void *sap, + LM_REASON reason, + struct sk_buff *skb) +{ + struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance; + + DEBUG(2, __FUNCTION__ "()\n"); + + ASSERT(self != NULL, return;); + ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); + + if (!self->tty) + return; + + ircomm_tty_do_event(self, IRCOMM_TTY_DISCONNECT_INDICATION, NULL, + NULL); +} + +/* * Function ircomm_tty_getvalue_confirm (result, obj_id, value, priv) * * Got result from the IAS query we make @@ -315,7 +344,7 @@ /* Check if request succeeded */ if (result != IAS_SUCCESS) { - DEBUG(0, __FUNCTION__ "(), got NULL value!\n"); + DEBUG(4, __FUNCTION__ "(), got NULL value!\n"); return; } @@ -421,29 +450,35 @@ /* * IrCOMM link is now up, and if we are not using hardware - * flow-control, then declare the hardware as running + * flow-control, then declare the hardware as running. Otherwise + * the client will have to wait for the CD to be set. */ if (!(self->flags & ASYNC_CTS_FLOW)) { DEBUG(2, __FUNCTION__ "(), starting hardware!\n"); if (!self->tty) return; self->tty->hw_stopped = 0; - - /* Kick client */ - ircomm_tty_do_softint(self); } + /* Wake up processes blocked on open */ + wake_up_interruptible(&self->open_wait); + + /* + * Wake up processes blocked on write, or waiting for a write + * wakeup notification + */ + queue_task(&self->tqueue, &tq_immediate); + mark_bh(IMMEDIATE_BH); } /* * Function irlan_start_watchdog_timer (self, timeout) * - * - * + * Start the watchdog timer. This timer is used to make sure that any + * connection attempt is successful, and if not, we will retry after + * the timeout */ void ircomm_tty_start_watchdog_timer(struct ircomm_tty_cb *self, int timeout) { - DEBUG(4, __FUNCTION__ "()\n"); - irda_start_timer(&self->watchdog_timer, timeout, (void *) self, ircomm_tty_watchdog_timer_expired); } @@ -458,7 +493,7 @@ { struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) data; - DEBUG(1, __FUNCTION__ "()\n"); + DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); @@ -479,7 +514,7 @@ { int ret = 0; - DEBUG(1, __FUNCTION__": state=%s, event=%s\n", + DEBUG(2, __FUNCTION__": state=%s, event=%s\n", ircomm_tty_state[self->state], ircomm_tty_event[event]); switch (event) { @@ -507,9 +542,11 @@ /* Accept connection */ ircomm_connect_response(self->ircomm, NULL); - - ircomm_tty_link_established(self); ircomm_tty_next_state(self, IRCOMM_TTY_READY); + + /* Init connection */ + ircomm_tty_send_initial_parameters(self); + ircomm_tty_link_established(self); break; case IRCOMM_TTY_WD_TIMER_EXPIRED: /* Just stay idle */ @@ -518,7 +555,7 @@ ircomm_tty_next_state(self, IRCOMM_TTY_IDLE); break; default: - DEBUG(0, __FUNCTION__"(), unknown event: %s\n", + DEBUG(2, __FUNCTION__"(), unknown event: %s\n", ircomm_tty_event[event]); return -EINVAL; } @@ -538,7 +575,7 @@ { int ret = 0; - DEBUG(1, __FUNCTION__": state=%s, event=%s\n", + DEBUG(2, __FUNCTION__": state=%s, event=%s\n", ircomm_tty_state[self->state], ircomm_tty_event[event]); switch (event) { @@ -568,8 +605,11 @@ /* Accept connection */ ircomm_connect_response(self->ircomm, NULL); - ircomm_tty_link_established(self); ircomm_tty_next_state(self, IRCOMM_TTY_READY); + + /* Init connection */ + ircomm_tty_send_initial_parameters(self); + ircomm_tty_link_established(self); break; case IRCOMM_TTY_WD_TIMER_EXPIRED: /* Try to discover any remote devices */ @@ -580,7 +620,7 @@ ircomm_tty_next_state(self, IRCOMM_TTY_IDLE); break; default: - DEBUG(0, __FUNCTION__"(), unknown event: %s\n", + DEBUG(2, __FUNCTION__"(), unknown event: %s\n", ircomm_tty_event[event]); return -EINVAL; } @@ -600,7 +640,7 @@ { int ret = 0; - DEBUG(1, __FUNCTION__": state=%s, event=%s\n", + DEBUG(2, __FUNCTION__": state=%s, event=%s\n", ircomm_tty_state[self->state], ircomm_tty_event[event]); switch (event) { @@ -624,14 +664,17 @@ /* Accept connection */ ircomm_connect_response(self->ircomm, NULL); - ircomm_tty_link_established(self); ircomm_tty_next_state(self, IRCOMM_TTY_READY); + + /* Init connection */ + ircomm_tty_send_initial_parameters(self); + ircomm_tty_link_established(self); break; case IRCOMM_TTY_DETACH_CABLE: ircomm_tty_next_state(self, IRCOMM_TTY_IDLE); break; default: - DEBUG(0, __FUNCTION__"(), unknown event: %s\n", + DEBUG(2, __FUNCTION__"(), unknown event: %s\n", ircomm_tty_event[event]); return -EINVAL; } @@ -651,7 +694,7 @@ { int ret = 0; - DEBUG(1, __FUNCTION__": state=%s, event=%s\n", + DEBUG(2, __FUNCTION__": state=%s, event=%s\n", ircomm_tty_state[self->state], ircomm_tty_event[event]); switch (event) { @@ -673,14 +716,17 @@ /* Accept connection */ ircomm_connect_response(self->ircomm, NULL); - ircomm_tty_link_established(self); ircomm_tty_next_state(self, IRCOMM_TTY_READY); + + /* Init connection */ + ircomm_tty_send_initial_parameters(self); + ircomm_tty_link_established(self); break; case IRCOMM_TTY_DETACH_CABLE: ircomm_tty_next_state(self, IRCOMM_TTY_IDLE); break; default: - DEBUG(0, __FUNCTION__"(), unknown event: %s\n", + DEBUG(2, __FUNCTION__"(), unknown event: %s\n", ircomm_tty_event[event]); return -EINVAL; } @@ -700,38 +746,20 @@ { int ret = 0; - DEBUG(1, __FUNCTION__": state=%s, event=%s\n", + DEBUG(2, __FUNCTION__": state=%s, event=%s\n", ircomm_tty_state[self->state], ircomm_tty_event[event]); switch (event) { case IRCOMM_TTY_CONNECT_CONFIRM: - ircomm_tty_link_established(self); + del_timer(&self->watchdog_timer); ircomm_tty_next_state(self, IRCOMM_TTY_READY); - + /* * Send initial parameters. This will also send out queued * parameters waiting for the connection to come up */ ircomm_tty_send_initial_parameters(self); - - ASSERT(self->tty != NULL, return -1;); - - /* Send queued frames */ - while ((skb = skb_dequeue(&self->tx_queue))) { - ret = ircomm_data_request(self->ircomm, skb); - if (ret < 0) - break; - } - - /* Wake up processes blocked on open */ - wake_up_interruptible(&self->open_wait); - - /* - * Wake up processes blocked on write, or waiting for a write - * wakeup notification - */ - queue_task(&self->tqueue, &tq_immediate); - mark_bh(IMMEDIATE_BH); + ircomm_tty_link_established(self); break; case IRCOMM_TTY_CONNECT_INDICATION: del_timer(&self->watchdog_timer); @@ -739,6 +767,10 @@ /* Accept connection */ ircomm_connect_response(self->ircomm, NULL); ircomm_tty_next_state(self, IRCOMM_TTY_READY); + + /* Init connection */ + ircomm_tty_send_initial_parameters(self); + ircomm_tty_link_established(self); break; case IRCOMM_TTY_WD_TIMER_EXPIRED: /* Go back to search mode */ @@ -750,7 +782,7 @@ ircomm_tty_next_state(self, IRCOMM_TTY_IDLE); break; default: - DEBUG(0, __FUNCTION__"(), unknown event: %s\n", + DEBUG(2, __FUNCTION__"(), unknown event: %s\n", ircomm_tty_event[event]); return -EINVAL; } @@ -774,14 +806,20 @@ case IRCOMM_TTY_DATA_REQUEST: ret = ircomm_data_request(self->ircomm, skb); break; - case IRCOMM_TTY_DATA_INDICATION: - break; case IRCOMM_TTY_DETACH_CABLE: ircomm_disconnect_request(self->ircomm, NULL); ircomm_tty_next_state(self, IRCOMM_TTY_IDLE); break; + case IRCOMM_TTY_DISCONNECT_INDICATION: + ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH); + ircomm_tty_start_watchdog_timer(self, 3*HZ); + + /* Drop carrier */ + self->session.dce = IRCOMM_DELTA_CD; + ircomm_tty_check_modem_status(self); + break; default: - DEBUG(0, __FUNCTION__"(), unknown event: %s\n", + DEBUG(2, __FUNCTION__"(), unknown event: %s\n", ircomm_tty_event[event]); return -EINVAL; } @@ -813,7 +851,7 @@ { self->state = state; - DEBUG(1, __FUNCTION__": next state=%s, service type=%d\n", + DEBUG(2, __FUNCTION__": next state=%s, service type=%d\n", ircomm_tty_state[self->state], self->service_type); } diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/irda/ircomm/ircomm_tty_ioctl.c linux.ac/net/irda/ircomm/ircomm_tty_ioctl.c --- linux.vanilla/net/irda/ircomm/ircomm_tty_ioctl.c Thu Sep 2 00:48:51 1999 +++ linux.ac/net/irda/ircomm/ircomm_tty_ioctl.c Sat Sep 18 01:41:43 1999 @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli * Created at: Thu Jun 10 14:39:09 1999 - * Modified at: Wed Aug 25 14:11:02 1999 + * Modified at: Tue Aug 31 10:29:36 1999 * Modified by: Dag Brattli * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -196,12 +196,12 @@ DEBUG(1, __FUNCTION__ "()\n"); - result = ((self->session.dte & IRCOMM_RTS) ? TIOCM_RTS : 0) - | ((self->session.dte & IRCOMM_DTR) ? TIOCM_DTR : 0) - | ((self->session.dce & IRCOMM_DELTA_CD) ? TIOCM_CAR : 0) - | ((self->session.dce & IRCOMM_DELTA_RI) ? TIOCM_RNG : 0) - | ((self->session.dce & IRCOMM_DELTA_DSR) ? TIOCM_DSR : 0) - | ((self->session.dce & IRCOMM_DELTA_CTS) ? TIOCM_CTS : 0); + result = ((self->session.dte & IRCOMM_RTS) ? TIOCM_RTS : 0) + | ((self->session.dte & IRCOMM_DTR) ? TIOCM_DTR : 0) + | ((self->session.dce & IRCOMM_CD) ? TIOCM_CAR : 0) + | ((self->session.dce & IRCOMM_RI) ? TIOCM_RNG : 0) + | ((self->session.dce & IRCOMM_DSR) ? TIOCM_DSR : 0) + | ((self->session.dce & IRCOMM_CTS) ? TIOCM_CTS : 0); return put_user(result, value); } @@ -286,21 +286,19 @@ memset(&info, 0, sizeof(info)); info.line = self->line; - /* info.flags = self->flags; */ + info.flags = self->flags; info.baud_base = self->session.data_rate; -#if 0 - info.close_delay = driver->close_delay; - info.closing_wait = driver->closing_wait; -#endif + info.close_delay = self->close_delay; + info.closing_wait = self->closing_wait; + /* For compatibility */ info.type = PORT_16550A; info.port = 0; info.irq = 0; info.xmit_fifo_size = 0; info.hub6 = 0; -#if 0 - info.custom_divisor = driver->custom_divisor; -#endif + info.custom_divisor = 0; + if (copy_to_user(retinfo, &info, sizeof(*retinfo))) return -EFAULT; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/irda/irda_device.c linux.ac/net/irda/irda_device.c --- linux.vanilla/net/irda/irda_device.c Sat Sep 11 00:54:18 1999 +++ linux.ac/net/irda/irda_device.c Sat Sep 18 01:41:43 1999 @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli * Created at: Wed Sep 2 20:22:08 1998 - * Modified at: Tue Aug 24 14:31:13 1999 + * Modified at: Thu Sep 9 12:55:02 1999 * Modified by: Dag Brattli * Modified at: Fri May 28 3:11 CST 1999 * Modified by: Horst von Brand @@ -155,16 +155,16 @@ /* Allocate memory if needed */ if (self->rx_buff.truesize > 0) { - self->rx_buff.head = ( __u8 *) kmalloc(self->rx_buff.truesize, - self->rx_buff.flags); + self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize, + self->rx_buff.flags); if (self->rx_buff.head == NULL) return -ENOMEM; memset(self->rx_buff.head, 0, self->rx_buff.truesize); } if (self->tx_buff.truesize > 0) { - self->tx_buff.head = ( __u8 *) kmalloc(self->tx_buff.truesize, - self->tx_buff.flags); + self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, + self->tx_buff.flags); if (self->tx_buff.head == NULL) { kfree(self->rx_buff.head); return -ENOMEM; @@ -191,14 +191,15 @@ /* Initialize IrDA net device */ do { sprintf(self->name, "%s%d", "irda", i++); - } while (dev_get(self->name) != NULL); + } while (dev_get(self->name)); self->netdev.name = self->name; self->netdev.priv = (void *) self; self->netdev.next = NULL; - - if ((result = register_netdev(&self->netdev)) != 0) { - DEBUG(0, __FUNCTION__ "(), register_netdev() failed!\n"); + + result = register_netdev(&self->netdev); + if (result) { + ERROR(__FUNCTION__ "(), register_netdev() failed!\n"); return -1; } @@ -214,7 +215,7 @@ hashbin_insert(irda_device, (QUEUE *) self, (int) self, NULL); /* Open network device */ - dev_open(&self->netdev); + /*dev_open(&self->netdev);*/ MESSAGE("IrDA: Registered device %s\n", self->name); @@ -238,7 +239,7 @@ /* We do this test to know if the device has been registered at all */ if (self->netdev.type == ARPHRD_IRDA) { - dev_close(&self->netdev); + /*dev_close(&self->netdev);*/ /* Remove netdevice */ unregister_netdev(&self->netdev); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/irda/irlan/Config.in linux.ac/net/irda/irlan/Config.in --- linux.vanilla/net/irda/irlan/Config.in Sun Mar 7 23:26:44 1999 +++ linux.ac/net/irda/irlan/Config.in Mon Sep 13 00:22:42 1999 @@ -1 +1 @@ -dep_tristate 'IrLAN protocol' CONFIG_IRLAN $CONFIG_IRDA +dep_tristate ' IrLAN protocol' CONFIG_IRLAN $CONFIG_IRDA diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/irda/irlan/irlan_common.c linux.ac/net/irda/irlan/irlan_common.c --- linux.vanilla/net/irda/irlan/irlan_common.c Thu Sep 2 00:48:51 1999 +++ linux.ac/net/irda/irlan/irlan_common.c Sat Sep 18 01:41:43 1999 @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli * Created at: Sun Aug 31 20:14:37 1997 - * Modified at: Tue Aug 17 15:30:40 1999 + * Modified at: Thu Sep 9 11:39:43 1999 * Modified by: Dag Brattli * * Copyright (c) 1997, 1999 Dag Brattli , @@ -237,7 +237,7 @@ /* Get the first free irlan name */ do { sprintf(self->ifname, "%s%d", "irlan", i++); - } while (dev_get(self->ifname) != NULL); + } while (dev_get(self->ifname)); } self->dev.name = self->ifname; @@ -615,7 +615,7 @@ irias_add_string_attrib(obj, "DeviceID", "HWP19F0"); irias_add_integer_attrib(obj, "CompCnt", 1); if (self->provider.access_type == ACCESS_PEER) - irias_add_string_attrib(obj, "Comp#02", "PNP8389"); + irias_add_string_attrib(obj, "Comp#01", "PNP8389"); else irias_add_string_attrib(obj, "Comp#01", "PNP8294"); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/irda/irlap_event.c linux.ac/net/irda/irlap_event.c --- linux.vanilla/net/irda/irlap_event.c Thu Sep 2 00:48:52 1999 +++ linux.ac/net/irda/irlap_event.c Sat Sep 18 01:41:43 1999 @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli * Created at: Sat Aug 16 00:59:29 1997 - * Modified at: Wed Aug 25 14:49:47 1999 + * Modified at: Thu Sep 9 11:37:00 1999 * Modified by: Dag Brattli * * Copyright (c) 1998-1999 Dag Brattli , @@ -310,8 +310,6 @@ discovery_t *discovery_rsp; int ret = 0; - DEBUG(4, __FUNCTION__ "()\n"); - ASSERT(self != NULL, return -1;); ASSERT(self->magic == LAP_MAGIC, return -1;); @@ -337,16 +335,21 @@ irlap_next_state(self, LAP_SETUP); } break; - case RECV_SNRM_CMD: - self->daddr = info->daddr; - self->caddr = info->caddr; - - irlap_next_state(self, LAP_CONN); - - irlap_connect_indication(self, skb); + /* Check if the frame contains and I field */ + if (info) { + self->daddr = info->daddr; + self->caddr = info->caddr; + + irlap_next_state(self, LAP_CONN); + + irlap_connect_indication(self, skb); + } else { + DEBUG(0, __FUNCTION__ "(), SNRM frame does not contain" + " and I field!\n"); + dev_kfree_skb(skb); + } break; - case DISCOVERY_REQUEST: ASSERT(info != NULL, return -1;); @@ -422,6 +425,10 @@ default: DEBUG(2, __FUNCTION__ "(), Unknown event %s\n", irlap_event[event]); + + if (skb) + dev_kfree_skb(skb); + ret = -1; break; } @@ -499,7 +506,7 @@ irlap_event[event]); if (skb) - dev_kfree_skb( skb); + dev_kfree_skb(skb); ret = -1; break; @@ -615,27 +622,21 @@ irlap_start_wd_timer(self, self->wd_timeout); irlap_next_state( self, LAP_NRM_S); break; - - case RECV_SNRM_CMD: - DEBUG( 3, __FUNCTION__ "(), event RECV_SNRM_CMD!\n"); -#if 0 - irlap_next_state( self, LAP_NDM); -#endif - break; - case RECV_DISCOVERY_XID_CMD: DEBUG( 3, __FUNCTION__ "(), event RECV_DISCOVER_XID_CMD!\n"); irlap_next_state( self, LAP_NDM); - break; - + break; case DISCONNECT_REQUEST: irlap_send_dm_frame( self); irlap_next_state( self, LAP_CONN); break; - default: DEBUG(1, __FUNCTION__ "(), Unknown event %d, %s\n", event, irlap_event[event]); + + if (skb) + dev_kfree_skb(skb); + ret = -1; break; } @@ -694,7 +695,7 @@ * The device with the largest device address wins the battle * (both have sent a SNRM command!) */ - if (info->daddr > self->saddr) { + if (info &&(info->daddr > self->saddr)) { del_timer(&self->final_timer); irlap_initiate_connection_state(self); @@ -718,6 +719,7 @@ irlap_next_state(self, LAP_NRM_S); } else { /* We just ignore the other device! */ + dev_kfree_skb(skb); irlap_next_state(self, LAP_SETUP); } break; @@ -756,10 +758,14 @@ irlap_disconnect_indication(self, LAP_DISC_INDICATION); break; - /* DM handled in irlap_frame.c, irlap_input() */ - + /* DM handled in irlap_frame.c, irlap_driver_rcv() */ default: - DEBUG( 4, "irlap_state_setup: Unknown event"); + DEBUG(1, __FUNCTION__ "(), Unknown event %d, %s\n", event, + irlap_event[event]); + + if (skb) + dev_kfree_skb(skb); + ret = -1; break; } @@ -931,6 +937,10 @@ break; default: DEBUG(1, __FUNCTION__ "(), Unknown event %d\n", event); + + if (skb) + dev_kfree_skb(skb); + ret = -1; break; } @@ -1373,6 +1383,9 @@ default: DEBUG(1, __FUNCTION__ "(), Unknown event %s\n", irlap_event[event]); + if (skb) + dev_kfree_skb(skb); + ret = -1; break; } @@ -1443,17 +1456,31 @@ } break; case RECV_SNRM_CMD: - DEBUG(3, __FUNCTION__ "(), RECV_SNRM_CMD\n"); - irlap_initiate_connection_state(self); - irlap_wait_min_turn_around(self, &self->qos_tx); - irlap_send_ua_response_frame(self, &self->qos_rx); - irlap_reset_confirm(); - irlap_start_wd_timer(self, self->wd_timeout); - irlap_next_state(self, LAP_NDM); + /* + * SNRM frame is not allowed to contain an I-field in this + * state + */ + if (!info) { + DEBUG(3, __FUNCTION__ "(), RECV_SNRM_CMD\n"); + irlap_initiate_connection_state(self); + irlap_wait_min_turn_around(self, &self->qos_tx); + irlap_send_ua_response_frame(self, &self->qos_rx); + irlap_reset_confirm(); + irlap_start_wd_timer(self, self->wd_timeout); + irlap_next_state(self, LAP_NDM); + } else { + DEBUG(0, __FUNCTION__ "(), SNRM frame contained an I " + "field!\n"); + dev_kfree_skb(skb); + } break; default: DEBUG(1, __FUNCTION__ "(), Unknown event %s\n", irlap_event[event]); + + if (skb) + dev_kfree_skb(skb); + ret = -1; break; } @@ -1531,6 +1558,9 @@ default: DEBUG(1, __FUNCTION__ "(), Unknown event %s\n", irlap_event[event]); + if (skb) + dev_kfree_skb(skb); + ret = -EINVAL; break; } @@ -1785,11 +1815,18 @@ break; case RECV_SNRM_CMD: - del_timer(&self->wd_timer); - DEBUG(1, __FUNCTION__ "(), received SNRM cmd\n"); - irlap_next_state(self, LAP_RESET_CHECK); - - irlap_reset_indication(self); + /* SNRM frame is not allowed to contain an I-field */ + if (!info) { + del_timer(&self->wd_timer); + DEBUG(1, __FUNCTION__ "(), received SNRM cmd\n"); + irlap_next_state(self, LAP_RESET_CHECK); + + irlap_reset_indication(self); + } else { + DEBUG(0, __FUNCTION__ "(), SNRM frame contained an " + "I-field!\n"); + dev_kfree_skb(skb); + } break; case WD_TIMER_EXPIRED: DEBUG( 4, "WD_TIMER_EXPIRED: %ld\n", jiffies); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/irda/irlap_frame.c linux.ac/net/irda/irlap_frame.c --- linux.vanilla/net/irda/irlap_frame.c Thu Sep 2 00:48:52 1999 +++ linux.ac/net/irda/irlap_frame.c Sat Sep 18 01:41:43 1999 @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli * Created at: Tue Aug 19 10:27:26 1997 - * Modified at: Wed Aug 25 13:15:53 1999 + * Modified at: Thu Sep 9 11:23:49 1999 * Modified by: Dag Brattli * * Copyright (c) 1998-1999 Dag Brattli , @@ -161,27 +161,33 @@ { struct snrm_frame *frame; - DEBUG(3, __FUNCTION__ "()\n"); - - ASSERT(skb != NULL, return;); - ASSERT(info != NULL, return;); - frame = (struct snrm_frame *) skb->data; - - /* Copy peer device address */ - info->daddr = le32_to_cpu(frame->saddr); - - /* Copy connection address */ - info->caddr = frame->ncaddr; - - /* Check if connection address has got a valid value */ - if ((info->caddr == 0x00) || (info->caddr == 0xfe)) { - DEBUG(3, __FUNCTION__ "(), invalid connection address!\n"); - dev_kfree_skb(skb); - return; - } - - irlap_do_event(self, RECV_SNRM_CMD, skb, info); + + if (skb->len >= sizeof(struct snrm_frame)) { + /* Copy the new connection address */ + info->caddr = frame->ncaddr; + + /* Check if the new connection address is valid */ + if ((info->caddr == 0x00) || (info->caddr == 0xfe)) { + DEBUG(3, __FUNCTION__ + "(), invalid connection address!\n"); + dev_kfree_skb(skb); + return; + } + + /* Copy peer device address */ + info->daddr = le32_to_cpu(frame->saddr); + info->saddr = le32_to_cpu(frame->saddr); + + /* Only accept if addressed directly to us */ + if (info->saddr != self->saddr) { + dev_kfree_skb(skb); + return; + } + irlap_do_event(self, RECV_SNRM_CMD, skb, info); + } else + /* Signal that this SNRM frame does not contain and I-field */ + irlap_do_event(self, RECV_SNRM_CMD, skb, NULL); } /* @@ -318,7 +324,7 @@ skb_put(skb, 14); frame = (struct xid_frame *) skb->data; - if ( command) { + if (command) { frame->caddr = CBROADCAST | CMD_FRAME; frame->control = XID_CMD | PF_BIT; } else { @@ -334,7 +340,7 @@ else frame->daddr = cpu_to_le32(discovery->daddr); - switch(S) { + switch (S) { case 1: frame->flags = 0x00; break; @@ -402,18 +408,24 @@ ASSERT(self != NULL, return;); ASSERT(self->magic == LAP_MAGIC, return;); + xid = (struct xid_frame *) skb->data; + + info->daddr = le32_to_cpu(xid->saddr); + info->saddr = le32_to_cpu(xid->daddr); + + /* Make sure frame is addressed to us */ + if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) { + dev_kfree_skb(skb); + DEBUG(0, __FUNCTION__ "(), frame is not addressed to us!\n"); + return; + } + if ((discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC)) == NULL) { - DEBUG(0, __FUNCTION__ "(), kmalloc failed!\n"); + WARNING(__FUNCTION__ "(), kmalloc failed!\n"); return; } memset(discovery, 0, sizeof(discovery_t)); - xid = (struct xid_frame *) skb->data; - - /* - * Copy peer device address and set the source address - */ - info->daddr = le32_to_cpu(xid->saddr); discovery->daddr = info->daddr; discovery->saddr = self->saddr; discovery->timestamp = jiffies; @@ -462,17 +474,17 @@ __u8 *discovery_info; char *text; - DEBUG(4, __FUNCTION__ "()\n"); - - ASSERT(self != NULL, return;); - ASSERT(self->magic == LAP_MAGIC, return;); - ASSERT(skb != NULL, return;); - ASSERT(info != NULL, return;); - xid = (struct xid_frame *) skb->data; - - /* Copy peer device address */ + info->daddr = le32_to_cpu(xid->saddr); + info->saddr = le32_to_cpu(xid->daddr); + + /* Make sure frame is addressed to us */ + if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) { + DEBUG(0, __FUNCTION__ "(), frame is not addressed to us!\n"); + dev_kfree_skb(skb); + return; + } switch (xid->flags & 0x03) { case 0x00: @@ -567,7 +579,7 @@ * * Received RR (Receive Ready) frame from peer station, no harm in * making it inline since its called only from one single place - * (irlap_input). + * (irlap_driver_rcv). */ static inline void irlap_recv_rr_frame(struct irlap_cb *self, struct sk_buff *skb, @@ -642,21 +654,16 @@ static void irlap_recv_ua_frame(struct irlap_cb *self, struct sk_buff *skb, struct irlap_info *info) { - DEBUG(4, __FUNCTION__ "(), <%ld>\n", jiffies); - - ASSERT(skb != NULL, return;); - ASSERT(info != NULL, return;); - irlap_do_event(self, RECV_UA_RSP, skb, info); } /* * Function irlap_send_data_primary(self, skb) * - * + * Send I-frames as the primary station but without the poll bit set * */ -void irlap_send_data_primary( struct irlap_cb *self, struct sk_buff *skb) +void irlap_send_data_primary(struct irlap_cb *self, struct sk_buff *skb) { struct sk_buff *tx_skb; @@ -784,7 +791,7 @@ ASSERT( skb != NULL, return;); /* Is this reliable or unreliable data? */ - if ( skb->data[1] == I_FRAME) { + if (skb->data[1] == I_FRAME) { /* * Insert frame sequence number (Vs) in control field before @@ -792,17 +799,17 @@ */ skb->data[1] = I_FRAME | (self->vs << 1); - tx_skb = skb_clone( skb, GFP_ATOMIC); - if ( tx_skb == NULL) { - dev_kfree_skb( skb); + tx_skb = skb_clone(skb, GFP_ATOMIC); + if (tx_skb == NULL) { + dev_kfree_skb(skb); return; } if (skb->sk != NULL) - skb_set_owner_w( tx_skb, skb->sk); + skb_set_owner_w(tx_skb, skb->sk); /* Insert frame in store */ - skb_queue_tail( &self->wx_list, skb); + skb_queue_tail(&self->wx_list, skb); tx_skb->data[1] |= PF_BIT; @@ -810,21 +817,21 @@ self->window = self->window_size; self->ack_required = FALSE; - irlap_start_wd_timer( self, self->wd_timeout); + irlap_start_wd_timer(self, self->wd_timeout); - irlap_send_i_frame( self, tx_skb, RSP_FRAME); + irlap_send_i_frame(self, tx_skb, RSP_FRAME); } else { - if ( self->ack_required) { - irlap_send_ui_frame( self, skb, RSP_FRAME); - irlap_send_rr_frame( self, RSP_FRAME); + if (self->ack_required) { + irlap_send_ui_frame(self, skb, RSP_FRAME); + irlap_send_rr_frame(self, RSP_FRAME); self->ack_required = FALSE; } else { skb->data[1] |= PF_BIT; - irlap_send_ui_frame( self, skb, RSP_FRAME); + irlap_send_ui_frame(self, skb, RSP_FRAME); } self->window = self->window_size; - irlap_start_wd_timer( self, self->wd_timeout); + irlap_start_wd_timer(self, self->wd_timeout); } } @@ -834,16 +841,12 @@ * Send I(nformation) frame as secondary without final bit set * */ -void irlap_send_data_secondary( struct irlap_cb *self, struct sk_buff *skb) +void irlap_send_data_secondary(struct irlap_cb *self, struct sk_buff *skb) { struct sk_buff *tx_skb = NULL; - ASSERT( self != NULL, return;); - ASSERT( self->magic == LAP_MAGIC, return;); - ASSERT( skb != NULL, return;); - /* Is this reliable or unreliable data? */ - if ( skb->data[1] == I_FRAME) { + if (skb->data[1] == I_FRAME) { /* * Insert frame sequence number (Vs) in control field before @@ -851,25 +854,25 @@ */ skb->data[1] = I_FRAME | (self->vs << 1); - tx_skb = skb_clone( skb, GFP_ATOMIC); - if ( tx_skb == NULL) { - dev_kfree_skb( skb); + tx_skb = skb_clone(skb, GFP_ATOMIC); + if (tx_skb == NULL) { + dev_kfree_skb(skb); return; } if (skb->sk != NULL) - skb_set_owner_w( tx_skb, skb->sk); + skb_set_owner_w(tx_skb, skb->sk); /* Insert frame in store */ - skb_queue_tail( &self->wx_list, skb); + skb_queue_tail(&self->wx_list, skb); self->vs = (self->vs + 1) % 8; self->ack_required = FALSE; self->window -= 1; - irlap_send_i_frame( self, tx_skb, RSP_FRAME); + irlap_send_i_frame(self, tx_skb, RSP_FRAME); } else { - irlap_send_ui_frame( self, skb, RSP_FRAME); + irlap_send_ui_frame(self, skb, RSP_FRAME); self->window -= 1; } } @@ -883,16 +886,14 @@ * * FIXME: It is not safe to traverse a this list without locking it! */ -void irlap_resend_rejected_frames( struct irlap_cb *self, int command) +void irlap_resend_rejected_frames(struct irlap_cb *self, int command) { struct sk_buff *tx_skb; struct sk_buff *skb; int count; - ASSERT( self != NULL, return;); - ASSERT( self->magic == LAP_MAGIC, return;); - - DEBUG(2, __FUNCTION__ "(), retry_count=%d\n", self->retry_count); + ASSERT(self != NULL, return;); + ASSERT(self->magic == LAP_MAGIC, return;); /* Initialize variables */ skb = tx_skb = NULL; @@ -900,22 +901,22 @@ /* * Resend all unacknowledged frames */ - count = skb_queue_len( &self->wx_list); - skb = skb_peek( &self->wx_list); - while ( skb != NULL) { - irlap_wait_min_turn_around( self, &self->qos_tx); + count = skb_queue_len(&self->wx_list); + skb = skb_peek(&self->wx_list); + while (skb != NULL) { + irlap_wait_min_turn_around(self, &self->qos_tx); /* We copy the skb to be retransmitted since we will have to * modify it. Cloning will confuse packet sniffers */ /* tx_skb = skb_clone( skb, GFP_ATOMIC); */ tx_skb = skb_copy(skb, GFP_ATOMIC); - if ( tx_skb == NULL) { + if (tx_skb == NULL) { /* Unlink tx_skb from list */ tx_skb->next = tx_skb->prev = NULL; tx_skb->list = NULL; - dev_kfree_skb( skb); + dev_kfree_skb(skb); return; } /* Unlink tx_skb from list */ @@ -925,8 +926,8 @@ /* * make sure the skb->sk accounting of memory usage is sane */ - if ( skb->sk != NULL) - skb_set_owner_w( tx_skb, skb->sk); + if (skb->sk != NULL) + skb_set_owner_w(tx_skb, skb->sk); /* Clear old Nr field + poll bit */ tx_skb->data[1] &= 0x0f; @@ -934,18 +935,18 @@ /* * Set poll bit on the last frame retransmitted */ - if ( count-- == 1) + if (count-- == 1) tx_skb->data[1] |= PF_BIT; /* Set p/f bit */ else tx_skb->data[1] &= ~PF_BIT; /* Clear p/f bit */ - irlap_send_i_frame( self, tx_skb, command); + irlap_send_i_frame(self, tx_skb, command); /* * If our skb is the last buffer in the list, then * we are finished, if not, move to the next sk-buffer */ - if ( skb == skb_peek_tail( &self->wx_list)) + if (skb == skb_peek_tail( &self->wx_list)) skb = NULL; else skb = skb->next; @@ -955,13 +956,13 @@ */ return; /* Skip this for now, DB */ - while ( skb_queue_len( &self->tx_list) > 0) { + while (skb_queue_len( &self->tx_list) > 0) { - DEBUG( 0, __FUNCTION__ "(), sending additional frames!\n"); - if (( skb_queue_len( &self->tx_list) > 0) && - ( self->window > 0)) { + DEBUG(0, __FUNCTION__ "(), sending additional frames!\n"); + if ((skb_queue_len( &self->tx_list) > 0) && + (self->window > 0)) { skb = skb_dequeue( &self->tx_list); - ASSERT( skb != NULL, return;); + ASSERT(skb != NULL, return;); /* * If send window > 1 then send frame with pf @@ -989,11 +990,11 @@ { __u8 *frame; - DEBUG( 4, __FUNCTION__ "()\n"); + DEBUG(4, __FUNCTION__ "()\n"); - ASSERT( self != NULL, return;); - ASSERT( self->magic == LAP_MAGIC, return;); - ASSERT( skb != NULL, return;); + ASSERT(self != NULL, return;); + ASSERT(self->magic == LAP_MAGIC, return;); + ASSERT(skb != NULL, return;); frame = skb->data; @@ -1012,16 +1013,12 @@ void irlap_send_i_frame(struct irlap_cb *self, struct sk_buff *skb, int command) { - __u8 *frame; - - frame = skb->data; - /* Insert connection address */ - frame[0] = self->caddr; - frame[0] |= (command) ? CMD_FRAME : 0; + skb->data[0] = self->caddr; + skb->data[0] |= (command) ? CMD_FRAME : 0; /* Insert next to receive (Vr) */ - frame[1] |= (self->vr << 5); /* insert nr */ + skb->data[1] |= (self->vr << 5); /* insert nr */ irlap_queue_xmit(self, skb); } @@ -1030,7 +1027,7 @@ * Function irlap_recv_i_frame (skb, frame) * * Receive and parse an I (Information) frame, no harm in making it inline - * since it's called only from one single place (irlap_input). + * since it's called only from one single place (irlap_driver_rcv). */ static inline void irlap_recv_i_frame(struct irlap_cb *self, struct sk_buff *skb, @@ -1079,12 +1076,12 @@ __u8 *frame; int w, x, y, z; - DEBUG( 0, __FUNCTION__ "()\n"); + DEBUG(0, __FUNCTION__ "()\n"); - ASSERT( self != NULL, return;); - ASSERT( self->magic == LAP_MAGIC, return;); - ASSERT( skb != NULL, return;); - ASSERT( info != NULL, return;); + ASSERT(self != NULL, return;); + ASSERT(self->magic == LAP_MAGIC, return;); + ASSERT(skb != NULL, return;); + ASSERT(info != NULL, return;); frame = skb->data; @@ -1183,6 +1180,12 @@ info->daddr = le32_to_cpu(frame->saddr); info->saddr = le32_to_cpu(frame->daddr); + /* Make sure frame is addressed to us */ + if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) { + dev_kfree_skb(skb); + return; + } + if (command) irlap_do_event(self, RECV_TEST_CMD, skb, info); else @@ -1208,7 +1211,12 @@ idev = (struct irda_device *) dev->priv; self = idev->irlap; - ASSERT(skb->len > 1, return -1;); + /* Check if frame is large enough for parsing */ + if (skb->len < 2) { + DEBUG(0, __FUNCTION__ "(), frame to short!\n"); + dev_kfree_skb(skb); + return -1; + } command = skb->data[0] & CMD_FRAME; info.caddr = skb->data[0] & CBROADCAST; @@ -1218,10 +1226,9 @@ control = info.control; - /* First check if this frame addressed to us */ + /* First we check if this frame has a valid connection address */ if ((info.caddr != self->caddr) && (info.caddr != CBROADCAST)) { - DEBUG(2, __FUNCTION__ "(), Received frame is not for us!\n"); - + DEBUG(0, __FUNCTION__ "(), wrong connection address!\n"); dev_kfree_skb(skb); return 0; } diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/irda/irlmp.c linux.ac/net/irda/irlmp.c --- linux.vanilla/net/irda/irlmp.c Thu Sep 2 00:48:52 1999 +++ linux.ac/net/irda/irlmp.c Sat Sep 18 01:41:43 1999 @@ -6,7 +6,7 @@ * Status: Stable. * Author: Dag Brattli * Created at: Sun Aug 17 20:54:32 1997 - * Modified at: Mon Aug 23 09:30:56 1999 + * Modified at: Wed Sep 8 12:08:07 1999 * Modified by: Dag Brattli * * Copyright (c) 1998-1999 Dag Brattli , @@ -1117,6 +1117,10 @@ case S_OBEX: hint.byte[0] |= HINT_EXTENSION; hint.byte[1] |= HINT_OBEX; + break; + case S_TELEPHONY: + hint.byte[0] |= HINT_EXTENSION; + hint.byte[1] |= HINT_TELEPHONY; break; case S_ANY: hint.word = 0xffff; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/irda/irlmp_event.c linux.ac/net/irda/irlmp_event.c --- linux.vanilla/net/irda/irlmp_event.c Tue Sep 7 22:07:14 1999 +++ linux.ac/net/irda/irlmp_event.c Sat Sep 18 01:41:43 1999 @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli * Created at: Mon Aug 4 20:40:53 1997 - * Modified at: Wed Aug 25 14:38:49 1999 + * Modified at: Sun Sep 5 18:30:06 1999 * Modified by: Dag Brattli * * Copyright (c) 1998-1999 Dag Brattli , @@ -638,7 +638,20 @@ irlmp_connect_confirm(self, skb); break; case LM_DISCONNECT_INDICATION: - DEBUG(0, __FUNCTION__ "(), this should never happen!!\n"); + irlmp_next_lsap_state(self, LSAP_DISCONNECTED); + + ASSERT(self->lap != NULL, return -1;); + ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;); + + ASSERT(skb != NULL, return -1;); + ASSERT(skb->len > 3, return -1;); + reason = skb->data[3]; + + /* Try to close the LAP connection */ + DEBUG(4, __FUNCTION__ "(), trying to close IrLAP\n"); + irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL); + + irlmp_disconnect_indication(self, reason, skb); break; case LM_LAP_DISCONNECT_INDICATION: irlmp_next_lsap_state(self, LSAP_DISCONNECTED); diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/irda/irttp.c linux.ac/net/irda/irttp.c --- linux.vanilla/net/irda/irttp.c Thu Sep 2 00:48:52 1999 +++ linux.ac/net/irda/irttp.c Sat Sep 18 01:41:43 1999 @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli * Created at: Sun Aug 31 20:14:31 1997 - * Modified at: Thu Jul 8 21:25:31 1999 + * Modified at: Tue Aug 31 14:55:24 1999 * Modified by: Dag Brattli * * Copyright (c) 1998-1999 Dag Brattli , @@ -797,7 +797,7 @@ DEBUG(4, __FUNCTION__ "() send=%d,avail=%d,remote=%d\n", self->send_credit, self->avail_credit, self->remote_credit); - DEBUG(0, __FUNCTION__ "(), MaxSduSize=%d\n", self->tx_max_sdu_size); + DEBUG(2, __FUNCTION__ "(), MaxSduSize=%d\n", self->tx_max_sdu_size); if (self->notify.connect_confirm) { self->notify.connect_confirm(self->notify.instance, self, qos, @@ -869,8 +869,6 @@ /* Remove parameters */ skb_pull(skb, MIN(skb->len, plen+1)); } - - DEBUG(4, __FUNCTION__ "(), initial send_credit=%d\n", n); if (self->notify.connect_indication) { self->notify.connect_indication(self->notify.instance, self, diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/irda/qos.c linux.ac/net/irda/qos.c --- linux.vanilla/net/irda/qos.c Thu Sep 2 00:48:52 1999 +++ linux.ac/net/irda/qos.c Sat Sep 18 01:41:43 1999 @@ -7,7 +7,7 @@ * Status: Experimental. * Author: Dag Brattli * Created at: Tue Sep 9 00:00:26 1997 - * Modified at: Tue Aug 17 10:25:21 1999 + * Modified at: Wed Sep 1 09:14:55 1999 * Modified by: Dag Brattli * * Copyright (c) 1998-1999 Dag Brattli , @@ -278,7 +278,7 @@ if (get) { param->pv.i = self->qos_rx.baud_rate.bits; - DEBUG(0, __FUNCTION__ "(), baud rate = 0x%02x\n", param->pv.i); + DEBUG(2, __FUNCTION__ "(), baud rate = 0x%02x\n", param->pv.i); } else { /* * Stations must agree on baud rate, so calculate diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/khttpd/Config.in linux.ac/net/khttpd/Config.in --- linux.vanilla/net/khttpd/Config.in Mon Aug 23 15:12:20 1999 +++ linux.ac/net/khttpd/Config.in Mon Sep 13 00:22:42 1999 @@ -1,4 +1,4 @@ # # kHTTPd # -tristate 'Kernel httpd acceleration (experimental)' CONFIG_KHTTPD +tristate ' Kernel httpd acceleration (EXPERIMENTAL)' CONFIG_KHTTPD diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/netsyms.c linux.ac/net/netsyms.c --- linux.vanilla/net/netsyms.c Thu Sep 2 00:48:52 1999 +++ linux.ac/net/netsyms.c Sun Sep 5 15:14:43 1999 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -67,6 +68,8 @@ #endif +extern int netdev_finish_unregister(struct net_device *dev); + #include #if defined(CONFIG_ULTRA) || defined(CONFIG_WD80x3) || \ @@ -447,6 +450,12 @@ EXPORT_SYMBOL(tr_freedev); #endif +#ifdef CONFIG_NET_FC +EXPORT_SYMBOL(register_fcdev); +EXPORT_SYMBOL(unregister_fcdev); +EXPORT_SYMBOL(init_fcdev); +#endif + /* Device callback registration */ EXPORT_SYMBOL(register_netdevice_notifier); EXPORT_SYMBOL(unregister_netdevice_notifier); @@ -515,8 +524,10 @@ EXPORT_SYMBOL(unregister_hipdev); #endif +#ifdef CONFIG_SYSCTL EXPORT_SYMBOL(sysctl_wmem_max); EXPORT_SYMBOL(sysctl_rmem_max); +#endif #if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE) #include diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/sched/Config.in linux.ac/net/sched/Config.in --- linux.vanilla/net/sched/Config.in Thu Aug 26 14:42:29 1999 +++ linux.ac/net/sched/Config.in Mon Sep 13 00:22:42 1999 @@ -8,7 +8,7 @@ #tristate 'H-PFQ packet scheduler' CONFIG_NET_SCH_HPFQ #tristate 'H-FSC packet scheduler' CONFIG_NET_SCH_HFCS if [ "$CONFIG_ATM" = "y" ]; then - bool 'ATM pseudo-scheduler' CONFIG_NET_SCH_ATM + bool 'ATM pseudo-scheduler' CONFIG_NET_SCH_ATM fi tristate 'The simplest PRIO pseudoscheduler' CONFIG_NET_SCH_PRIO tristate 'RED queue' CONFIG_NET_SCH_RED @@ -17,20 +17,20 @@ tristate 'TBF queue' CONFIG_NET_SCH_TBF bool 'QoS support' CONFIG_NET_QOS if [ "$CONFIG_NET_QOS" = "y" ]; then - bool 'Rate estimator' CONFIG_NET_ESTIMATOR + bool ' Rate estimator' CONFIG_NET_ESTIMATOR fi bool 'Packet classifier API' CONFIG_NET_CLS if [ "$CONFIG_NET_CLS" = "y" ]; then - tristate 'Routing table based classifier' CONFIG_NET_CLS_ROUTE4 - if [ "$CONFIG_NET_CLS_ROUTE4" != "n" ]; then - define_bool CONFIG_NET_CLS_ROUTE y - fi - tristate 'Firewall based classifier' CONFIG_NET_CLS_FW - tristate 'U32 classifier' CONFIG_NET_CLS_U32 - if [ "$CONFIG_NET_QOS" = "y" ]; then - tristate 'Special RSVP classifier' CONFIG_NET_CLS_RSVP - tristate 'Special RSVP classifier for IPv6' CONFIG_NET_CLS_RSVP6 - bool 'Ingres traffic policing' CONFIG_NET_CLS_POLICE - fi + tristate ' Routing table based classifier' CONFIG_NET_CLS_ROUTE4 + if [ "$CONFIG_NET_CLS_ROUTE4" != "n" ]; then + define_bool CONFIG_NET_CLS_ROUTE y + fi + tristate ' Firewall based classifier' CONFIG_NET_CLS_FW + tristate ' U32 classifier' CONFIG_NET_CLS_U32 + if [ "$CONFIG_NET_QOS" = "y" ]; then + tristate ' Special RSVP classifier' CONFIG_NET_CLS_RSVP + tristate ' Special RSVP classifier for IPv6' CONFIG_NET_CLS_RSVP6 + bool ' Ingres traffic policing' CONFIG_NET_CLS_POLICE + fi fi diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/socket.c linux.ac/net/socket.c --- linux.vanilla/net/socket.c Tue Sep 7 22:07:14 1999 +++ linux.ac/net/socket.c Wed Sep 15 23:56:18 1999 @@ -670,7 +670,7 @@ /* This function may be called only under socket lock or callback_lock */ -int sock_wake_async(struct socket *sock, int how) +int sock_wake_async(struct socket *sock, int how, int band) { if (!sock || !sock->fasync_list) return -1; @@ -689,9 +689,11 @@ call_kill: /* read_lock(&sock->sk->callback_lock); */ if(sock->fasync_list != NULL) - kill_fasync(sock->fasync_list, SIGIO); + kill_fasync(sock->fasync_list, SIGIO, band); /* read_unlock(&sock->sk->callback_lock); */ break; + case 3: + kill_fasync(sock->fasync_list, SIGURG, band); } return 0; } diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/unix/af_unix.c linux.ac/net/unix/af_unix.c --- linux.vanilla/net/unix/af_unix.c Sat Sep 11 00:54:18 1999 +++ linux.ac/net/unix/af_unix.c Fri Sep 10 17:56:53 1999 @@ -299,7 +299,7 @@ read_lock(&sk->callback_lock); if (!sk->dead && unix_writable(sk)) { wake_up_interruptible(sk->sleep); - sock_wake_async(sk->socket, 2); + sock_wake_async(sk->socket, 2, POLL_OUT); } read_unlock(&sk->callback_lock); } diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/wanrouter/wanmain.c linux.ac/net/wanrouter/wanmain.c --- linux.vanilla/net/wanrouter/wanmain.c Thu Sep 2 00:48:52 1999 +++ linux.ac/net/wanrouter/wanmain.c Sun Sep 19 17:41:01 1999 @@ -11,6 +11,8 @@ * * Author: Gene Kozin * +* Fixes: Arnaldo Carvalho de Melo +* * Copyright: (c) 1995-1997 Sangoma Technologies Inc. * * This program is free software; you can redistribute it and/or diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/net/x25/x25_in.c linux.ac/net/x25/x25_in.c --- linux.vanilla/net/x25/x25_in.c Mon Jul 27 07:35:58 1998 +++ linux.ac/net/x25/x25_in.c Wed Sep 15 23:56:18 1999 @@ -278,6 +278,7 @@ kill_proc(sk->proc, SIGURG, 1); else kill_pg(-sk->proc, SIGURG, 1); + sock_wake_async(sk, 3, POLL_PRI); } x25_write_internal(sk, X25_INTERRUPT_CONFIRMATION); break; diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/old.c linux.ac/old.c --- linux.vanilla/old.c Thu Jan 1 01:00:00 1970 +++ linux.ac/old.c Mon Sep 20 00:52:10 1999 @@ -0,0 +1,2496 @@ +/*****************************************************************************/ + +/* + * sonicvibes.c -- S3 Sonic Vibes audio driver. + * + * Copyright (C) 1998 Thomas Sailer (sailer@ife.ee.ethz.ch) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You 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. + * + * Special thanks to David C. Niemi + * + * + * Module command line parameters: + * none so far + * + * + * Supported devices: + * /dev/dsp standard /dev/dsp device, (mostly) OSS compatible + * /dev/mixer standard /dev/mixer device, (mostly) OSS compatible + * /dev/midi simple MIDI UART interface, no ioctl + * + * The card has both an FM and a Wavetable synth, but I have to figure + * out first how to drive them... + * + * Revision history + * 06.05.98 0.1 Initial release + * 10.05.98 0.2 Fixed many bugs, esp. ADC rate calculation + * First stab at a simple midi interface (no bells&whistles) + * 13.05.98 0.3 Fix stupid cut&paste error: set_adc_rate was called instead of + * set_dac_rate in the FMODE_WRITE case in sv_open + * Fix hwptr out of bounds (now mpg123 works) + * 14.05.98 0.4 Don't allow excessive interrupt rates + * 08.06.98 0.5 First release using Alan Cox' soundcore instead of miscdevice + * 03.08.98 0.6 Do not include modversions.h + * Now mixer behaviour can basically be selected between + * "OSS documented" and "OSS actual" behaviour + * 31.08.98 0.7 Fix realplayer problems - dac.count issues + * 10.12.98 0.8 Fix drain_dac trying to wait on not yet initialized DMA + * 16.12.98 0.9 Fix a few f_file & FMODE_ bugs + * 06.01.99 0.10 remove the silly SA_INTERRUPT flag. + * hopefully killed the egcs section type conflict + * 12.03.99 0.11 cinfo.blocks should be reset after GETxPTR ioctl. + * reported by Johan Maes + * 22.03.99 0.12 return EAGAIN instead of EBUSY when O_NONBLOCK + * read/write cannot be executed + * + */ + +/*****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dm.h" + +/* --------------------------------------------------------------------- */ + +#undef OSS_DOCUMENTED_MIXER_SEMANTICS + +/* --------------------------------------------------------------------- */ + +#ifndef PCI_VENDOR_ID_S3 +#define PCI_VENDOR_ID_S3 0x5333 +#endif +#ifndef PCI_DEVICE_ID_S3_SONICVIBES +#define PCI_DEVICE_ID_S3_SONICVIBES 0xca00 +#endif + +#define SV_MAGIC ((PCI_VENDOR_ID_S3<<16)|PCI_DEVICE_ID_S3_SONICVIBES) + +#define SV_EXTENT_SB 0x10 +#define SV_EXTENT_ENH 0x10 +#define SV_EXTENT_SYNTH 0x4 +#define SV_EXTENT_MIDI 0x4 +#define SV_EXTENT_GAME 0x8 +#define SV_EXTENT_DMA 0x10 + + +#define SV_MIDI_DATA 0 +#define SV_MIDI_COMMAND 1 +#define SV_MIDI_STATUS 1 + +#define SV_DMA_ADDR0 0 +#define SV_DMA_ADDR1 1 +#define SV_DMA_ADDR2 2 +#define SV_DMA_ADDR3 3 +#define SV_DMA_COUNT0 4 +#define SV_DMA_COUNT1 5 +#define SV_DMA_COUNT2 6 +#define SV_DMA_MODE 0xb +#define SV_DMA_RESET 0xd +#define SV_DMA_MASK 0xf + +/* + * DONT reset the DMA controllers unless you understand + * the reset semantics. Assuming reset semantics as in + * the 8237 does not work. + */ + +#define DMA_MODE_AUTOINIT 0x10 +#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */ +#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */ + +#define SV_CODEC_CONTROL 0 +#define SV_CODEC_INTMASK 1 +#define SV_CODEC_STATUS 2 +#define SV_CODEC_IADDR 4 +#define SV_CODEC_IDATA 5 + +#define SV_CCTRL_RESET 0x80 +#define SV_CCTRL_INTADRIVE 0x20 +#define SV_CCTRL_WAVETABLE 0x08 +#define SV_CCTRL_REVERB 0x04 +#define SV_CCTRL_ENHANCED 0x01 + +#define SV_CINTMASK_DMAA 0x01 +#define SV_CINTMASK_DMAC 0x04 +#define SV_CINTMASK_SPECIAL 0x08 +#define SV_CINTMASK_UPDOWN 0x40 +#define SV_CINTMASK_MIDI 0x80 + +#define SV_CSTAT_DMAA 0x01 +#define SV_CSTAT_DMAC 0x04 +#define SV_CSTAT_SPECIAL 0x08 +#define SV_CSTAT_UPDOWN 0x40 +#define SV_CSTAT_MIDI 0x80 + +#define SV_CIADDR_TRD 0x80 +#define SV_CIADDR_MCE 0x40 + +/* codec indirect registers */ +#define SV_CIMIX_ADCINL 0x00 +#define SV_CIMIX_ADCINR 0x01 +#define SV_CIMIX_AUX1INL 0x02 +#define SV_CIMIX_AUX1INR 0x03 +#define SV_CIMIX_CDINL 0x04 +#define SV_CIMIX_CDINR 0x05 +#define SV_CIMIX_LINEINL 0x06 +#define SV_CIMIX_LINEINR 0x07 +#define SV_CIMIX_MICIN 0x08 +#define SV_CIMIX_SYNTHINL 0x0A +#define SV_CIMIX_SYNTHINR 0x0B +#define SV_CIMIX_AUX2INL 0x0C +#define SV_CIMIX_AUX2INR 0x0D +#define SV_CIMIX_ANALOGINL 0x0E +#define SV_CIMIX_ANALOGINR 0x0F +#define SV_CIMIX_PCMINL 0x10 +#define SV_CIMIX_PCMINR 0x11 + +#define SV_CIGAMECONTROL 0x09 +#define SV_CIDATAFMT 0x12 +#define SV_CIENABLE 0x13 +#define SV_CIUPDOWN 0x14 +#define SV_CIREVISION 0x15 +#define SV_CIADCOUTPUT 0x16 +#define SV_CIDMAABASECOUNT1 0x18 +#define SV_CIDMAABASECOUNT0 0x19 +#define SV_CIDMACBASECOUNT1 0x1c +#define SV_CIDMACBASECOUNT0 0x1d +#define SV_CIPCMSR0 0x1e +#define SV_CIPCMSR1 0x1f +#define SV_CISYNTHSR0 0x20 +#define SV_CISYNTHSR1 0x21 +#define SV_CIADCCLKSOURCE 0x22 +#define SV_CIADCALTSR 0x23 +#define SV_CIADCPLLM 0x24 +#define SV_CIADCPLLN 0x25 +#define SV_CISYNTHPLLM 0x26 +#define SV_CISYNTHPLLN 0x27 +#define SV_CIUARTCONTROL 0x2a +#define SV_CIDRIVECONTROL 0x2b +#define SV_CISRSSPACE 0x2c +#define SV_CISRSCENTER 0x2d +#define SV_CIWAVETABLESRC 0x2e +#define SV_CIANALOGPWRDOWN 0x30 +#define SV_CIDIGITALPWRDOWN 0x31 + + +#define SV_CIMIX_ADCSRC_CD 0x20 +#define SV_CIMIX_ADCSRC_DAC 0x40 +#define SV_CIMIX_ADCSRC_AUX2 0x60 +#define SV_CIMIX_ADCSRC_LINE 0x80 +#define SV_CIMIX_ADCSRC_AUX1 0xa0 +#define SV_CIMIX_ADCSRC_MIC 0xc0 +#define SV_CIMIX_ADCSRC_MIXOUT 0xe0 +#define SV_CIMIX_ADCSRC_MASK 0xe0 + +#define SV_CFMT_STEREO 0x01 +#define SV_CFMT_16BIT 0x02 +#define SV_CFMT_MASK 0x03 +#define SV_CFMT_ASHIFT 0 +#define SV_CFMT_CSHIFT 4 + +static const unsigned sample_size[] = { 1, 2, 2, 4 }; +static const unsigned sample_shift[] = { 0, 1, 1, 2 }; + +#define SV_CENABLE_PPE 0x4 +#define SV_CENABLE_RE 0x2 +#define SV_CENABLE_PE 0x1 + + +/* MIDI buffer sizes */ + +#define MIDIINBUF 256 +#define MIDIOUTBUF 256 + +#define FMODE_MIDI_SHIFT 2 +#define FMODE_MIDI_READ (FMODE_READ << FMODE_MIDI_SHIFT) +#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT) + +#define FMODE_DMFM 0x10 + +#define SND_DEV_DSP16 5 + +/* --------------------------------------------------------------------- */ + +struct sv_state { + /* magic */ + unsigned int magic; + + /* we keep sv cards in a linked list */ + struct sv_state *next; + + /* soundcore stuff */ + int dev_audio; + int dev_mixer; + int dev_midi; + int dev_dmfm; + + /* hardware resources */ + unsigned int iosb, ioenh, iosynth, iomidi, iogame, iodmaa, iodmac, irq; + + /* mixer stuff */ + struct { + unsigned int modcnt; +#ifndef OSS_DOCUMENTED_MIXER_SEMANTICS + unsigned short vol[13]; +#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */ + } mix; + + /* wave stuff */ + unsigned int rateadc, ratedac; + unsigned char fmt, enable; + + spinlock_t lock; + struct semaphore open_sem; + mode_t open_mode; + struct wait_queue *open_wait; + + struct dmabuf { + void *rawbuf; + unsigned buforder; + unsigned numfrag; + unsigned fragshift; + unsigned hwptr, swptr; + unsigned total_bytes; + int count; + unsigned error; /* over/underrun */ + struct wait_queue *wait; + /* redundant, but makes calculations easier */ + unsigned fragsize; + unsigned dmasize; + unsigned fragsamples; + /* OSS stuff */ + unsigned mapped:1; + unsigned ready:1; + unsigned endcleared:1; + unsigned ossfragshift; + int ossmaxfrags; + unsigned subdivision; + } dma_dac, dma_adc; + + /* midi stuff */ + struct { + unsigned ird, iwr, icnt; + unsigned ord, owr, ocnt; + struct wait_queue *iwait; + struct wait_queue *owait; + struct timer_list timer; + unsigned char ibuf[MIDIINBUF]; + unsigned char obuf[MIDIOUTBUF]; + } midi; +}; + +/* --------------------------------------------------------------------- */ + +static struct sv_state *devs = NULL; +static unsigned long wavetable_mem = 0; + +/* --------------------------------------------------------------------- */ + +extern __inline__ unsigned ld2(unsigned int x) +{ + unsigned r = 0; + + if (x >= 0x10000) { + x >>= 16; + r += 16; + } + if (x >= 0x100) { + x >>= 8; + r += 8; + } + if (x >= 0x10) { + x >>= 4; + r += 4; + } + if (x >= 4) { + x >>= 2; + r += 2; + } + if (x >= 2) + r++; + return r; +} + +/* + * hweightN: returns the hamming weight (i.e. the number + * of bits set) of a N-bit word + */ + +#ifdef hweight32 +#undef hweight32 +#endif + +extern __inline__ unsigned int hweight32(unsigned int w) +{ + unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555); + res = (res & 0x33333333) + ((res >> 2) & 0x33333333); + res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F); + res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF); + return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF); +} + +/* --------------------------------------------------------------------- */ + +/* + * Why use byte IO? Nobody knows, but S3 does it also in their Windows driver. + */ + +#undef DMABYTEIO + +static void set_dmaa(struct sv_state *s, unsigned int addr, unsigned int count) +{ +#ifdef DMABYTEIO + unsigned io = s->iodmaa, u; + + count--; + for (u = 4; u > 0; u--, addr >>= 8, io++) + outb(addr & 0xff, io); + for (u = 3; u > 0; u--, count >>= 8, io++) + outb(count & 0xff, io); +#else /* DMABYTEIO */ + count--; + outl(addr, s->iodmaa + SV_DMA_ADDR0); + outl(count, s->iodmaa + SV_DMA_COUNT0); +#endif /* DMABYTEIO */ + outb(0x18, s->iodmaa + SV_DMA_MODE); +} + +static void set_dmac(struct sv_state *s, unsigned int addr, unsigned int count) +{ +#ifdef DMABYTEIO + unsigned io = s->iodmac, u; + + count >>= 1; + count--; + for (u = 4; u > 0; u--, addr >>= 8, io++) + outb(addr & 0xff, io); + for (u = 3; u > 0; u--, count >>= 8, io++) + outb(count & 0xff, io); +#else /* DMABYTEIO */ + count >>= 1; + count--; + outl(addr, s->iodmac + SV_DMA_ADDR0); + outl(count, s->iodmac + SV_DMA_COUNT0); +#endif /* DMABYTEIO */ + outb(0x14, s->iodmac + SV_DMA_MODE); +} + +extern __inline__ unsigned get_dmaa(struct sv_state *s) +{ +#ifdef DMABYTEIO + unsigned io = s->iodmaa+6, v = 0, u; + + for (u = 3; u > 0; u--, io--) { + v <<= 8; + v |= inb(io); + } + return v + 1; +#else /* DMABYTEIO */ + return (inl(s->iodmaa + SV_DMA_COUNT0) & 0xffffff) + 1; +#endif /* DMABYTEIO */ +} + +extern __inline__ unsigned get_dmac(struct sv_state *s) +{ +#ifdef DMABYTEIO + unsigned io = s->iodmac+6, v = 0, u; + + for (u = 3; u > 0; u--, io--) { + v <<= 8; + v |= inb(io); + } + return (v + 1) << 1; +#else /* DMABYTEIO */ + return ((inl(s->iodmac + SV_DMA_COUNT0) & 0xffffff) + 1) << 1; +#endif /* DMABYTEIO */ +} + +static void wrindir(struct sv_state *s, unsigned char idx, unsigned char data) +{ + outb(idx & 0x3f, s->ioenh + SV_CODEC_IADDR); + udelay(10); + outb(data, s->ioenh + SV_CODEC_IDATA); + udelay(10); +} + +static unsigned char rdindir(struct sv_state *s, unsigned char idx) +{ + unsigned char v; + + outb(idx & 0x3f, s->ioenh + SV_CODEC_IADDR); + udelay(10); + v = inb(s->ioenh + SV_CODEC_IDATA); + udelay(10); + return v; +} + +static void set_fmt(struct sv_state *s, unsigned char mask, unsigned char data) +{ + unsigned long flags; + + spin_lock_irqsave(&s->lock, flags); + outb(SV_CIDATAFMT | SV_CIADDR_MCE, s->ioenh + SV_CODEC_IADDR); + if (mask) { + s->fmt = inb(s->ioenh + SV_CODEC_IDATA); + udelay(10); + } + s->fmt = (s->fmt & mask) | data; + outb(s->fmt, s->ioenh + SV_CODEC_IDATA); + udelay(10); + outb(0, s->ioenh + SV_CODEC_IADDR); + spin_unlock_irqrestore(&s->lock, flags); + udelay(10); +} + +static void frobindir(struct sv_state *s, unsigned char idx, unsigned char mask, unsigned char data) +{ + outb(idx & 0x3f, s->ioenh + SV_CODEC_IADDR); + udelay(10); + outb((inb(s->ioenh + SV_CODEC_IDATA) & mask) ^ data, s->ioenh + SV_CODEC_IDATA); + udelay(10); +} + +#define REFFREQUENCY 24576000 +#define ADCMULT 512 +#define FULLRATE 48000 + +static unsigned setpll(struct sv_state *s, unsigned char reg, unsigned rate) +{ + unsigned long flags; + unsigned char r, m, n; + unsigned xm, xn, xr, xd, metric = ~0U; + /* the warnings about m and n used uninitialized are bogus and may safely be ignored */ + + if (rate < 625000/ADCMULT) + rate = 625000/ADCMULT; + if (rate > 150000000/ADCMULT) + rate = 150000000/ADCMULT; + /* slight violation of specs, needed for continuous sampling rates */ + for (r = 0; rate < 75000000/ADCMULT; r += 0x20, rate <<= 1); + for (xn = 3; xn < 35; xn++) + for (xm = 3; xm < 130; xm++) { + xr = REFFREQUENCY/ADCMULT * xm / xn; + xd = abs((signed)(xr - rate)); + if (xd < metric) { + metric = xd; + m = xm - 2; + n = xn - 2; + } + } + reg &= 0x3f; + spin_lock_irqsave(&s->lock, flags); + outb(reg, s->ioenh + SV_CODEC_IADDR); + udelay(10); + outb(m, s->ioenh + SV_CODEC_IDATA); + udelay(10); + outb(reg+1, s->ioenh + SV_CODEC_IADDR); + udelay(10); + outb(r | n, s->ioenh + SV_CODEC_IDATA); + spin_unlock_irqrestore(&s->lock, flags); + udelay(10); + return (REFFREQUENCY/ADCMULT * (m + 2) / (n + 2)) >> ((r >> 5) & 7); +} + +#if 0 + +static unsigned getpll(struct sv_state *s, unsigned char reg) +{ + unsigned long flags; + unsigned char m, n; + + reg &= 0x3f; + spin_lock_irqsave(&s->lock, flags); + outb(reg, s->ioenh + SV_CODEC_IADDR); + udelay(10); + m = inb(s->ioenh + SV_CODEC_IDATA); + udelay(10); + outb(reg+1, s->ioenh + SV_CODEC_IADDR); + udelay(10); + n = inb(s->ioenh + SV_CODEC_IDATA); + spin_unlock_irqrestore(&s->lock, flags); + udelay(10); + return (REFFREQUENCY/ADCMULT * (m + 2) / ((n & 0x1f) + 2)) >> ((n >> 5) & 7); +} + +#endif + +static void set_dac_rate(struct sv_state *s, unsigned rate) +{ + unsigned div; + unsigned long flags; + + if (rate > 48000) + rate = 48000; + if (rate < 4000) + rate = 4000; + div = (rate * 65536 + FULLRATE/2) / FULLRATE; + if (div > 65535) + div = 65535; + spin_lock_irqsave(&s->lock, flags); + wrindir(s, SV_CIPCMSR1, div >> 8); + wrindir(s, SV_CIPCMSR0, div); + spin_unlock_irqrestore(&s->lock, flags); + s->ratedac = (div * FULLRATE + 32768) / 65536; +} + +static void set_adc_rate(struct sv_state *s, unsigned rate) +{ + unsigned long flags; + unsigned rate1, rate2, div; + + if (rate > 48000) + rate = 48000; + if (rate < 4000) + rate = 4000; + rate1 = setpll(s, SV_CIADCPLLM, rate); + div = (48000 + rate/2) / rate; + if (div > 8) + div = 8; + rate2 = (48000 + div/2) / div; + spin_lock_irqsave(&s->lock, flags); + wrindir(s, SV_CIADCALTSR, (div-1) << 4); + if (abs((signed)(rate-rate2)) <= abs((signed)(rate-rate1))) { + wrindir(s, SV_CIADCCLKSOURCE, 0x10); + s->rateadc = rate2; + } else { + wrindir(s, SV_CIADCCLKSOURCE, 0x00); + s->rateadc = rate1; + } + spin_unlock_irqrestore(&s->lock, flags); +} + +/* --------------------------------------------------------------------- */ + +extern inline void stop_adc(struct sv_state *s) +{ + unsigned long flags; + + spin_lock_irqsave(&s->lock, flags); + s->enable &= ~SV_CENABLE_RE; + wrindir(s, SV_CIENABLE, s->enable); + spin_unlock_irqrestore(&s->lock, flags); +} + +extern inline void stop_dac(struct sv_state *s) +{ + unsigned long flags; + + spin_lock_irqsave(&s->lock, flags); + s->enable &= ~(SV_CENABLE_PPE | SV_CENABLE_PE); + wrindir(s, SV_CIENABLE, s->enable); + spin_unlock_irqrestore(&s->lock, flags); +} + +static void start_dac(struct sv_state *s) +{ + unsigned long flags; + + spin_lock_irqsave(&s->lock, flags); + if ((s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) { + s->enable = (s->enable & ~SV_CENABLE_PPE) | SV_CENABLE_PE; + wrindir(s, SV_CIENABLE, s->enable); + } + spin_unlock_irqrestore(&s->lock, flags); +} + +static void start_adc(struct sv_state *s) +{ + unsigned long flags; + + spin_lock_irqsave(&s->lock, flags); + if ((s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) + && s->dma_adc.ready) { + s->enable |= SV_CENABLE_RE; + wrindir(s, SV_CIENABLE, s->enable); + } + spin_unlock_irqrestore(&s->lock, flags); +} + +/* --------------------------------------------------------------------- */ + +#define DMABUF_DEFAULTORDER (17-PAGE_SHIFT) +#define DMABUF_MINORDER 1 + +static void dealloc_dmabuf(struct dmabuf *db) +{ + unsigned long map, mapend; + + if (db->rawbuf) { + /* undo marking the pages as reserved */ + mapend = MAP_NR(db->rawbuf + (PAGE_SIZE << db->buforder) - 1); + for (map = MAP_NR(db->rawbuf); map <= mapend; map++) + clear_bit(PG_reserved, &mem_map[map].flags); + free_pages((unsigned long)db->rawbuf, db->buforder); + } + db->rawbuf = NULL; + db->mapped = db->ready = 0; +} + + +/* DMAA is used for playback, DMAC is used for recording */ + +static int prog_dmabuf(struct sv_state *s, unsigned rec) +{ + struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac; + unsigned rate = rec ? s->rateadc : s->ratedac; + int order; + unsigned bytepersec; + unsigned bufs; + unsigned long map, mapend; + unsigned char fmt; + unsigned long flags; + + spin_lock_irqsave(&s->lock, flags); + fmt = s->fmt; + if (rec) { + s->enable &= ~SV_CENABLE_RE; + fmt >>= SV_CFMT_CSHIFT; + } else { + s->enable &= ~SV_CENABLE_PE; + fmt >>= SV_CFMT_ASHIFT; + } + wrindir(s, SV_CIENABLE, s->enable); + spin_unlock_irqrestore(&s->lock, flags); + fmt &= SV_CFMT_MASK; + db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0; + if (!db->rawbuf) { + db->ready = db->mapped = 0; + for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER && !db->rawbuf; order--) + db->rawbuf = (void *)__get_free_pages(GFP_KERNEL | GFP_DMA, order); + if (!db->rawbuf) + return -ENOMEM; + db->buforder = order; + if ((virt_to_bus(db->rawbuf) ^ (virt_to_bus(db->rawbuf) + (PAGE_SIZE << db->buforder) - 1)) & ~0xffff) + printk(KERN_DEBUG "sv: DMA buffer crosses 64k boundary: busaddr 0x%lx size %ld\n", + virt_to_bus(db->rawbuf), PAGE_SIZE << db->buforder); + if ((virt_to_bus(db->rawbuf) + (PAGE_SIZE << db->buforder) - 1) & ~0xffffff) + printk(KERN_DEBUG "sv: DMA buffer beyond 16MB: busaddr 0x%lx size %ld\n", + virt_to_bus(db->rawbuf), PAGE_SIZE << db->buforder); + /* now mark the pages as reserved; otherwise remap_page_range doesn't do what we want */ + mapend = MAP_NR(db->rawbuf + (PAGE_SIZE << db->buforder) - 1); + for (map = MAP_NR(db->rawbuf); map <= mapend; map++) + set_bit(PG_reserved, &mem_map[map].flags); + } + bytepersec = rate << sample_shift[fmt]; + bufs = PAGE_SIZE << db->buforder; + if (db->ossfragshift) { + if ((1000 << db->ossfragshift) < bytepersec) + db->fragshift = ld2(bytepersec/1000); + else + db->fragshift = db->ossfragshift; + } else { + db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1)); + if (db->fragshift < 3) + db->fragshift = 3; + } + db->numfrag = bufs >> db->fragshift; + while (db->numfrag < 4 && db->fragshift > 3) { + db->fragshift--; + db->numfrag = bufs >> db->fragshift; + } + db->fragsize = 1 << db->fragshift; + if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag) + db->numfrag = db->ossmaxfrags; + db->fragsamples = db->fragsize >> sample_shift[fmt]; + db->dmasize = db->numfrag << db->fragshift; + memset(db->rawbuf, (fmt & SV_CFMT_16BIT) ? 0 : 0x80, db->dmasize); + spin_lock_irqsave(&s->lock, flags); + if (rec) { + set_dmac(s, virt_to_bus(db->rawbuf), db->numfrag << db->fragshift); + /* program enhanced mode registers */ + wrindir(s, SV_CIDMACBASECOUNT1, (db->fragsamples-1) >> 8); + wrindir(s, SV_CIDMACBASECOUNT0, db->fragsamples-1); + } else { + set_dmaa(s, virt_to_bus(db->rawbuf), db->numfrag << db->fragshift); + /* program enhanced mode registers */ + wrindir(s, SV_CIDMAABASECOUNT1, (db->fragsamples-1) >> 8); + wrindir(s, SV_CIDMAABASECOUNT0, db->fragsamples-1); + } + spin_unlock_irqrestore(&s->lock, flags); + db->ready = 1; + return 0; +} + +extern __inline__ void clear_advance(struct sv_state *s) +{ + unsigned char c = (s->fmt & (SV_CFMT_16BIT << SV_CFMT_ASHIFT)) ? 0 : 0x80; + unsigned char *buf = s->dma_dac.rawbuf; + unsigned bsize = s->dma_dac.dmasize; + unsigned bptr = s->dma_dac.swptr; + unsigned len = s->dma_dac.fragsize; + + if (bptr + len > bsize) { + unsigned x = bsize - bptr; + memset(buf + bptr, c, x); + bptr = 0; + len -= x; + } + memset(buf + bptr, c, len); +} + +/* call with spinlock held! */ +static void sv_update_ptr(struct sv_state *s) +{ + unsigned hwptr; + int diff; + + /* update ADC pointer */ + if (s->dma_adc.ready) { + hwptr = (s->dma_adc.dmasize - get_dmac(s)) % s->dma_adc.dmasize; + diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize; + s->dma_adc.hwptr = hwptr; + s->dma_adc.total_bytes += diff; + s->dma_adc.count += diff; + if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) + wake_up(&s->dma_adc.wait); + if (!s->dma_adc.mapped) { + if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) { + s->enable &= ~SV_CENABLE_RE; + wrindir(s, SV_CIENABLE, s->enable); + s->dma_adc.error++; + } + } + } + /* update DAC pointer */ + if (s->dma_dac.ready) { + hwptr = (s->dma_dac.dmasize - get_dmaa(s)) % s->dma_dac.dmasize; + diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize; + s->dma_dac.hwptr = hwptr; + s->dma_dac.total_bytes += diff; + if (s->dma_dac.mapped) { + s->dma_dac.count += diff; + if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) + wake_up(&s->dma_dac.wait); + } else { + s->dma_dac.count -= diff; + if (s->dma_dac.count <= 0) { + s->enable &= ~SV_CENABLE_PE; + wrindir(s, SV_CIENABLE, s->enable); + s->dma_dac.error++; + } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) { + clear_advance(s); + s->dma_dac.endcleared = 1; + } + if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize) + wake_up(&s->dma_dac.wait); + } + } +} + +/* hold spinlock for the following! */ +static void sv_handle_midi(struct sv_state *s) +{ + unsigned char ch; + int wake; + + wake = 0; + while (!(inb(s->iomidi+1) & 0x80)) { + ch = inb(s->iomidi); + if (s->midi.icnt < MIDIINBUF) { + s->midi.ibuf[s->midi.iwr] = ch; + s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF; + s->midi.icnt++; + } + wake = 1; + } + if (wake) + wake_up(&s->midi.iwait); + wake = 0; + while (!(inb(s->iomidi+1) & 0x40) && s->midi.ocnt > 0) { + outb(s->midi.obuf[s->midi.ord], s->iomidi); + s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF; + s->midi.ocnt--; + if (s->midi.ocnt < MIDIOUTBUF-16) + wake = 1; + } + if (wake) + wake_up(&s->midi.owait); +} + +static void sv_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct sv_state *s = (struct sv_state *)dev_id; + unsigned int intsrc; + + /* fastpath out, to ease interrupt sharing */ + intsrc = inb(s->ioenh + SV_CODEC_STATUS); + if (!(intsrc & (SV_CSTAT_DMAA | SV_CSTAT_DMAC | SV_CSTAT_MIDI))) + return; + spin_lock(&s->lock); + sv_update_ptr(s); + sv_handle_midi(s); + spin_unlock(&s->lock); +} + +static void sv_midi_timer(unsigned long data) +{ + struct sv_state *s = (struct sv_state *)data; + unsigned long flags; + + spin_lock_irqsave(&s->lock, flags); + sv_handle_midi(s); + spin_unlock_irqrestore(&s->lock, flags); + s->midi.timer.expires = jiffies+1; + add_timer(&s->midi.timer); +} + +/* --------------------------------------------------------------------- */ + +static const char invalid_magic[] = KERN_CRIT "sv: invalid magic value\n"; + +#define VALIDATE_STATE(s) \ +({ \ + if (!(s) || (s)->magic != SV_MAGIC) { \ + printk(invalid_magic); \ + return -ENXIO; \ + } \ +}) + +/* --------------------------------------------------------------------- */ + +#define MT_4 1 +#define MT_5MUTE 2 +#define MT_4MUTEMONO 3 +#define MT_6MUTE 4 + +static const struct { + unsigned left:5; + unsigned right:5; + unsigned type:3; + unsigned rec:3; +} mixtable[SOUND_MIXER_NRDEVICES] = { + [SOUND_MIXER_RECLEV] = { SV_CIMIX_ADCINL, SV_CIMIX_ADCINR, MT_4, 0 }, + [SOUND_MIXER_LINE1] = { SV_CIMIX_AUX1INL, SV_CIMIX_AUX1INR, MT_5MUTE, 5 }, + [SOUND_MIXER_CD] = { SV_CIMIX_CDINL, SV_CIMIX_CDINR, MT_5MUTE, 1 }, + [SOUND_MIXER_LINE] = { SV_CIMIX_LINEINL, SV_CIMIX_LINEINR, MT_5MUTE, 4 }, + [SOUND_MIXER_MIC] = { SV_CIMIX_MICIN, SV_CIMIX_ADCINL, MT_4MUTEMONO, 6 }, + [SOUND_MIXER_SYNTH] = { SV_CIMIX_SYNTHINL, SV_CIMIX_SYNTHINR, MT_5MUTE, 2 }, + [SOUND_MIXER_LINE2] = { SV_CIMIX_AUX2INL, SV_CIMIX_AUX2INR, MT_5MUTE, 3 }, + [SOUND_MIXER_VOLUME] = { SV_CIMIX_ANALOGINL, SV_CIMIX_ANALOGINR, MT_5MUTE, 7 }, + [SOUND_MIXER_PCM] = { SV_CIMIX_PCMINL, SV_CIMIX_PCMINR, MT_6MUTE, 0 } +}; + +#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS + +static int return_mixval(struct sv_state *s, unsigned i, int *arg) +{ + unsigned long flags; + unsigned char l, r, rl, rr; + + spin_lock_irqsave(&s->lock, flags); + l = rdindir(s, mixtable[i].left); + r = rdindir(s, mixtable[i].right); + spin_unlock_irqrestore(&s->lock, flags); + switch (mixtable[i].type) { + case MT_4: + r &= 0xf; + l &= 0xf; + rl = 10 + 6 * (l & 15); + rr = 10 + 6 * (r & 15); + break; + + case MT_4MUTEMONO: + rl = 55 - 3 * (l & 15); + if (r & 0x10) + rl += 45; + rr = rl; + r = l; + break; + + case MT_5MUTE: + default: + rl = 100 - 3 * (l & 31); + rr = 100 - 3 * (r & 31); + break; + + case MT_6MUTE: + rl = 100 - 3 * (l & 63) / 2; + rr = 100 - 3 * (r & 63) / 2; + break; + } + if (l & 0x80) + rl = 0; + if (r & 0x80) + rr = 0; + return put_user((rr << 8) | rl, arg); +} + +#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */ + +static const unsigned char volidx[SOUND_MIXER_NRDEVICES] = +{ + [SOUND_MIXER_RECLEV] = 1, + [SOUND_MIXER_LINE1] = 2, + [SOUND_MIXER_CD] = 3, + [SOUND_MIXER_LINE] = 4, + [SOUND_MIXER_MIC] = 5, + [SOUND_MIXER_SYNTH] = 6, + [SOUND_MIXER_LINE2] = 7, + [SOUND_MIXER_VOLUME] = 8, + [SOUND_MIXER_PCM] = 9 +}; + +#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */ + +static unsigned mixer_recmask(struct sv_state *s) +{ + unsigned long flags; + int i, j; + + spin_lock_irqsave(&s->lock, flags); + j = rdindir(s, SV_CIMIX_ADCINL) >> 5; + spin_unlock_irqrestore(&s->lock, flags); + j &= 7; + for (i = 0; i < SOUND_MIXER_NRDEVICES && mixtable[i].rec != j; i++); + return 1 << i; +} + +static int mixer_ioctl(struct sv_state *s, unsigned int cmd, unsigned long arg) +{ + unsigned long flags; + int i, val; + unsigned char l, r, rl, rr; + + VALIDATE_STATE(s); + if (cmd == SOUND_MIXER_INFO) { + mixer_info info; + strncpy(info.id, "SonicVibes", sizeof(info.id)); + strncpy(info.name, "S3 SonicVibes", sizeof(info.name)); + info.modify_counter = s->mix.modcnt; + if (copy_to_user((void *)arg, &info, sizeof(info))) + return -EFAULT; + return 0; + } + if (cmd == SOUND_OLD_MIXER_INFO) { + _old_mixer_info info; + strncpy(info.id, "SonicVibes", sizeof(info.id)); + strncpy(info.name, "S3 SonicVibes", sizeof(info.name)); + if (copy_to_user((void *)arg, &info, sizeof(info))) + return -EFAULT; + return 0; + } + if (cmd == OSS_GETVERSION) + return put_user(SOUND_VERSION, (int *)arg); + if (cmd == SOUND_MIXER_PRIVATE1) { /* SRS settings */ + get_user_ret(val, (int *)arg, -EFAULT); + spin_lock_irqsave(&s->lock, flags); + if (val & 1) { + if (val & 2) { + l = 4 - ((val >> 2) & 7); + if (l & ~3) + l = 4; + r = 4 - ((val >> 5) & 7); + if (r & ~3) + r = 4; + wrindir(s, SV_CISRSSPACE, l); + wrindir(s, SV_CISRSCENTER, r); + } else + wrindir(s, SV_CISRSSPACE, 0x80); + } + l = rdindir(s, SV_CISRSSPACE); + r = rdindir(s, SV_CISRSCENTER); + spin_unlock_irqrestore(&s->lock, flags); + if (l & 0x80) + return put_user(0, (int *)arg); + return put_user(((4 - (l & 7)) << 2) | ((4 - (r & 7)) << 5) | 2, (int *)arg); + } + if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int)) + return -EINVAL; + if (_IOC_DIR(cmd) == _IOC_READ) { + switch (_IOC_NR(cmd)) { + case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ + return put_user(mixer_recmask(s), (int *)arg); + + case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */ + for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++) + if (mixtable[i].type) + val |= 1 << i; + return put_user(val, (int *)arg); + + case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */ + for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++) + if (mixtable[i].rec) + val |= 1 << i; + return put_user(val, (int *)arg); + + case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */ + for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++) + if (mixtable[i].type && mixtable[i].type != MT_4MUTEMONO) + val |= 1 << i; + return put_user(val, (int *)arg); + + case SOUND_MIXER_CAPS: + return put_user(SOUND_CAP_EXCL_INPUT, (int *)arg); + + default: + i = _IOC_NR(cmd); + if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type) + return -EINVAL; +#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS + return return_mixval(s, i, (int *)arg); +#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */ + if (!volidx[i]) + return -EINVAL; + return put_user(s->mix.vol[volidx[i]-1], (int *)arg); +#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */ + } + } + if (_IOC_DIR(cmd) != (_IOC_READ|_IOC_WRITE)) + return -EINVAL; + s->mix.modcnt++; + switch (_IOC_NR(cmd)) { + case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ + get_user_ret(val, (int *)arg, -EFAULT); + i = hweight32(val); + if (i == 0) + return 0; /*val = mixer_recmask(s);*/ + else if (i > 1) + val &= ~mixer_recmask(s); + for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { + if (!(val & (1 << i))) + continue; + if (mixtable[i].rec) + break; + } + if (!mixtable[i].rec) + return 0; + spin_lock_irqsave(&s->lock, flags); + frobindir(s, SV_CIMIX_ADCINL, 0x1f, mixtable[i].rec << 5); + frobindir(s, SV_CIMIX_ADCINR, 0x1f, mixtable[i].rec << 5); + spin_unlock_irqrestore(&s->lock, flags); + return 0; + + default: + i = _IOC_NR(cmd); + if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type) + return -EINVAL; + get_user_ret(val, (int *)arg, -EFAULT); + l = val & 0xff; + r = (val >> 8) & 0xff; + if (mixtable[i].type == MT_4MUTEMONO) + l = (r + l) / 2; + if (l > 100) + l = 100; + if (r > 100) + r = 100; + spin_lock_irqsave(&s->lock, flags); + switch (mixtable[i].type) { + case MT_4: + if (l >= 10) + l -= 10; + if (r >= 10) + r -= 10; + frobindir(s, mixtable[i].left, 0xf0, l / 6); + frobindir(s, mixtable[i].right, 0xf0, l / 6); + break; + + case MT_4MUTEMONO: + rr = 0; + if (l < 10) + rl = 0x80; + else { + if (l >= 55) { + rr = 0x10; + l -= 45; + } + rl = (55 - l) / 3; + } + wrindir(s, mixtable[i].left, rl); + frobindir(s, mixtable[i].right, ~0x10, rr); + break; + + case MT_5MUTE: + if (l < 7) + rl = 0x80; + else + rl = (100 - l) / 3; + if (r < 7) + rr = 0x80; + else + rr = (100 - r) / 3; + wrindir(s, mixtable[i].left, rl); + wrindir(s, mixtable[i].right, rr); + break; + + case MT_6MUTE: + if (l < 6) + rl = 0x80; + else + rl = (100 - l) * 2 / 3; + if (r < 6) + rr = 0x80; + else + rr = (100 - r) * 2 / 3; + wrindir(s, mixtable[i].left, rl); + wrindir(s, mixtable[i].right, rr); + break; + } + spin_unlock_irqrestore(&s->lock, flags); +#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS + return return_mixval(s, i, (int *)arg); +#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */ + if (!volidx[i]) + return -EINVAL; + s->mix.vol[volidx[i]-1] = val; + return put_user(s->mix.vol[volidx[i]-1], (int *)arg); +#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */ + } +} + +/* --------------------------------------------------------------------- */ + +static loff_t sv_llseek(struct file *file, loff_t offset, int origin) +{ + return -ESPIPE; +} + +/* --------------------------------------------------------------------- */ + +static int sv_open_mixdev(struct inode *inode, struct file *file) +{ + int minor = MINOR(inode->i_rdev); + struct sv_state *s = devs; + + while (s && s->dev_mixer != minor) + s = s->next; + if (!s) + return -ENODEV; + VALIDATE_STATE(s); + file->private_data = s; + MOD_INC_USE_COUNT; + return 0; +} + +static int sv_release_mixdev(struct inode *inode, struct file *file) +{ + struct sv_state *s = (struct sv_state *)file->private_data; + + VALIDATE_STATE(s); + MOD_DEC_USE_COUNT; + return 0; +} + +static int sv_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + return mixer_ioctl((struct sv_state *)file->private_data, cmd, arg); +} + +static /*const*/ struct file_operations sv_mixer_fops = { + &sv_llseek, + NULL, /* read */ + NULL, /* write */ + NULL, /* readdir */ + NULL, /* poll */ + &sv_ioctl_mixdev, + NULL, /* mmap */ + &sv_open_mixdev, + NULL, /* flush */ + &sv_release_mixdev, + NULL, /* fsync */ + NULL, /* fasync */ + NULL, /* check_media_change */ + NULL, /* revalidate */ + NULL, /* lock */ +}; + +/* --------------------------------------------------------------------- */ + +static int drain_dac(struct sv_state *s, int nonblock) +{ + struct wait_queue wait = { current, NULL }; + unsigned long flags; + int count, tmo; + + if (s->dma_dac.mapped || !s->dma_dac.ready) + return 0; + current->state = TASK_INTERRUPTIBLE; + add_wait_queue(&s->dma_dac.wait, &wait); + for (;;) { + spin_lock_irqsave(&s->lock, flags); + count = s->dma_dac.count; + spin_unlock_irqrestore(&s->lock, flags); + if (count <= 0) + break; + if (signal_pending(current)) + break; + if (nonblock) { + remove_wait_queue(&s->dma_dac.wait, &wait); + current->state = TASK_RUNNING; + return -EBUSY; + } + tmo = (count * HZ) / s->ratedac; + tmo >>= sample_shift[(s->fmt >> SV_CFMT_ASHIFT) & SV_CFMT_MASK]; + if (!schedule_timeout(tmo ? : 1) && tmo) + printk(KERN_DEBUG "sv: dma timed out??\n"); + } + remove_wait_queue(&s->dma_dac.wait, &wait); + current->state = TASK_RUNNING; + if (signal_pending(current)) + return -ERESTARTSYS; + return 0; +} + +/* --------------------------------------------------------------------- */ + +static ssize_t sv_read(struct file *file, char *buffer, size_t count, loff_t *ppos) +{ + struct sv_state *s = (struct sv_state *)file->private_data; + ssize_t ret; + unsigned long flags; + unsigned swptr; + int cnt; + + VALIDATE_STATE(s); + if (ppos != &file->f_pos) + return -ESPIPE; + if (s->dma_adc.mapped) + return -ENXIO; + if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1))) + return ret; + if (!access_ok(VERIFY_WRITE, buffer, count)) + return -EFAULT; + ret = 0; +#if 0 + spin_lock_irqsave(&s->lock, flags); + sv_update_ptr(s); + spin_unlock_irqrestore(&s->lock, flags); +#endif + while (count > 0) { + spin_lock_irqsave(&s->lock, flags); + swptr = s->dma_adc.swptr; + cnt = s->dma_adc.dmasize-swptr; + if (s->dma_adc.count < cnt) + cnt = s->dma_adc.count; + spin_unlock_irqrestore(&s->lock, flags); + if (cnt > count) + cnt = count; + if (cnt <= 0) { + start_adc(s); + if (file->f_flags & O_NONBLOCK) + return ret ? ret : -EAGAIN; + interruptible_sleep_on(&s->dma_adc.wait); + if (signal_pending(current)) + return ret ? ret : -ERESTARTSYS; + continue; + } + if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) + return ret ? ret : -EFAULT; + swptr = (swptr + cnt) % s->dma_adc.dmasize; + spin_lock_irqsave(&s->lock, flags); + s->dma_adc.swptr = swptr; + s->dma_adc.count -= cnt; + spin_unlock_irqrestore(&s->lock, flags); + count -= cnt; + buffer += cnt; + ret += cnt; + start_adc(s); + } + return ret; +} + +static ssize_t sv_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) +{ + struct sv_state *s = (struct sv_state *)file->private_data; + ssize_t ret; + unsigned long flags; + unsigned swptr; + int cnt; + + VALIDATE_STATE(s); + if (ppos != &file->f_pos) + return -ESPIPE; + if (s->dma_dac.mapped) + return -ENXIO; + if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0))) + return ret; + if (!access_ok(VERIFY_READ, buffer, count)) + return -EFAULT; + ret = 0; +#if 0 + spin_lock_irqsave(&s->lock, flags); + sv_update_ptr(s); + spin_unlock_irqrestore(&s->lock, flags); +#endif + while (count > 0) { + spin_lock_irqsave(&s->lock, flags); + if (s->dma_dac.count < 0) { + s->dma_dac.count = 0; + s->dma_dac.swptr = s->dma_dac.hwptr; + } + swptr = s->dma_dac.swptr; + cnt = s->dma_dac.dmasize-swptr; + if (s->dma_dac.count + cnt > s->dma_dac.dmasize) + cnt = s->dma_dac.dmasize - s->dma_dac.count; + spin_unlock_irqrestore(&s->lock, flags); + if (cnt > count) + cnt = count; + if (cnt <= 0) { + start_dac(s); + if (file->f_flags & O_NONBLOCK) + return ret ? ret : -EAGAIN; + interruptible_sleep_on(&s->dma_dac.wait); + if (signal_pending(current)) + return ret ? ret : -ERESTARTSYS; + continue; + } + if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) + return ret ? ret : -EFAULT; + swptr = (swptr + cnt) % s->dma_dac.dmasize; + spin_lock_irqsave(&s->lock, flags); + s->dma_dac.swptr = swptr; + s->dma_dac.count += cnt; + s->dma_dac.endcleared = 0; + spin_unlock_irqrestore(&s->lock, flags); + count -= cnt; + buffer += cnt; + ret += cnt; + start_dac(s); + } + return ret; +} + +static unsigned int sv_poll(struct file *file, struct poll_table_struct *wait) +{ + struct sv_state *s = (struct sv_state *)file->private_data; + unsigned long flags; + unsigned int mask = 0; + + VALIDATE_STATE(s); + if (file->f_mode & FMODE_WRITE) + poll_wait(file, &s->dma_dac.wait, wait); + if (file->f_mode & FMODE_READ) + poll_wait(file, &s->dma_adc.wait, wait); + spin_lock_irqsave(&s->lock, flags); + sv_update_ptr(s); + if (file->f_mode & FMODE_READ) { + if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) + mask |= POLLIN | POLLRDNORM; + } + if (file->f_mode & FMODE_WRITE) { + if (s->dma_dac.mapped) { + if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) + mask |= POLLOUT | POLLWRNORM; + } else { + if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize) + mask |= POLLOUT | POLLWRNORM; + } + } + spin_unlock_irqrestore(&s->lock, flags); + return mask; +} + +static int sv_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct sv_state *s = (struct sv_state *)file->private_data; + struct dmabuf *db; + int ret; + unsigned long size; + + VALIDATE_STATE(s); + if (vma->vm_flags & VM_WRITE) { + if ((ret = prog_dmabuf(s, 1)) != 0) + return ret; + db = &s->dma_dac; + } else if (vma->vm_flags & VM_READ) { + if ((ret = prog_dmabuf(s, 0)) != 0) + return ret; + db = &s->dma_adc; + } else + return -EINVAL; + if (vma->vm_offset != 0) + return -EINVAL; + size = vma->vm_end - vma->vm_start; + if (size > (PAGE_SIZE << db->buforder)) + return -EINVAL; + if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot)) + return -EAGAIN; + db->mapped = 1; + return 0; +} + +static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + struct sv_state *s = (struct sv_state *)file->private_data; + unsigned long flags; + audio_buf_info abinfo; + count_info cinfo; + int val, mapped, ret; + unsigned char fmtm, fmtd; + + VALIDATE_STATE(s); + mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) || + ((file->f_mode & FMODE_READ) && s->dma_adc.mapped); + switch (cmd) { + case OSS_GETVERSION: + return put_user(SOUND_VERSION, (int *)arg); + + case SNDCTL_DSP_SYNC: + if (file->f_mode & FMODE_WRITE) + return drain_dac(s, 0/*file->f_flags & O_NONBLOCK*/); + return 0; + + case SNDCTL_DSP_SETDUPLEX: + return 0; + + case SNDCTL_DSP_GETCAPS: + return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg); + + case SNDCTL_DSP_RESET: + if (file->f_mode & FMODE_WRITE) { + stop_dac(s); + synchronize_irq(); + s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0; + } + if (file->f_mode & FMODE_READ) { + stop_adc(s); + synchronize_irq(); + s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0; + } + return 0; + + case SNDCTL_DSP_SPEED: + get_user_ret(val, (int *)arg, -EFAULT); + if (val >= 0) { + if (file->f_mode & FMODE_READ) { + stop_adc(s); + s->dma_adc.ready = 0; + set_adc_rate(s, val); + } + if (file->f_mode & FMODE_WRITE) { + stop_dac(s); + s->dma_dac.ready = 0; + set_dac_rate(s, val); + } + } + return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg); + + case SNDCTL_DSP_STEREO: + get_user_ret(val, (int *)arg, -EFAULT); + fmtd = 0; + fmtm = ~0; + if (file->f_mode & FMODE_READ) { + stop_adc(s); + s->dma_adc.ready = 0; + if (val) + fmtd |= SV_CFMT_STEREO << SV_CFMT_CSHIFT; + else + fmtm &= ~(SV_CFMT_STEREO << SV_CFMT_CSHIFT); + } + if (file->f_mode & FMODE_WRITE) { + stop_dac(s); + s->dma_dac.ready = 0; + if (val) + fmtd |= SV_CFMT_STEREO << SV_CFMT_ASHIFT; + else + fmtm &= ~(SV_CFMT_STEREO << SV_CFMT_ASHIFT); + } + set_fmt(s, fmtm, fmtd); + return 0; + + case SNDCTL_DSP_CHANNELS: + get_user_ret(val, (int *)arg, -EFAULT); + if (val != 0) { + fmtd = 0; + fmtm = ~0; + if (file->f_mode & FMODE_READ) { + stop_adc(s); + s->dma_adc.ready = 0; + if (val >= 2) + fmtd |= SV_CFMT_STEREO << SV_CFMT_CSHIFT; + else + fmtm &= ~(SV_CFMT_STEREO << SV_CFMT_CSHIFT); + } + if (file->f_mode & FMODE_WRITE) { + stop_dac(s); + s->dma_dac.ready = 0; + if (val >= 2) + fmtd |= SV_CFMT_STEREO << SV_CFMT_ASHIFT; + else + fmtm &= ~(SV_CFMT_STEREO << SV_CFMT_ASHIFT); + } + set_fmt(s, fmtm, fmtd); + } + return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_STEREO << SV_CFMT_CSHIFT) + : (SV_CFMT_STEREO << SV_CFMT_ASHIFT))) ? 2 : 1, (int *)arg); + + case SNDCTL_DSP_GETFMTS: /* Returns a mask */ + return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg); + + case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/ + get_user_ret(val, (int *)arg, -EFAULT); + if (val != AFMT_QUERY) { + fmtd = 0; + fmtm = ~0; + if (file->f_mode & FMODE_READ) { + stop_adc(s); + s->dma_adc.ready = 0; + if (val == AFMT_S16_LE) + fmtd |= SV_CFMT_16BIT << SV_CFMT_CSHIFT; + else + fmtm &= ~(SV_CFMT_16BIT << SV_CFMT_CSHIFT); + } + if (file->f_mode & FMODE_WRITE) { + stop_dac(s); + s->dma_dac.ready = 0; + if (val == AFMT_S16_LE) + fmtd |= SV_CFMT_16BIT << SV_CFMT_ASHIFT; + else + fmtm &= ~(SV_CFMT_16BIT << SV_CFMT_ASHIFT); + } + set_fmt(s, fmtm, fmtd); + } + return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_16BIT << SV_CFMT_CSHIFT) + : (SV_CFMT_16BIT << SV_CFMT_ASHIFT))) ? AFMT_S16_LE : AFMT_U8, (int *)arg); + + case SNDCTL_DSP_POST: + return 0; + + case SNDCTL_DSP_GETTRIGGER: + val = 0; + if (file->f_mode & FMODE_READ && s->enable & SV_CENABLE_RE) + val |= PCM_ENABLE_INPUT; + if (file->f_mode & FMODE_WRITE && s->enable & SV_CENABLE_PE) + val |= PCM_ENABLE_OUTPUT; + return put_user(val, (int *)arg); + + case SNDCTL_DSP_SETTRIGGER: + get_user_ret(val, (int *)arg, -EFAULT); + if (file->f_mode & FMODE_READ) { + if (val & PCM_ENABLE_INPUT) { + if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1))) + return ret; + start_adc(s); + } else + stop_adc(s); + } + if (file->f_mode & FMODE_WRITE) { + if (val & PCM_ENABLE_OUTPUT) { + if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0))) + return ret; + start_dac(s); + } else + stop_dac(s); + } + return 0; + + case SNDCTL_DSP_GETOSPACE: + if (!(file->f_mode & FMODE_WRITE)) + return -EINVAL; + if (!(s->enable & SV_CENABLE_PE) && (val = prog_dmabuf(s, 0)) != 0) + return val; + spin_lock_irqsave(&s->lock, flags); + sv_update_ptr(s); + abinfo.fragsize = s->dma_dac.fragsize; + abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count; + abinfo.fragstotal = s->dma_dac.numfrag; + abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift; + spin_unlock_irqrestore(&s->lock, flags); + return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; + + case SNDCTL_DSP_GETISPACE: + if (!(file->f_mode & FMODE_READ)) + return -EINVAL; + if (!(s->enable & SV_CENABLE_RE) && (val = prog_dmabuf(s, 1)) != 0) + return val; + spin_lock_irqsave(&s->lock, flags); + sv_update_ptr(s); + abinfo.fragsize = s->dma_adc.fragsize; + abinfo.bytes = s->dma_adc.count; + abinfo.fragstotal = s->dma_adc.numfrag; + abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift; + spin_unlock_irqrestore(&s->lock, flags); + return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; + + case SNDCTL_DSP_NONBLOCK: + file->f_flags |= O_NONBLOCK; + return 0; + + case SNDCTL_DSP_GETODELAY: + if (!(file->f_mode & FMODE_WRITE)) + return -EINVAL; + spin_lock_irqsave(&s->lock, flags); + sv_update_ptr(s); + val = s->dma_dac.count; + spin_unlock_irqrestore(&s->lock, flags); + return put_user(val, (int *)arg); + + case SNDCTL_DSP_GETIPTR: + if (!(file->f_mode & FMODE_READ)) + return -EINVAL; + spin_lock_irqsave(&s->lock, flags); + sv_update_ptr(s); + cinfo.bytes = s->dma_adc.total_bytes; + cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift; + cinfo.ptr = s->dma_adc.hwptr; + if (s->dma_adc.mapped) + s->dma_adc.count &= s->dma_adc.fragsize-1; + spin_unlock_irqrestore(&s->lock, flags); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)); + + case SNDCTL_DSP_GETOPTR: + if (!(file->f_mode & FMODE_WRITE)) + return -EINVAL; + spin_lock_irqsave(&s->lock, flags); + sv_update_ptr(s); + cinfo.bytes = s->dma_dac.total_bytes; + cinfo.blocks = s->dma_dac.count >> s->dma_dac.fragshift; + cinfo.ptr = s->dma_dac.hwptr; + if (s->dma_dac.mapped) + s->dma_dac.count &= s->dma_dac.fragsize-1; + spin_unlock_irqrestore(&s->lock, flags); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)); + + case SNDCTL_DSP_GETBLKSIZE: + if (file->f_mode & FMODE_WRITE) { + if ((val = prog_dmabuf(s, 0))) + return val; + return put_user(s->dma_dac.fragsize, (int *)arg); + } + if ((val = prog_dmabuf(s, 1))) + return val; + return put_user(s->dma_adc.fragsize, (int *)arg); + + case SNDCTL_DSP_SETFRAGMENT: + get_user_ret(val, (int *)arg, -EFAULT); + if (file->f_mode & FMODE_READ) { + s->dma_adc.ossfragshift = val & 0xffff; + s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff; + if (s->dma_adc.ossfragshift < 4) + s->dma_adc.ossfragshift = 4; + if (s->dma_adc.ossfragshift > 15) + s->dma_adc.ossfragshift = 15; + if (s->dma_adc.ossmaxfrags < 4) + s->dma_adc.ossmaxfrags = 4; + } + if (file->f_mode & FMODE_WRITE) { + s->dma_dac.ossfragshift = val & 0xffff; + s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff; + if (s->dma_dac.ossfragshift < 4) + s->dma_dac.ossfragshift = 4; + if (s->dma_dac.ossfragshift > 15) + s->dma_dac.ossfragshift = 15; + if (s->dma_dac.ossmaxfrags < 4) + s->dma_dac.ossmaxfrags = 4; + } + return 0; + + case SNDCTL_DSP_SUBDIVIDE: + if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) || + (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision)) + return -EINVAL; + get_user_ret(val, (int *)arg, -EFAULT); + if (val != 1 && val != 2 && val != 4) + return -EINVAL; + if (file->f_mode & FMODE_READ) + s->dma_adc.subdivision = val; + if (file->f_mode & FMODE_WRITE) + s->dma_dac.subdivision = val; + return 0; + + case SOUND_PCM_WRITE_FILTER: + case SNDCTL_DSP_SETSYNCRO: + case SOUND_PCM_READ_RATE: + case SOUND_PCM_READ_CHANNELS: + case SOUND_PCM_READ_BITS: + case SOUND_PCM_READ_FILTER: + return -EINVAL; + + } + return mixer_ioctl(s, cmd, arg); +} + +static int sv_open(struct inode *inode, struct file *file) +{ + int minor = MINOR(inode->i_rdev); + struct sv_state *s = devs; + unsigned char fmtm = ~0, fmts = 0; + + while (s && ((s->dev_audio ^ minor) & ~0xf)) + s = s->next; + if (!s) + return -ENODEV; + VALIDATE_STATE(s); + file->private_data = s; + /* wait for device to become free */ + down(&s->open_sem); + while (s->open_mode & file->f_mode) { + if (file->f_flags & O_NONBLOCK) { + up(&s->open_sem); + return -EBUSY; + } + up(&s->open_sem); + interruptible_sleep_on(&s->open_wait); + if (signal_pending(current)) + return -ERESTARTSYS; + down(&s->open_sem); + } + if (file->f_mode & FMODE_READ) { + fmtm &= ~((SV_CFMT_STEREO | SV_CFMT_16BIT) << SV_CFMT_CSHIFT); + if ((minor & 0xf) == SND_DEV_DSP16) + fmts |= SV_CFMT_16BIT << SV_CFMT_CSHIFT; + s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0; + set_adc_rate(s, 8000); + } + if (file->f_mode & FMODE_WRITE) { + fmtm &= ~((SV_CFMT_STEREO | SV_CFMT_16BIT) << SV_CFMT_ASHIFT); + if ((minor & 0xf) == SND_DEV_DSP16) + fmts |= SV_CFMT_16BIT << SV_CFMT_ASHIFT; + s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0; + set_dac_rate(s, 8000); + } + set_fmt(s, fmtm, fmts); + s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); + up(&s->open_sem); + MOD_INC_USE_COUNT; + return 0; +} + +static int sv_release(struct inode *inode, struct file *file) +{ + struct sv_state *s = (struct sv_state *)file->private_data; + + VALIDATE_STATE(s); + if (file->f_mode & FMODE_WRITE) + drain_dac(s, file->f_flags & O_NONBLOCK); + down(&s->open_sem); + if (file->f_mode & FMODE_WRITE) { + stop_dac(s); + dealloc_dmabuf(&s->dma_dac); + } + if (file->f_mode & FMODE_READ) { + stop_adc(s); + dealloc_dmabuf(&s->dma_adc); + } + s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); + up(&s->open_sem); + wake_up(&s->open_wait); + MOD_DEC_USE_COUNT; + return 0; +} + +static /*const*/ struct file_operations sv_audio_fops = { + &sv_llseek, + &sv_read, + &sv_write, + NULL, /* readdir */ + &sv_poll, + &sv_ioctl, + &sv_mmap, + &sv_open, + NULL, /* flush */ + &sv_release, + NULL, /* fsync */ + NULL, /* fasync */ + NULL, /* check_media_change */ + NULL, /* revalidate */ + NULL, /* lock */ +}; + +/* --------------------------------------------------------------------- */ + +static ssize_t sv_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos) +{ + struct sv_state *s = (struct sv_state *)file->private_data; + ssize_t ret; + unsigned long flags; + unsigned ptr; + int cnt; + + VALIDATE_STATE(s); + if (ppos != &file->f_pos) + return -ESPIPE; + if (!access_ok(VERIFY_WRITE, buffer, count)) + return -EFAULT; + ret = 0; + while (count > 0) { + spin_lock_irqsave(&s->lock, flags); + ptr = s->midi.ird; + cnt = MIDIINBUF - ptr; + if (s->midi.icnt < cnt) + cnt = s->midi.icnt; + spin_unlock_irqrestore(&s->lock, flags); + if (cnt > count) + cnt = count; + if (cnt <= 0) { + if (file->f_flags & O_NONBLOCK) + return ret ? ret : -EAGAIN; + interruptible_sleep_on(&s->midi.iwait); + if (signal_pending(current)) + return ret ? ret : -ERESTARTSYS; + continue; + } + if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) + return ret ? ret : -EFAULT; + ptr = (ptr + cnt) % MIDIINBUF; + spin_lock_irqsave(&s->lock, flags); + s->midi.ird = ptr; + s->midi.icnt -= cnt; + spin_unlock_irqrestore(&s->lock, flags); + count -= cnt; + buffer += cnt; + ret += cnt; + } + return ret; +} + +static ssize_t sv_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) +{ + struct sv_state *s = (struct sv_state *)file->private_data; + ssize_t ret; + unsigned long flags; + unsigned ptr; + int cnt; + + VALIDATE_STATE(s); + if (ppos != &file->f_pos) + return -ESPIPE; + if (!access_ok(VERIFY_READ, buffer, count)) + return -EFAULT; + ret = 0; + while (count > 0) { + spin_lock_irqsave(&s->lock, flags); + ptr = s->midi.owr; + cnt = MIDIOUTBUF - ptr; + if (s->midi.ocnt + cnt > MIDIOUTBUF) + cnt = MIDIOUTBUF - s->midi.ocnt; + if (cnt <= 0) + sv_handle_midi(s); + spin_unlock_irqrestore(&s->lock, flags); + if (cnt > count) + cnt = count; + if (cnt <= 0) { + if (file->f_flags & O_NONBLOCK) + return ret ? ret : -EAGAIN; + interruptible_sleep_on(&s->midi.owait); + if (signal_pending(current)) + return ret ? ret : -ERESTARTSYS; + continue; + } + if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) + return ret ? ret : -EFAULT; + ptr = (ptr + cnt) % MIDIOUTBUF; + spin_lock_irqsave(&s->lock, flags); + s->midi.owr = ptr; + s->midi.ocnt += cnt; + spin_unlock_irqrestore(&s->lock, flags); + count -= cnt; + buffer += cnt; + ret += cnt; + spin_lock_irqsave(&s->lock, flags); + sv_handle_midi(s); + spin_unlock_irqrestore(&s->lock, flags); + } + return ret; +} + +static unsigned int sv_midi_poll(struct file *file, struct poll_table_struct *wait) +{ + struct sv_state *s = (struct sv_state *)file->private_data; + unsigned long flags; + unsigned int mask = 0; + + VALIDATE_STATE(s); + if (file->f_mode & FMODE_WRITE) + poll_wait(file, &s->midi.owait, wait); + if (file->f_mode & FMODE_READ) + poll_wait(file, &s->midi.iwait, wait); + spin_lock_irqsave(&s->lock, flags); + if (file->f_mode & FMODE_READ) { + if (s->midi.icnt > 0) + mask |= POLLIN | POLLRDNORM; + } + if (file->f_mode & FMODE_WRITE) { + if (s->midi.ocnt < MIDIOUTBUF) + mask |= POLLOUT | POLLWRNORM; + } + spin_unlock_irqrestore(&s->lock, flags); + return mask; +} + +static int sv_midi_open(struct inode *inode, struct file *file) +{ + int minor = MINOR(inode->i_rdev); + struct sv_state *s = devs; + unsigned long flags; + + while (s && s->dev_midi != minor) + s = s->next; + if (!s) + return -ENODEV; + VALIDATE_STATE(s); + file->private_data = s; + /* wait for device to become free */ + down(&s->open_sem); + while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) { + if (file->f_flags & O_NONBLOCK) { + up(&s->open_sem); + return -EBUSY; + } + up(&s->open_sem); + interruptible_sleep_on(&s->open_wait); + if (signal_pending(current)) + return -ERESTARTSYS; + down(&s->open_sem); + } + spin_lock_irqsave(&s->lock, flags); + if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { + s->midi.ird = s->midi.iwr = s->midi.icnt = 0; + s->midi.ord = s->midi.owr = s->midi.ocnt = 0; + //outb(inb(s->ioenh + SV_CODEC_CONTROL) | SV_CCTRL_WAVETABLE, s->ioenh + SV_CODEC_CONTROL); + outb(inb(s->ioenh + SV_CODEC_INTMASK) | SV_CINTMASK_MIDI, s->ioenh + SV_CODEC_INTMASK); + wrindir(s, SV_CIUARTCONTROL, 5); /* output MIDI data to external and internal synth */ + wrindir(s, SV_CIWAVETABLESRC, 1); /* Wavetable in PC RAM */ + outb(0xff, s->iomidi+1); /* reset command */ + outb(0x3f, s->iomidi+1); /* uart command */ + if (!(inb(s->iomidi+1) & 0x80)) + inb(s->iomidi); + s->midi.ird = s->midi.iwr = s->midi.icnt = 0; + init_timer(&s->midi.timer); + s->midi.timer.expires = jiffies+1; + s->midi.timer.data = (unsigned long)s; + s->midi.timer.function = sv_midi_timer; + add_timer(&s->midi.timer); + } + if (file->f_mode & FMODE_READ) { + s->midi.ird = s->midi.iwr = s->midi.icnt = 0; + } + if (file->f_mode & FMODE_WRITE) { + s->midi.ord = s->midi.owr = s->midi.ocnt = 0; + } + spin_unlock_irqrestore(&s->lock, flags); + s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); + up(&s->open_sem); + MOD_INC_USE_COUNT; + return 0; +} + +static int sv_midi_release(struct inode *inode, struct file *file) +{ + struct sv_state *s = (struct sv_state *)file->private_data; + struct wait_queue wait = { current, NULL }; + unsigned long flags; + unsigned count, tmo; + + VALIDATE_STATE(s); + + if (file->f_mode & FMODE_WRITE) { + current->state = TASK_INTERRUPTIBLE; + add_wait_queue(&s->midi.owait, &wait); + for (;;) { + spin_lock_irqsave(&s->lock, flags); + count = s->midi.ocnt; + spin_unlock_irqrestore(&s->lock, flags); + if (count <= 0) + break; + if (signal_pending(current)) + break; + if (file->f_flags & O_NONBLOCK) { + remove_wait_queue(&s->midi.owait, &wait); + current->state = TASK_RUNNING; + return -EBUSY; + } + tmo = (count * HZ) / 3100; + if (!schedule_timeout(tmo ? : 1) && tmo) + printk(KERN_DEBUG "sv: midi timed out??\n"); + } + remove_wait_queue(&s->midi.owait, &wait); + current->state = TASK_RUNNING; + } + down(&s->open_sem); + s->open_mode &= (~(file->f_mode << FMODE_MIDI_SHIFT)) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE); + spin_lock_irqsave(&s->lock, flags); + if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { + outb(inb(s->ioenh + SV_CODEC_INTMASK) & ~SV_CINTMASK_MIDI, s->ioenh + SV_CODEC_INTMASK); + del_timer(&s->midi.timer); + } + spin_unlock_irqrestore(&s->lock, flags); + up(&s->open_sem); + wake_up(&s->open_wait); + MOD_DEC_USE_COUNT; + return 0; +} + +static /*const*/ struct file_operations sv_midi_fops = { + &sv_llseek, + &sv_midi_read, + &sv_midi_write, + NULL, /* readdir */ + &sv_midi_poll, + NULL, /* ioctl */ + NULL, /* mmap */ + &sv_midi_open, + NULL, /* flush */ + &sv_midi_release, + NULL, /* fsync */ + NULL, /* fasync */ + NULL, /* check_media_change */ + NULL, /* revalidate */ + NULL, /* lock */ +}; + +/* --------------------------------------------------------------------- */ + +static int sv_dmfm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + static const unsigned char op_offset[18] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15 + }; + struct sv_state *s = (struct sv_state *)file->private_data; + struct dm_fm_voice v; + struct dm_fm_note n; + struct dm_fm_params p; + unsigned int io; + unsigned int regb; + + switch (cmd) { + case FM_IOCTL_RESET: + for (regb = 0xb0; regb < 0xb9; regb++) { + outb(regb, s->iosynth); + outb(0, s->iosynth+1); + outb(regb, s->iosynth+2); + outb(0, s->iosynth+3); + } + return 0; + + case FM_IOCTL_PLAY_NOTE: + if (copy_from_user(&n, (void *)arg, sizeof(n))) + return -EFAULT; + if (n.voice >= 18) + return -EINVAL; + if (n.voice >= 9) { + regb = n.voice - 9; + io = s->iosynth+2; + } else { + regb = n.voice; + io = s->iosynth; + } + outb(0xa0 + regb, io); + outb(n.fnum & 0xff, io+1); + outb(0xb0 + regb, io); + outb(((n.fnum >> 8) & 3) | ((n.octave & 7) << 2) | ((n.key_on & 1) << 5), io+1); + return 0; + + case FM_IOCTL_SET_VOICE: + if (copy_from_user(&v, (void *)arg, sizeof(v))) + return -EFAULT; + if (v.voice >= 18) + return -EINVAL; + regb = op_offset[v.voice]; + io = s->iosynth + ((v.op & 1) << 1); + outb(0x20 + regb, io); + outb(((v.am & 1) << 7) | ((v.vibrato & 1) << 6) | ((v.do_sustain & 1) << 5) | + ((v.kbd_scale & 1) << 4) | (v.harmonic & 0xf), io+1); + outb(0x40 + regb, io); + outb(((v.scale_level & 0x3) << 6) | (v.volume & 0x3f), io+1); + outb(0x60 + regb, io); + outb(((v.attack & 0xf) << 4) | (v.decay & 0xf), io+1); + outb(0x80 + regb, io); + outb(((v.sustain & 0xf) << 4) | (v.release & 0xf), io+1); + outb(0xe0 + regb, io); + outb(v.waveform & 0x7, io+1); + if (n.voice >= 9) { + regb = n.voice - 9; + io = s->iosynth+2; + } else { + regb = n.voice; + io = s->iosynth; + } + outb(0xc0 + regb, io); + outb(((v.right & 1) << 5) | ((v.left & 1) << 4) | ((v.feedback & 7) << 1) | + (v.connection & 1), io+1); + return 0; + + case FM_IOCTL_SET_PARAMS: + if (copy_from_user(&p, (void *)arg, sizeof(p))) + return -EFAULT; + outb(0x08, s->iosynth); + outb((p.kbd_split & 1) << 6, s->iosynth+1); + outb(0xbd, s->iosynth); + outb(((p.am_depth & 1) << 7) | ((p.vib_depth & 1) << 6) | ((p.rhythm & 1) << 5) | ((p.bass & 1) << 4) | + ((p.snare & 1) << 3) | ((p.tomtom & 1) << 2) | ((p.cymbal & 1) << 1) | (p.hihat & 1), s->iosynth+1); + return 0; + + case FM_IOCTL_SET_OPL: + outb(4, s->iosynth+2); + outb(arg, s->iosynth+3); + return 0; + + case FM_IOCTL_SET_MODE: + outb(5, s->iosynth+2); + outb(arg & 1, s->iosynth+3); + return 0; + + default: + return -EINVAL; + } +} + +static int sv_dmfm_open(struct inode *inode, struct file *file) +{ + int minor = MINOR(inode->i_rdev); + struct sv_state *s = devs; + + while (s && s->dev_dmfm != minor) + s = s->next; + if (!s) + return -ENODEV; + VALIDATE_STATE(s); + file->private_data = s; + /* wait for device to become free */ + down(&s->open_sem); + while (s->open_mode & FMODE_DMFM) { + if (file->f_flags & O_NONBLOCK) { + up(&s->open_sem); + return -EBUSY; + } + up(&s->open_sem); + interruptible_sleep_on(&s->open_wait); + if (signal_pending(current)) + return -ERESTARTSYS; + down(&s->open_sem); + } + /* init the stuff */ + outb(1, s->iosynth); + outb(0x20, s->iosynth+1); /* enable waveforms */ + outb(4, s->iosynth+2); + outb(0, s->iosynth+3); /* no 4op enabled */ + outb(5, s->iosynth+2); + outb(1, s->iosynth+3); /* enable OPL3 */ + s->open_mode |= FMODE_DMFM; + up(&s->open_sem); + MOD_INC_USE_COUNT; + return 0; +} + +static int sv_dmfm_release(struct inode *inode, struct file *file) +{ + struct sv_state *s = (struct sv_state *)file->private_data; + unsigned int regb; + + VALIDATE_STATE(s); + down(&s->open_sem); + s->open_mode &= ~FMODE_DMFM; + for (regb = 0xb0; regb < 0xb9; regb++) { + outb(regb, s->iosynth); + outb(0, s->iosynth+1); + outb(regb, s->iosynth+2); + outb(0, s->iosynth+3); + } + up(&s->open_sem); + wake_up(&s->open_wait); + MOD_DEC_USE_COUNT; + return 0; +} + +static /*const*/ struct file_operations sv_dmfm_fops = { + &sv_llseek, + NULL, /* read */ + NULL, /* write */ + NULL, /* readdir */ + NULL, /* poll */ + &sv_dmfm_ioctl, + NULL, /* mmap */ + &sv_dmfm_open, + NULL, /* flush */ + &sv_dmfm_release, + NULL, /* fsync */ + NULL, /* fasync */ + NULL, /* check_media_change */ + NULL, /* revalidate */ + NULL, /* lock */ +}; + +/* --------------------------------------------------------------------- */ + +/* maximum number of devices */ +#define NR_DEVICE 5 + +static int reverb[NR_DEVICE] = { 0, }; + +#if 0 +static int wavetable[NR_DEVICE] = { 0, }; +#endif + +static unsigned dmaio = 0xac00; + +/* --------------------------------------------------------------------- */ + +static struct initvol { + int mixch; + int vol; +} initvol[] __initdata = { + { SOUND_MIXER_WRITE_RECLEV, 0x4040 }, + { SOUND_MIXER_WRITE_LINE1, 0x4040 }, + { SOUND_MIXER_WRITE_CD, 0x4040 }, + { SOUND_MIXER_WRITE_LINE, 0x4040 }, + { SOUND_MIXER_WRITE_MIC, 0x4040 }, + { SOUND_MIXER_WRITE_SYNTH, 0x4040 }, + { SOUND_MIXER_WRITE_LINE2, 0x4040 }, + { SOUND_MIXER_WRITE_VOLUME, 0x4040 }, + { SOUND_MIXER_WRITE_PCM, 0x4040 } +}; + +#ifdef MODULE +__initfunc(int init_module(void)) +#else +__initfunc(int init_sonicvibes(void)) +#endif +{ + struct sv_state *s; + struct pci_dev *pcidev = NULL; + mm_segment_t fs; + int i, val, index = 0; + + if (!pci_present()) /* No PCI bus in this machine! */ + return -ENODEV; + printk(KERN_INFO "sv: version v0.12 time " __TIME__ " " __DATE__ "\n"); +#if 0 + if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT))) + printk(KERN_INFO "sv: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n"); +#endif + while (index < NR_DEVICE && + (pcidev = pci_find_device(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_SONICVIBES, pcidev))) { + if (pcidev->base_address[1] == 0 || + (pcidev->base_address[1] & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_IO) + continue; + if (pcidev->base_address[2] == 0 || + (pcidev->base_address[2] & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_IO) + continue; + if (pcidev->base_address[3] == 0 || + (pcidev->base_address[3] & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_IO) + continue; + if (pcidev->irq == 0) + continue; + if (!(s = kmalloc(sizeof(struct sv_state), GFP_KERNEL))) { + printk(KERN_WARNING "sv: out of memory\n"); + continue; + } + memset(s, 0, sizeof(struct sv_state)); + init_waitqueue(&s->dma_adc.wait); + init_waitqueue(&s->dma_dac.wait); + init_waitqueue(&s->open_wait); + init_waitqueue(&s->midi.iwait); + init_waitqueue(&s->midi.owait); + s->open_sem = MUTEX; + s->magic = SV_MAGIC; + s->iosb = pcidev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK; + s->ioenh = pcidev->base_address[1] & PCI_BASE_ADDRESS_IO_MASK; + s->iosynth = pcidev->base_address[2] & PCI_BASE_ADDRESS_IO_MASK; + s->iomidi = pcidev->base_address[3] & PCI_BASE_ADDRESS_IO_MASK; + s->iogame = pcidev->base_address[4] & PCI_BASE_ADDRESS_IO_MASK; + pci_read_config_dword(pcidev, 0x40, &s->iodmaa); + pci_read_config_dword(pcidev, 0x48, &s->iodmac); + dmaio &= ~(SV_EXTENT_DMA-1); + s->iodmaa &= ~(SV_EXTENT_DMA-1); + s->iodmac &= ~(SV_EXTENT_DMA-1); + if (!(s->iodmaa)) { + s->iodmaa = dmaio; + dmaio += SV_EXTENT_DMA; + printk(KERN_INFO "sv: BIOS did not allocate DDMA channel A io, allocated at %#x\n", + s->iodmaa); + } + if (!(s->iodmac)) { + s->iodmac = dmaio; + dmaio += SV_EXTENT_DMA; + printk(KERN_INFO "sv: BIOS did not allocate DDMA channel C io, allocated at %#x\n", + s->iodmac); + } + pci_write_config_dword(pcidev, 0x40, s->iodmaa | 9); /* enable and use extended mode */ + pci_write_config_dword(pcidev, 0x48, s->iodmac | 9); /* enable */ + printk(KERN_DEBUG "sv: io ports: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + s->iosb, s->ioenh, s->iosynth, s->iomidi, s->iogame, s->iodmaa, s->iodmac); + if (s->ioenh == 0 || s->iodmaa == 0 || s->iodmac == 0) + continue; + s->irq = pcidev->irq; + + /* hack */ + pci_write_config_dword(pcidev, 0x60, wavetable_mem >> 12); /* wavetable base address */ + + if (check_region(s->ioenh, SV_EXTENT_ENH)) { + printk(KERN_ERR "sv: io ports %#x-%#x in use\n", s->ioenh, s->ioenh+SV_EXTENT_ENH-1); + goto err_region5; + } + request_region(s->ioenh, SV_EXTENT_ENH, "S3 SonicVibes PCM"); + if (check_region(s->iodmaa, SV_EXTENT_DMA)) { + printk(KERN_ERR "sv: io ports %#x-%#x in use\n", s->iodmaa, s->iodmaa+SV_EXTENT_DMA-1); + goto err_region4; + } + request_region(s->iodmaa, SV_EXTENT_DMA, "S3 SonicVibes DMAA"); + if (check_region(s->iodmac, SV_EXTENT_DMA)) { + printk(KERN_ERR "sv: io ports %#x-%#x in use\n", s->iodmac, s->iodmac+SV_EXTENT_DMA-1); + goto err_region3; + } + request_region(s->iodmac, SV_EXTENT_DMA, "S3 SonicVibes DMAC"); + if (check_region(s->iomidi, SV_EXTENT_MIDI)) { + printk(KERN_ERR "sv: io ports %#x-%#x in use\n", s->iomidi, s->iomidi+SV_EXTENT_MIDI-1); + goto err_region2; + } + request_region(s->iomidi, SV_EXTENT_MIDI, "S3 SonicVibes Midi"); + if (check_region(s->iosynth, SV_EXTENT_SYNTH)) { + printk(KERN_ERR "sv: io ports %#x-%#x in use\n", s->iosynth, s->iosynth+SV_EXTENT_SYNTH-1); + goto err_region1; + } + request_region(s->iosynth, SV_EXTENT_SYNTH, "S3 SonicVibes Synth"); + /* initialize codec registers */ + outb(0x80, s->ioenh + SV_CODEC_CONTROL); /* assert reset */ + udelay(50); + outb(0x00, s->ioenh + SV_CODEC_CONTROL); /* deassert reset */ + udelay(50); + outb(SV_CCTRL_INTADRIVE | SV_CCTRL_ENHANCED /*| SV_CCTRL_WAVETABLE */ + | (reverb[index] ? SV_CCTRL_REVERB : 0), s->ioenh + SV_CODEC_CONTROL); + inb(s->ioenh + SV_CODEC_STATUS); /* clear ints */ + wrindir(s, SV_CIDRIVECONTROL, 0); /* drive current 16mA */ + wrindir(s, SV_CIENABLE, s->enable = 0); /* disable DMAA and DMAC */ + outb(~(SV_CINTMASK_DMAA | SV_CINTMASK_DMAC), s->ioenh + SV_CODEC_INTMASK); + //outb(0xff, s->iodmaa + SV_DMA_RESET); + //outb(0xff, s->iodmac + SV_DMA_RESET); + inb(s->ioenh + SV_CODEC_STATUS); /* ack interrupts */ + wrindir(s, SV_CIADCCLKSOURCE, 0); /* use pll as ADC clock source */ + wrindir(s, SV_CIANALOGPWRDOWN, 0); /* power up the analog parts of the device */ + wrindir(s, SV_CIDIGITALPWRDOWN, 0); /* power up the digital parts of the device */ + setpll(s, SV_CIADCPLLM, 8000); + wrindir(s, SV_CISRSSPACE, 0x80); /* SRS off */ + wrindir(s, SV_CIPCMSR0, (8000 * 65536 / FULLRATE) & 0xff); + wrindir(s, SV_CIPCMSR1, ((8000 * 65536 / FULLRATE) >> 8) & 0xff); + wrindir(s, SV_CIADCOUTPUT, 0); + /* request irq */ + if (request_irq(s->irq, sv_interrupt, SA_SHIRQ, "S3 SonicVibes", s)) { + printk(KERN_ERR "sv: irq %u in use\n", s->irq); + goto err_irq; + } + printk(KERN_INFO "sv: found adapter at io %#06x irq %u dmaa %#06x dmac %#06x revision %u\n", + s->ioenh, s->irq, s->iodmaa, s->iodmac, rdindir(s, SV_CIREVISION)); + /* register devices */ + if ((s->dev_audio = register_sound_dsp(&sv_audio_fops, -1)) < 0) + goto err_dev1; + if ((s->dev_mixer = register_sound_mixer(&sv_mixer_fops, -1)) < 0) + goto err_dev2; + if ((s->dev_midi = register_sound_midi(&sv_midi_fops, -1)) < 0) + goto err_dev3; + if ((s->dev_dmfm = register_sound_special(&sv_dmfm_fops, 15 /* ?? */)) < 0) + goto err_dev4; + /* initialize the chips */ + fs = get_fs(); + set_fs(KERNEL_DS); + val = SOUND_MASK_LINE|SOUND_MASK_SYNTH; + mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val); + for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) { + val = initvol[i].vol; + mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val); + } + set_fs(fs); + /* queue it for later freeing */ + s->next = devs; + devs = s; + index++; + continue; + + err_dev4: + unregister_sound_midi(s->dev_midi); + err_dev3: + unregister_sound_mixer(s->dev_mixer); + err_dev2: + unregister_sound_dsp(s->dev_audio); + err_dev1: + printk(KERN_ERR "sv: cannot register misc device\n"); + free_irq(s->irq, s); + err_irq: + release_region(s->iosynth, SV_EXTENT_SYNTH); + err_region1: + release_region(s->iomidi, SV_EXTENT_MIDI); + err_region2: + release_region(s->iodmac, SV_EXTENT_DMA); + err_region3: + release_region(s->iodmaa, SV_EXTENT_DMA); + err_region4: + release_region(s->ioenh, SV_EXTENT_ENH); + err_region5: + kfree_s(s, sizeof(struct sv_state)); + } + if (!devs) { + if (wavetable_mem) + free_pages(wavetable_mem, 20-PAGE_SHIFT); + return -ENODEV; + } + return 0; +} + +/* --------------------------------------------------------------------- */ + +#ifdef MODULE + +MODULE_PARM(reverb, "1-" __MODULE_STRING(NR_DEVICE) "i"); +MODULE_PARM_DESC(reverb, "if 1 enables the reverb circuitry. NOTE: your card must have the reverb RAM"); +#if 0 +MODULE_PARM(wavetable, "1-" __MODULE_STRING(NR_DEVICE) "i"); +MODULE_PARM_DESC(wavetable, "if 1 the wavetable synth is enabled"); +#endif + +MODULE_PARM(dmaio, "i"); +MODULE_PARM_DESC(dmaio, "if the motherboard BIOS did not allocate DDMA io, allocate them starting at this address"); + +MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); +MODULE_DESCRIPTION("S3 SonicVibes Driver"); + +void cleanup_module(void) +{ + struct sv_state *s; + + while ((s = devs)) { + devs = devs->next; + outb(~0, s->ioenh + SV_CODEC_INTMASK); /* disable ints */ + synchronize_irq(); + inb(s->ioenh + SV_CODEC_STATUS); /* ack interrupts */ + wrindir(s, SV_CIENABLE, 0); /* disable DMAA and DMAC */ + //outb(0, s->iodmaa + SV_DMA_RESET); + //outb(0, s->iodmac + SV_DMA_RESET); + free_irq(s->irq, s); + release_region(s->iodmac, SV_EXTENT_DMA); + release_region(s->iodmaa, SV_EXTENT_DMA); + release_region(s->ioenh, SV_EXTENT_ENH); + release_region(s->iomidi, SV_EXTENT_MIDI); + release_region(s->iosynth, SV_EXTENT_SYNTH); + unregister_sound_dsp(s->dev_audio); + unregister_sound_mixer(s->dev_mixer); + unregister_sound_midi(s->dev_midi); + unregister_sound_special(s->dev_dmfm); + kfree_s(s, sizeof(struct sv_state)); + } + if (wavetable_mem) + free_pages(wavetable_mem, 20-PAGE_SHIFT); + printk(KERN_INFO "sv: unloading\n"); +} + +#endif /* MODULE */ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/scripts/Configure linux.ac/scripts/Configure --- linux.vanilla/scripts/Configure Mon Feb 1 20:03:20 1999 +++ linux.ac/scripts/Configure Tue Sep 14 20:59:14 1999 @@ -143,6 +143,10 @@ # define_bool define value # function define_bool () { + define_tristate $1 $2 +} + +function define_tristate () { case "$2" in "y") echo "$1=y" >>$CONFIG @@ -213,11 +217,11 @@ while :; do readln "$1 ($2) [$defprompt] " "$def" "$old" case "$ans" in - [yY] | [yY]es ) define_bool "$2" "y" + [yY] | [yY]es ) define_tristate "$2" "y" break ;; - [nN] | [nN]o ) define_bool "$2" "n" + [nN] | [nN]o ) define_tristate "$2" "n" break ;; - [mM] ) define_bool "$2" "m" + [mM] ) define_tristate "$2" "m" break ;; * ) help "$2" ;; @@ -246,7 +250,7 @@ while [ $# -gt 0 ]; do case "$1" in n) - define_bool "$var" "n" + define_tristate "$var" "n" return ;; m) @@ -268,9 +272,9 @@ while :; do readln "$ques ($var) [$defprompt] " "$def" "$old" case "$ans" in - [nN] | [nN]o ) define_bool "$var" "n" + [nN] | [nN]o ) define_tristate "$var" "n" break ;; - [mM] ) define_bool "$var" "m" + [mM] ) define_tristate "$var" "m" break ;; [yY] | [yY]es ) echo echo " This answer is not allowed, because it is not consistent with" @@ -288,6 +292,23 @@ else tristate "$ques" "$var" fi +} + +function dep_bool () { + ques=$1 + var=$2 + shift 2 + while [ $# -gt 0 ]; do + case "$1" in + m | n) + define_bool "$var" "n" + return + ;; + esac + shift + done + + bool "$ques" "$var" } # diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/scripts/Menuconfig linux.ac/scripts/Menuconfig --- linux.vanilla/scripts/Menuconfig Sun May 2 17:51:16 1999 +++ linux.ac/scripts/Menuconfig Wed Sep 15 23:59:04 1999 @@ -68,6 +68,12 @@ # # 24 January 1999, Michael Elizabeth Chastain, # - Improve the exit message (Jeff Ronne). +# +# 06 July 1999, Andrzej M. Krzysztofowicz, +# - Support for multiple conditions in dep_tristate(). +# - Implemented new functions: define_tristate(), define_int(), define_hex(), +# define_string(), dep_bool(). +# # @@ -132,6 +138,22 @@ eval $1=$2 } +function define_tristate () { + eval $1=$2 +} + +function define_hex () { + eval $1=$2 +} + +function define_int () { + eval $1=$2 +} + +function define_string () { + eval $1="$2" +} + # # Create a boolean (Yes/No) function for our current menu # which calls our local bool function. @@ -188,13 +210,52 @@ # else in the kernel. # function dep_tristate () { - if [ "$3" = "y" ]; then - tristate "$1" "$2" - else if [ "$3" = "m" ]; then - mod_bool "$1" "$2" + ques="$1" + var="$2" + dep=y + shift 2 + while [ $# -gt 0 ]; do + if [ "$1" = y ]; then + shift + elif [ "$1" = m ]; then + dep=m + shift + else + dep=n + shift $# + fi + done + if [ "$dep" = y ]; then + tristate "$ques" "$var" + elif [ "$dep" = m ]; then + mod_bool "$ques" "$var" + else + define_tristate "$var" n + fi +} + +# +# Same as above, but now only Y and N are allowed as dependency +# (i.e. third and next arguments). +# +function dep_bool () { + ques="$1" + var="$2" + dep=y + shift 2 + while [ $# -gt 0 ]; do + if [ "$1" = y ]; then + shift + else + dep=n + shift $# + fi + done + if [ "$dep" = y ]; then + bool "$ques" "$var" else - define_bool "$2" n - fi; fi + define_bool "$var" n + fi } # @@ -633,12 +694,13 @@ printf("submenu %s MCmenu%s\n", $0, menu_no) >>menu + newmenu = sprintf("MCmenu%d", menu_no); printf( "function MCmenu%s () {\n"\ "default=$1\n"\ "menu_name %s\n",\ - menu_no, $0) >"MCmenu"menu_no + menu_no, $0) >newmenu - parser(ifile, "MCmenu"menu_no) + parser(ifile, newmenu) } else if ($1 ~ "endmenu") { printf("}\n") >>menu @@ -988,13 +1050,37 @@ function tristate () { set_x_info "$2" "n" - eval define_bool "$2" "$x" + eval define_tristate "$2" "$x" } function dep_tristate () { set_x_info "$2" "n" - if [ "$3" = "m" -a "$x" = "y" ]; then x="m"; fi - define_bool "$2" "$x" + var="$2" + shift 2 + while [ $# -gt 0 ]; do + if [ "$1" = y ]; then + shift + elif [ "$1" = m -a "$x" != n ]; then + x=m; shift + else + x=n; shift $# + fi + done + define_tristate "$var" "$x" + } + + function dep_bool () { + set_x_info "$2" "n" + var="$2" + shift 2 + while [ $# -gt 0 ]; do + if [ "$1" = y ]; then + shift + else + x=n; shift $# + fi + done + define_bool "$var" "$x" } function int () { @@ -1015,7 +1101,29 @@ echo "#define $2 \"$x\"" >>$CONFIG_H } + function define_hex () { + eval $1="$2" + echo "$1=$2" >>$CONFIG + echo "#define $1 0x${2##*[x,X]}" >>$CONFIG_H + } + + function define_int () { + eval $1="$2" + echo "$1=$2" >>$CONFIG + echo "#define $1 ($2)" >>$CONFIG_H + } + + function define_string () { + eval $1="$2" + echo "$1=\"$2\"" >>$CONFIG + echo "#define $1 \"$2\"" >>$CONFIG_H + } + function define_bool () { + define_tristate "$1" "$2" + } + + function define_tristate () { eval $1="$2" case "$2" in diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/scripts/header.tk linux.ac/scripts/header.tk --- linux.vanilla/scripts/header.tk Mon Feb 1 20:03:20 1999 +++ linux.ac/scripts/header.tk Tue Sep 14 20:59:14 1999 @@ -32,7 +32,7 @@ proc vfix { var } { global $var if [ catch {eval concat $$var} ] { - set $var 0 + set $var 4 } } @@ -42,6 +42,7 @@ set CONSTANT_Y 1 set CONSTANT_M 2 set CONSTANT_N 0 +set CONSTANT_E 4 # # Create a "reference" object to steal colors from. @@ -67,9 +68,11 @@ proc menu_option { w menu_num text } { global menus_per_column - if { $menu_num <= $menus_per_column } then { + global processed_top_level + set processed_top_level [expr $processed_top_level + 1] + if { $processed_top_level <= $menus_per_column } then { set myframe left - } elseif { $menu_num <= [expr 2 * $menus_per_column] } then { + } elseif { $processed_top_level <= [expr 2 * $menus_per_column] } then { set myframe middle } else { set myframe right @@ -211,7 +214,7 @@ } close $file1 update_choices - update_mainmenu .rdupd + update_mainmenu } proc write_comment { file1 file2 text } { puts $file1 "" @@ -223,17 +226,49 @@ puts $file2 " */" } -proc write_tristate { file1 file2 varname variable dep } { - if { $variable == 0 } \ - then { puts $file1 "# $varname is not set"; \ - puts $file2 "#undef $varname"} \ - elseif { $variable == 2 || ($dep == 2 && $variable == 1) } \ +proc effective_dep { deplist } { + global CONFIG_MODULES + set depend 1 + foreach i $deplist { + if {$i == 0} then {set depend 0} + if {$i == 2 && $depend == 1} then {set depend 2} + } + if {$depend == 2 && $CONFIG_MODULES == 0} then {set depend 0} + return $depend +} + +proc sync_tristate { var dep } { + global CONFIG_MODULES + if {$dep == 0 && ($var == 1 || $var == 2)} then { + set var 0 + } elseif {$dep == 2 && $var == 1} then { + set var 2 + } elseif {$var == 2 && $CONFIG_MODULES == 0} then { + if {$dep == 1} then {set var 1} else {set var 0} + } + return $var +} + +proc sync_bool { var dep } { + set var [sync_tristate $var $dep] + if {$dep == 2} then { + set var 0 + } + return $var +} + +proc write_tristate { file1 file2 varname variable deplist } { + set variable [sync_tristate $variable [effective_dep $deplist]] + if { $variable == 1 }\ + then { puts $file1 "$varname=y"; \ + puts $file2 "#define $varname 1" } \ + elseif { $variable == 2 } \ then { puts $file1 "$varname=m"; \ puts $file2 "#undef $varname"; \ puts $file2 "#define ${varname}_MODULE 1" } \ - elseif { $variable == 1 && $dep != 2 } \ - then { puts $file1 "$varname=y"; \ - puts $file2 "#define $varname 1" } \ + elseif { $variable == 0 } \ + then { puts $file1 "# $varname is not set"; \ + puts $file2 "#undef $varname"} \ else { \ puts stdout "ERROR - Attempting to write value for unconfigured variable ($varname)." \ } @@ -245,7 +280,7 @@ puts $file2 "#undef $varname"} \ else { puts $file1 "$varname=$variable"; \ - puts $file2 "#define $varname $variable"; \ + puts $file2 "#define $varname ($variable)"; \ } } @@ -255,7 +290,8 @@ puts $file2 "#undef $varname"} \ else { puts $file1 "$varname=$variable"; \ - puts $file2 "#define $varname 0x$variable"; \ + puts -nonewline $file2 "#define $varname 0x"; \ + puts $file2 [exec echo $variable | sed s/^0\[xX\]//]; \ } } @@ -282,11 +318,11 @@ proc toggle_switch2 {w mnum line text variable} { frame $w.x$line -relief sunken radiobutton $w.x$line.y -text "y" -variable $variable -value 1 \ - -relief groove -width 2 -command "update_menu$mnum .menu$mnum" + -relief groove -width 2 -command "update_active" radiobutton $w.x$line.m -text "-" -variable $variable -value 2 \ - -relief groove -width 2 -command "update_menu$mnum .menu$mnum" + -relief groove -width 2 -command "update_active" radiobutton $w.x$line.n -text "n" -variable $variable -value 0 \ - -relief groove -width 2 -command "update_menu$mnum .menu$mnum" + -relief groove -width 2 -command "update_active" option_name $w $mnum $line $text $variable @@ -296,11 +332,11 @@ proc toggle_switch3 {w mnum line text variable} { frame $w.x$line -relief sunken radiobutton $w.x$line.y -text "y" -variable $variable -value 1 \ - -relief groove -width 2 -command "update_menu$mnum .menu$mnum" + -relief groove -width 2 -command "update_active" radiobutton $w.x$line.m -text "m" -variable $variable -value 2 \ - -relief groove -width 2 -command "update_menu$mnum .menu$mnum" + -relief groove -width 2 -command "update_active" radiobutton $w.x$line.n -text "n" -variable $variable -value 0 \ - -relief groove -width 2 -command "update_menu$mnum .menu$mnum" + -relief groove -width 2 -command "update_active" option_name $w $mnum $line $text $variable @@ -322,10 +358,14 @@ pack $w.x$line -anchor w -fill both -expand on } -proc dep_tristate {w mnum line text variable depend } { +proc dep_tristate {w mnum line text variable } { tristate $w $mnum $line $text $variable } +proc dep_bool {w mnum line text variable } { + bool $w $mnum $line $text $variable +} + proc int { w mnum line text variable } { frame $w.x$line entry $w.x$line.x -width 18 -relief sunken -borderwidth 2 \ @@ -358,6 +398,18 @@ pack $w.x$line -anchor w -fill both -expand on } +proc submenu { w mnum line text subnum } { + frame $w.x$line + button $w.x$line.l -text "" -width 15 -relief groove + $w.x$line.l configure -activefore [cget $w.x$line.l -fg] \ + -activeback [cget $w.x$line.l -bg] -state disabled + button $w.x$line.m -text "$text" -relief raised -anchor w \ + -command "catch {destroy .menu$subnum}; menu$subnum .menu$subnum \"$text\"" + pack $w.x$line.l -side left -fill both + pack $w.x$line.m -anchor w -side right -fill both -expand on + pack $w.x$line -anchor w -fill both -expand on +} + proc comment {w line text } { #nothing done for comments now. } @@ -417,7 +469,7 @@ # frame $w.f2 button $w.f2.ok -text "OK" \ - -width 10 -command "destroy $w; focus $oldFocus" + -width 10 -command "destroy $w; catch {focus $oldFocus}" pack $w.f2.ok -side bottom -pady 6 -anchor n pack $w.f2 -side bottom -padx 10 -anchor s @@ -458,6 +510,55 @@ } +proc unregister_active {num} { + global active_menus + set index [lsearch -exact $active_menus $num] + if {$index != -1} then {set active_menus [lreplace $active_menus $index $index]} +} + +proc update_active {} { + global active_menus total_menus + set max 0 + if {[llength $active_menus] > 0} then { + set max [lindex $active_menus end] + update_define [toplevel_menu [lindex $active_menus 0]] $max 0 + } + foreach i $active_menus { + if {[winfo exists .menu$i] == 0} then { + unregister_active $i + } else { + update_menu$i + } + } + update_define [expr $max + 1] $total_menus 1 + update_mainmenu +} + +proc configure_entry {w option items} { + foreach i $items { + $w.$i configure -state $option + } +} + +proc validate_int {name val default} { + if {([exec echo $val | sed s/^-//g | tr -d \[:digit:\] ] != "")} then { + global $name; set $name $default + } +} + +proc validate_hex {name val default} { + if {([exec echo $val | tr -d \[:xdigit:\] ] != "")} then { + global $name; set $name $default + } +} + +proc update_define {first last allow_update} { + for {set i $first} {$i <= $last} {incr i} { + update_define_menu$i + if {$allow_update == 1} then update + } +} + # # Next set up the particulars for the top level menu, and define a few # buttons which we will stick down at the bottom. @@ -468,3 +569,5 @@ frame .f0.middle frame .f0.right +set active_menus [list] +set processed_top_level 0 diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/scripts/lxdialog/Makefile linux.ac/scripts/lxdialog/Makefile --- linux.vanilla/scripts/lxdialog/Makefile Mon Jul 20 18:05:16 1998 +++ linux.ac/scripts/lxdialog/Makefile Wed Sep 15 23:56:54 1999 @@ -30,8 +30,11 @@ lxdialog: $(OBJS) ncurses: - @x=`find /lib/ /usr/lib/ /usr/local/lib/ -maxdepth 1 -name 'libncurses.*'` ;\ - if [ ! "$$x" ]; then \ + @echo "main() {}" > lxtemp.c + @if $(CC) -lncurses lxtemp.c ; then \ + rm -f lxtemp.c a.out; \ + else \ + rm -f lxtemp.c; \ echo -e "\007" ;\ echo ">> Unable to find the Ncurses libraries." ;\ echo ">>" ;\ diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/scripts/tail.tk linux.ac/scripts/tail.tk --- linux.vanilla/scripts/tail.tk Fri Jan 15 22:36:20 1999 +++ linux.ac/scripts/tail.tk Tue Sep 14 20:59:14 1999 @@ -29,10 +29,12 @@ read_config $defaults } -update_mainmenu .f0 +update_define 1 $total_menus 0 +update_mainmenu button .f0.right.save -anchor w -text "Save and Exit" \ - -command { writeconfig .config include/linux/autoconf.h; wrapup .wrap } + -command { catch {exec cp -f .config .config.old}; \ + writeconfig .config include/linux/autoconf.h; wrapup .wrap } button .f0.right.quit -anchor w -text "Quit Without Saving" \ -command { maybe_exit .maybe } diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/scripts/tkcond.c linux.ac/scripts/tkcond.c --- linux.vanilla/scripts/tkcond.c Wed Jan 20 18:05:49 1999 +++ linux.ac/scripts/tkcond.c Tue Sep 14 20:59:14 1999 @@ -14,6 +14,12 @@ * every architecture and comparing it character-for-character against * the output of the old tkparse. * + * 07 July 1999, Andrzej M. Krzysztofowicz + * - kvariables removed; all variables are stored in a single table now + * - some elimination of options non-valid for current architecture + * implemented. + * - negation (!) eliminated from conditions + * * TO DO: * - xconfig is at the end of its life cycle. Contact if * you are interested in working on the replacement. @@ -28,73 +34,88 @@ /* - * Transform op_variable to op_kvariable. - * - * This works, but it's gross, speed-wise. It would benefit greatly - * from a simple hash table that maps names to cfg. - * - * Note well: this is actually better than the loop structure xconfig - * has been staggering along with for three years, which performs - * this whole procedure inside *another* loop on active conditionals. + * Mark variables which are defined anywhere. */ -void transform_to_kvariable( struct kconfig * scfg ) +static void mark_variables( struct kconfig * scfg ) { struct kconfig * cfg; + int i; + for ( i = 1; i <= max_varnum; i++ ) + vartable[i].defined = 0; for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) { - struct condition * cond; - - for ( cond = cfg->cond; cond != NULL; cond = cond->next ) + if ( cfg->token == token_bool + || cfg->token == token_choice_item + || cfg->token == token_define_bool + || cfg->token == token_define_hex + || cfg->token == token_define_int + || cfg->token == token_define_string + || cfg->token == token_define_tristate + || cfg->token == token_dep_bool + || cfg->token == token_dep_tristate + || cfg->token == token_hex + || cfg->token == token_int + || cfg->token == token_string + || cfg->token == token_tristate + || cfg->token == token_unset ) { - if ( cond->op == op_variable ) + if ( cfg->nameindex > 0 ) /* paranoid */ { - /* Here's where it gets DISGUSTING. */ - struct kconfig * cfg1; + vartable[cfg->nameindex].defined = 1; + } + } + } +} + + + +static void free_cond( struct condition *cond ) +{ + struct condition *tmp, *tmp1; + for ( tmp = cond; tmp; tmp = tmp1 ) + { + tmp1 = tmp->next; + free( (void*)tmp ); + } +} + - for ( cfg1 = scfg; cfg1 != NULL; cfg1 = cfg1->next ) + +/* + * Remove the bang operator from a condition to avoid priority problems. + * "!" has different priorities as "test" command argument and in + * a tk script. + */ +static struct condition * remove_bang( struct condition * condition ) +{ + struct condition * conda, * condb, * prev = NULL; + + for ( conda = condition; conda; conda = conda->next ) + { + if ( conda->op == op_bang && conda->next && + ( condb = conda->next->next ) ) + { + if ( condb->op == op_eq || condb->op == op_neq ) + { + condb->op = (condb->op == op_eq) ? op_neq : op_eq; + conda->op = op_nuked; + if ( prev ) { - if ( cfg1->token == token_bool - || cfg1->token == token_choice_item - || cfg1->token == token_dep_tristate - || cfg1->token == token_hex - || cfg1->token == token_int - || cfg1->token == token_string - || cfg1->token == token_tristate ) - { - if ( strcmp( cond->str, cfg1->optionname ) == 0 ) - { - cond->op = op_kvariable; - cond->str = NULL; - cond->cfg = cfg1; - break; - } - } + prev->next = conda->next; } - } - -#if 0 - /* - * Maybe someday this will be useful, but right now it - * gives a lot of false positives on files like - * drivers/video/Config.in that are meant for more - * than one architecture. Turn it on if you want to play - * with it though; it does work. -- mec - */ - if ( cond->op == op_variable ) - { - if ( strcmp( cond->str, "ARCH" ) != 0 - && strcmp( cond->str, "CONSTANT_Y" ) != 0 - && strcmp( cond->str, "CONSTANT_M" ) != 0 - && strcmp( cond->str, "CONSTANT_N" ) != 0 ) + else { - fprintf( stderr, "warning: $%s used but not defined\n", - cond->str ); + condition = conda->next; } + conda->next = NULL; + free_cond( conda ); + conda = condb; } -#endif } + prev = conda; } + return condition; } @@ -103,27 +124,65 @@ * Make a new condition chain by joining the current condition stack with * the "&&" operator for glue. */ -struct condition * join_condition_stack( struct condition * conditions [], +static struct condition * join_condition_stack( struct condition * conditions [], int depth ) { struct condition * cond_list; struct condition * cond_last; - int i; + int i, is_first = 1; cond_list = cond_last = NULL; + + for ( i = 0; i < depth; i++ ) + { + if ( conditions[i]->op == op_false ) + { + struct condition * cnew; + + /* It is always false condition */ + cnew = malloc( sizeof(*cnew) ); + memset( cnew, 0, sizeof(*cnew) ); + cnew->op = op_false; + cond_list = cond_last = cnew; + goto join_done; + } + } for ( i = 0; i < depth; i++ ) { struct condition * cond; struct condition * cnew; + int add_paren; + + /* omit always true conditions */ + if ( conditions[i]->op == op_true ) + continue; + + /* if i have another condition, add an '&&' operator */ + if ( !is_first ) + { + cnew = malloc( sizeof(*cnew) ); + memset( cnew, 0, sizeof(*cnew) ); + cnew->op = op_and; + cond_last->next = cnew; + cond_last = cnew; + } - /* add a '(' */ - cnew = malloc( sizeof(*cnew) ); - memset( cnew, 0, sizeof(*cnew) ); - cnew->op = op_lparen; - if ( cond_last == NULL ) - { cond_list = cond_last = cnew; } + if ( conditions[i]->op != op_lparen ) + { + /* add a '(' */ + add_paren = 1; + cnew = malloc( sizeof(*cnew) ); + memset( cnew, 0, sizeof(*cnew) ); + cnew->op = op_lparen; + if ( cond_last == NULL ) + { cond_list = cond_last = cnew; } + else + { cond_last->next = cnew; cond_last = cnew; } + } else - { cond_last->next = cnew; cond_last = cnew; } + { + add_paren = 0; + } /* duplicate the chain */ for ( cond = conditions [i]; cond != NULL; cond = cond->next ) @@ -132,27 +191,23 @@ cnew->next = NULL; cnew->op = cond->op; cnew->str = cond->str ? strdup( cond->str ) : NULL; - cnew->cfg = cond->cfg; - cond_last->next = cnew; - cond_last = cnew; + cnew->nameindex = cond->nameindex; + if ( cond_last == NULL ) + { cond_list = cond_last = cnew; } + else + { cond_last->next = cnew; cond_last = cnew; } } - /* add a ')' */ - cnew = malloc( sizeof(*cnew) ); - memset( cnew, 0, sizeof(*cnew) ); - cnew->op = op_rparen; - cond_last->next = cnew; - cond_last = cnew; - - /* if i have another condition, add an '&&' operator */ - if ( i < depth - 1 ) + if ( add_paren ) { + /* add a ')' */ cnew = malloc( sizeof(*cnew) ); memset( cnew, 0, sizeof(*cnew) ); - cnew->op = op_and; + cnew->op = op_rparen; cond_last->next = cnew; cond_last = cnew; } + is_first = 0; } /* @@ -171,7 +226,7 @@ cond1e = cond1d->next; if ( cond1e == NULL ) break; cond1f = cond1e->next; if ( cond1f == NULL ) break; - if ( cond1b->op == op_kvariable + if ( cond1b->op == op_variable && ( cond1c->op == op_eq || cond1c->op == op_neq ) && cond1d->op == op_constant && cond1e->op == op_rparen ) @@ -189,8 +244,8 @@ cond2f = cond2e->next; /* look for match */ - if ( cond2b->op == op_kvariable - && cond2b->cfg == cond1b->cfg + if ( cond2b->op == op_variable + && cond2b->nameindex == cond1b->nameindex && cond2c->op == cond1c->op && cond2d->op == op_constant && strcmp( cond2d->str, cond1d->str ) == 0 @@ -219,64 +274,159 @@ } } +join_done: return cond_list; } +static char * current_arch = NULL; + /* - * This is the main transformation function. + * Eliminating conditions with ARCH = . */ -void fix_conditionals( struct kconfig * scfg ) +static struct condition *eliminate_other_arch( struct condition *list ) { - struct kconfig * cfg; - - /* - * Transform op_variable to op_kvariable. - */ - transform_to_kvariable( scfg ); - - /* - * Transform conditions that use variables from "choice" statements. - * Choice values appear to the user as a collection of booleans, and the - * script can test the individual booleans. But internally, all I have is - * the N-way value of an unnamed temporary for the whole statement. So I - * have to tranform '"$CONFIG_M386" != "y"' - * into '"$tmpvar_N" != "CONFIG_M386"'. - */ - for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + struct condition *cond1a = list, *cond1b = NULL, *cond1c = NULL, *cond1d = NULL; + if ( current_arch == NULL ) + current_arch = getenv( "ARCH" ); + if ( current_arch == NULL ) { - struct condition * cond; - - for ( cond = cfg->cond; cond != NULL; cond = cond->next ) + fprintf( stderr, "error: ARCH undefined\n" ); + exit( 1 ); + } + if ( cond1a->op == op_variable + && ! strcmp( vartable[cond1a->nameindex].name, "ARCH" ) ) + { + cond1b = cond1a->next; if ( cond1b == NULL ) goto done; + cond1c = cond1b->next; if ( cond1c == NULL ) goto done; + cond1d = cond1c->next; + if ( cond1c->op == op_constant && cond1d == NULL ) { - if ( cond->op == op_kvariable && cond->cfg->token == token_choice_item ) + if ( (cond1b->op == op_eq && strcmp( cond1c->str, current_arch )) + || (cond1b->op == op_neq && ! strcmp( cond1c->str, current_arch )) ) { - /* - * Look two more tokens down for the comparison token. - * It has to be "y" for this trick to work. - * - * If you get this error, don't even think about relaxing the - * strcmp test. You will produce incorrect TK code. Instead, - * look for the place in your Config.in script where you are - * comparing a 'choice' variable to a value other than 'y', - * and rewrite the comparison to be '= "y"' or '!= "y"'. - */ - struct condition * cond2 = cond->next->next; - const char * label; - - if ( strcmp( cond2->str, "y" ) != 0 ) + /* This is for another architecture */ + cond1a->op = op_false; + cond1a->next = NULL; + free_cond( cond1b ); + return cond1a; + } + else if ( (cond1b->op == op_neq && strcmp( cond1c->str, current_arch )) + || (cond1b->op == op_eq && ! strcmp( cond1c->str, current_arch )) ) + { + /* This is for current architecture */ + cond1a->op = op_true; + cond1a->next = NULL; + free_cond( cond1b ); + return cond1a; + } + } + else if ( cond1c->op == op_constant && cond1d->op == op_or ) + { + if ( (cond1b->op == op_eq && strcmp( cond1c->str, current_arch )) + || (cond1b->op == op_neq && ! strcmp( cond1c->str, current_arch )) ) + { + /* This is for another architecture */ + cond1b = cond1d->next; + cond1d->next = NULL; + free_cond( cond1a ); + return eliminate_other_arch( cond1b ); + } + else if ( (cond1b->op == op_neq && strcmp( cond1c->str, current_arch )) + || (cond1b->op == op_eq && ! strcmp( cond1c->str, current_arch )) ) + { + /* This is for current architecture */ + cond1a->op = op_true; + cond1a->next = NULL; + free_cond( cond1b ); + return cond1a; + } + } + else if ( cond1c->op == op_constant && cond1d->op == op_and ) + { + if ( (cond1b->op == op_eq && strcmp( cond1c->str, current_arch )) + || (cond1b->op == op_neq && ! strcmp( cond1c->str, current_arch )) ) + { + /* This is for another architecture */ + int l_par = 0; + + for ( cond1c = cond1d->next; cond1c; cond1c = cond1c->next ) { - fprintf( stderr, "tkparse choked in fix_choice_cond\n" ); - exit( 1 ); + if ( cond1c->op == op_lparen ) + l_par++; + else if ( cond1c->op == op_rparen ) + l_par--; + else if ( cond1c->op == op_or && l_par == 0 ) + /* Expression too complex - don't touch */ + return cond1a; + else if ( l_par < 0 ) + { + fprintf( stderr, "incorrect condition: programming error ?\n" ); + exit( 1 ); + } } + cond1a->op = op_false; + cond1a->next = NULL; + free_cond( cond1b ); + return cond1a; + } + else if ( (cond1b->op == op_neq && strcmp( cond1c->str, current_arch )) + || (cond1b->op == op_eq && ! strcmp( cond1c->str, current_arch )) ) + { + /* This is for current architecture */ + cond1b = cond1d->next; + cond1d->next = NULL; + free_cond( cond1a ); + return eliminate_other_arch( cond1b ); + } + } + } + if ( cond1a->op == op_variable && ! vartable[cond1a->nameindex].defined ) + { + cond1b = cond1a->next; if ( cond1b == NULL ) goto done; + cond1c = cond1b->next; if ( cond1c == NULL ) goto done; + cond1d = cond1c->next; - label = cond->cfg->label; - cond->cfg = cond->cfg->cfg_parent; - cond2->str = strdup( label ); + if ( cond1c->op == op_constant + && ( cond1d == NULL || cond1d->op == op_and ) ) /*???*/ + { + if ( cond1b->op == op_eq && strcmp( cond1c->str, "" ) ) + { + cond1a->op = op_false; + cond1a->next = NULL; + free_cond( cond1b ); + return cond1a; + } + } + else if ( cond1c->op == op_constant && cond1d->op == op_or ) + { + if ( cond1b->op == op_eq && strcmp( cond1c->str, "" ) ) + { + cond1b = cond1d->next; + cond1d->next = NULL; + free_cond( cond1a ); + return eliminate_other_arch( cond1b ); } } } +done: + return list; +} + + + +/* + * This is the main transformation function. + */ +void fix_conditionals( struct kconfig * scfg ) +{ + struct kconfig * cfg; + + /* + * Transform op_variable to op_kvariable. + */ + mark_variables( scfg ); /* * Walk the statement list, maintaining a stack of current conditions. @@ -290,16 +440,19 @@ { struct condition * cond_stack [32]; int depth = 0; + struct kconfig * prev = NULL; for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) { + int good = 1; switch ( cfg->token ) { default: break; case token_if: - cond_stack [depth++] = cfg->cond; + cond_stack [depth++] = + remove_bang( eliminate_other_arch( cfg->cond ) ); cfg->cond = NULL; break; @@ -325,6 +478,8 @@ case op_or: cond->op = op_and1; break; case op_neq: cond->op = op_eq; break; case op_eq: cond->op = op_neq; break; + case op_true: cond->op = op_false;break; + case op_false:cond->op = op_true; break; } } } @@ -336,25 +491,109 @@ case token_bool: case token_choice_item: + case token_choice_header: case token_comment: case token_define_bool: + case token_define_hex: + case token_define_int: + case token_define_string: + case token_define_tristate: case token_hex: case token_int: case token_mainmenu_option: case token_string: case token_tristate: + case token_unset: cfg->cond = join_condition_stack( cond_stack, depth ); + if ( cfg->cond && cfg->cond->op == op_false ) + { + good = 0; + if ( prev ) + prev->next = cfg->next; + else + scfg = cfg->next; + } break; + case token_dep_bool: case token_dep_tristate: /* * Same as the other simple statements, plus an additional * condition for the dependency. */ - cond_stack [depth] = cfg->cond; - cfg->cond = join_condition_stack( cond_stack, depth+1 ); + if ( cfg->cond ) + { + cond_stack [depth] = eliminate_other_arch( cfg->cond ); + cfg->cond = join_condition_stack( cond_stack, depth+1 ); + } + else + { + cfg->cond = join_condition_stack( cond_stack, depth ); + } + if ( cfg->cond && cfg->cond->op == op_false ) + { + good = 0; + if ( prev ) + prev->next = cfg->next; + else + scfg = cfg->next; + } break; } + if ( good ) + prev = cfg; } } } + + + +#if 0 +void dump_condition( struct condition *list ) +{ + struct condition *tmp; + for ( tmp = list; tmp; tmp = tmp->next ) + { + switch (tmp->op) + { + default: + break; + case op_variable: + printf( " %s", vartable[tmp->nameindex].name ); + break; + case op_constant: + printf( " %s", tmp->str ); + break; + case op_eq: + printf( " =" ); + break; + case op_bang: + printf( " !" ); + break; + case op_neq: + printf( " !=" ); + break; + case op_and: + case op_and1: + printf( " -a" ); + break; + case op_or: + printf( " -o" ); + break; + case op_true: + printf( " TRUE" ); + break; + case op_false: + printf( " FALSE" ); + break; + case op_lparen: + printf( " (" ); + break; + case op_rparen: + printf( " )" ); + break; + } + } + printf( "\n" ); +} +#endif diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/scripts/tkgen.c linux.ac/scripts/tkgen.c --- linux.vanilla/scripts/tkgen.c Sun May 2 17:51:16 1999 +++ linux.ac/scripts/tkgen.c Tue Sep 14 20:59:14 1999 @@ -92,33 +92,58 @@ * * 23 January 1999, Michael Elizabeth Chastain * - Remove bug-compatible code. + * + * 07 July 1999, Andrzej M. Krzysztofowicz + * Some bugfixes, including + * - disabling "m" options when CONFIG_MODULES is set to "n" as well as "y" + * option in dep_tristate when dependency is set to "m", + * - deactivating choices which should not be available, + * - basic validation for int and hex introduced if the entered one is not + * valid, + * - updates of all opened menus instead of the active only. I was afraid + * that it would slow down updates, but I don't even see any speed difference + * on my machine. If it slows you can still work with only a single menu + * opened, + * - fixed error when focussing non-existent window (especially Help windows), + * Higher level submenus implemented. */ #include +#include #include +#include #include "tkparse.h" - /* * Total number of menus. */ static int tot_menu_num = 0; - +/* + * Pointers to mainmenu_option and endmenu of each menu. + */ +struct kconfig * menu_first [100]; +struct kconfig * menu_last [100]; /* * Generate portion of wish script for the beginning of a submenu. * The guts get filled in with the various options. */ -static void start_proc( char * label, int menu_num, int flag ) +static void start_proc( char * label, int menu_num, int toplevel ) { - if ( flag ) + if ( toplevel ) printf( "menu_option menu%d %d \"%s\"\n", menu_num, menu_num, label ); printf( "proc menu%d {w title} {\n", menu_num ); - printf( "\tcatch {destroy $w}\n" ); + printf( "\tset oldFocus [focus]\n" ); + if ( menu_first[menu_num]->menu_number != 0 ) + printf( "\tcatch {focus .menu%d}\n", + menu_first[menu_num]->menu_number ); + printf( "\tcatch {destroy $w; unregister_active %d}\n", menu_num ); printf( "\ttoplevel $w -class Dialog\n" ); printf( "\twm withdraw $w\n" ); + printf( "\tglobal active_menus\n" ); + printf( "\tset active_menus [lsort -integer [linsert $active_menus end %d]]\n", menu_num ); printf( "\tmessage $w.m -width 400 -aspect 300 -text \\\n" ); printf( "\t\t\"%s\" -relief raised\n", label ); printf( "\tpack $w.m -pady 10 -side top -padx 10\n" ); @@ -127,16 +152,41 @@ /* * Attach the "Prev", "Next" and "OK" buttons at the end of the window. */ - printf( "\tset oldFocus [focus]\n" ); printf( "\tframe $w.f\n" ); - printf( "\tbutton $w.f.back -text \"Main Menu\" \\\n" ); - printf( "\t\t-width 15 -command \"destroy $w; focus $oldFocus; update_mainmenu $w\"\n" ); + if ( toplevel ) + printf( "\tbutton $w.f.back -text \"Main Menu\" \\\n" ); + else + printf( "\tbutton $w.f.back -text \"OK\" \\\n" ); + printf( "\t\t-width 15 -command \"catch {focus $oldFocus}; destroy $w; unregister_active %d\"\n", + menu_num ); printf( "\tbutton $w.f.next -text \"Next\" \\\n" ); - printf( "\t\t-width 15 -command \" destroy $w; focus $oldFocus; menu%d .menu%d \\\"$title\\\"\"\n", menu_num+1, menu_num+1 ); + printf( "\t\t-width 15 -command \"catch {focus $oldFocus}; " ); + /* + * We are checking which windows should be destroyed and which are + * common parrents with the next one. Remember that menu_num field + * in mainmenu_option record reports number of its *parent* menu. + */ + if ( menu_num < tot_menu_num + && menu_first[menu_num + 1]->menu_number != menu_num ) + { + int to_destr; + + printf( "destroy $w; unregister_active %d; ", menu_num ); + to_destr = menu_first[menu_num]->menu_number; + while ( to_destr > 0 && menu_first[menu_num + 1]->menu_number != to_destr ) + { + printf( "catch {destroy .menu%d}; unregister_active %d; ", + to_destr, to_destr ); + to_destr = menu_first[to_destr]->menu_number; + } + } + printf( "menu%d .menu%d \\\"$title\\\"\"\n", + menu_num+1, menu_num+1 ); if ( menu_num == tot_menu_num ) printf( "\t$w.f.next configure -state disabled\n" ); printf( "\tbutton $w.f.prev -text \"Prev\" \\\n" ); - printf( "\t\t-width 15 -command \" destroy $w; focus $oldFocus; menu%d .menu%d \\\"$title\\\"\"\n", menu_num-1, menu_num-1 ); + printf( "\t\t-width 15 -command \"catch {focus $oldFocus}; destroy $w; unregister_active %d; menu%d .menu%d \\\"$title\\\"\"\n", + menu_num, menu_num-1, menu_num-1 ); if ( menu_num == 1 ) printf( "\t$w.f.prev configure -state disabled\n" ); printf( "\tpack $w.f.back $w.f.next $w.f.prev -side left -expand on\n" ); @@ -177,12 +227,11 @@ * a global declaration so we know whether we need to insert one for a * given function or not. */ -void clear_globalflags( struct kconfig * scfg ) +static void clear_globalflags(void) { - struct kconfig * cfg; - - for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) - cfg->global_written = 0; + int i; + for ( i = 1; i <= max_varnum; i++ ) + vartable[i].global_written = 0; } @@ -194,7 +243,7 @@ */ void global( const char *var ) { - printf( "\tglobal %s; vfix %s\n", var, var ); + printf( "\tglobal %s\n", var ); } @@ -207,6 +256,22 @@ int menu_num, int line_num ) { struct condition * cond; + struct dependency * tmp; + struct kconfig * cfg1; + +if ( cfg->token == token_mainmenu_option ) + if ( line_num >= -1 ) + { + if ( cfg->token == token_define_bool || cfg->token == token_define_hex + || cfg->token == token_define_int || cfg->token == token_define_string + || cfg->token == token_define_tristate || cfg->token == token_unset ) + return; + } + else + { + if ( cfg->token == token_string || cfg->token == token_mainmenu_option ) + return; + } /* * First write any global declarations we need for this conditional. @@ -219,14 +284,10 @@ break; case op_variable: - global( cond->str ); - break; - - case op_kvariable: - if ( ! cond->cfg->global_written ) + if ( ! vartable[cond->nameindex].global_written ) { - cond->cfg->global_written = 1; - global( cond->cfg->optionname ); + vartable[cond->nameindex].global_written = 1; + global( vartable[cond->nameindex].name ); } break; } @@ -235,10 +296,10 @@ /* * Now write this option. */ - if ( ! cfg->global_written && cfg->optionname != NULL ) + if ( cfg->nameindex > 0 && ! vartable[cfg->nameindex].global_written ) { - cfg->global_written = 1; - global( cfg->optionname ); + vartable[cfg->nameindex].global_written = 1; + global( vartable[cfg->nameindex].name ); } /* @@ -262,156 +323,310 @@ case op_rparen: printf( ")" ); break; case op_variable: - printf( "$%s", cond->str ); - break; - - case op_kvariable: - printf( "$%s", cond->cfg->optionname ); + printf( "$%s", vartable[cond->nameindex].name ); break; case op_constant: if ( strcmp( cond->str, "y" ) == 0 ) printf( "1" ); else if ( strcmp( cond->str, "n" ) == 0 ) printf( "0" ); else if ( strcmp( cond->str, "m" ) == 0 ) printf( "2" ); + else if ( strcmp( cond->str, "" ) == 0 ) printf( "4" ); else printf( "\"%s\"", cond->str ); break; } } - printf( "} then { " ); + printf( "} then {" ); /* * Generate a procedure call to write the value. * This code depends on procedures in header.tk. */ - switch ( cfg->token ) + if ( line_num >= -1 ) { - default: - printf( " }\n" ); - break; - - case token_bool: - printf( ".menu%d.config.f.x%d.y configure -state normal;", - menu_num, line_num ); - printf( ".menu%d.config.f.x%d.n configure -state normal;", - menu_num, line_num ); - printf( ".menu%d.config.f.x%d.l configure -state normal;", - menu_num, line_num ); - printf( "set %s [expr $%s&15];", - cfg->optionname, cfg->optionname ); - printf( "} else { "); - printf( ".menu%d.config.f.x%d.y configure -state disabled;", - menu_num, line_num ); - printf( ".menu%d.config.f.x%d.n configure -state disabled;", - menu_num, line_num ); - printf( ".menu%d.config.f.x%d.l configure -state disabled;", - menu_num, line_num ); - printf( "set %s [expr $%s|16];}\n", - cfg->optionname, cfg->optionname ); - break; + switch ( cfg->token ) + { + default: + printf( " }\n" ); + break; - case token_choice_header: - fprintf( stderr, "Internal error on token_choice_header\n" ); - exit( 1 ); + case token_dep_bool: + printf( "\n" ); + for ( tmp = cfg->depend; tmp; tmp = tmp->next ) + if ( ! vartable[get_varnum( tmp->name )].global_written ) + { + global( tmp->name ); + } + printf( "\tset tmpvar_dep [effective_dep [list" ); + for ( tmp = cfg->depend; tmp; tmp = tmp->next ) + printf( " $%s", tmp->name ); + printf( "]];set %s [sync_bool $%s $tmpvar_dep];", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); + printf( "if {$tmpvar_dep != 1} then {" ); + printf( "configure_entry .menu%d.config.f.x%d disabled {y};", + menu_num, line_num ); + printf( "} else {" ); + printf( "configure_entry .menu%d.config.f.x%d normal {y};", + menu_num, line_num ); + printf( "}; " ); + case token_bool: + if ( cfg->token == token_bool ) + printf( "\n\t" ); + printf( "configure_entry .menu%d.config.f.x%d normal {n l", + menu_num, line_num ); + if ( cfg->token == token_bool ) + printf( " y" ); + printf( "}" ); + printf( "} else {"); + printf( "configure_entry .menu%d.config.f.x%d disabled {y n l}}\n", + menu_num, line_num ); + break; - case token_choice_item: - fprintf( stderr, "Internal error on token_choice_item\n" ); - exit( 1 ); + case token_choice_header: + printf( "configure_entry .menu%d.config.f.x%d normal {x l}", + menu_num, line_num ); + printf( "} else {" ); + printf( "configure_entry .menu%d.config.f.x%d disabled {x l}", + menu_num, line_num ); + printf( "}\n" ); + break; - case token_define_bool: - printf( "set %s %s } \n", - cfg->optionname, cfg->value ); - break; + case token_choice_item: + fprintf( stderr, "Internal error on token_choice_item\n" ); + exit( 1 ); - case token_dep_tristate: - case token_tristate: - if ( cfg->token == token_dep_tristate ) - { - global( cfg->depend ); - printf( "if { $%s != 1 && $%s != 0 } then {", - cfg->depend, cfg->depend ); - printf( ".menu%d.config.f.x%d.y configure -state disabled;", + case token_dep_tristate: + printf( "\n" ); + for ( tmp = cfg->depend; tmp; tmp = tmp->next ) + if ( ! vartable[get_varnum( tmp->name )].global_written ) + { + global( tmp->name ); + } + printf( "\tset tmpvar_dep [effective_dep [list" ); + for ( tmp = cfg->depend; tmp; tmp = tmp->next ) + printf( " $%s", tmp->name ); + printf( "]];set %s [sync_tristate $%s $tmpvar_dep];", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); + printf( "\tif {$tmpvar_dep != 1} then {" ); + printf( "configure_entry .menu%d.config.f.x%d disabled {y}", + menu_num, line_num ); + printf( "} else {" ); + printf( "configure_entry .menu%d.config.f.x%d normal {y}", + menu_num, line_num ); + printf( "}; " ); + printf( "if {$tmpvar_dep == 0} then {" ); + printf( "configure_entry .menu%d.config.f.x%d disabled {m}", menu_num, line_num ); printf( "} else {" ); - printf( ".menu%d.config.f.x%d.y configure -state normal;", - menu_num, line_num); + printf( "configure_entry .menu%d.config.f.x%d normal {m}", + menu_num, line_num ); printf( "}; " ); - } - else - { - printf( ".menu%d.config.f.x%d.y configure -state normal;", + case token_tristate: + if ( cfg->token == token_tristate ) + { + printf( "\n\tconfigure_entry .menu%d.config.f.x%d normal {y}; ", + menu_num, line_num ); + } + printf( "if {($CONFIG_MODULES == 1)} then {" ); + printf( "configure_entry .menu%d.config.f.x%d normal {m}} else {", + menu_num, line_num ); + printf( "configure_entry .menu%d.config.f.x%d disabled {m}}; ", + menu_num, line_num ); + printf( "configure_entry .menu%d.config.f.x%d normal {n l}", + menu_num, line_num ); + + /* + * Or in a bit to the variable - this causes all of the radiobuttons + * to be deselected (i.e. not be red). + */ + printf( "} else {" ); + printf( "configure_entry .menu%d.config.f.x%d disabled {y n m l}}\n", + menu_num, line_num ); + break; + + case token_hex: + case token_int: + case token_string: + printf( ".menu%d.config.f.x%d.x configure -state normal -foreground [ cget .ref -foreground ]; ", + menu_num, line_num ); + printf( ".menu%d.config.f.x%d.l configure -state normal; ", + menu_num, line_num ); + printf( "} else {" ); + printf( ".menu%d.config.f.x%d.x configure -state disabled -foreground [ cget .ref -disabledforeground ]; ", + menu_num, line_num ); + printf( ".menu%d.config.f.x%d.l configure -state disabled}\n", menu_num, line_num ); + break; + + case token_mainmenu_option: + if ( line_num >= 0 ) + { + printf( "configure_entry .menu%d.config.f.x%d normal {m}", + menu_num, line_num ); + printf( "} else {" ); + printf( "configure_entry .menu%d.config.f.x%d disabled {m}}\n", + menu_num, line_num ); + } + else + printf( ".f0.x%d configure -state normal } else { .f0.x%d configure -state disabled }\n", + menu_num, menu_num ); + break; } + } + else + { + switch ( cfg->token ) + { + default: + printf( " }\n" ); + break; + + case token_dep_bool: + printf( "\n" ); + for ( tmp = cfg->depend; tmp; tmp = tmp->next ) + if ( ! vartable[get_varnum( tmp->name )].global_written ) + { + global( tmp->name ); + } + printf( "\tset tmpvar_dep [effective_dep [list" ); + for ( tmp = cfg->depend; tmp; tmp = tmp->next ) + printf( " $%s", tmp->name ); + printf( "]];set %s [sync_bool $%s $tmpvar_dep];", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); + case token_bool: + if ( cfg->token == token_bool ) + printf( "\n\t" ); + printf( "set %s [expr $%s&15]", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); + printf( "} else {"); + printf( "set %s [expr $%s|16]}\n", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); + break; + + case token_choice_header: + printf( "} else {" ); + for ( cfg1 = cfg->next; + cfg1 != NULL && cfg1->token == token_choice_item; + cfg1 = cfg1->next ) + printf( "set %s 4;", vartable[cfg1->nameindex].name ); + printf( "}\n" ); + break; + + case token_choice_item: + fprintf( stderr, "Internal error on token_choice_item\n" ); + exit( 1 ); + + case token_define_bool: + case token_define_tristate: + if ( ! vartable[get_varnum( cfg->value )].global_written ) + { + global( cfg->value ); + } + printf( "set %s $%s }\n", + vartable[cfg->nameindex].name, cfg->value ); + break; + + case token_define_hex: + case token_define_int: + printf( "set %s %s }\n", + vartable[cfg->nameindex].name, cfg->value ); + break; - printf( ".menu%d.config.f.x%d.n configure -state normal;", - menu_num, line_num ); - printf( "global CONFIG_MODULES; if {($CONFIG_MODULES == 1)} then { .menu%d.config.f.x%d.m configure -state normal };", - menu_num, line_num ); - printf( ".menu%d.config.f.x%d.l configure -state normal;", - menu_num, line_num ); + case token_define_string: + printf( "set %s \"%s\" }\n", + vartable[cfg->nameindex].name, cfg->value ); + break; + case token_dep_tristate: + printf( "\n" ); + for ( tmp = cfg->depend; tmp; tmp = tmp->next ) + if ( ! vartable[get_varnum( tmp->name )].global_written ) + { + global( tmp->name ); + } + printf( "\tset tmpvar_dep [effective_dep [list" ); + for ( tmp = cfg->depend; tmp; tmp = tmp->next ) + printf( " $%s", tmp->name ); + printf( "]]; set %s [sync_tristate $%s $tmpvar_dep]; ", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); + case token_tristate: + if ( cfg->token == token_tristate ) + printf( "if {($CONFIG_MODULES == 0) && ($%s == 2)} then {set %s 1}; ", + vartable[cfg->nameindex].name, + vartable[cfg->nameindex].name ); /* * Or in a bit to the variable - this causes all of the radiobuttons * to be deselected (i.e. not be red). */ - printf( "set %s [expr $%s&15];", - cfg->optionname, cfg->optionname ); - printf( "} else { " ); - printf( ".menu%d.config.f.x%d.y configure -state disabled;", - menu_num, line_num ); - printf( ".menu%d.config.f.x%d.n configure -state disabled;", - menu_num, line_num ); - printf( ".menu%d.config.f.x%d.m configure -state disabled;", - menu_num, line_num ); - printf( ".menu%d.config.f.x%d.l configure -state disabled;", - menu_num, line_num ); + printf( "set %s [expr $%s&15]", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); + printf( "} else {" ); /* * Clear the disable bit to enable the correct radiobutton. */ - printf( "set %s [expr $%s|16];}\n", - cfg->optionname, cfg->optionname ); - break; + printf( "set %s [expr $%s|16]}\n", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); + break; - case token_hex: - case token_int: - case token_string: - printf( ".menu%d.config.f.x%d.x configure -state normal -foreground [ cget .ref -foreground ]; ", - menu_num, line_num); - printf( ".menu%d.config.f.x%d.l configure -state normal; ", - menu_num, line_num); - printf( "} else { " ); - printf( ".menu%d.config.f.x%d.x configure -state disabled -foreground [ cget .ref -disabledforeground ];", - menu_num, line_num ); - printf( ".menu%d.config.f.x%d.l configure -state disabled;}\n", - menu_num, line_num ); - break; + case token_hex: + case token_int: + if ( cfg->value && *cfg->value == '$' ) + { + int index = get_varnum( cfg->value+1 ); + printf( "\n" ); + if ( ! vartable[index].global_written ) + { + global( vartable[index].name ); + } + printf( "\t" ); + } + if ( cfg->token == token_hex ) + printf( "validate_hex " ); + else if ( cfg->token == token_int ) + printf( "validate_int " ); + printf( "%s \"$%s\" %s}\n", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name, + cfg->value ); + break; - case token_mainmenu_option: - printf( ".f0.x%d configure -state normal } else { .f0.x%d configure -state disabled }\n", - menu_num, menu_num ); - break; + case token_unset: + printf( "set %s 4}\n", vartable[cfg->nameindex].name ); + break; + } } } - /* * Generate a line that writes a variable to the output file. */ void generate_writeconfig( struct kconfig * cfg ) { struct condition * cond; - + struct dependency * tmp; + /* * Generate global declaration for this symbol. */ if ( cfg->token != token_comment ) { - if ( ! cfg->global_written ) + if ( cfg->nameindex > 0 && ! vartable[cfg->nameindex].global_written ) + { + vartable[cfg->nameindex].global_written = 1; + global( vartable[cfg->nameindex].name ); + } + if ( cfg->token == token_define_tristate || cfg->token == token_define_bool ) + { + if ( ! vartable[get_varnum( cfg->value )].global_written ) + { + vartable[get_varnum( cfg->value )].global_written = 1; + global( cfg->value ); + } + } + else if ( cfg->nameindex <= 0 && cfg->token == token_choice_header ) { - cfg->global_written = 1; - printf( "\tglobal %s\n", cfg->optionname ); + printf( "\tglobal tmpvar_%d\n", -(cfg->nameindex) ); } } @@ -426,14 +641,10 @@ break; case op_variable: - global( cond->str ); - break; - - case op_kvariable: - if ( ! cond->cfg->global_written ) + if ( ! vartable[cond->nameindex].global_written ) { - cond->cfg->global_written = 1; - global( cond->cfg->optionname ); + vartable[cond->nameindex].global_written = 1; + global( vartable[cond->nameindex].name ); } break; } @@ -442,7 +653,6 @@ /* * Generate indentation. */ - if ( cfg->token != token_choice_header ) printf( "\t" ); /* @@ -466,17 +676,14 @@ case op_rparen: printf( ")" ); break; case op_variable: - printf( "$%s", cond->str ); - break; - - case op_kvariable: - printf( "$%s", cond->cfg->optionname ); + printf( "$%s", vartable[cond->nameindex].name ); break; case op_constant: if ( strcmp( cond->str, "n" ) == 0 ) printf( "0" ); else if ( strcmp( cond->str, "y" ) == 0 ) printf( "1" ); else if ( strcmp( cond->str, "m" ) == 0 ) printf( "2" ); + else if ( strcmp( cond->str, "" ) == 0 ) printf( "4" ); else printf( "\"%s\"", cond->str ); break; @@ -499,10 +706,8 @@ case token_bool: case token_tristate: - if ( cfg->cond ) - printf( " " ); - printf( "write_tristate $cfg $autocfg %s $%s $notmod", - cfg->optionname, cfg->optionname ); + printf( "write_tristate $cfg $autocfg %s $%s [list $notmod]", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); if ( cfg->cond != NULL ) printf( " }" ); printf( "\n" ); @@ -520,12 +725,15 @@ cfg1 != NULL && cfg1->token == token_choice_item; cfg1 = cfg1->next ) { - printf("\tif { $%s == \"%s\" } then { write_tristate $cfg $autocfg %s 1 $notmod } else { write_tristate $cfg $autocfg %s 0 $notmod }\n", - cfg->optionname, cfg1->label, - cfg1->optionname, - cfg1->optionname ); + printf("\n\tif { $tmpvar_%d == \"%s\" } then { write_tristate $cfg $autocfg %s 1 [list $notmod] } else { write_tristate $cfg $autocfg %s 0 [list $notmod] }", + -(cfg->nameindex), cfg1->label, + vartable[cfg1->nameindex].name, + vartable[cfg1->nameindex].name ); } } + if ( cfg->cond != NULL ) + printf( "}" ); + printf( "\n" ); break; case token_choice_item: @@ -541,53 +749,74 @@ break; case token_define_bool: + case token_define_tristate: if ( cfg->cond == NULL ) { - printf( "write_tristate $cfg $autocfg %s $%s $notmod\n", - cfg->optionname, cfg->optionname ); + printf( "write_tristate $cfg $autocfg %s $%s [list $notmod]\n", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); } else { - printf( "write_tristate $cfg $autocfg %s %s $notmod }\n", - cfg->optionname, cfg->value ); + printf( "write_tristate $cfg $autocfg %s $%s [list $notmod] }\n", + vartable[cfg->nameindex].name, cfg->value ); } break; + case token_dep_bool: case token_dep_tristate: - if ( cfg->cond ) - printf( " " ); - printf( "write_tristate $cfg $autocfg %s $%s $%s", - cfg->optionname, cfg->optionname, cfg->depend ); + printf( "write_tristate $cfg $autocfg %s $%s [list", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); + for ( tmp = cfg->depend; tmp; tmp = tmp->next ) + printf( " $%s", tmp->name ); + printf( "]" ); if ( cfg->cond != NULL ) printf( " }" ); - printf( " \n" ); + printf( "\n" ); break; - case token_hex: + case token_define_hex: + printf( "write_hex $cfg $autocfg %s %s $notmod", + vartable[cfg->nameindex].name, cfg->value ); + if ( cfg->cond != NULL ) + printf( " }" ); + printf( "\n" ); + break; + + case token_define_int: + printf( "write_int $cfg $autocfg %s %s $notmod", + vartable[cfg->nameindex].name, cfg->value ); + if ( cfg->cond != NULL ) + printf( " }" ); + printf( "\n" ); + break; + + case token_define_string: + printf( "write_string $cfg $autocfg %s \"%s\" $notmod", + vartable[cfg->nameindex].name, cfg->value ); if ( cfg->cond != NULL ) - printf( " " ); + printf( " }" ); + printf( "\n" ); + break; + + case token_hex: printf( "write_hex $cfg $autocfg %s $%s $notmod", - cfg->optionname, cfg->optionname ); + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); if ( cfg->cond != NULL ) printf( " }" ); printf( "\n" ); break; case token_int: - if ( cfg->cond != NULL ) - printf( " " ); printf( "write_int $cfg $autocfg %s $%s $notmod", - cfg->optionname, cfg->optionname ); + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); if ( cfg->cond != NULL ) printf( " }" ); printf( "\n" ); break; case token_string: - if ( cfg->cond != NULL ) - printf( " " ); - printf( "write_string $cfg $autocfg %s $%s $notmod", - cfg->optionname, cfg->optionname ); + printf( "write_string $cfg $autocfg %s \"$%s\" $notmod", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); if ( cfg->cond != NULL ) printf( " }" ); printf( "\n" ); @@ -595,6 +824,108 @@ } } +static void generate_update_var( struct kconfig * scfg, int menu_num ) +{ + struct kconfig * cfg; + + if ( menu_num>0 ) + printf( "proc update_define_menu%d {} {\n", menu_num ); + clear_globalflags(); + global( "CONFIG_MODULES" ); + vartable[ get_varnum( "CONFIG_MODULES" ) ].global_written = 1; + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + if ( cfg->menu_number == menu_num && (cfg->token == token_define_bool || cfg->token == token_define_tristate + || cfg->token == token_define_hex || cfg->token == token_define_int + || cfg->token == token_define_string || cfg->token == token_unset + || cfg->token == token_tristate) ) + { + if ( ! vartable[cfg->nameindex].global_written ) + { + vartable[cfg->nameindex].global_written = 1; + global( vartable[cfg->nameindex].name ); + } + } + } + + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + char tmp[20]; + struct kconfig * cfg1; + + if ( cfg->menu_number == menu_num ) + { + switch ( cfg->token ) + { + default: + case token_choice_item: + break; + case token_choice_header: + sprintf( tmp, "tmpvar_%d", -(cfg->nameindex) ); + global( tmp ); + for ( cfg1 = cfg->next; + cfg1 != NULL && cfg1->token == token_choice_item; + cfg1 = cfg1->next ) + { + vartable[cfg1->nameindex].global_written = 1; + global( vartable[cfg1->nameindex].name ); + printf( "\tif {$tmpvar_%d == \"%s\"} then {set %s 1} else {set %s 0}\n", + -(cfg->nameindex), cfg1->label, + vartable[cfg1->nameindex].name, + vartable[cfg1->nameindex].name ); + } + break; + case token_bool: + case token_define_bool: + case token_define_tristate: + case token_define_hex: + case token_define_int: + case token_define_string: + case token_dep_bool: + case token_dep_tristate: + case token_int: + case token_hex: + case token_mainmenu_option: + case token_tristate: + case token_unset: + if ( cfg->cond != NULL ) + generate_if( cfg, cfg->cond, menu_num, -2 ); + else switch ( cfg->token ) + { + case token_tristate: + printf( "\n\tif {($CONFIG_MODULES == 0)} then {if {($%s == 2)} then {set %s 1}}\n", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); + break; + case token_define_bool: + case token_define_tristate: + if ( ! vartable[get_varnum( cfg->value )].global_written ) + { + vartable[get_varnum( cfg->value )].global_written = 1; + global( cfg->value ); + } + printf( "\tset %s $%s\n", vartable[cfg->nameindex].name, + cfg->value ); + break; + case token_define_hex: + case token_define_int: + printf( "\tset %s %s\n", vartable[cfg->nameindex].name, + cfg->value ); + break; + case token_define_string: + printf( "\tset %s \"%s\"\n", vartable[cfg->nameindex].name, + cfg->value ); + break; + case token_unset: + printf( "\tset %s 4\n", vartable[cfg->nameindex].name ); + default: + break; + } + } + } + } + if ( menu_num>0 ) + printf( "}\n\n\n" ); +} /* @@ -603,13 +934,24 @@ static void end_proc( struct kconfig * scfg, int menu_num ) { struct kconfig * cfg; + int i; printf( "\n\n\n" ); printf( "\tfocus $w\n" ); - printf( "\tupdate_menu%d $w.config.f\n", - menu_num ); + printf( "\tupdate_active\n" ); printf( "\tglobal winx; global winy\n" ); - printf( "\tset winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30]\n" ); + if ( menu_first[menu_num]->menu_number != 0 ) + { + printf( "\tif {[winfo exists .menu%d] == 0} then ", + menu_first[menu_num]->menu_number ); + printf( "{menu%d .menu%d \"%s\"}\n", + menu_first[menu_num]->menu_number, menu_first[menu_num]->menu_number, + menu_first[menu_first[menu_num]->menu_number]->label ); + printf( "\tset winx [expr [winfo x .menu%d]+30]; set winy [expr [winfo y .menu%d]+30]\n", + menu_first[menu_num]->menu_number, menu_first[menu_num]->menu_number ); + } + else + printf( "\tset winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30]\n" ); printf( "\twm geometry $w +$winx+$winy\n" ); /* @@ -660,27 +1002,12 @@ * widgets, and will be called first when the window is mapped, * and each time one of the buttons in the window are clicked. */ - printf( "proc update_menu%d {w} {\n", menu_num ); - printf( "\tupdate_define\n" ); + printf( "proc update_menu%d {} {\n", menu_num ); /* * Clear all of the booleans that are defined in this menu. */ - clear_globalflags( scfg ); - for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) - { - if ( cfg->menu_number == menu_num && cfg->token == token_define_bool - && cfg->optionname != NULL ) - { - if ( ! cfg->global_written ) - { - cfg->global_written = 1; - printf( "\tglobal %s\n", cfg->optionname ); - printf( "\tset %s 0\n", cfg->optionname ); - } - } - } - + clear_globalflags(); for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) { if ( cfg->menu_number == menu_num @@ -688,28 +1015,47 @@ && cfg->token != token_choice_item ) { if ( cfg->cond != NULL ) + { + int i; + if ( (cfg->token == token_tristate || cfg->token == token_dep_tristate) + && ! vartable[i = get_varnum( "CONFIG_MODULES" )].global_written ) + { + global( "CONFIG_MODULES" ); + vartable[i].global_written = 1; + } generate_if( cfg, cfg->cond, cfg->menu_number, cfg->menu_line ); + } else { - /* - * Treat tristate like conditional here. - */ - if ( cfg->token == token_dep_tristate ) + if ( cfg->token == token_tristate ) { - global( cfg->depend ); - printf( "\tif {$%s != 1 && $%s != 0 } then { .menu%d.config.f.x%d.y configure -state disabled } else { .menu%d.config.f.x%d.y configure -state normal}\n", - cfg->depend, cfg->depend, + if ( ! vartable[cfg->nameindex].global_written ) + { + vartable[cfg->nameindex].global_written = 1; + printf( "\tglobal %s\n", vartable[cfg->nameindex].name ); + } + if ( ! vartable[i = get_varnum( "CONFIG_MODULES" )].global_written ) + { + global( "CONFIG_MODULES" ); + vartable[i].global_written = 1; + } + printf( "\n\tif {($CONFIG_MODULES == 1)} then {configure_entry .menu%d.config.f.x%d normal {m}} else {configure_entry .menu%d.config.f.x%d disabled {m}}\n", menu_num, cfg->menu_line, menu_num, cfg->menu_line ); } } } + else if ( cfg->token == token_mainmenu_option + && cfg->menu_number == menu_num + && cfg->cond != NULL ) + { + generate_if( cfg, cfg->cond, menu_num, cfg->menu_line ); + } } - printf("}\n\n\n"); -} - + generate_update_var( scfg, menu_num ); +} /* * This is the top level function for generating the tk script. @@ -718,18 +1064,20 @@ { int menu_depth; int menu_num [64]; - struct kconfig * menu_first [256]; - struct kconfig * menu_last [256]; - int imenu; + int imenu, i; + int top_level_num = 0; struct kconfig * cfg; struct kconfig * cfg1 = NULL; const char * name = "No Name"; /* - * Thread the menu pointers so I can walk each menu separately. - */ + * Mark begin and end of each menu so I can omit submenus when walking + * over a parent menu. + */ tot_menu_num = 0; menu_depth = 0; + menu_num [0] = 0; + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) { switch ( cfg->token ) @@ -744,14 +1092,22 @@ case token_mainmenu_option: if ( ++menu_depth >= 64 ) { fprintf( stderr, "menus too deep\n" ); exit( 1 ); } - if ( ++tot_menu_num >= 256 ) + if ( ++tot_menu_num >= 100 ) { fprintf( stderr, "too many menus\n" ); exit( 1 ); } menu_num [menu_depth] = tot_menu_num; menu_first [tot_menu_num] = cfg; menu_last [tot_menu_num] = cfg; + /* + * Note, that menu_number is set to the number of parent + * (upper level) menu. + */ + cfg->menu_number = menu_num[menu_depth - 1]; + if ( menu_depth == 1 ) + ++top_level_num; break; case token_endmenu: + menu_last [menu_num [menu_depth]] = cfg; /* flatten menus with proper scoping */ if ( --menu_depth < 0 ) { fprintf( stderr, "unmatched endmenu\n" ); exit( 1 ); } @@ -760,19 +1116,24 @@ case token_bool: case token_choice_header: case token_choice_item: + case token_dep_bool: case token_dep_tristate: case token_hex: case token_int: case token_string: case token_tristate: + cfg->menu_number = menu_num[menu_depth]; if ( menu_depth == 0 ) { fprintf( stderr, "statement not in menu\n" ); exit( 1 ); } - menu_last [menu_num [menu_depth]]->menu_next = cfg; - menu_last [menu_num [menu_depth]] = cfg; - cfg->menu_next = NULL; break; case token_define_bool: + case token_define_hex: + case token_define_int: + case token_define_string: + case token_define_tristate: + case token_unset: + cfg->menu_number = menu_num[menu_depth]; break; } } @@ -784,7 +1145,21 @@ * one blank button * add two to round up for division */ - printf( "set menus_per_column %d\n\n", (tot_menu_num + 4 + 1 + 2) / 3 ); + printf( "set menus_per_column %d\n", (top_level_num + 4 + 1 + 2) / 3 ); + printf( "set total_menus %d\n\n", tot_menu_num ); + + printf( "proc toplevel_menu {num} {\n" ); + for ( imenu = 1; imenu <= tot_menu_num; ++imenu ) + { + int parent = 1; + + if ( menu_first[imenu]->menu_number == 0 ) + parent = menu_first[imenu]->menu_number; + else + printf( "\tif {$num == %d} then {return %d}\n", + imenu, menu_first[imenu]->menu_number ); + } + printf( "\treturn $num\n}\n\n" ); /* * Generate the menus. @@ -793,24 +1168,33 @@ for ( imenu = 1; imenu <= tot_menu_num; ++imenu ) { int menu_line = 0; + int nr_submenu = imenu; - clear_globalflags( scfg ); - start_proc( menu_first[imenu]->label, imenu, 1 ); + clear_globalflags(); + start_proc( menu_first[imenu]->label, imenu, + !menu_first[imenu]->menu_number ); - for ( cfg = menu_first[imenu]; cfg != NULL; cfg = cfg->menu_next ) + for ( cfg = menu_first[imenu]->next; cfg != NULL && cfg != menu_last[imenu]; cfg = cfg->next ) { - cfg->menu_number = imenu; - switch ( cfg->token ) { default: break; + case token_mainmenu_option: + while ( menu_first[++nr_submenu]->menu_number > imenu ) + ; + cfg->menu_line = menu_line++; + printf( "\tsubmenu $w.config.f %d %d \"%s\" %d\n", + cfg->menu_number, cfg->menu_line, cfg->label, nr_submenu ); + cfg = menu_last[nr_submenu]; + break; + case token_bool: cfg->menu_line = menu_line++; printf( "\tbool $w.config.f %d %d \"%s\" %s\n", cfg->menu_number, cfg->menu_line, cfg->label, - cfg->optionname ); + vartable[cfg->nameindex].name ); break; case token_choice_header: @@ -819,54 +1203,61 @@ * help text from Documentation/Configure.help. */ cfg->menu_line = menu_line++; - printf( "\tglobal %s\n", cfg->optionname ); - printf( "\tminimenu $w.config.f %d %d \"%s\" %s %s\n", + printf( "\tglobal tmpvar_%d\n", -(cfg->nameindex) ); + printf( "\tminimenu $w.config.f %d %d \"%s\" tmpvar_%d %s\n", cfg->menu_number, cfg->menu_line, cfg->label, - cfg->optionname, cfg->next->optionname ); + -(cfg->nameindex), vartable[cfg->next->nameindex].name ); printf( "\tmenu $w.config.f.x%d.x.menu\n", cfg->menu_line ); cfg1 = cfg; break; case token_choice_item: /* note: no menu line; uses choice header menu line */ - printf( "\t$w.config.f.x%d.x.menu add radiobutton -label \"%s\" -variable %s -value \"%s\" -command \"update_menu%d .menu%d.config.f\"\n", - cfg1->menu_line, cfg->label, cfg1->optionname, - cfg->label, cfg1->menu_number, cfg1->menu_number ); + printf( "\t$w.config.f.x%d.x.menu add radiobutton -label \"%s\" -variable tmpvar_%d -value \"%s\" -command \"update_active\"\n", + cfg1->menu_line, cfg->label, -(cfg1->nameindex), + cfg->label ); + break; + + case token_dep_bool: + cfg->menu_line = menu_line++; + printf( "\tdep_bool $w.config.f %d %d \"%s\" %s\n", + cfg->menu_number, cfg->menu_line, cfg->label, + vartable[cfg->nameindex].name ); break; case token_dep_tristate: cfg->menu_line = menu_line++; - printf( "\tdep_tristate $w.config.f %d %d \"%s\" %s %s\n", + printf( "\tdep_tristate $w.config.f %d %d \"%s\" %s\n", cfg->menu_number, cfg->menu_line, cfg->label, - cfg->optionname, cfg->depend ); + vartable[cfg->nameindex].name ); break; case token_hex: cfg->menu_line = menu_line++; printf( "\thex $w.config.f %d %d \"%s\" %s\n", cfg->menu_number, cfg->menu_line, cfg->label, - cfg->optionname ); + vartable[cfg->nameindex].name ); break; case token_int: cfg->menu_line = menu_line++; printf( "\tint $w.config.f %d %d \"%s\" %s\n", cfg->menu_number, cfg->menu_line, cfg->label, - cfg->optionname ); + vartable[cfg->nameindex].name ); break; case token_string: cfg->menu_line = menu_line++; printf( "\tistring $w.config.f %d %d \"%s\" %s\n", cfg->menu_number, cfg->menu_line, cfg->label, - cfg->optionname ); + vartable[cfg->nameindex].name ); break; case token_tristate: cfg->menu_line = menu_line++; printf( "\ttristate $w.config.f %d %d \"%s\" %s\n", cfg->menu_number, cfg->menu_line, cfg->label, - cfg->optionname ); + vartable[cfg->nameindex].name ); break; } } @@ -880,31 +1271,16 @@ * the top level menu, and this procedure will ensure that things are * correct. */ - clear_globalflags( scfg ); - printf( "proc update_mainmenu {w} {\n" ); - for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + clear_globalflags(); + printf( "proc update_mainmenu {} {\n" ); + for ( imenu = 1; imenu <= tot_menu_num; imenu++ ) { - if ( cfg->token == token_mainmenu_option && cfg->cond != NULL ) - generate_if( cfg, cfg->cond, cfg->menu_number, cfg->menu_line ); + if ( menu_first[imenu]->cond != NULL && menu_first[imenu]->menu_number == 0 ) + generate_if( menu_first[imenu], menu_first[imenu]->cond, imenu, -1 ); } printf( "}\n\n\n" ); -#if 0 - /* - * Generate code to set the variables that are "defined". - */ - for ( cfg = config; cfg != NULL; cfg = cfg->next ) - { - if ( cfg->token == token_define_bool ) - { - if ( cfg->cond != NULL ) - generate_if( cfg, cfg->cond, menu_num, cfg->menu_line ); - else - printf( "\twrite_define %s %s\n", cfg->optionname, cfg->value ); - } - } - #endif - + clear_globalflags(); /* * Generate code to load the default settings into the variables. * The script in tail.tk will attempt to load .config, @@ -919,27 +1295,50 @@ case token_bool: case token_choice_item: + case token_dep_bool: case token_dep_tristate: case token_tristate: - printf( "set %s 0\n", cfg->optionname ); + if ( ! vartable[cfg->nameindex].global_written ) + { + printf( "set %s 0\n", vartable[cfg->nameindex].name ); + vartable[cfg->nameindex].global_written = 1; + } break; case token_choice_header: - printf( "set %s \"(not set)\"\n", cfg->optionname ); + printf( "set tmpvar_%d \"(not set)\"\n", -(cfg->nameindex) ); break; case token_hex: case token_int: - printf( "set %s %s\n", cfg->optionname, cfg->value ? cfg->value : "0"); + if ( ! vartable[cfg->nameindex].global_written ) + { + printf( "set %s %s\n", vartable[cfg->nameindex].name, cfg->value ? cfg->value : "0" ); + vartable[cfg->nameindex].global_written = 1; + } break; case token_string: - printf( "set %s \"%s\"\n", cfg->optionname, cfg->value ? cfg->value : ""); + if ( ! vartable[cfg->nameindex].global_written ) + { + printf( "set %s \"%s\"\n", vartable[cfg->nameindex].name, cfg->value ); + vartable[cfg->nameindex].global_written = 1; + } break; } } /* + * Define to an empty value all other variables (which are never defined) + */ + for ( i = 1; i <= max_varnum; i++ ) + { + if ( ! vartable[i].global_written + && strncmp( vartable[i].name, "CONSTANT_", 9 ) ) + printf( "set %s 4\n", vartable[i].name ); + } + + /* * Generate a function to write all of the variables to a file. */ printf( "proc writeconfig {file1 file2} {\n" ); @@ -956,7 +1355,7 @@ printf( "\tputs $autocfg \" */\"\n" ); printf( "\tputs $autocfg \"#define AUTOCONF_INCLUDED\"\n" ); - clear_globalflags( scfg ); + clear_globalflags(); for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) { switch ( cfg->token ) @@ -968,6 +1367,11 @@ case token_choice_header: case token_comment: case token_define_bool: + case token_define_hex: + case token_define_int: + case token_define_string: + case token_define_tristate: + case token_dep_bool: case token_dep_tristate: case token_hex: case token_int: @@ -996,7 +1400,8 @@ cfg1 = cfg1->next ) { printf( "\tglobal %s; set %s 0\n", - cfg1->optionname, cfg1->optionname ); + vartable[cfg1->nameindex].name, + vartable[cfg1->nameindex].name ); } } } @@ -1007,41 +1412,28 @@ { if ( cfg->token == token_choice_header ) { - printf( "\tglobal %s\n", cfg->optionname ); + printf( "\tglobal tmpvar_%d\n", -(cfg->nameindex) ); + printf("\tset tmpvar_%d \"%s\"\n", -(cfg->nameindex), cfg->value); for ( cfg1 = cfg->next; cfg1 != NULL && cfg1->token == token_choice_item; cfg1 = cfg1->next ) { - printf( "\tglobal %s\n", cfg1->optionname ); - printf( "\tif { $%s == 1 } then { set %s \"%s\" }\n", - cfg1->optionname, cfg->optionname, cfg1->label ); + printf( "\tglobal %s\n", vartable[cfg1->nameindex].name ); + printf( "\tif { $%s == 1 } then { set tmpvar_%d \"%s\" }\n", + vartable[cfg1->nameindex].name, + -(cfg->nameindex), cfg1->label ); } } } printf( "}\n\n\n" ); - printf( "proc update_define { } {\n" ); - clear_globalflags( scfg ); - for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) +/* printf( "proc update_define {} {\n" ); + generate_update_var( scfg, 0 ); + for ( i = 1; i <= tot_menu_num; i++ ) { - if ( cfg->token == token_define_bool ) - { - cfg->global_written = 1; - printf( "\tglobal %s\n", cfg->optionname ); - } + printf( "\tupdate_define_menu%d; if { update\n", i ); } - - for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) - { - if( cfg->token == token_define_bool ) - { - if ( cfg->cond == NULL ) - printf( "\tset %s %s\n", cfg->optionname, cfg->value ); - else - generate_if( cfg, cfg->cond, -1, 0 ); - } - } - printf( "}\n\n\n" ); + printf( "}\n\n\n" );*/ /* * That's it. We are done. The output of this file will have header.tk diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/scripts/tkparse.c linux.ac/scripts/tkparse.c --- linux.vanilla/scripts/tkparse.c Sun May 2 17:51:16 1999 +++ linux.ac/scripts/tkparse.c Tue Sep 14 20:59:14 1999 @@ -29,6 +29,17 @@ * 23 January 1999, Michael Elizabeth Chastain, * - Remove bug-compatible code. * + * 07 July 1999, Andrzej M. Krzysztofowicz, + * - Submenus implemented, + * - plenty of option updating/displaying fixes, + * - dep_bool, define_hex, define_int, define_string, define_tristate and + * undef implemented, + * - dep_tristate fixed to support multiple dependencies, + * - handling of variables with an empty value implemented, + * - value checking for int and hex fields, + * - more checking during condition parsing; choice variables are treated as + * all others now, + * * TO DO: * - xconfig is at the end of its life cycle. Contact if * you are interested in working on the replacement. @@ -51,8 +62,6 @@ int my_strcmp( const char * s1, const char * s2 ) { return strcmp( s1, s2 ); } #define strcmp my_strcmp - - /* * Report a syntax error. */ @@ -65,6 +74,30 @@ /* + * Find index of a specyfic variable in the symbol table. + * Create a new entry if it does not exist yet. + */ +#define VARTABLE_SIZE 2048 +struct variable vartable[VARTABLE_SIZE]; +int max_varnum = 0; + +int get_varnum( char * name ) +{ + int i; + + for ( i = 1; i <= max_varnum; i++ ) + if ( strcmp( vartable[i].name, name ) == 0 ) + return i; + if (max_varnum > VARTABLE_SIZE-1) + syntax_error( "Too many variables defined." ); + vartable[++max_varnum].name = malloc( strlen( name )+1 ); + strcpy( vartable[max_varnum].name, name ); + return max_varnum; +} + + + +/* * Get a string. */ static const char * get_string( const char * pnt, char ** label ) @@ -138,6 +171,7 @@ } + /* * Tokenize an 'if' statement condition. */ @@ -145,6 +179,7 @@ { struct condition * list; struct condition * last; + struct condition * prev; /* eat the open bracket */ while ( *pnt == ' ' || *pnt == '\t' ) @@ -170,30 +205,53 @@ cond = malloc( sizeof(*cond) ); memset( cond, 0, sizeof(*cond) ); if ( last == NULL ) - { list = last = cond; } + { list = last = cond; prev = NULL; } else - { last->next = cond; last = cond; } + { prev = last; last->next = cond; last = cond; } /* determine the token value */ if ( *pnt == '-' && pnt[1] == 'a' ) - { cond->op = op_and; pnt += 2; continue; } + { + if ( ! prev || ( prev->op != op_variable && prev->op != op_constant ) ) + syntax_error( "incorrect argument" ); + cond->op = op_and; pnt += 2; continue; + } if ( *pnt == '-' && pnt[1] == 'o' ) - { cond->op = op_or; pnt += 2; continue; } + { + if ( ! prev || ( prev->op != op_variable && prev->op != op_constant ) ) + syntax_error( "incorrect argument" ); + cond->op = op_or; pnt += 2; continue; + } if ( *pnt == '!' && pnt[1] == '=' ) - { cond->op = op_neq; pnt += 2; continue; } + { + if ( ! prev || ( prev->op != op_variable && prev->op != op_constant ) ) + syntax_error( "incorrect argument" ); + cond->op = op_neq; pnt += 2; continue; + } if ( *pnt == '=' ) - { cond->op = op_eq; pnt += 1; continue; } + { + if ( ! prev || ( prev->op != op_variable && prev->op != op_constant ) ) + syntax_error( "incorrect argument" ); + cond->op = op_eq; pnt += 1; continue; + } if ( *pnt == '!' ) - { cond->op = op_bang; pnt += 1; continue; } + { + if ( prev && ( prev->op != op_and && prev->op != op_or + && prev->op != op_bang ) ) + syntax_error( "incorrect argument" ); + cond->op = op_bang; pnt += 1; continue; + } if ( *pnt == '"' ) { const char * word; + if ( prev && ( prev->op == op_variable || prev->op == op_constant ) ) + syntax_error( "incorrect argument" ); /* advance to the word */ pnt++; if ( *pnt == '$' ) @@ -217,7 +275,15 @@ char * str = malloc( pnt - word + 1 ); memcpy( str, word, pnt - word ); str [pnt - word] = '\0'; - cond->str = str; + if ( cond->op == op_variable ) + { + cond->nameindex = get_varnum( str ); + free( str ); + } + else /* op_constant */ + { + cond->str = str; + } } pnt++; @@ -241,6 +307,7 @@ for ( ; ; ) { struct kconfig * cfg; + char * buffer = malloc( 64 ); /* skip whitespace */ while ( *pnt == ' ' || *pnt == '\t' ) @@ -262,7 +329,8 @@ pnt = get_string( pnt, &cfg->label ); while ( *pnt == ' ' || *pnt == '\t' ) pnt++; - pnt = get_string( pnt, &cfg->optionname ); + pnt = get_string( pnt, &buffer ); + cfg->nameindex = get_varnum( buffer ); } return pnt; @@ -270,8 +338,6 @@ - - /* * Tokenize one line. */ @@ -280,6 +346,8 @@ static struct kconfig * last_menuoption = NULL; enum e_token token; struct kconfig * cfg; + struct dependency ** dep_ptr; + char * buffer = malloc( 64 ); /* skip white space */ while ( *pnt == ' ' || *pnt == '\t' ) @@ -313,6 +381,11 @@ case 'd': match_token( token_define_bool, "define_bool" ); + match_token( token_define_hex, "define_hex" ); + match_token( token_define_int, "define_int" ); + match_token( token_define_string, "define_string" ); + match_token( token_define_tristate, "define_tristate" ); + match_token( token_dep_bool, "dep_bool" ); match_token( token_dep_tristate, "dep_tristate" ); break; @@ -371,11 +444,13 @@ syntax_error( "bogus 'then'" ); } +#if 0 if ( token == token_unset ) { fprintf( stderr, "Ignoring 'unset' command\n" ); return; } +#endif if ( token == token_UNKNOWN ) syntax_error( "unknown command" ); @@ -404,8 +479,9 @@ case token_bool: case token_tristate: - pnt = get_qstring ( pnt, &cfg->label ); - pnt = get_string ( pnt, &cfg->optionname ); + pnt = get_qstring ( pnt, &cfg->label ); + pnt = get_string ( pnt, &buffer ); + cfg->nameindex = get_varnum( buffer ); break; case token_choice_header: @@ -417,9 +493,7 @@ pnt = get_qstring ( pnt, &choice_list ); pnt = get_string ( pnt, &cfg->value ); - cfg->optionname = malloc( 32 ); - sprintf( cfg->optionname, "tmpvar_%d", choose_number++ ); - + cfg->nameindex = -(choose_number++); tokenize_choices( cfg, choice_list ); free( choice_list ); } @@ -436,56 +510,133 @@ break; case token_define_bool: - pnt = get_string( pnt, &cfg->optionname ); + case token_define_tristate: + pnt = get_string( pnt, &buffer ); + cfg->nameindex = get_varnum( buffer ); while ( *pnt == ' ' || *pnt == '\t' ) pnt++; - if ( *pnt == 'n' || *pnt == 'N' ) cfg->value = "0"; - else if ( *pnt == 'y' || *pnt == 'Y' ) cfg->value = "1"; - else if ( *pnt == 'm' || *pnt == 'M' ) cfg->value = "2"; + if ( ( pnt[0] == 'Y' || pnt[0] == 'M' || pnt[0] == 'N' + || pnt[0] == 'y' || pnt[0] == 'm' || pnt[0] == 'n' ) + && ( pnt[1] == '\0' || pnt[1] == ' ' || pnt[1] == '\t' ) ) + { + if ( *pnt == 'n' || *pnt == 'N' ) cfg->value = strdup( "CONSTANT_N" ); + else if ( *pnt == 'y' || *pnt == 'Y' ) cfg->value = strdup( "CONSTANT_Y" ); + else if ( *pnt == 'm' || *pnt == 'M' ) cfg->value = strdup( "CONSTANT_M" ); + } + else if ( *pnt == '$' ) + { + pnt++; + pnt = get_string( pnt, &cfg->value ); + } else { syntax_error( "unknown define_bool value" ); } + get_varnum( cfg->value ); + break; + + case token_define_hex: + case token_define_int: + pnt = get_string( pnt, &buffer ); + cfg->nameindex = get_varnum( buffer ); + pnt = get_string( pnt, &cfg->value ); break; + case token_define_string: + pnt = get_string( pnt, &buffer ); + cfg->nameindex = get_varnum( buffer ); + pnt = get_qstring( pnt, &cfg->value ); + break; + + case token_dep_bool: case token_dep_tristate: - pnt = get_qstring ( pnt, &cfg->label ); - pnt = get_string ( pnt, &cfg->optionname ); + pnt = get_qstring ( pnt, &cfg->label ); + pnt = get_string ( pnt, &buffer ); + cfg->nameindex = get_varnum( buffer ); while ( *pnt == ' ' || *pnt == '\t' ) pnt++; - if ( ( pnt[0] == 'Y' || pnt[0] == 'M' || pnt[0] == 'N' - || pnt[0] == 'y' || pnt[0] == 'm' || pnt[0] == 'n' ) - && ( pnt[1] == '\0' || pnt[1] == ' ' || pnt[1] == '\t' ) ) - { - /* dep_tristate 'foo' CONFIG_FOO m */ - if ( pnt[0] == 'Y' || pnt[0] == 'y' ) - cfg->depend = strdup( "CONSTANT_Y" ); - else if ( pnt[0] == 'M' || pnt[0] == 'm' ) - cfg->depend = strdup( "CONSTANT_M" ); + dep_ptr = &(cfg->depend); + + do { + *dep_ptr = (struct dependency *) malloc( sizeof( struct dependency ) ); + (*dep_ptr)->next = NULL; + + if ( ( pnt[0] == 'Y' || pnt[0] == 'M' || pnt[0] == 'N' + || pnt[0] == 'y' || pnt[0] == 'm' || pnt[0] == 'n' ) + && ( pnt[1] == '\0' || pnt[1] == ' ' || pnt[1] == '\t' ) ) + { + /* dep_tristate 'foo' CONFIG_FOO m */ + if ( pnt[0] == 'Y' || pnt[0] == 'y' ) + (*dep_ptr)->name = strdup( "CONSTANT_Y" ); + else if ( pnt[0] == 'N' || pnt[0] == 'n' ) + (*dep_ptr)->name = strdup( "CONSTANT_N" ); + else + (*dep_ptr)->name = strdup( "CONSTANT_M" ); + pnt++; + get_varnum( (*dep_ptr)->name ); + } + else if ( *pnt == '$' ) + { + pnt++; + pnt = get_string( pnt, &(*dep_ptr)->name ); + get_varnum( (*dep_ptr)->name ); + } else - cfg->depend = strdup( "CONSTANT_N" ); - pnt++; - } - else if ( *pnt == '$' ) - { - pnt++; - pnt = get_string( pnt, &cfg->depend ); - } - else - { - syntax_error( "can't handle dep_tristate condition" ); - } + { + syntax_error( "can't handle dep_bool/dep_tristate condition" ); + } + dep_ptr = &(*dep_ptr)->next; + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + } while ( *pnt ); /* - * Create a conditional for this object's dependency. + * Create a conditional for this object's dependencies. */ { char fake_if [1024]; - sprintf( fake_if, "[ \"$%s\" = \"y\" -o \"$%s\" = \"m\" ]; then", - cfg->depend, cfg->depend ); - cfg->cond = tokenize_if( fake_if ); + struct dependency * dep; + struct condition ** cond_ptr; + int first = 1; + + cond_ptr = &(cfg->cond); + for ( dep = cfg->depend; dep; dep = dep->next ) + { + if ( token == token_dep_tristate + && ! strcmp( dep->name, "CONSTANT_M" ) ) + { + continue; + } + if ( first ) + { + first = 0; + } + else + { + *cond_ptr = malloc( sizeof(struct condition) ); + memset( *cond_ptr, 0, sizeof(struct condition) ); + (*cond_ptr)->op = op_and; + cond_ptr = &(*cond_ptr)->next; + } + *cond_ptr = malloc( sizeof(struct condition) ); + memset( *cond_ptr, 0, sizeof(struct condition) ); + (*cond_ptr)->op = op_lparen; + if ( token == token_dep_tristate ) + sprintf( fake_if, "[ \"$%s\" = \"y\" -o \"$%s\" = \"m\" -o \"$%s\" = \"\" ]; then", + dep->name, dep->name, dep->name ); + else + sprintf( fake_if, "[ \"$%s\" = \"y\" -o \"$%s\" = \"\" ]; then", + dep->name, dep->name ); + (*cond_ptr)->next = tokenize_if( fake_if ); + while ( *cond_ptr ) + cond_ptr = &(*cond_ptr)->next; + *cond_ptr = malloc( sizeof(struct condition) ); + memset( *cond_ptr, 0, sizeof(struct condition) ); + (*cond_ptr)->op = op_rparen; + cond_ptr = &(*cond_ptr)->next; + } } break; @@ -496,15 +647,17 @@ case token_hex: case token_int: - pnt = get_qstring ( pnt, &cfg->label ); - pnt = get_string ( pnt, &cfg->optionname ); - pnt = get_string ( pnt, &cfg->value ); + pnt = get_qstring ( pnt, &cfg->label ); + pnt = get_string ( pnt, &buffer ); + cfg->nameindex = get_varnum( buffer ); + pnt = get_string ( pnt, &cfg->value ); break; case token_string: - pnt = get_qstring ( pnt, &cfg->label ); - pnt = get_string ( pnt, &cfg->optionname ); - pnt = get_qstring ( pnt, &cfg->value ); + pnt = get_qstring ( pnt, &cfg->label ); + pnt = get_string ( pnt, &buffer ); + cfg->nameindex = get_varnum( buffer ); + pnt = get_qstring ( pnt, &cfg->value ); break; case token_if: @@ -521,8 +674,25 @@ else pnt = get_qstring( pnt, &cfg->label ); break; - } + case token_unset: + pnt = get_string( pnt, &buffer ); + cfg->nameindex = get_varnum( buffer ); + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + while (*pnt) + { + cfg->next = (struct kconfig *) malloc( sizeof(struct kconfig) ); + memset( cfg->next, 0, sizeof(struct kconfig) ); + cfg = cfg->next; + cfg->token = token_unset; + pnt = get_string( pnt, &buffer ); + cfg->nameindex = get_varnum( buffer ); + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + } + break; + } return; } diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/scripts/tkparse.h linux.ac/scripts/tkparse.h --- linux.vanilla/scripts/tkparse.h Mon Feb 1 20:03:19 1999 +++ linux.ac/scripts/tkparse.h Tue Sep 14 20:59:14 1999 @@ -14,6 +14,11 @@ token_choice_item, token_comment, token_define_bool, + token_define_hex, + token_define_int, + token_define_string, + token_define_tristate, + token_dep_bool, token_dep_tristate, token_else, token_endmenu, @@ -46,7 +51,8 @@ op_rparen, op_constant, op_variable, - op_kvariable, + op_true, + op_false, op_nuked }; @@ -55,21 +61,29 @@ * Some operators take strings: * * op_constant "foo" - * op_variable "$ARCH", "$CONFIG_PMAC" - * op_kvariable "$CONFIG_EXPERIMENTAL" + * op_variable "$ARCH", "$CONFIG_PMAC", "$CONFIG_EXPERIMENTAL" * * Most "$..." constructs refer to a variable which is defined somewhere - * in the script, so they become op_kvariable's instead. Note that it - * is legal to test variables which are never defined, such as variables - * that are meaningful only on other architectures. + * in the script. Note that it is legal to test variables which are never + * defined, such as variables that are meaningful only on other architectures. */ struct condition { - struct condition * next; - enum operator op; - const char * str; /* op_constant, op_variable */ - struct kconfig * cfg; /* op_kvariable */ + struct condition * next; + enum operator op; + const char * str; /* op_constant */ + int nameindex; /* op_variable */ +}; + +/* + * Dependency list for dep_bool, dep_tristate + */ + +struct dependency +{ + char * name; + struct dependency * next; }; /* @@ -80,21 +94,28 @@ { struct kconfig * next; enum e_token token; - char * optionname; + int nameindex; char * label; char * value; struct condition * cond; - char * depend; /* token_dep_tristate */ + struct dependency * depend; /* token_dep_tristate */ struct kconfig * cfg_parent; /* token_choice_item */ /* used only in tkgen.c */ - char global_written; int menu_number; int menu_line; struct kconfig * menu_next; }; +struct variable +{ + char * name; + char defined; + char global_written; +}; +extern struct variable vartable[]; +extern int max_varnum; /* * Prototypes @@ -102,3 +123,4 @@ extern void fix_conditionals ( struct kconfig * scfg ); /* tkcond.c */ extern void dump_tk_script ( struct kconfig * scfg ); /* tkgen.c */ +extern int get_varnum ( char * name ); /* tkparse.c */