diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/Documentation/Configure.help linux.19pre5-ac1/Documentation/Configure.help --- linux.19p5/Documentation/Configure.help Thu Apr 4 13:21:10 2002 +++ linux.19pre5-ac1/Documentation/Configure.help Thu Apr 4 14:16:23 2002 @@ -2049,6 +2049,11 @@ which allows for more memory. Your system is most probably running in M-Mode, so you should say N here. +Lasi ethernet +CONFIG_LASI_82596 + Say Y here to support the on-board Intel 82596 ethernet controller + built into Hewlett-Packard PA-RISC machines. + MIPS JAZZ onboard SONIC Ethernet support CONFIG_MIPS_JAZZ_SONIC This is the driver for the onboard card of MIPS Magnum 4000, @@ -4511,7 +4516,8 @@ CONFIG_FB_MATROX Say Y here if you have a Matrox Millennium, Millennium II, Mystique, Mystique 220, Productiva G100, Mystique G200, Millennium G200, - Marvel G200 video, G400, G450, or G550 card in your box. + Matrox G400, G450 or G550 card in your box. At this time, support for + the G-series digital output is almost non-existant. This driver is also available as a module ( = code which can be inserted and removed from the running kernel whenever you want). @@ -4550,6 +4556,10 @@ "I2C support" and "I2C bit-banging support" in the character devices section, and then to "Matrox I2C support" and "G400 second head support" here in the framebuffer section. + + If you have G550, you must also compile support for G450/G550 secondary + head into kernel, otherwise picture will be shown only on the output you + are probably not using... If you need support for G450 or G550 secondary head, say Y to "Matrox G450/G550 second head support" below. @@ -4600,7 +4610,8 @@ Matrox G450 second head support CONFIG_FB_MATROX_G450 Say Y or M here if you want to use a secondary head (meaning two - monitors in parallel) on G450 or G550. + monitors in parallel) on G450, or if you are using analog output + of G550. If you compile it as module, two modules are created, matroxfb_crtc2.o and matroxfb_g450.o. Both modules are needed if you @@ -4742,6 +4753,12 @@ The IMS Twin Turbo is a PCI-based frame buffer card bundled with many Macintosh and compatible computers. +CONFIG_FB_TX3912 + The TX3912 is a Toshiba RISC processor based on the MIPS 3900 core; + see . + + Say Y here to enable kernel support for the on-board framebuffer. + Virtual Frame Buffer support (ONLY FOR TESTING!) CONFIG_FB_VIRTUAL This is a `virtual' frame buffer device. It operates on a chunk of @@ -5055,6 +5072,19 @@ replacement for kerneld.) Say Y here and read about configuring it in . +Kernel .config file saved in kernel image +CONFIG_IKCONFIG + This option enables the complete Linux kernel ".config" file contents + to be saved in the kernel (zipped) image file. It provides + documentation of which kernel options are used in a running kernel or + in an on-disk kernel. It can be extracted from the kernel image file + with a script and used as input to rebuild the current kernel or to + build another kernel. Since the kernel image is zipped, using this + option adds approximately 8 KB to a kernel image file. + This option is not available as a module. If you want a separate + file to save the kernel's .config contents, use 'installkernel' or 'cp' + or a similar tool, or just save it in '/lib/modules/'. + ARP daemon support CONFIG_ARPD Normally, the kernel maintains an internal cache which maps IP @@ -6063,6 +6093,12 @@ This is a Logical Link Layer protocol used for X.25 connections over Ethernet, using ordinary Ethernet cards. +ANSI/IEEE 802.2 Data link layer User Interface SAPs (EXPERIMENTAL) +CONFIG_LLC_UI + LLC User Interface SAPs is a Linux socket interface into the LLC datalink + layer. This allows a user to create entire user space network layers tied + to a real SAP. + Frame Diverter CONFIG_NET_DIVERT The Frame Diverter allows you to divert packets from the @@ -6203,6 +6239,19 @@ briefly removed during revalidation. If you say Y here, packets to such neighbours are silently discarded instead. +RFC1483/2684 Bridged protocols +CONFIG_ATM_BR2684 + ATM PVCs can carry ethernet PDUs according to rfc2684 (formerly 1483) + This device will act like an ethernet from the kernels point of view, + with the traffic being carried by ATM PVCs (currently 1 PVC/device). + This is sometimes used over DSL lines. If in doubt, say N. + +Per-VC IP filter kludge +CONFIG_ATM_BR2684_IPFILTER + This is an experimental mechanism for users who need to terminating a + large number of IP-only vcc's. Do not enable this unless you are sure + you know what you are doing. + LAN Emulation (LANE) support CONFIG_ATM_LANE LAN Emulation emulates services of existing LANs across an ATM @@ -6527,6 +6576,12 @@ If you do not have any Quicknet telephony cards, you can safely say N here. +QuickNet Internet LineJack/PhoneJack PCMCIA support +CONFIG_PHONE_IXJ_PCMCIA + Say Y here to configure in PCMCIA service support for the Quicknet + cards manufactured by Quicknet Technologies, Inc. This builds an + additional support module for the PCMCIA version of the card. + FORE Systems 200E-series CONFIG_ATM_FORE200E_MAYBE This is a driver for the FORE Systems 200E-series ATM adapter @@ -7836,6 +7891,12 @@ The module will be called qlogicfc.o. If you want to compile it as a module, say M here and read . +Include loadable firmware in driver +CONFIG_SCSI_QLOGIC_FC_FIRMWARE + Say Y to include ISP2100 Fabric Initiator/Target Firmware, with + expanded LUN addressing and FcTape (FCP-2) support, in the + Qlogic QLA 1280 driver. This is required on some platforms. + Qlogic QLA 1280 SCSI support CONFIG_SCSI_QLOGIC_1280 Say Y if you have a QLogic ISP1x80/1x160 SCSI host adapter. @@ -8985,6 +9046,7 @@ The module will be called ibmtr_cs.o. If you want to compile it as a module, say M here and read . + Xircom Tulip-like CardBus support (old driver) CONFIG_PCMCIA_XIRTULIP This driver is for the Digital "Tulip" Ethernet CardBus adapters. @@ -8998,6 +9060,19 @@ it as a module, say M here and read . If unsure, say N. +Xircom CardBus support (new driver) +CONFIG_PCMCIA_XIRCOM + This driver is for the Digital "Tulip" Ethernet CardBus adapters. + It should work with most DEC 21*4*-based chips/ethercards, as well + as with work-alike chips from Lite-On (PNIC) and Macronix (MXIC) and + ASIX. + + 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 xircom_cb.o. If you want to compile + it as a module, say M here and read + . If unsure, say N. + PCMCIA Wireless LAN CONFIG_NET_PCMCIA_RADIO Say Y here if you would like to use a PCMCIA (PC-card) device to @@ -9248,6 +9323,28 @@ If you want to do that, say M here. The module will be called sealevel.o. +TMPTX3912/PR31700 serial port support +CONFIG_SERIAL_TX3912 + The TX3912 is a Toshiba RISC processor based o the MIPS 3900 core; + see . + Say Y here to enable kernel support for the on-board serial port. + +Console on TMPTX3912/PR31700 serial port +CONFIG_SERIAL_TX3912_CONSOLE + The TX3912 is a Toshiba RISC processor based o the MIPS 3900 core; + see . + Say Y here to direct console I/O to the on-board serial port. + +Enable Au1000 serial console +CONFIG_AU1000_SERIAL_CONSOLE + If you have an Alchemy AU1000 processor (MIPS based) and you want + to use a console on a serial port, say Y. Otherwise, say N. + +Enable Au1000 UART Support +CONFIG_AU1000_UART + If you have an Alchemy AU1000 processor (MIPS based) and you want + to use serial ports, say Y. Otherwise, say N. + SyncLink HDLC/SYNCPPP support CONFIG_SYNCLINK_SYNCPPP Enables HDLC/SYNCPPP support for the SyncLink WAN driver. @@ -11243,6 +11340,12 @@ cards. Specifications and data at . +LP486E on board Ethernet +CONFIG_LP486E + Say Y here to support the 82596-based on-board Ethernet controller + for the Panther motherboard, which is one of the two shipped in the + Intel Professional Workstation. + ICL EtherTeam 16i/32 support CONFIG_ETH16I If you have a network (Ethernet) card of this type, say Y and read @@ -11593,6 +11696,24 @@ The module will be called smctr.o. If you want to compile it as a module, say M here and read . +3COM 3C359 Token Link Velocity XL PCI adapter support +CONFIG_3C359 + This is support for the 3Com PCI Velocity XL cards, specifically + the 3Com 3C359, please note this is not for the 3C339 cards, you + should use the tms380 driver instead. + + If you have such an adapter, say Y and read the Token-Ring + mini-HOWTO, available from . + + 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 will be called 3c359.o. If you want to compile it + as a module, say M here and read Documentation/modules.txt. + + Also read the file or check the + Linux Token Ring Project site for the latest information at + + Sun Happy Meal 10/100baseT support CONFIG_HAPPYMEAL This driver supports the "hme" interface present on most Ultra @@ -13119,6 +13240,20 @@ module, say M here and read . +EMI 2|6 USB Audio interface support +CONFIG_USB_EMI26 + This driver loads firmware to Emagic EMI 2|6 low latency USB + Audio interface. + + After firmware load the device is handled with standard linux + USB Audio driver. + + This code 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 audio.o. If you want to compile it as a + module, say M here and read . + + USB Modem (CDC ACM) support CONFIG_USB_ACM This driver supports USB modems and ISDN adapters which support the @@ -13824,6 +13959,16 @@ The module will be called auerswald.o. If you want to compile it as a module, say M here and read . +USB Auerswald ISDN device support +CONFIG_USB_AUERSWALD + Say Y here if you want to connect an Auerswald USB ISDN Device + to your computer's USB port. + + This code 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 auerswald.o. If you want to compile it as + a module, say M here and read . + D-Link DSB-R100 FM radio support CONFIG_USB_DSBR Say Y here if you want to connect this type of radio to your @@ -14729,13 +14874,10 @@ If you would like to include the NFSv3 server as well as the NFSv2 server, say Y here. If unsure, say Y. -Provide NFS over TCP server support DEVELOPER ONLY +Provide NFS over TCP server support EXPERIMENTAL CONFIG_NFSD_TCP - If you are a developer and want to work on fixing problems with - NFS server over TCP support, say Y here. If unsure, say N. - - Some problems can be found by looking for FIXME in - . + Enable NFS service over TCP connections. This the officially + still experimental, but seems to work well. OS/2 HPFS file system support CONFIG_HPFS_FS @@ -15220,6 +15362,25 @@ hard drives and ADFS-formatted floppy disks. This is experimental codes, so if you're unsure, say N. +JFS filesystem support +CONFIG_JFS_FS + This is a port of IBM's Journaled Filesystem . More information is + available in the file Documentation/filesystems/jfs.txt. + + If you do not intend to use the JFS filesystem, say N. + +JFS Debugging +CONFIG_JFS_DEBUG + If you are experiencing any problems with the JFS filesystem, say + Y here. This will result in additional debugging messages to be + written to the system log. Under normal circumstances, this + results in very little overhead. + +JFS Statistics +CONFIG_JFS_STATISTICS + Enabling this option will cause statistics from the JFS file system + to be made available to the user in the /proc/fs/jfs/ directory. + /dev/pts file system for Unix98 PTYs CONFIG_DEVPTS_FS You should say Y here if you said Y to "Unix98 PTY support" above. @@ -16700,6 +16861,28 @@ . The module will be called i2c-elektor.o. +ITE I2C Algorithm +CONFIG_ITE_I2C_ALGO + This supports the use the ITE8172 I2C interface found on some MIPS + systems. Say Y if you have one of these. You should also say Y for + the ITE I2C peripheral driver support below. + + This support is also available as a module. If you want to compile + it as a modules, say M here and read + . + The module will be called i2c-algo-ite.o. + +ITE I2C Adapter +CONFIG_ITE_I2C_ADAP + This supports the ITE8172 I2C peripheral found on some MIPS + systems. Say Y if you have one of these. You should also say Y for + the ITE I2C driver algorithm support above. + + This support is also available as a module. If you want to compile + it as a module, say M here and read + . + The module will be called i2c-adap-ite.o. + I2C device interface CONFIG_I2C_CHARDEV Say Y here to use i2c-* device files, usually found in the /dev @@ -17759,6 +17942,17 @@ module, say M here and read . Most people will say N. +ALi M7101 Watchdog Timer +CONFIG_ALIM7101_WDT + This is the driver for the hardware watchdog on the ALi M7101 PMU + as used in the x86 Cobalt servers. + + 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 is called alim7101_wdt.o. If you want to compile it as a + module, say M here and read . Most + people will say N. + IB700 SBC Watchdog Timer CONFIG_IB700_WDT This is the driver for the hardware watchdog on the IB700 Single @@ -17800,6 +17994,18 @@ The module is called machzwd.o. If you want to compile it as a module, say M here and read . +CONFIG_SC1200_WDT + This is a driver for National Semiconductor PC87307/PC97307 hardware + watchdog cards as found on the SC1200. This watchdog is mainly used + for power management purposes and can be used to power down the device + during inactivity periods (includes interrupt activity monitoring). + + 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 is called sc1200wdt.o. If you want to compile it as a + module, say M here and read . Most + people will say N. + SuperH 3/4 Watchdog CONFIG_SH_WDT This driver adds watchdog support for the integrated watchdog in the @@ -17810,6 +18016,17 @@ inserted in and removed from the running kernel whenever you want). The module is called shwdt.o. If you want to compile it as a module, say M here and read Documentation/modules.txt. + +Wafer 5823 Watchdog +CONFIG_WAFER_WDT + This is a driver for the hardware watchdog on the ICP Wafer 5823 + Single Board Computer (and probably other similar models). + + This driver is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + If you want to compile it as a module, say M here and read + . The module will be called + wafer5823wdt.o Machine Check Exception CONFIG_X86_MCE @@ -17817,14 +18034,10 @@ kernel if it detects a problem (e.g. overheating, component failure). The action the kernel takes depends on the severity of the problem, ranging from a warning message on the console, to halting the machine. - Your processor must be a Pentium or newer to support this - check the - flags in /proc/cpuinfo for mce. Note that some older Pentium systems - have a design flaw which leads to false MCE events - hence MCE is - disabled on all P5 processors, unless explicitly enabled with "mce" - as a boot argument. Similarly, if MCE is built in and creates a - problem on some new non-standard machine, you can boot with "nomce" - to disable it. MCE support simply ignores non-MCE processors like - the 386 and 486, so nearly everyone can say Y here. + You can safely select this on machines that do not support this feature. + + For pentium machines the mce support defaults to off as the mainboard + support is not always present. You must activate it as a boot option. Toshiba Laptop support CONFIG_TOSHIBA @@ -17913,6 +18126,28 @@ CPU-1410 cards. These are PC/104 SBCs. Spec sheets and product information are at . +W83877F Watchdog Timer +CONFIG_W83877F_WDT + This is the driver for the hardware watchdog on the W83877F chipset + as used in EMACS PC-104 motherboards (and may work on others). This + watchdog simply watches your kernel to make sure it doesn't freeze, + and if it does, it reboots your computer after a certain amount of + time. + + You can compile this driver directly into the kernel, or use + it as a module. The module will be called w83877f_wdt.o. + +SC520 (AMD Elan) Watchdog Timer +CONFIG_SC520_WDT + This is the driver for the hardware watchdog built in to the + AMD "Elan" SC520 microcomputer commonly used in embedded systems. + This watchdog simply watches your kernel to make sure it doesn't + freeze, and if it does, it reboots your computer after a certain + amount of time. + + You can compile this driver directly into the kernel, or use + it as a module. The module will be called sc520_wdt.o. + Enhanced Real Time Clock Support CONFIG_RTC If you say Y here and create a character special file /dev/rtc with @@ -18407,7 +18642,7 @@ then you can get the persistent DMA buffer functionality by passing the command-line argument "dmabuf=1" to the sound.o module. - Say Y unless you have 16MB or more RAM or a PCI sound card. + Say Y unless you have 16MB or less RAM or a PCI sound card. Support for Aztech Sound Galaxy (non-PnP) cards CONFIG_SOUND_SGALAXY @@ -18583,6 +18818,12 @@ for more info on this driver's capabilities. +NEC Vrc5477 AC97 sound +CONFIG_SOUND_VRC5477 + Say Y here to enable sound support for the NEC Vrc5477 chip, an + integrated, multi-function controller chip for MIPS CPUs. Works + with the AC97 codec. + Ensoniq SoundScape support CONFIG_SOUND_SSCAPE Answer Y if you have a sound card based on the Ensoniq SoundScape @@ -18930,6 +19171,12 @@ driver as a module you have to specify the MPU I/O base address with the parameter 'mpu_base=0xNNN'. +SC-6600 CDROM Interface (4=None, 3=IDE, 1=Panasonic, 0=?Sony?) +CONFIG_SC6600_CDROM + This is used to activate the CD-ROM interface of the Audio Excel + DSP 16 card. Enter: 0 for Sony, 1 for Panasonic, 2 for IDE, 4 for no + CD-ROM present. + C-Media PCI (CMI8338/8378) CONFIG_SOUND_CMPCI Say Y or M if you have a PCI sound card using the CMI8338 @@ -18973,6 +19220,41 @@ This package will among other things help you enable SPDIF out/in/loop/monitor. +Enable legacy FM +CONFIG_SOUND_CMPCI_FM + Say Y here to enable the legacy FM (frequency-modulation) synthesis + support on a card using the CMI8338 or CMI8378 chipset. + +FM I/O 388, 3C8, 3E0, 3E8 +CONFIG_SOUND_CMPCI_FMIO + Set the base I/O address for FM synthesis control on a card using + the CMI8338 or CMI8378 chipset. + +Enable legacy MPU-401 +CONFIG_SOUND_CMPCI_MIDI + Say Y here to enable the legacy MP401 MIDI synthesis support on a + card using the CMI8338 or CMI8378 chipset. + +MPU-401 I/O 330, 320, 310, 300 +CONFIG_SOUND_CMPCI_MPUIO + Set the base I/O address for MP401 MIDI synthesis control on a card + using the CMI8338 or CMI8378 chipset. + +Inverse S/PDIF in for CMI8738 +CONFIG_SOUND_CMPCI_SPDIFINVERSE + Say Y here to have the driver invert the signal presented on SPDIF IN + of a card using the CMI8338 or CMI8378 chipset. + +Use Line-in as Read-out +CONFIG_SOUND_CMPCI_LINE_REAR + Say Y here to enable using line-in jack as an output jack for a rear + speaker. + +Use Line-in as Bass +CONFIG_SOUND_CMPCI_LINE_BASS + Say Y here to enable using line-in jack as an output jack for a bass + speaker. + Creative SBLive! (EMU10K1) based PCI sound cards CONFIG_SOUND_EMU10K1 Say Y or M if you have a PCI sound card using the EMU10K1 chipset, @@ -19178,8 +19460,9 @@ RME Hammerfall (RME96XX) support CONFIG_SOUND_RME96XX - Say Y or M if you have a Hammerfall, Hammerfall light or Hammerfall - DSP card from RME. + Say Y or M if you have a Hammerfall or Hammerfall light multichannel card + from RME. If you want to acess advanced features of the card, read + Documentation/sound/rme96xx. Are you using a crosscompiler CONFIG_CROSSCOMPILE @@ -21919,6 +22202,18 @@ Say Y here to include support for the Iomega Buz video card. There is a Buz/Linux homepage at . +Miro DC10(+) support +CONFIG_VIDEO_ZORAN_DC10 + Say Y to support the Pinnacle Systems Studio DC10 plus TV/Video + card. Linux page at + . Vendor + page at . + +Linux Media Labs LML33 support +CONFIG_VIDEO_ZORAN_LML33 + Say Y here to support the Linux Media Labs LML33 TV/Video card. + Resources page is at . + Zoran ZR36120/36125 Video For Linux CONFIG_VIDEO_ZR36120 Support for ZR36120/ZR36125 based frame grabber/overlay boards. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/Documentation/filesystems/00-INDEX linux.19pre5-ac1/Documentation/filesystems/00-INDEX --- linux.19p5/Documentation/filesystems/00-INDEX Thu Apr 4 13:20:30 2002 +++ linux.19pre5-ac1/Documentation/filesystems/00-INDEX Thu Feb 14 20:46:53 2002 @@ -22,6 +22,8 @@ - info and mount options for the OS/2 HPFS. isofs.txt - info and mount options for the ISO 9660 (CDROM) filesystem. +jfs.txt + - info and mount options for the JFS filesystem. ncpfs.txt - info on Novell Netware(tm) filesystem using NCP protocol. ntfs.txt diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/Documentation/filesystems/changelog.jfs linux.19pre5-ac1/Documentation/filesystems/changelog.jfs --- linux.19p5/Documentation/filesystems/changelog.jfs Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/Documentation/filesystems/changelog.jfs Thu Feb 14 20:46:53 2002 @@ -0,0 +1,191 @@ +IBM's Journaled File System (JFS) for Linux version 1.0.14 +Team members +Steve Best sbest@us.ibm.com +Dave Kleikamp shaggy@austin.ibm.com +Barry Arndt barndt@us.ibm.com +Christoph Hellwig hch@caldera.de + + +Release January 28, 2002 (version 1.0.14) + +This is our fifty-second release of IBM's Enterprise JFS technology port to Linux. +Beta 1 was release 0.1.0 on 12/8/2000, Beta 2 was release 0.2.0 on 3/7/2001, +Beta 3 was release 0.3.0 on 4/30/2001, and release 1.0.0 on 6/28/2001. + +Function and Fixes in drop 52 (1.0.14) + - Fix hang in invalidate_metapages when jfs.o is built as a module + - Fix anon_list removal logic in txLock + +Function and Fixes in drop 51 (1.0.13) + - chmod changes on newly created directories are lost after umount (bug 2535) + - Page locking race fixes + - Improve metapage locking + - Fix timing window. Lock page while metapage is active to avoid page going + away before the metadata is released. (Fixed crash during mount/umount testing) + - Make changes for 2.5.2 kernel + - Fix race condition truncating large files + +Function and Fixes in drop50 (1.0.12) + - Add O_DIRECT support + - Add support for 2.4.17 kernel + - Make sure COMMIT_STALE gets reset before the inode is unlocked. Fixing + this gets rid of XT_GETPAGE errors + - Remove invalid __exit keyword from metapage_exit and txExit. + - fix assert(log->cqueue.head == NULL by waiting longer + +Function and Fixes in drop49 (1.0.11) + - Readdir was not handling multibyte codepages correctly. + - Make mount option parsing more robust. + - Add iocharset mount option. + - Journalling of symlinks incorrect, resulting in logredo failure of -265. + - Add jfsutils information to Changes file + - Improve recoverability of the file system when metadata corruption is detected. + - Fix kernel OOPS when root inode is corrupted + +Function and Fixes in drop48 (1.0.10) + - put inodes later on hash queues + - Fix boundary case in xtTruncate + - When invalidating metadata, try to flush the dirty buffers rather than sync them. + - Add another sanity check to avoid trapping when imap is corrupt + - Fix file truncate while removing large file (assert(cmp == 0)) + - read_cache_page returns ERR_PTR, not NULL on error + - Add dtSearchNode and dtRelocate + - JFS needs to use generic_file_open & generic_file_llseek + - Remove lazyQwait, etc. It created an unnecessary bottleneck in TxBegin. + +Function and Fixes in drop47 (1.0.9) + - Fix data corruption problem when creating files while deleting others. (jitterbug 183) + - Make sure all metadata is written before finalizing the log + - Fix serialization problem in shutdown by setting i_size of directory sooner. (bugzilla #334) + - JFS should quit whining when special files are marked dirty during read-only mount. + - Must always check rc after DT_GETPAGE + - Add diExtendFS + - Removing defconfig form JFS source - not really needed + +Function and Fixes in drop46 (1.0.8) + - Synclist was being built backwards causing logredo to quit too early + - jfs_compat.h needs to include module.h + - uncomment EXPORTS_NO_SYMBOLS in super.c + - Minor code cleanup + - xtree of zero-truncated file not being logged + - Fix logging on file truncate + - remove unused metapage fields + +Function and Fixes in drop45 (1.0.7) + - cleanup remove IS_KIOBUFIO define. + - cleanup remove TRUNC_NO_TOSS define. + - have jFYI's use the name directly from dentry + - Remove nul _ALLOC and _FREE macros and also make spinlocks static. + - cleanup add externs where needed in the header files + - jfs_write_inode is a bad place to call iput. Also limit warnings. + - More truncate cleanup + - Truncate cleanup + - Add missing statics in jfs_metapage.c + - fsync fixes + - Clean up symlink code - use page_symlink_inode_operations + - unicode handling cleanup + - cleanup replace UniChar with wchar_t + - Get rid of CDLL_* macros - use list.h instead + - 2.4.11-prex mount problem Call new_inode instead of get_empty_inode + - use kernel min/max macros + - Add MODULE_LICENSE stub for older kernels + - IA64/gcc3 fixes + - Log Manager fixes, introduce __SLEEP_COND macro + - Mark superblock dirty when some errors detected (forcing fsck to be run). + - More robust remounting from r/o to r/w. + - Misc. cleanup add static where appropriate + - small cleanup in jfs_umount_rw + - add MODULE_ stuff + - Set *dropped_lock in alloc_metapage + - Get rid of unused log list + - cleanup jfs_imap.c to remove _OLD_STUFF and _NO_MORE_MOUNT_INODE defines + - Log manager cleanup + - Transaction manager cleanup + - correct memory allocations flags + - Better handling of iterative truncation + - Change continue to break, otherwise we don't re-acquire LAZY_LOCK + +Function and Fixes in drop44 (1.0.6) + - Create jfs_incore.h which merges linux/jfs_fs.h, linux/jfs_fs_i.h, and jfs_fs_sb.h + - Create a configuration option to handle JFS_DEBUG define + - Fixed a few cases where positive error codes were returned to the VFS. + - Replace jfs_dir_read by generic_read_dir. + - jfs_fsync_inode is only called by jfs_fsync_file, merge the two and rename to jfs_fsync. + - Add a bunch of missing externs. + - jfs_rwlock_lock is unused, nuke it. + - Always use atomic set/test_bit operations to protect jfs_ip->cflag + - Combine jfs_ip->flag with jfs_ip->cflag + - Fixed minor format errors reported by fsck + - cflags should be long so bitops always works correctly + - Use GFP_NOFS for runtime memory allocations + - Support VM changes in 2.4.10 of the kernel + - Remove ifdefs supporting older 2.4 kernels. JFS now requires at least 2.4.3 or 2.4.2-ac2 + - Simplify and remove one use of IWRITE_TRYLOCK + - jfs_truncate was not passing tid to xtTruncate + - removed obsolete extent_page workaround + - correct recovery from failed diAlloc call (disk full) + - In write_metapage, don't call commit_write if prepare_write failed + +Function and Fixes in drop43 (1.0.5) + - Allow separate allocation of JFS-private superblock/inode data. + - Remove checks in namei.c that are already done by the VFS. + - Remove redundant mutex defines. + - Replace all occurrences of #include with #include + - Work around race condition in remount -fixes OOPS during shutdown + - Truncate large files incrementally ( affects directories too) + +Function and Fixes in drop42 (1.0.4) + - Fixed compiler warnings in the FS when building on 64 bits systems + - Fixed deadlock where jfsCommit hung in hold_metapage + - Fixed problems with remount + - Reserve metapages for jfsCommit thread + - Get rid of buggy invalidate_metapage & use discard_metapage + - Don't hand metapages to jfsIOthread (too many context switches) (jitterbug 125, bugzilla 238) + - Fix error message in jfs_strtoUCS + +Function and Fixes in drop41 (1.0.3) + - Patch to move from previous release to latest release needs to update the version number in super.c + - Jitterbug problems (134,140,152) removing files have been fixed + - Set rc=ENOSPC if ialloc fails in jfs_create and jfs_mkdir + - Fixed jfs_txnmgr.c 775! assert + - Fixed jfs_txnmgr.c 884! assert(mp->nohomeok==0) + - Fix hang - prevent tblocks from being exhausted + - Fix oops trying to mount reiserfs + - Fail more gracefully in jfs_imap.c + - Print more information when char2uni fails + - Fix timing problem between Block map and metapage cache - jitterbug 139 + - Code Cleanup (removed many ifdef's, obsolete code, ran code through indent) Mostly 2.4 tree + - Split source tree (Now have a separate source tree for 2.2, 2.4, and jfsutils) + +Function and Fixes in drop40 (1.0.2) + - Fixed multiple truncate hang + - Fixed hang on unlink a file and sync happening at the same time + - Improved handling of kmalloc error conditions + - Fixed hang in blk_get_queue and SMP deadlock: bh_end_io call generic_make_request + (jitterbug 145 and 146) + - stbl was not set correctly set in dtDelete + - changed trap to printk in dbAllocAG to avoid system hang + +Function and Fixes in drop 39 (1.0.1) + - Fixed hang during copying files on 2.2.x series + - Fixed TxLock compile problem + - Fixed to correctly update the number of blocks for directories (this was causing the FS + to show fsck error after compiling mozilla). + - Fixed to prevent old data from being written to disk from the page cache. + +Function and Fixes in drop 38 (1.0.0) + - Fixed some general log problems + +Please send bugs, comments, cards and letters to linuxjfs@us.ibm.com. + +The JFS mailing list can be subscribed to by using the link labeled "Mail list Subscribe" +at our web page http://oss.software.ibm.com/jfs/. + + + + + + + + + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/Documentation/filesystems/jfs.txt linux.19pre5-ac1/Documentation/filesystems/jfs.txt --- linux.19p5/Documentation/filesystems/jfs.txt Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/Documentation/filesystems/jfs.txt Thu Feb 14 20:46:53 2002 @@ -0,0 +1,136 @@ +IBM's Journaled File System (JFS) for Linux version 1.0.14 +Team members +Steve Best sbest@us.ibm.com +Dave Kleikamp shaggy@austin.ibm.com +Barry Arndt barndt@us.ibm.com +Christoph Hellwig hch@caldera.de + + +Release January 28, 2002 (version 1.0.14) + +This is our fifty-second release of IBM's Enterprise JFS technology port to Linux. +Beta 1 was release 0.1.0 on 12/8/2000, Beta 2 was release 0.2.0 on 3/7/2001, +Beta 3 was release 0.3.0 on 4/30/2001, and release 1.0.0 on 6/28/2001. + +The changelog.jfs file contains detailed information of changes done in each source +code drop. + +JFS has a source tree that can be built on 2.4.3 - 2.4.17 and 2.5.2 kernel.org +source trees. + +Our current goal on the 2.5.x series of the kernel is to update to the latest +2.5.x version and only support the latest version of this kernel. +This will change when the distros start shipping the 2.5.x series of the kernel. + +Our current goal on the 2.4.x series of the kernel is to continue to support +all of the kernels in this series as we do today. + +There is a anonymous cvs access available for the JFS tree. The steps below are +what is needed to pull the JFS cvs tree from the oss.software.ibm.com server. + +id anoncvs +password anoncvs + +To checkout 2.4.x series of the JFS files do the following: +CVSROOT should be set to :pserver:anoncvs@oss.software.ibm.com:/usr/cvs/jfs +cvs checkout linux24 + +To checkout 2.5.2 series of the JFS files do the following: +CVSROOT should be set to :pserver:anoncvs@oss.software.ibm.com:/usr/cvs/jfs +cvs checkout linux25 + +To checkout the JFS utilities do the following: +CVSROOT should be set to :pserver:anoncvs@oss.software.ibm.com:/usr/cvs/jfs +cvs checkout jfsutils + +The cvs tree contains the latest changes being done to JFS. To receive notification +of commits to the cvs tree, please send e-mail to linuxjfs@us.ibm.com stating that +you would like notifications sent to you. + +The jfs-2.4-1.0.14-patch.tar.gz is the easiest way to get the latest file system +source code on your system. There are also patch files that can move your jfs source +code from one release to another. If you have release 1.0.13 and would like to move +to release 1.0.14 the patch file named jfs-2.4-1_0_13-to-1_0_14-patch.gz will do that. + +The jfs-2.4-1.0.14-patch.tar.gz file contains a readme and patch files for different +levels of the 2.4 kernel. Please see the README in the jfs-2.4-1.0.14-patch.tar.gz +file for help on applying the two patch files. + + +The following files in the kernel source tree have been changed so JFS can be built. +The jfs-2.4-1.0.14.tar.gz source tar ball contains each of the files below with +the extension of the kernel level it is associated with. As an example, there are now +four Config.in files named Config.in-2.4.0, Config.in-2.4.5, Config.in-2.4.7 and +Config.in-2.4.17. + + +If you use the jfs-2.4-1.0.14.tar.gz to build JFS you must rename each of the +kernel files to the file names listed below. The standard kernel from www.kernel.org +is the source of the kernel files that are included in the jfs tar file. + + +In sub dir fs Config.in, Makefile +In sub dir fs/nls Config.in +In sub dir Documentation Configure.help, Changes +In sub dir Documentation/filesystems 00-INDEX +In sub dir linux MAINTAINERS + +Please backup the above files before the JFS tar file is added to the kernel source +tree. All JFS files are located in the include/linux/jfs or fs/jfs sub dirs. + +Our development team has used the Linux kernel levels 2.4.3 - 2.4.17 kernels +with gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release) +for our port so far. A goal of the JFS team is to have JFS run on all architectures +that Linux supports, there is no architecture specific code in JFS. JFS has been run +on the following architectures (x86, PowerPC, Alpha, s/390, ARM) so far. + +To make JFS build, during the "make config" step of building the kernel answer y to +the Prompt for development and/or incomplete code/drivers in the Code maturity level +options section. In the Filesystems section use the m for the answer to +JFS filesystem support (experimental) (CONFIG_JFS_FS) [Y/m/n?] + + +Build in /usr/src/linux with the command: + + +make modules +make modules_install + +If you rebuild jfs.o after having mounted and unmounted a partition, "modprobe -r jfs" +will unload the old module. + +For the file system debugging messages are being written to /var/log/messages. + +Please see the readme in the utilities package for information about building +the JFS utilities. + +JFS TODO list: + +Plans for our near term development items + + - get defrag capabilities operational in the FS + - get extendfs capabilities operational in the FS + - test EXTENDFS utility, for growing JFS partitions + - test defrag utility, calls file system to defrag the file system. + - add support for block sizes (512,1024,2048) + - add support for logfile on dedicated partition + + +Longer term work items + + - get access control list functionality operational + - get extended attributes functionality operational + - add quota support + +Please send bugs, comments, cards and letters to linuxjfs@us.ibm.com. + +The JFS mailing list can be subscribed to by using the link labeled "Mail list Subscribe" +at our web page http://oss.software.ibm.com/jfs/. + + + + + + + + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/Documentation/sonypi.txt linux.19pre5-ac1/Documentation/sonypi.txt --- linux.19p5/Documentation/sonypi.txt Thu Apr 4 13:20:35 2002 +++ linux.19pre5-ac1/Documentation/sonypi.txt Thu Mar 14 23:00:23 2002 @@ -43,7 +43,7 @@ to /etc/modules.conf file, when the driver is compiled as a module or by adding the following to the kernel command line (in your bootloader): - sonypi=minor[[[[,camera],fnkeyinit],verbose],compat] + sonypi=minor[[[[[,camera],fnkeyinit],verbose],compat],nojogdial] where: @@ -71,6 +71,9 @@ (prior to version 1.5) and does not work anymore, add this option and report to the author. + nojogdial: gives more accurate PKEY events on those Vaio models + which don't have a jogdial (like the FX series). + Module use: ----------- diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/Documentation/video4linux/API.html linux.19pre5-ac1/Documentation/video4linux/API.html --- linux.19p5/Documentation/video4linux/API.html Thu Apr 4 13:20:34 2002 +++ linux.19pre5-ac1/Documentation/video4linux/API.html Tue Feb 26 23:33:41 2002 @@ -105,7 +105,7 @@ heightThe height of the image capture. chromakeyA host order RGB32 value for the chroma key. flagsAdditional capture flags. -clipsA list of clipping rectangles. (Set only) +clipsA list of clipping rectangles. (Set only) clipcountThe number of clipping rectangles. (Set only)

@@ -120,6 +120,7 @@

Merely setting the window does not enable capturing. Overlay capturing +(i.e. PCI-PCI transfer to the frame buffer of the video card) is activated by passing the VIDIOCCAPTURE ioctl a value of 1, and disabled by passing it a value of 0.

@@ -310,9 +311,10 @@

Reading Images

-Each call to the read syscall returns the next available image from -the device. It is up to the caller to set the format and then to pass a -suitable size buffer and length to the function. Not all devices will support +Each call to the read syscall returns the next available image +from the device. It is up to the caller to set format and size (using +the VIDIOCSPICT and VIDIOCSWIN ioctls) and then to pass a suitable +size buffer and length to the function. Not all devices will support read operations.

A second way to handle image capture is via the mmap interface if supported. @@ -329,16 +331,39 @@ offsetsThe offset of each frame

-Once the mmap has been made the VIDIOCMCAPTURE ioctl sets the image size -you wish to use (which should match or be below the initial query size). -Having done so it will begin capturing to the memory mapped buffer. Whenever -a buffer is "used" by the program it should called VIDIOCSYNC to free this -frame up and continue. to add:VIDIOCSYNC takes the frame number -you are freeing as its argument. When the buffer is unmapped or all the -buffers are full capture ceases. While capturing to memory the driver will -make a "best effort" attempt to capture to screen as well if requested. This -normally means all frames that "miss" memory mapped capture will go to the -display. +Once the mmap has been made the VIDIOCMCAPTURE ioctl starts the +capture to a frame using the format and image size specified in the +video_mmap (which should match or be below the initial query size). +When the VIDIOCMCAPTURE ioctl returns the frame is not +captured yet, the driver just instructed the hardware to start the +capture. The application has to use the VIDIOCSYNC ioctl to wait +until the capture of a frame is finished. VIDIOCSYNC takes the frame +number you want to wait for as argument. +

+It is allowed to call VIDIOCMCAPTURE multiple times (with different +frame numbers in video_mmap->frame of course) and thus have multiple +outstanding capture requests. A simple way do to double-buffering +using this feature looks like this: +

+/* setup everything */
+VIDIOCMCAPTURE(0)
+while (whatever) {
+   VIDIOCMCAPTURE(1)
+   VIDIOCSYNC(0)
+   /* process frame 0 while the hardware captures frame 1 */
+   VIDIOCMCAPTURE(0)
+   VIDIOCSYNC(1)
+   /* process frame 1 while the hardware captures frame 0 */
+}
+
+Note that you are not limited to only two frames. The API +allows up to 32 frames, the VIDIOCGMBUF ioctl returns the number of +frames the driver granted. Thus it is possible to build deeper queues +to avoid loosing frames on load peaks. +

+While capturing to memory the driver will make a "best effort" attempt +to capture to screen as well if requested. This normally means all +frames that "miss" memory mapped capture will go to the display.

A final ioctl exists to allow a device to obtain related devices if a driver has multiple components (for example video0 may not be associated diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/Documentation/vm/overcommit-accounting linux.19pre5-ac1/Documentation/vm/overcommit-accounting --- linux.19p5/Documentation/vm/overcommit-accounting Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/Documentation/vm/overcommit-accounting Fri Mar 8 16:59:48 2002 @@ -0,0 +1,73 @@ +* This describes the overcommit management facility in the latest kernel + tree (FIXME: actually it also describes the stuff that isnt yet done) + +The Linux kernel supports four overcommit handling modes + +0 - Heuristic overcommit handling. Obvious overcommits of + address space are refused. Used for a typical system. It + ensures a seriously wild allocation fails while allowing + overcommit to reduce swap usage + +1 - No overcommit handling. Appropriate for some scientific + applications + +2 - (NEW) strict overcommit. The total address space commit + for the system is not permitted to exceed swap + half ram. + In almost all situations this means a process will not be + killed while accessing pages but only by malloc failures + that are reported back by the kernel mmap/brk code. + +3 - (NEW) paranoid overcommit The total address space commit + for the system is not permitted to exceed swap. The machine + will never kill a process accessing pages it has mapped + except due to a bug (ie report it!) + +Gotchas +------- + +The C language stack growth does an implicit mremap. If you want absolute +guarantees and run close to the edge you MUST mmap your stack for the +largest size you think you will need. For typical stack usage is does +not matter much but its a corner case if you really really care + +In modes 2 and 3 the MAP_NORESERVE flag is ignored. + + +How It Works +------------ + +The overcommit is based on the following rules + +For a file backed map + SHARED or READ only - 0 cost (the file is the map not swap) + + WRITABLE SHARED - size of mapping per instance + +For a direct map + SHARED or READ only - size of mapping + PRIVATE WRITEABLE - size of mapping per instance + +Additional accounting + Pages made writable copies by mmap + shmfs memory drawn from the same pool + +Status +------ + +o We account mmap memory mappings +o We account mprotect changes in commit +o We account mremap changes in size +o We account brk +o We account munmap +o We report the commit status in /proc +o Account and check on fork +o Review stack handling/building on exec +o SHMfs accounting +o Implement actual limit enforcement + +To Do +----- +o Account ptrace pages (this is hard) +o Disable MAP_NORESERVE in mode 2/3 +o Account for shared anonymous mappings properly + - right now we account them per instance diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/MAINTAINERS linux.19pre5-ac1/MAINTAINERS --- linux.19p5/MAINTAINERS Thu Apr 4 13:21:10 2002 +++ linux.19pre5-ac1/MAINTAINERS Thu Apr 4 13:27:08 2002 @@ -153,6 +153,14 @@ W: http://www.ibm.com/linux/ltc/ S: Supported +AACRAID SCSI RAID DRIVER +P: Adaptec OEM Raid Solutions +M: linux-aacraid-devel@dell.com +L: linux-aacraid-devel@dell.com +L: linux-aacraid-announce@dell.com +W: http://domsch.com/linux +S: Supported + ACPI P: Andy Grover M: andrew.grover@intel.com @@ -854,6 +862,13 @@ W: http://sources.redhat.com/jffs2/ S: Maintained +JFS FILESYSTEM +P: Dave Kleikamp +M: shaggy@austin.ibm.com +L: jfs-discussion@oss.software.ibm.com +W: http://oss.software.ibm.com/developerworks/opensource/jfs/ +S: Supported + JOYSTICK DRIVER P: Vojtech Pavlik M: vojtech@suse.cz @@ -928,6 +943,11 @@ L: linuxppc-dev@lists.linuxppc.org S: Maintained +LLC (802.2) +P: Arnaldo Carvalho de Melo +M: acme@conectiva.com.br +S: Maintained + LINUX FOR 64BIT POWERPC P: David Engebretsen M: engebret@us.ibm.com @@ -1243,13 +1263,6 @@ L: linux-net@vger.kernel.org S: Maintained -PHILIPS NINO PALM PC -P: Steven Hill -M: sjhill@realitydiluted.com -L: linux-mips@oss.sgi.com -W: http://www.realitydiluted.com/projects/nino -S: Maintained - PERMEDIA 3 FRAMEBUFFER DRIVER P: Romain Dolbeau M: dolbeau@irisa.fr @@ -1257,6 +1270,13 @@ W: http://www.irisa.fr/prive/dolbeau/pm3fb/pm3fb.html S: Maintained +PHILIPS NINO PALM PC +P: Steven Hill +M: sjhill@realitydiluted.com +L: linux-mips@oss.sgi.com +W: http://www.realitydiluted.com/projects/nino +S: Maintained + PNP SUPPORT P: Tom Lees M: tom@lpsg.demon.co.uk @@ -1337,6 +1357,12 @@ L: linux-kernel@vger.kernel.org S: Maintained +RME96XX MULTICHANNEL SOUND DRIVER +P: Guenter Geiger +M: geiger@epy.co.at +L: linux-kernel@vger.kernel.org +S: Maintained + RTLINUX REALTIME LINUX P: Victor Yodaiken M: yodaiken@fsmlabs.com @@ -1364,6 +1390,11 @@ L: linux-kernel@vger.kernel.org S: Maintained +SC1200 WDT DRIVER +P: Zwane Mwaikambo +M: zwane@commfireservices.com +S: Maintained + SCSI CDROM DRIVER P: Jens Axboe M: axboe@suse.de @@ -1395,6 +1426,13 @@ M: mingo@redhat.com S: Maintained +SIS 5513 IDE CONTROLLER DRIVER +P: Lionel Bouton +M: Lionel.Bouton@inet6.fr +W: http://inet6.dyn.dhs.org/sponsoring/sis5513/index.html +W: http://gyver.homeip.net/sis5513/index.html +S: Maintained + SIS 900/7016 FAST ETHERNET DRIVER P: Ollie Lho M: ollie@sis.com.tw @@ -1779,7 +1817,6 @@ VIDEO FOR LINUX P: Gerd Knorr M: kraxel@bytesex.org -W: http://roadrunner.swansea.linux.org.uk/v4l.shtml S: Maintained WAN ROUTER & SANGOMA WANPIPE DRIVERS & API (X.25, FRAME RELAY, PPP, CISCO HDLC) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/Makefile linux.19pre5-ac1/Makefile --- linux.19p5/Makefile Thu Apr 4 13:21:10 2002 +++ linux.19pre5-ac1/Makefile Thu Apr 4 13:27:27 2002 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 19 -EXTRAVERSION = -pre5 +EXTRAVERSION = -pre5-ac1 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) @@ -169,7 +169,7 @@ DRIVERS-$(CONFIG_FC4) += drivers/fc4/fc4.a DRIVERS-$(CONFIG_ALL_PPC) += drivers/macintosh/macintosh.o DRIVERS-$(CONFIG_MAC) += drivers/macintosh/macintosh.o -DRIVERS-$(CONFIG_ISAPNP) += drivers/pnp/pnp.o +DRIVERS-$(CONFIG_PNP) += drivers/pnp/pnp.o DRIVERS-$(CONFIG_SGI_IP22) += drivers/sgi/sgi.a DRIVERS-$(CONFIG_VT) += drivers/video/video.o DRIVERS-$(CONFIG_PARIDE) += drivers/block/paride/paride.a @@ -194,6 +194,7 @@ kernel/ksyms.lst include/linux/compile.h \ vmlinux System.map \ .tmp* \ + scripts/mkconfigs kernel/configs.c kernel/configs.o \ drivers/char/consolemap_deftbl.c drivers/video/promcon_tbl.c \ drivers/char/conmakehash \ drivers/char/drm/*-mod.c \ @@ -233,6 +234,7 @@ include/asm \ .hdepend scripts/mkdep scripts/split-include scripts/docproc \ $(TOPDIR)/include/linux/modversions.h \ + scripts/mkconfigs kernel/configs.c kernel/configs.o \ kernel.spec # directories removed with 'make mrproper' diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/alpha/config.in linux.19pre5-ac1/arch/alpha/config.in --- linux.19p5/arch/alpha/config.in Thu Apr 4 13:21:10 2002 +++ linux.19pre5-ac1/arch/alpha/config.in Sat Mar 9 20:41:03 2002 @@ -421,3 +421,5 @@ fi endmenu + +source lib/Config.in diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/arm/config.in linux.19pre5-ac1/arch/arm/config.in --- linux.19p5/arch/arm/config.in Thu Apr 4 13:21:10 2002 +++ linux.19pre5-ac1/arch/arm/config.in Thu Apr 4 13:28:20 2002 @@ -655,3 +655,5 @@ dep_bool ' Kernel low-level debugging messages via footbridge serial port' CONFIG_DEBUG_DC21285_PORT $CONFIG_DEBUG_LL $CONFIG_FOOTBRIDGE dep_bool ' Kernel low-level debugging messages via UART2' CONFIG_DEBUG_CLPS711X_UART2 $CONFIG_DEBUG_LL $CONFIG_ARCH_CLPS711X endmenu + +source lib/Config.in diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/cris/config.in linux.19pre5-ac1/arch/cris/config.in --- linux.19p5/arch/cris/config.in Thu Apr 4 13:20:26 2002 +++ linux.19pre5-ac1/arch/cris/config.in Sat Mar 9 20:41:04 2002 @@ -253,4 +253,6 @@ if [ "$CONFIG_PROFILE" = "y" ]; then int ' Profile shift count' CONFIG_PROFILE_SHIFT 2 fi + +source lib/Config.in endmenu diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/config.in linux.19pre5-ac1/arch/i386/config.in --- linux.19p5/arch/i386/config.in Thu Apr 4 13:21:10 2002 +++ linux.19pre5-ac1/arch/i386/config.in Wed Mar 20 16:03:57 2002 @@ -270,6 +270,8 @@ tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC +bool 'Kernel .config support' CONFIG_IKCONFIG + bool 'Power Management support' CONFIG_PM if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then @@ -424,6 +426,11 @@ bool ' Memory mapped I/O debugging' CONFIG_DEBUG_IOVIRT bool ' Magic SysRq key' CONFIG_MAGIC_SYSRQ bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK + if [ "$CONFIG_HIGHMEM" = "y" ]; then + bool ' Emulate HIGHMEM on lowmem machines' CONFIG_HIGHMEM_EMULATION + fi fi endmenu + +source lib/Config.in diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/defconfig linux.19pre5-ac1/arch/i386/defconfig --- linux.19p5/arch/i386/defconfig Thu Apr 4 13:21:10 2002 +++ linux.19pre5-ac1/arch/i386/defconfig Wed Mar 20 16:00:34 2002 @@ -31,6 +31,7 @@ # CONFIG_MPENTIUM4 is not set # CONFIG_MK6 is not set # CONFIG_MK7 is not set +# CONFIG_MELAN is not set # CONFIG_MCRUSOE is not set # CONFIG_MWINCHIPC6 is not set # CONFIG_MWINCHIP2 is not set @@ -96,6 +97,8 @@ # CONFIG_HOTPLUG_PCI is not set # CONFIG_HOTPLUG_PCI_COMPAQ is not set # CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +# CONFIG_HOTPLUG_PCI_IBM is not set +# CONFIG_HOTPLUG_PCI_ACPI is not set CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y @@ -104,6 +107,7 @@ CONFIG_BINFMT_AOUT=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=y +# CONFIG_IKCONFIG is not set CONFIG_PM=y # CONFIG_APM is not set @@ -131,6 +135,7 @@ # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_CISS_SCSI_TAPE is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set @@ -154,7 +159,7 @@ # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK is not set +# CONFIG_NETLINK_DEV is not set # CONFIG_NETFILTER is not set # CONFIG_FILTER is not set CONFIG_UNIX=y @@ -205,6 +210,7 @@ # CONFIG_BLK_DEV_HD is not set CONFIG_BLK_DEV_IDEDISK=y CONFIG_IDEDISK_MULTI_MODE=y +# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDEDISK_VENDOR is not set # CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set # CONFIG_BLK_DEV_IDEDISK_IBM is not set @@ -219,6 +225,7 @@ # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set # CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set # # IDE chipset support/bugfixes @@ -230,12 +237,15 @@ CONFIG_BLK_DEV_IDEPCI=y CONFIG_IDEPCI_SHARE_IRQ=y CONFIG_BLK_DEV_IDEDMA_PCI=y -CONFIG_BLK_DEV_ADMA=y # CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_PCI_WIP is not set +# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set # CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set +CONFIG_BLK_DEV_ADMA=y # CONFIG_BLK_DEV_AEC62XX is not set # CONFIG_AEC62XX_TUNING is not set # CONFIG_BLK_DEV_ALI15X3 is not set @@ -243,6 +253,7 @@ # CONFIG_BLK_DEV_AMD74XX is not set # CONFIG_AMD74XX_OVERRIDE is not set # CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_CMD680 is not set # CONFIG_BLK_DEV_CY82C693 is not set # CONFIG_BLK_DEV_CS5530 is not set # CONFIG_BLK_DEV_HPT34X is not set @@ -261,6 +272,7 @@ # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set # CONFIG_IDE_CHIPSETS is not set +# CONFIG_BLK_DEV_ELEVATOR_NOOP is not set CONFIG_IDEDMA_AUTO=y # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set @@ -395,7 +407,6 @@ # CONFIG_HAPPYMEAL is not set # CONFIG_SUNBMAC is not set # CONFIG_SUNQE is not set -# CONFIG_SUNLANCE is not set # CONFIG_SUNGEM is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -412,6 +423,7 @@ # CONFIG_APRICOT is not set # CONFIG_CS89x0 is not set # CONFIG_TULIP is not set +# CONFIG_TC35815 is not set # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set @@ -427,11 +439,13 @@ # CONFIG_8139TOO_PIO is not set # CONFIG_8139TOO_TUNE_TWISTER is not set # CONFIG_8139TOO_8129 is not set +# CONFIG_8139_NEW_RX_RESET is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set +# CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set # CONFIG_NET_POCKET is not set @@ -474,10 +488,10 @@ # CONFIG_PCMCIA_3C574 is not set # CONFIG_PCMCIA_FMVJ18X is not set CONFIG_PCMCIA_PCNET=y +# CONFIG_PCMCIA_AXNET is not set # CONFIG_PCMCIA_NMCLAN is not set # CONFIG_PCMCIA_SMC91C92 is not set # CONFIG_PCMCIA_XIRC2PS is not set -# CONFIG_PCMCIA_AXNET is not set # CONFIG_ARCNET_COM20020_CS is not set # CONFIG_PCMCIA_IBMTR is not set # CONFIG_PCMCIA_XIRCOM is not set @@ -497,9 +511,6 @@ # IrDA (infrared) support # # CONFIG_IRDA is not set -CONFIG_IRDA_CACHE_LAST_LSAP=y -CONFIG_IRDA_FAST_RR=y -CONFIG_IRDA_DEBUG=y # # ISDN subsystem @@ -545,6 +556,7 @@ CONFIG_PSMOUSE=y # CONFIG_82C710_MOUSE is not set # CONFIG_PC110_PAD is not set +# CONFIG_MK712_MOUSE is not set # # Joysticks @@ -564,7 +576,9 @@ # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_AMD_RNG is not set # CONFIG_INTEL_RNG is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set # CONFIG_DTLK is not set @@ -584,18 +598,24 @@ CONFIG_AGP_ALI=y # CONFIG_AGP_SWORKS is not set CONFIG_DRM=y +# CONFIG_DRM_OLD is not set + +# +# DRM 4.1 drivers +# +CONFIG_DRM_NEW=y CONFIG_DRM_TDFX=y -# CONFIG_DRM_GAMMA is not set # CONFIG_DRM_R128 is not set CONFIG_DRM_RADEON=y # CONFIG_DRM_I810 is not set +# CONFIG_DRM_I830 is not set # CONFIG_DRM_MGA is not set +# CONFIG_DRM_SIS is not set # # PCMCIA character devices # # CONFIG_PCMCIA_SERIAL_CS is not set -# CONFIG_MWAVE is not set # # Multimedia devices @@ -632,6 +652,9 @@ CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set # CONFIG_MINIX_FS is not set # CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set @@ -675,7 +698,6 @@ # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set # CONFIG_ZISOFS_FS is not set -# CONFIG_ZLIB_FS_INFLATE is not set # # Partition Types @@ -731,8 +753,9 @@ # CONFIG_USB_LONG_TIMEOUT is not set # -# USB Controllers +# USB Host Controller Drivers # +# CONFIG_USB_EHCI_HCD is not set CONFIG_USB_UHCI_ALT=y # CONFIG_USB_OHCI is not set @@ -740,6 +763,7 @@ # USB Device Class drivers # # CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set # CONFIG_USB_BLUETOOTH is not set CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set @@ -803,6 +827,7 @@ # CONFIG_USB_SERIAL_EMPEG is not set # CONFIG_USB_SERIAL_FTDI_SIO is not set # CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set # CONFIG_USB_SERIAL_IR is not set # CONFIG_USB_SERIAL_EDGEPORT is not set # CONFIG_USB_SERIAL_KEYSPAN_PDA is not set @@ -816,6 +841,7 @@ # CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set # CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set # CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_KLSI is not set # CONFIG_USB_SERIAL_PL2303 is not set # CONFIG_USB_SERIAL_CYBERJACK is not set # CONFIG_USB_SERIAL_XIRCOM is not set @@ -825,8 +851,15 @@ # USB Miscellaneous drivers # # CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set # # Kernel hacking # # CONFIG_DEBUG_KERNEL is not set + +# +# Library routines +# +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/apic.c linux.19pre5-ac1/arch/i386/kernel/apic.c --- linux.19p5/arch/i386/kernel/apic.c Thu Apr 4 13:19:53 2002 +++ linux.19pre5-ac1/arch/i386/kernel/apic.c Tue Mar 19 19:23:37 2002 @@ -582,12 +582,17 @@ * Detect and enable local APICs on non-SMP boards. * Original code written by Keir Fraser. */ +int dont_enable_local_apic __initdata = 0; static int __init detect_init_APIC (void) { u32 h, l, features; extern void get_cpu_vendor(struct cpuinfo_x86*); + /* Disabled by DMI scan or kernel option? */ + if (dont_enable_local_apic) + return -1; + /* Workaround for us being called before identify_cpu(). */ get_cpu_vendor(&boot_cpu_data); @@ -796,8 +801,7 @@ */ slice = clocks / (smp_num_cpus+1); - printk("cpu: %d, clocks: %d, slice: %d\n", - smp_processor_id(), clocks, slice); + printk("cpu: %d, clocks: %d, slice: %d\n", smp_processor_id(), clocks, slice); /* * Wait for IRQ0's slice: @@ -820,8 +824,7 @@ __setup_APIC_LVTT(clocks); - printk("CPU%d\n", - smp_processor_id(), t0, t1, delta, slice, clocks); + printk("CPU%d\n", smp_processor_id(), t0, t1, delta, slice, clocks); __restore_flags(flags); } @@ -905,8 +908,14 @@ static unsigned int calibration_result; +int dont_use_local_apic_timer __initdata = 0; + void __init setup_APIC_clocks (void) { + /* Disabled by DMI scan or kernel option? */ + if (dont_use_local_apic_timer) + return; + printk("Using local APIC timer interrupts.\n"); using_apic_timer = 1; @@ -924,6 +933,26 @@ smp_call_function(setup_APIC_timer, (void *)calibration_result, 1, 1); } +void __init disable_APIC_timer(void) +{ + if (using_apic_timer) { + unsigned long v; + + v = apic_read(APIC_LVTT); + apic_write_around(APIC_LVTT, v | APIC_LVT_MASKED); + } +} + +void enable_APIC_timer(void) +{ + if (using_apic_timer) { + unsigned long v; + + v = apic_read(APIC_LVTT); + apic_write_around(APIC_LVTT, v & ~APIC_LVT_MASKED); + } +} + /* * the frequency of the profiling timer can be changed * by writing a multiplier value into /proc/profile. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/dmi_scan.c linux.19pre5-ac1/arch/i386/kernel/dmi_scan.c --- linux.19p5/arch/i386/kernel/dmi_scan.c Thu Apr 4 13:21:10 2002 +++ linux.19pre5-ac1/arch/i386/kernel/dmi_scan.c Tue Mar 26 18:50:15 2002 @@ -293,6 +293,62 @@ return 0; } +/* + * Some machines, usually laptops, can't handle an enabled local APIC. + * The symptoms include hangs or reboots when suspending or resuming, + * attaching or detaching the power cord, or entering BIOS setup screens + * through magic key sequences. + */ +static int __init local_apic_kills_bios(struct dmi_blacklist *d) +{ +#ifdef CONFIG_X86_LOCAL_APIC + extern int dont_enable_local_apic; + if (!dont_enable_local_apic) { + dont_enable_local_apic = 1; + printk(KERN_WARNING "%s with broken BIOS detected. " + "Refusing to enable the local APIC.\n", + d->ident); + } +#endif + return 0; +} + +/* + * The Microstar 6163-2 (a.k.a Pro) mainboard will hang shortly after + * resumes, and also at what appears to be asynchronous APM events, + * if the local APIC is enabled. + */ +static int __init apm_kills_local_apic(struct dmi_blacklist *d) +{ +#ifdef CONFIG_X86_LOCAL_APIC + extern int dont_enable_local_apic; + if (apm_info.bios.version && !dont_enable_local_apic) { + dont_enable_local_apic = 1; + printk(KERN_WARNING "%s with broken BIOS detected. " + "Refusing to enable the local APIC.\n", + d->ident); + } +#endif + return 0; +} + +/* + * The Intel AL440LX mainboard will hang randomly if the local APIC + * timer is running and the APM BIOS hasn't been disabled. + */ +static int __init apm_kills_local_apic_timer(struct dmi_blacklist *d) +{ +#ifdef CONFIG_X86_LOCAL_APIC + extern int dont_use_local_apic_timer; + if (apm_info.bios.version && !dont_use_local_apic_timer) { + dont_use_local_apic_timer = 1; + printk(KERN_WARNING "%s with broken BIOS detected. " + "The local APIC timer will not be used.\n", + d->ident); + } +#endif + return 0; +} /* * Check for clue free BIOS implementations who use @@ -415,6 +471,22 @@ return 0; } +/* + * Work around broken HP Pavilion Notebooks which assign USB to + * IRQ 9 even though it is actually wired to IRQ 11 + */ +static __init int fix_broken_hp_bios_irq9(struct dmi_blacklist *d) +{ +#ifdef CONFIG_PCI + extern int broken_hp_bios_irq9; + if (broken_hp_bios_irq9 == 0) + { + broken_hp_bios_irq9 = 1; + printk(KERN_INFO "%s detected - fixing broken IRQ routing\n", d->ident); + } +#endif + return 0; +} /* * Simple "print if true" callback @@ -551,6 +623,12 @@ MATCH(DMI_BIOS_DATE, "08/11/00"), NO_MATCH } }, + { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-Z600LEK(DE) */ + MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), + MATCH(DMI_BIOS_VERSION, "R0206Z3"), + MATCH(DMI_BIOS_DATE, "12/25/00"), NO_MATCH + } }, + { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-Z505LS */ MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), MATCH(DMI_BIOS_VERSION, "R0203D0"), @@ -580,6 +658,36 @@ MATCH(DMI_BIOS_DATE, "09/12/00"), NO_MATCH } }, + /* Machines which have problems handling enabled local APICs */ + + { local_apic_kills_bios, "Dell Inspiron", { + MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), + MATCH(DMI_PRODUCT_NAME, "Inspiron"), + NO_MATCH, NO_MATCH + } }, + + { local_apic_kills_bios, "Dell Latitude", { + MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), + MATCH(DMI_PRODUCT_NAME, "Latitude"), + NO_MATCH, NO_MATCH + } }, + + { local_apic_kills_bios, "IBM Thinkpad T20", { + MATCH(DMI_BOARD_VENDOR, "IBM"), + MATCH(DMI_BOARD_NAME, "264741U"), + NO_MATCH, NO_MATCH + } }, + + { apm_kills_local_apic, "Microstar 6163", { + MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), + MATCH(DMI_BOARD_NAME, "MS-6163"), + NO_MATCH, NO_MATCH } }, + + { apm_kills_local_apic_timer, "Intel AL440LX", { + MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), + MATCH(DMI_BOARD_NAME, "AL440LX"), + NO_MATCH, NO_MATCH } }, + /* Problem Intel 440GX bioses */ { broken_pirq, "SABR1 Bios", { /* Bad $PIR */ @@ -636,7 +744,14 @@ NO_MATCH, NO_MATCH } }, - + { fix_broken_hp_bios_irq9, "HP Pavilion N5400 Series Laptop", { + MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + MATCH(DMI_BIOS_VERSION, "GE.M1.03"), + MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook Model GE"), + MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736") + } }, + + /* * Generic per vendor APM settings */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/entry.S linux.19pre5-ac1/arch/i386/kernel/entry.S --- linux.19p5/arch/i386/kernel/entry.S Thu Apr 4 13:21:10 2002 +++ linux.19pre5-ac1/arch/i386/kernel/entry.S Thu Mar 14 22:04:33 2002 @@ -77,7 +77,7 @@ exec_domain = 16 need_resched = 20 tsk_ptrace = 24 -processor = 52 +cpu = 32 ENOSYS = 38 @@ -176,9 +176,11 @@ ENTRY(ret_from_fork) +#if CONFIG_SMP pushl %ebx call SYMBOL_NAME(schedule_tail) addl $4, %esp +#endif GET_CURRENT(%ebx) testb $0x02,tsk_ptrace(%ebx) # PT_TRACESYS jne tracesys_exit diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/head.S linux.19pre5-ac1/arch/i386/kernel/head.S --- linux.19p5/arch/i386/kernel/head.S Thu Apr 4 13:21:10 2002 +++ linux.19pre5-ac1/arch/i386/kernel/head.S Thu Mar 14 22:45:03 2002 @@ -445,4 +445,15 @@ .quad 0x00409a0000000000 /* 0x48 APM CS code */ .quad 0x00009a0000000000 /* 0x50 APM CS 16 code (16 bit) */ .quad 0x0040920000000000 /* 0x58 APM DS data */ + /* Segments used for calling PnP BIOS */ + .quad 0x00c09a0000000000 /* 0x60 32-bit code */ + .quad 0x00809a0000000000 /* 0x68 16-bit code */ + .quad 0x0080920000000000 /* 0x70 16-bit data */ + .quad 0x0080920000000000 /* 0x78 16-bit data */ + .quad 0x0080920000000000 /* 0x80 16-bit data */ + .quad 0x0000000000000000 /* 0x88 not used */ + .quad 0x0000000000000000 /* 0x90 not used */ + .quad 0x0000000000000000 /* 0x98 not used */ + /* Per CPU segments */ .fill NR_CPUS*4,8,0 /* space for TSS's and LDT's */ + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/i8259.c linux.19pre5-ac1/arch/i386/kernel/i8259.c --- linux.19p5/arch/i386/kernel/i8259.c Thu Apr 4 13:19:53 2002 +++ linux.19pre5-ac1/arch/i386/kernel/i8259.c Wed Feb 27 18:32:03 2002 @@ -79,6 +79,7 @@ * through the ICC by us (IPIs) */ #ifdef CONFIG_SMP +BUILD_SMP_INTERRUPT(task_migration_interrupt,TASK_MIGRATION_VECTOR) BUILD_SMP_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) BUILD_SMP_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR) BUILD_SMP_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) @@ -473,6 +474,9 @@ */ set_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt); + /* IPI for task migration */ + set_intr_gate(TASK_MIGRATION_VECTOR, task_migration_interrupt); + /* IPI for invalidation */ set_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/mpparse.c linux.19pre5-ac1/arch/i386/kernel/mpparse.c --- linux.19p5/arch/i386/kernel/mpparse.c Thu Apr 4 13:21:10 2002 +++ linux.19pre5-ac1/arch/i386/kernel/mpparse.c Thu Mar 21 00:36:42 2002 @@ -35,18 +35,20 @@ * MP-table. */ int apic_version [MAX_APICS]; -int mp_bus_id_to_type [MAX_MP_BUSSES]; -int mp_bus_id_to_node [MAX_MP_BUSSES]; -int mp_bus_id_to_local [MAX_MP_BUSSES]; int quad_local_to_mp_bus_id [NR_CPUS/4][4]; -int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 }; int mp_current_pci_id; +int *mp_bus_id_to_type; +int *mp_bus_id_to_node; +int *mp_bus_id_to_local; +int *mp_bus_id_to_pci_bus; +int max_mp_busses; +int max_irq_sources; /* I/O APIC entries */ struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS]; /* # of MP IRQ source entries */ -struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; +struct mpc_config_intsrc *mp_irqs; /* MP IRQ source entries */ int mp_irq_entries; @@ -221,6 +223,7 @@ if (m->mpc_apicid > MAX_APICS) { printk("Processor #%d INVALID. (Max ID: %d).\n", m->mpc_apicid, MAX_APICS); + --num_processors; return; } ver = m->mpc_apicver; @@ -302,7 +305,7 @@ m->mpc_irqtype, m->mpc_irqflag & 3, (m->mpc_irqflag >> 2) & 3, m->mpc_srcbus, m->mpc_srcbusirq, m->mpc_dstapic, m->mpc_dstirq); - if (++mp_irq_entries == MAX_IRQ_SOURCES) + if (++mp_irq_entries == max_irq_sources) panic("Max # of irq sources exceeded!!\n"); } @@ -395,6 +398,9 @@ char str[16]; int count=sizeof(*mpc); unsigned char *mpt=((unsigned char *)mpc)+count; + int num_bus = 0; + int num_irq = 0; + unsigned char *bus_data; if (memcmp(mpc->mpc_signature,MPC_SIGNATURE,4)) { panic("SMP mptable: bad signature [%c%c%c%c]!\n", @@ -440,9 +446,70 @@ mpc_record = 0; } + /* Pre-scan to determine the number of bus and + * interrupts records we have + */ + while (count < mpc->mpc_length) { + switch (*mpt) { + case MP_PROCESSOR: + mpt += sizeof(struct mpc_config_processor); + count += sizeof(struct mpc_config_processor); + break; + case MP_BUS: + ++num_bus; + mpt += sizeof(struct mpc_config_bus); + count += sizeof(struct mpc_config_bus); + break; + case MP_INTSRC: + ++num_irq; + mpt += sizeof(struct mpc_config_intsrc); + count += sizeof(struct mpc_config_intsrc); + break; + case MP_IOAPIC: + mpt += sizeof(struct mpc_config_ioapic); + count += sizeof(struct mpc_config_ioapic); + break; + case MP_LINTSRC: + mpt += sizeof(struct mpc_config_lintsrc); + count += sizeof(struct mpc_config_lintsrc); + break; + default: + count = mpc->mpc_length; + break; + } + } + /* + * Paranoia: Allocate one extra of both the number of busses and number + * of irqs, and make sure that we have at least 4 interrupts per PCI + * slot. But some machines do not report very many busses, so we need + * to fall back on the older defaults. + */ + ++num_bus; + max_mp_busses = max(num_bus, MAX_MP_BUSSES); + if (num_irq < (4 * max_mp_busses)) + num_irq = 4 * num_bus; /* 4 intr/PCI slot */ + ++num_irq; + max_irq_sources = max(num_irq, MAX_IRQ_SOURCES); + + count = (max_mp_busses * sizeof(int)) * 4; + count += (max_irq_sources * sizeof(struct mpc_config_intsrc)); + bus_data = alloc_bootmem(count); + if (!bus_data) { + printk(KERN_ERR "SMP mptable: out of memory!\n"); + return 0; + } + mp_bus_id_to_type = (int *)&bus_data[0]; + mp_bus_id_to_node = (int *)&bus_data[(max_mp_busses * sizeof(int))]; + mp_bus_id_to_local = (int *)&bus_data[(max_mp_busses * sizeof(int)) * 2]; + mp_bus_id_to_pci_bus = (int *)&bus_data[(max_mp_busses * sizeof(int)) * 3]; + mp_irqs = (struct mpc_config_intsrc *)&bus_data[(max_mp_busses * sizeof(int)) * 4]; + memset(mp_bus_id_to_pci_bus, -1, max_mp_busses); + /* * Now process the configuration blocks. */ + count = sizeof(*mpc); + mpt = ((unsigned char *)mpc)+count; while (count < mpc->mpc_length) { switch(*mpt) { case MP_PROCESSOR: diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/pci-irq.c linux.19pre5-ac1/arch/i386/kernel/pci-irq.c --- linux.19p5/arch/i386/kernel/pci-irq.c Thu Apr 4 13:21:10 2002 +++ linux.19pre5-ac1/arch/i386/kernel/pci-irq.c Fri Mar 15 22:17:58 2002 @@ -22,6 +22,8 @@ #define PIRQ_SIGNATURE (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24)) #define PIRQ_VERSION 0x0100 +int broken_hp_bios_irq9; + static struct irq_routing_table *pirq_table; /* @@ -585,6 +587,15 @@ DBG(" -> PIRQ %02x, mask %04x, excl %04x", pirq, mask, pirq_table->exclusive_irqs); mask &= pcibios_irq_mask; + /* Work around broken HP Pavilion Notebooks which assign USB to + IRQ 9 even though it is actually wired to IRQ 11 */ + + if (broken_hp_bios_irq9 && pirq == 0x59 && dev->irq == 9) { + dev->irq = 11; + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11); + r->set(pirq_router_dev, dev, pirq, 11); + } + /* * Find the best IRQ to assign: use the one * reported by the device if possible. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/process.c linux.19pre5-ac1/arch/i386/kernel/process.c --- linux.19p5/arch/i386/kernel/process.c Thu Apr 4 13:19:53 2002 +++ linux.19pre5-ac1/arch/i386/kernel/process.c Wed Feb 27 18:32:03 2002 @@ -124,15 +124,12 @@ void cpu_idle (void) { /* endless idle loop with no priority at all */ - init_idle(); - current->nice = 20; - current->counter = -100; while (1) { void (*idle)(void) = pm_idle; if (!idle) idle = default_idle; - while (!current->need_resched) + if (!current->need_resched) idle(); schedule(); check_pgt_cache(); @@ -697,15 +694,17 @@ asm volatile("movl %%gs,%0":"=m" (*(int *)&prev->gs)); /* - * Restore %fs and %gs. + * Restore %fs and %gs if needed. */ - loadsegment(fs, next->fs); - loadsegment(gs, next->gs); + if (unlikely(prev->fs | prev->gs | next->fs | next->gs)) { + loadsegment(fs, next->fs); + loadsegment(gs, next->gs); + } /* * Now maybe reload the debug registers */ - if (next->debugreg[7]){ + if (unlikely(next->debugreg[7])) { loaddebug(next, 0); loaddebug(next, 1); loaddebug(next, 2); @@ -715,7 +714,7 @@ loaddebug(next, 7); } - if (prev->ioperm || next->ioperm) { + if (unlikely(prev->ioperm || next->ioperm)) { if (next->ioperm) { /* * 4 cachelines copy ... not good, but not that diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/setup.c linux.19pre5-ac1/arch/i386/kernel/setup.c --- linux.19p5/arch/i386/kernel/setup.c Thu Apr 4 13:21:10 2002 +++ linux.19pre5-ac1/arch/i386/kernel/setup.c Tue Mar 19 19:23:37 2002 @@ -832,7 +832,20 @@ /* * Reserved space for vmalloc and iomap - defined in asm/page.h */ +#ifdef CONFIG_HIGHMEM_EMULATION +#define ORDER_DOWN(x) ((x >> (MAX_ORDER-1)) << (MAX_ORDER-1)) +#define MAXMEM_PFN \ +({ \ + int __max_pfn; \ + if (max_pfn > PFN_DOWN(MAXMEM)) \ + __max_pfn = PFN_DOWN(MAXMEM); \ + else \ + __max_pfn = ORDER_DOWN(max_pfn / 5); \ + __max_pfn; \ +}) +#else #define MAXMEM_PFN PFN_DOWN(MAXMEM) +#endif #define MAX_NONPAE_PFN (1 << 20) /* @@ -978,6 +991,10 @@ } #endif + if (test_bit(X86_FEATURE_HT, &boot_cpu_data.x86_capability[0])) + enable_acpi_smp_table = 1; + + /* * NOTE: before this point _nobody_ is allowed to allocate * any memory using the bootmem allocator. @@ -993,7 +1010,6 @@ */ if (smp_found_config) get_smp_config(); - init_apic_mappings(); #endif @@ -2936,9 +2952,10 @@ load_TR(nr); load_LDT(&init_mm); - /* - * Clear all 6 debug registers: - */ + /* Clear %fs and %gs. */ + asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs"); + + /* Clear all 6 debug registers: */ #define CD(register) __asm__("movl %0,%%db" #register ::"r"(0) ); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/smp.c linux.19pre5-ac1/arch/i386/kernel/smp.c --- linux.19p5/arch/i386/kernel/smp.c Thu Apr 4 13:19:53 2002 +++ linux.19pre5-ac1/arch/i386/kernel/smp.c Wed Feb 27 18:32:03 2002 @@ -105,7 +105,7 @@ /* The 'big kernel lock' */ spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED; -struct tlb_state cpu_tlbstate[NR_CPUS] = {[0 ... NR_CPUS-1] = { &init_mm, 0 }}; +struct tlb_state cpu_tlbstate[NR_CPUS] __cacheline_aligned = {[0 ... NR_CPUS-1] = { &init_mm, 0, }}; /* * the following functions deal with sending IPIs between CPUs. @@ -485,18 +485,57 @@ do_flush_tlb_all_local(); } +static spinlock_t migration_lock = SPIN_LOCK_UNLOCKED; +static task_t *new_task; + +/* + * This function sends a 'task migration' IPI to another CPU. + * Must be called from syscall contexts, with interrupts *enabled*. + */ +void smp_migrate_task(int cpu, task_t *p) +{ + /* + * The target CPU will unlock the migration spinlock: + */ + spin_lock(&migration_lock); + new_task = p; + send_IPI_mask(1 << cpu, TASK_MIGRATION_VECTOR); +} + +/* + * Task migration callback. + */ +asmlinkage void smp_task_migration_interrupt(void) +{ + task_t *p; + + ack_APIC_irq(); + p = new_task; + spin_unlock(&migration_lock); + sched_task_migrated(p); +} /* * this function sends a 'reschedule' IPI to another CPU. * it goes straight through and wastes no time serializing * anything. Worst case is that we lose a reschedule ... */ - void smp_send_reschedule(int cpu) { send_IPI_mask(1 << cpu, RESCHEDULE_VECTOR); } /* + * this function sends a reschedule IPI to all (other) CPUs. + * This should only be used if some 'global' task became runnable, + * such as a RT task, that must be handled now. The first CPU + * that manages to grab the task will run it. + */ +void smp_send_reschedule_all(void) +{ + send_IPI_allbutself(RESCHEDULE_VECTOR); +} + +/* * Structure and data for smp_call_function(). This is designed to minimise * static memory requirements. It also looks cleaner. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/smpboot.c linux.19pre5-ac1/arch/i386/kernel/smpboot.c --- linux.19p5/arch/i386/kernel/smpboot.c Thu Apr 4 13:21:10 2002 +++ linux.19pre5-ac1/arch/i386/kernel/smpboot.c Fri Mar 1 18:42:44 2002 @@ -308,14 +308,14 @@ if (tsc_values[i] < avg) realdelta = -realdelta; - printk("BIOS BUG: CPU#%d improperly initialized, has %ld usecs TSC skew! FIXED.\n", - i, realdelta); + printk("BIOS BUG: CPU#%d improperly initialized, has %ld usecs TSC skew! FIXED.\n", i, realdelta); } sum += delta; } if (!buggy) printk("passed.\n"); + ; } static void __init synchronize_tsc_ap (void) @@ -365,7 +365,7 @@ * (This works even if the APIC is not enabled.) */ phys_id = GET_APIC_ID(apic_read(APIC_ID)); - cpuid = current->processor; + cpuid = cpu(); if (test_and_set_bit(cpuid, &cpu_online_map)) { printk("huh, phys CPU#%d, CPU#%d already present??\n", phys_id, cpuid); @@ -435,6 +435,7 @@ */ smp_store_cpu_info(cpuid); + disable_APIC_timer(); /* * Allow the master to continue. */ @@ -465,6 +466,7 @@ smp_callin(); while (!atomic_read(&smp_commenced)) rep_nop(); + enable_APIC_timer(); /* * low-memory mappings have been cleared, flush them from * the local TLBs too. @@ -803,16 +805,13 @@ if (!idle) panic("No idle process for CPU %d", cpu); - idle->processor = cpu; - idle->cpus_runnable = 1 << cpu; /* we schedule the first task manually */ + init_idle(idle, cpu); map_cpu_to_boot_apicid(cpu, apicid); idle->thread.eip = (unsigned long) start_secondary; - del_from_runqueue(idle); unhash_process(idle); - init_tasks[cpu] = idle; /* start_eip had better be page-aligned! */ start_eip = setup_trampoline(); @@ -925,6 +924,7 @@ } cycles_t cacheflush_time; +unsigned long cache_decay_ticks; static void smp_tune_scheduling (void) { @@ -958,9 +958,13 @@ cacheflush_time = (cpu_khz>>10) * (cachesize<<10) / bandwidth; } + cache_decay_ticks = (long)cacheflush_time/cpu_khz * HZ / 1000; + printk("per-CPU timeslice cutoff: %ld.%02ld usecs.\n", (long)cacheflush_time/(cpu_khz/1000), ((long)cacheflush_time*100/(cpu_khz/1000)) % 100); + printk("task migration cache decay timeout: %ld msecs.\n", + (cache_decay_ticks + 1) * 1000 / HZ); } /* @@ -1023,8 +1027,7 @@ map_cpu_to_boot_apicid(0, boot_cpu_apicid); global_irq_holder = 0; - current->processor = 0; - init_idle(); + current->cpu = 0; smp_tune_scheduling(); /* diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/traps.c linux.19pre5-ac1/arch/i386/kernel/traps.c --- linux.19p5/arch/i386/kernel/traps.c Thu Apr 4 13:21:10 2002 +++ linux.19pre5-ac1/arch/i386/kernel/traps.c Fri Mar 29 16:17:33 2002 @@ -276,6 +276,20 @@ void die(const char * str, struct pt_regs * regs, long err) { +#ifdef CONFIG_PNPBIOS + if (regs->xcs == 0x60 || regs->xcs == 0x68) + { + extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp; + extern u32 pnp_bios_is_utter_crap; + pnp_bios_is_utter_crap = 1; + printk(KERN_CRIT "PNPBIOS fault.. attempting recovery.\n"); + __asm__ volatile( + "movl %0, %%esp\n\t" + "jmp %1\n\t" + : "=a" (pnp_bios_fault_esp), "=b" (pnp_bios_fault_eip)); + panic("do_trap: can't hit this"); + } +#endif console_verbose(); spin_lock_irq(&die_lock); bust_spinlocks(1); @@ -305,8 +319,13 @@ static void inline do_trap(int trapnr, int signr, char *str, int vm86, struct pt_regs * regs, long error_code, siginfo_t *info) { - if (vm86 && regs->eflags & VM_MASK) - goto vm86_trap; + if (regs->eflags & VM_MASK) { + if (vm86) + goto vm86_trap; + else + goto trap_signal; + } + if (!(regs->xcs & 3)) goto kernel_trap; @@ -514,10 +533,15 @@ { unsigned int condition; struct task_struct *tsk = current; + unsigned long eip = regs->eip; siginfo_t info; __asm__ __volatile__("movl %%db6,%0" : "=r" (condition)); + /* If the user set TF, it's simplest to clear it right away. */ + if ((eip >=PAGE_OFFSET) && (regs->eflags & TF_MASK)) + goto clear_TF; + /* Mask out spurious debug traps due to lazy DR7 setting */ if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) { if (!tsk->thread.debugreg[7]) @@ -958,6 +982,10 @@ EISA_bus = 1; #endif +#ifdef CONFIG_X86_LOCAL_APIC + init_apic_mappings(); +#endif + set_trap_gate(0,÷_error); set_trap_gate(1,&debug); set_intr_gate(2,&nmi); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/vm86.c linux.19pre5-ac1/arch/i386/kernel/vm86.c --- linux.19p5/arch/i386/kernel/vm86.c Thu Apr 4 13:19:53 2002 +++ linux.19pre5-ac1/arch/i386/kernel/vm86.c Tue Mar 26 18:30:14 2002 @@ -3,6 +3,13 @@ * * Copyright (C) 1994 Linus Torvalds */ + +/* + * Bugfixes Copyright 2002 by Manfred Spraul and + * Kasper Dupont + * + */ + #include #include #include @@ -290,12 +297,25 @@ regs->eflags &= ~TF_MASK; } +/* It is correct to call set_IF(regs) from the set_vflags_* + * functions. However someone forgot to call clear_IF(regs) + * in the opposite case. + * After the command sequence CLI PUSHF STI POPF you should + * end up with interrups disabled, but you ended up with + * interrupts enabled. + * ( I was testing my own changes, but the only bug I + * could find was in a function I had not changed. ) + * [KD] + */ + static inline void set_vflags_long(unsigned long eflags, struct kernel_vm86_regs * regs) { set_flags(VEFLAGS, eflags, current->thread.v86mask); set_flags(regs->eflags, eflags, SAFE_MASK); if (eflags & IF_MASK) set_IF(regs); + else + clear_IF(regs); } static inline void set_vflags_short(unsigned short flags, struct kernel_vm86_regs * regs) @@ -304,6 +324,8 @@ set_flags(regs->eflags, flags, SAFE_MASK); if (flags & IF_MASK) set_IF(regs); + else + clear_IF(regs); } static inline unsigned long get_vflags(struct kernel_vm86_regs * regs) @@ -327,75 +349,184 @@ * Boy are these ugly, but we need to do the correct 16-bit arithmetic. * Gcc makes a mess of it, so we do it inline and use non-obvious calling * conventions.. + * FIXME: is VM86_UNKNOWN really the correct return code? [MS??] + * No that wasn't correct, it depends on the context, so lets + * make it an argument to the macro. [KD] + */ +#define pushb(base, ptr, val, regs, errcode) \ + do { \ + int err; \ + __asm__ __volatile__( \ + "decw %w0\n\t" \ + "1: movb %3,0(%2,%0)\n\t" \ + "xor %1,%1\n\t" \ + "2:\n" \ + ".section .fixup,\"ax\"\n\t" \ + "3: movl $1,%1\n\t" \ + " jmp 2b\n\t" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,3b\n" \ + ".previous" \ + : "=r" (ptr), "=r" (err) \ + : "r" (base), "q" (val), "0" (ptr)); \ + if (err) \ + return_to_32bit(regs, errcode); \ + } while(0) + +#define pushw(base, ptr, val, regs, errcode) \ + do { \ + int err; \ + __asm__ __volatile__( \ + "decw %w0\n\t" \ + "1: movb %h3,0(%2,%0)\n\t" \ + "decw %w0\n\t" \ + "2: movb %b3,0(%2,%0)\n\t" \ + "xor %1,%1\n\t" \ + "3:\n" \ + ".section .fixup,\"ax\"\n\t" \ + "4: movl $1,%1\n\t" \ + " jmp 3b\n\t" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,4b\n" \ + " .long 2b,4b\n" \ + ".previous" \ + : "=r" (ptr), "=r" (err) \ + : "r" (base), "q" (val), "0" (ptr)); \ + if (err) \ + return_to_32bit(regs, errcode); \ + } while(0) + +#define pushl(base, ptr, val, regs, errcode) \ + do { \ + int err; \ + __asm__ __volatile__( \ + "decw %w0\n\t" \ + "rorl $16,%3\n\t" \ + "1: movb %h3,0(%2,%0)\n\t" \ + "decw %w0\n\t" \ + "2: movb %b3,0(%2,%0)\n\t" \ + "decw %w0\n\t" \ + "rorl $16,%3\n\t" \ + "3: movb %h3,0(%2,%0)\n\t" \ + "decw %w0\n\t" \ + "4: movb %b3,0(%2,%0)\n\t" \ + "xor %1,%1\n\t" \ + "5:\n" \ + ".section .fixup,\"ax\"\n\t" \ + "6: movl $1,%1\n\t" \ + " jmp 5b\n\t" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,6b\n" \ + " .long 2b,6b\n" \ + " .long 3b,6b\n" \ + " .long 4b,6b\n" \ + ".previous" \ + : "=r" (ptr), "=r" (err) \ + : "r" (base), "q" (val), "0" (ptr)); \ + if (err) \ + return_to_32bit(regs, errcode); \ + } while(0) + +#define popb(base, ptr, regs, errcode) \ + ({ \ + unsigned long __res; \ + unsigned int err; \ + __asm__ __volatile__( \ + "1:movb 0(%1,%0),%b2\n\t" \ + "incw %w0\n\t" \ + "xor %3,%3\n\t" \ + "2:\n" \ + ".section .fixup,\"ax\"\n\t" \ + "3: movl $1,%1\n\t" \ + " jmp 2b\n\t" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,3b\n" \ + ".previous" \ + : "=r" (ptr), "=r" (base), "=q" (__res), \ + "=r" (err) \ + : "0" (ptr), "1" (base), "2" (0)); \ + if (err) \ + return_to_32bit(regs, errcode); \ + __res; \ + }) + +#define popw(base, ptr, regs, errcode) \ + ({ \ + unsigned long __res; \ + unsigned int err; \ + __asm__ __volatile__( \ + "1:movb 0(%1,%0),%b2\n\t" \ + "incw %w0\n\t" \ + "2:movb 0(%1,%0),%h2\n\t" \ + "incw %w0\n\t" \ + "xor %3,%3\n\t" \ + "3:\n" \ + ".section .fixup,\"ax\"\n\t" \ + "4: movl $1,%1\n\t" \ + " jmp 3b\n\t" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,4b\n" \ + " .long 2b,4b\n" \ + ".previous" \ + : "=r" (ptr), "=r" (base), "=q" (__res), \ + "=r" (err) \ + : "0" (ptr), "1" (base), "2" (0)); \ + if (err) \ + return_to_32bit(regs, errcode); \ + __res; \ + }) + +#define popl(base, ptr, regs, errcode) \ + ({ \ + unsigned long __res; \ + unsigned int err; \ + __asm__ __volatile__( \ + "1:movb 0(%1,%0),%b2\n\t" \ + "incw %w0\n\t" \ + "2:movb 0(%1,%0),%h2\n\t" \ + "incw %w0\n\t" \ + "rorl $16,%2\n\t" \ + "3:movb 0(%1,%0),%b2\n\t" \ + "incw %w0\n\t" \ + "4:movb 0(%1,%0),%h2\n\t" \ + "incw %w0\n\t" \ + "rorl $16,%2\n\t" \ + "xor %3,%3\n\t" \ + "5:\n" \ + ".section .fixup,\"ax\"\n\t" \ + "6: movl $1,%1\n\t" \ + " jmp 5b\n\t" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,6b\n" \ + " .long 2b,6b\n" \ + " .long 3b,6b\n" \ + " .long 4b,6b\n" \ + ".previous" \ + : "=r" (ptr), "=r" (base), "=q" (__res), \ + "=r" (err) \ + : "0" (ptr), "1" (base), "2" (0)); \ + if (err) \ + return_to_32bit(regs, errcode); \ + __res; \ + }) + +/* There are so many possible reasons for this function to return + * VM86_INTx, so adding another doesn't bother me. We can expect + * userspace programs to be able to handle it. (Getting a problem + * in userspace is always better than an Oops anyway.) [KD] */ -#define pushb(base, ptr, val) \ -__asm__ __volatile__( \ - "decw %w0\n\t" \ - "movb %2,0(%1,%0)" \ - : "=r" (ptr) \ - : "r" (base), "q" (val), "0" (ptr)) - -#define pushw(base, ptr, val) \ -__asm__ __volatile__( \ - "decw %w0\n\t" \ - "movb %h2,0(%1,%0)\n\t" \ - "decw %w0\n\t" \ - "movb %b2,0(%1,%0)" \ - : "=r" (ptr) \ - : "r" (base), "q" (val), "0" (ptr)) - -#define pushl(base, ptr, val) \ -__asm__ __volatile__( \ - "decw %w0\n\t" \ - "rorl $16,%2\n\t" \ - "movb %h2,0(%1,%0)\n\t" \ - "decw %w0\n\t" \ - "movb %b2,0(%1,%0)\n\t" \ - "decw %w0\n\t" \ - "rorl $16,%2\n\t" \ - "movb %h2,0(%1,%0)\n\t" \ - "decw %w0\n\t" \ - "movb %b2,0(%1,%0)" \ - : "=r" (ptr) \ - : "r" (base), "q" (val), "0" (ptr)) - -#define popb(base, ptr) \ -({ unsigned long __res; \ -__asm__ __volatile__( \ - "movb 0(%1,%0),%b2\n\t" \ - "incw %w0" \ - : "=r" (ptr), "=r" (base), "=q" (__res) \ - : "0" (ptr), "1" (base), "2" (0)); \ -__res; }) - -#define popw(base, ptr) \ -({ unsigned long __res; \ -__asm__ __volatile__( \ - "movb 0(%1,%0),%b2\n\t" \ - "incw %w0\n\t" \ - "movb 0(%1,%0),%h2\n\t" \ - "incw %w0" \ - : "=r" (ptr), "=r" (base), "=q" (__res) \ - : "0" (ptr), "1" (base), "2" (0)); \ -__res; }) - -#define popl(base, ptr) \ -({ unsigned long __res; \ -__asm__ __volatile__( \ - "movb 0(%1,%0),%b2\n\t" \ - "incw %w0\n\t" \ - "movb 0(%1,%0),%h2\n\t" \ - "incw %w0\n\t" \ - "rorl $16,%2\n\t" \ - "movb 0(%1,%0),%b2\n\t" \ - "incw %w0\n\t" \ - "movb 0(%1,%0),%h2\n\t" \ - "incw %w0\n\t" \ - "rorl $16,%2" \ - : "=r" (ptr), "=r" (base), "=q" (__res) \ - : "0" (ptr), "1" (base)); \ -__res; }) - static void do_int(struct kernel_vm86_regs *regs, int i, unsigned char * ssp, unsigned long sp) { unsigned long *intr_ptr, segoffs; @@ -411,9 +542,9 @@ goto cannot_handle; if ((segoffs >> 16) == BIOSSEG) goto cannot_handle; - pushw(ssp, sp, get_vflags(regs)); - pushw(ssp, sp, regs->cs); - pushw(ssp, sp, IP(regs)); + pushw(ssp, sp, get_vflags(regs), regs, VM86_INTx + (i << 8)); + pushw(ssp, sp, regs->cs, regs, VM86_INTx + (i << 8)); + pushw(ssp, sp, IP(regs), regs, VM86_INTx + (i << 8)); regs->cs = segoffs >> 16; SP(regs) -= 6; IP(regs) = segoffs & 0xffff; @@ -448,6 +579,22 @@ return 0; } +/* I guess the most consistent with other stack access like + * PUSH AX and similar would be a SIGSEGV, but I really don't + * like that so I will just stick to Manfred's solution with + * a return code. The SIGSEGV would be harder to implement + * here, and also more difficult for userspace code to handle. + * I would prefer a new return code, but in order not to mess + * up unsuspecting applications I will not invent a new code + * yet. Either way we get the problem moved from kernel space + * to user space, which is one step in the right direction. + * Some existing user space code might even be ready to deal + * with VM86_UNKNOWN, since handle_vm86_fault can return that + * for so many other reasons as well. I have also fixed the + * problem with incorrect IP by moving the increment after the + * actual execution of the instruction. [KD] + */ +#define VM86_SIGSEGV VM86_UNKNOWN void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code) { unsigned char *csp, *ssp; @@ -455,7 +602,7 @@ #define CHECK_IF_IN_TRAP \ if (VMPI.vm86dbg_active && VMPI.vm86dbg_TFpendig) \ - pushw(ssp,sp,popw(ssp,sp) | TF_MASK); + pushw(ssp,sp,popw(ssp,sp, regs, VM86_SIGSEGV) | TF_MASK, regs, VM86_SIGSEGV); #define VM86_FAULT_RETURN \ if (VMPI.force_return_for_pic && (VEFLAGS & (IF_MASK | VIF_MASK))) \ return_to_32bit(regs, VM86_PICRETURN); \ @@ -466,35 +613,43 @@ sp = SP(regs); ip = IP(regs); - switch (popb(csp, ip)) { + switch (popb(csp, ip, regs, VM86_SIGSEGV)) { /* operand size override */ case 0x66: - switch (popb(csp, ip)) { + switch (popb(csp, ip, regs, VM86_SIGSEGV)) { /* pushfd */ case 0x9c: + pushl(ssp, sp, get_vflags(regs), regs, VM86_SIGSEGV); SP(regs) -= 4; IP(regs) += 2; - pushl(ssp, sp, get_vflags(regs)); VM86_FAULT_RETURN; /* popfd */ case 0x9d: + { + unsigned long newflags=popl(ssp, sp, regs, VM86_SIGSEGV); SP(regs) += 4; IP(regs) += 2; CHECK_IF_IN_TRAP - set_vflags_long(popl(ssp, sp), regs); + set_vflags_long(newflags, regs); VM86_FAULT_RETURN; + } /* iretd */ case 0xcf: + { + unsigned long newip=popl(ssp, sp, regs, VM86_SIGSEGV); + unsigned long newcs=popl(ssp, sp, regs, VM86_SIGSEGV); + unsigned long newflags=popl(ssp, sp, regs, VM86_SIGSEGV); SP(regs) += 12; - IP(regs) = (unsigned short)popl(ssp, sp); - regs->cs = (unsigned short)popl(ssp, sp); + IP(regs) = (unsigned short)newip; + regs->cs = (unsigned short)newcs; CHECK_IF_IN_TRAP - set_vflags_long(popl(ssp, sp), regs); + set_vflags_long(newflags, regs); VM86_FAULT_RETURN; + } /* need this to avoid a fallthrough */ default: return_to_32bit(regs, VM86_UNKNOWN); @@ -502,22 +657,25 @@ /* pushf */ case 0x9c: + pushw(ssp, sp, get_vflags(regs), regs, VM86_SIGSEGV); SP(regs) -= 2; IP(regs)++; - pushw(ssp, sp, get_vflags(regs)); VM86_FAULT_RETURN; /* popf */ case 0x9d: + { + unsigned short newflags=popw(ssp, sp, regs, VM86_SIGSEGV); SP(regs) += 2; IP(regs)++; CHECK_IF_IN_TRAP - set_vflags_short(popw(ssp, sp), regs); + set_vflags_short(newflags, regs); VM86_FAULT_RETURN; + } /* int xx */ case 0xcd: { - int intno=popb(csp, ip); + int intno=popb(csp, ip, regs, VM86_SIGSEGV); IP(regs) += 2; if (VMPI.vm86dbg_active) { if ( (1 << (intno &7)) & VMPI.vm86dbg_intxxtab[intno >> 3] ) @@ -529,12 +687,17 @@ /* iret */ case 0xcf: + { + unsigned short newip=popw(ssp, sp, regs, VM86_SIGSEGV); + unsigned short newcs=popw(ssp, sp, regs, VM86_SIGSEGV); + unsigned short newflags=popw(ssp, sp, regs, VM86_SIGSEGV); SP(regs) += 6; - IP(regs) = popw(ssp, sp); - regs->cs = popw(ssp, sp); + IP(regs) = newip; + regs->cs = newcs; CHECK_IF_IN_TRAP - set_vflags_short(popw(ssp, sp), regs); + set_vflags_short(newflags, regs); VM86_FAULT_RETURN; + } /* cli */ case 0xfa: diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/lib/mmx.c linux.19pre5-ac1/arch/i386/lib/mmx.c --- linux.19p5/arch/i386/lib/mmx.c Thu Apr 4 13:19:52 2002 +++ linux.19pre5-ac1/arch/i386/lib/mmx.c Wed Apr 3 01:07:16 2002 @@ -57,7 +57,7 @@ : : "r" (from) ); - for(; i>0; i--) + for(; i>5; i--) { __asm__ __volatile__ ( "1: prefetch 320(%0)\n" @@ -88,6 +88,30 @@ : : "r" (from), "r" (to) : "memory"); from+=64; to+=64; + } + + for(; i>0; i--) + { + __asm__ __volatile__ ( + " movq (%0), %%mm0\n" + " movq 8(%0), %%mm1\n" + " movq 16(%0), %%mm2\n" + " movq 24(%0), %%mm3\n" + " movq %%mm0, (%1)\n" + " movq %%mm1, 8(%1)\n" + " movq %%mm2, 16(%1)\n" + " movq %%mm3, 24(%1)\n" + " movq 32(%0), %%mm0\n" + " movq 40(%0), %%mm1\n" + " movq 48(%0), %%mm2\n" + " movq 56(%0), %%mm3\n" + " movq %%mm0, 32(%1)\n" + " movq %%mm1, 40(%1)\n" + " movq %%mm2, 48(%1)\n" + " movq %%mm3, 56(%1)\n" + : : "r" (from), "r" (to) : "memory"); + from+=64; + to+=64; } /* * Now do the tail of the block diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/mm/fault.c linux.19pre5-ac1/arch/i386/mm/fault.c --- linux.19p5/arch/i386/mm/fault.c Thu Apr 4 13:21:10 2002 +++ linux.19pre5-ac1/arch/i386/mm/fault.c Wed Mar 20 16:03:44 2002 @@ -86,8 +86,7 @@ out_of_memory: if (current->pid == 1) { - current->policy |= SCHED_YIELD; - schedule(); + yield(); goto survive; } goto bad_area; @@ -336,8 +335,7 @@ out_of_memory: up_read(&mm->mmap_sem); if (tsk->pid == 1) { - tsk->policy |= SCHED_YIELD; - schedule(); + yield(); down_read(&mm->mmap_sem); goto survive; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/ia64/config.in linux.19pre5-ac1/arch/ia64/config.in --- linux.19p5/arch/ia64/config.in Thu Apr 4 13:21:10 2002 +++ linux.19pre5-ac1/arch/ia64/config.in Sat Mar 9 20:41:04 2002 @@ -164,6 +164,10 @@ fi endmenu +if [ "$CONFIG_PCI" = "y" ]; then + source drivers/message/fusion/Config.in +fi + if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then if [ "$CONFIG_NET" = "y" ]; then @@ -235,6 +239,8 @@ source drivers/usb/Config.in +source lib/Config.in + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then source net/bluetooth/Config.in fi diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/ia64/ia32/sys_ia32.c linux.19pre5-ac1/arch/ia64/ia32/sys_ia32.c --- linux.19p5/arch/ia64/ia32/sys_ia32.c Thu Apr 4 13:21:10 2002 +++ linux.19pre5-ac1/arch/ia64/ia32/sys_ia32.c Fri Mar 1 18:44:01 2002 @@ -3693,24 +3693,25 @@ return result; } -struct dqblk32 { - __u32 dqb_bhardlimit; - __u32 dqb_bsoftlimit; - __u32 dqb_curblocks; +struct mem_dqblk32 { __u32 dqb_ihardlimit; __u32 dqb_isoftlimit; __u32 dqb_curinodes; + __u32 dqb_bhardlimit; + __u32 dqb_bsoftlimit; + /* Not __u64 because of alignment */ + __u32 dqb_curspace[2]; __kernel_time_t32 dqb_btime; __kernel_time_t32 dqb_itime; }; asmlinkage long -sys32_quotactl (int cmd, unsigned int special, int id, struct dqblk32 *addr) +sys32_quotactl (int cmd, unsigned int special, int id, struct mem_dqblk32 *addr) { - extern asmlinkage long sys_quotactl (int, const char *, int, caddr_t); + extern asmlinkage long sys_quotactl (int, const char *, int, __kernel_caddr_t); int cmds = cmd >> SUBCMDSHIFT; mm_segment_t old_fs; - struct dqblk d; + struct mem_dqblk d; char *spec; long err; @@ -3720,13 +3721,15 @@ case Q_SETQUOTA: case Q_SETUSE: case Q_SETQLIM: - if (copy_from_user (&d, addr, sizeof(struct dqblk32))) + if (copy_from_user (&d, (struct mem_dqblk32 *)addr, + sizeof(struct mem_dqblk32))) return -EFAULT; - d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime; - d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime; + d.dqb_itime = ((struct mem_dqblk32 *)&d)->dqb_itime; + d.dqb_btime = ((struct mem_dqblk32 *)&d)->dqb_btime; + memcpy(&d.dqb_curspace, ((struct mem_dqblk32 *)&d)->dqb_curspace, sizeof(__u64)); break; default: - return sys_quotactl(cmd, (void *) A(special), id, (caddr_t) addr); + return sys_quotactl(cmd, (void *) A(special), id, (__kernel_caddr_t) addr); } spec = getname32((void *) A(special)); err = PTR_ERR(spec); @@ -3734,17 +3737,22 @@ return err; old_fs = get_fs (); set_fs(KERNEL_DS); - err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d); + err = sys_quotactl(cmd, (const char *)spec, id, (__kernel_caddr_t)&d); set_fs(old_fs); putname(spec); + if (err) + return err; if (cmds == Q_GETQUOTA) { __kernel_time_t b = d.dqb_btime, i = d.dqb_itime; - ((struct dqblk32 *)&d)->dqb_itime = i; - ((struct dqblk32 *)&d)->dqb_btime = b; - if (copy_to_user(addr, &d, sizeof(struct dqblk32))) + qsize_t s = d.dqb_curspace; + ((struct mem_dqblk32 *)&d)->dqb_itime = i; + ((struct mem_dqblk32 *)&d)->dqb_btime = b; + memcpy(((struct mem_dqblk32 *)&d)->dqb_curspace, &s, sizeof(__u64)); + if (copy_to_user((struct mem_dqblk32 *)addr, &d, + sizeof(struct mem_dqblk32))) return -EFAULT; } - return err; + return 0; } asmlinkage long diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/ia64/mm/init.c linux.19pre5-ac1/arch/ia64/mm/init.c --- linux.19p5/arch/ia64/mm/init.c Thu Apr 4 13:20:20 2002 +++ linux.19pre5-ac1/arch/ia64/mm/init.c Fri Mar 15 22:07:36 2002 @@ -99,7 +99,7 @@ free_page(addr); ++totalram_pages; } - printk ("Freeing unused kernel memory: %ldkB freed\n", + printk (KERN_INFO "Freeing unused kernel memory: %ldkB freed\n", (&__init_end - &__init_begin) >> 10); } @@ -141,7 +141,7 @@ end = end & PAGE_MASK; if (start < end) - printk ("Freeing initrd memory: %ldkB freed\n", (end - start) >> 10); + printk (KERN_INFO "Freeing initrd memory: %ldkB freed\n", (end - start) >> 10); for (; start < end; start += PAGE_SIZE) { if (!VALID_PAGE(virt_to_page(start))) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/m68k/config.in linux.19pre5-ac1/arch/m68k/config.in --- linux.19p5/arch/m68k/config.in Thu Apr 4 13:21:10 2002 +++ linux.19pre5-ac1/arch/m68k/config.in Mon Mar 25 18:02:59 2002 @@ -565,3 +565,5 @@ fi endmenu + +source lib/Config.in diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/mips/config.in linux.19pre5-ac1/arch/mips/config.in --- linux.19p5/arch/mips/config.in Thu Apr 4 13:21:10 2002 +++ linux.19pre5-ac1/arch/mips/config.in Sat Mar 9 20:41:04 2002 @@ -644,3 +644,5 @@ bool 'Run uncached' CONFIG_MIPS_UNCACHED fi endmenu + +source lib/Config.in diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/mips/mm/init.c linux.19pre5-ac1/arch/mips/mm/init.c --- linux.19p5/arch/mips/mm/init.c Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/arch/mips/mm/init.c Fri Mar 15 22:07:36 2002 @@ -368,7 +368,7 @@ totalram_pages++; addr += PAGE_SIZE; } - printk("Freeing unused kernel memory: %dk freed\n", + printk(KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/mips64/config.in linux.19pre5-ac1/arch/mips64/config.in --- linux.19p5/arch/mips64/config.in Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/arch/mips64/config.in Sat Mar 9 20:41:04 2002 @@ -341,3 +341,5 @@ bool 'Run uncached' CONFIG_MIPS_UNCACHED fi endmenu + +source lib/Config.in diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/mips64/mm/init.c linux.19pre5-ac1/arch/mips64/mm/init.c --- linux.19p5/arch/mips64/mm/init.c Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/arch/mips64/mm/init.c Fri Mar 15 22:07:36 2002 @@ -325,7 +325,7 @@ totalram_pages++; addr += PAGE_SIZE; } - printk("Freeing unused kernel memory: %ldk freed\n", + printk(KERN_INFO "Freeing unused kernel memory: %ldk freed\n", (&__init_end - &__init_begin) >> 10); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/parisc/config.in linux.19pre5-ac1/arch/parisc/config.in --- linux.19p5/arch/parisc/config.in Thu Apr 4 13:20:26 2002 +++ linux.19pre5-ac1/arch/parisc/config.in Sat Mar 9 20:41:04 2002 @@ -208,3 +208,4 @@ bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ endmenu +source lib/Config.in diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/ppc/config.in linux.19pre5-ac1/arch/ppc/config.in --- linux.19p5/arch/ppc/config.in Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/arch/ppc/config.in Sat Mar 9 20:41:04 2002 @@ -396,6 +396,8 @@ source net/bluetooth/Config.in fi +source lib/Config.in + mainmenu_option next_comment comment 'Kernel hacking' diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/ppc/math-emu/op-4.h linux.19pre5-ac1/arch/ppc/math-emu/op-4.h --- linux.19p5/arch/ppc/math-emu/op-4.h Thu Apr 4 13:20:10 2002 +++ linux.19pre5-ac1/arch/ppc/math-emu/op-4.h Wed Feb 13 00:25:35 2002 @@ -279,7 +279,7 @@ X##_f[1] = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \ X##_f[2] = (rsize <= 2*_FP_W_TYPE_SIZE ? 0 : r >> 2*_FP_W_TYPE_SIZE); \ X##_f[3] = (rsize <= 3*_FP_W_TYPE_SIZE ? 0 : r >> 3*_FP_W_TYPE_SIZE); \ - } while (0); + } while (0) #define _FP_FRAC_CONV_4_1(dfs, sfs, D, S) \ do { \ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/ppc/mm/init.c linux.19pre5-ac1/arch/ppc/mm/init.c --- linux.19p5/arch/ppc/mm/init.c Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/arch/ppc/mm/init.c Fri Mar 15 22:07:36 2002 @@ -230,7 +230,7 @@ (unsigned long)(&__ ## TYPE ## _end), \ #TYPE); - printk ("Freeing unused kernel memory:"); + printk (KERN_INFO "Freeing unused kernel memory:"); FREESEC(init); if (_machine != _MACH_Pmac) FREESEC(pmac); @@ -247,7 +247,7 @@ #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { - printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); + printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10); for (; start < end; start += PAGE_SIZE) { ClearPageReserved(virt_to_page(start)); @@ -515,7 +515,7 @@ } #endif /* CONFIG_HIGHMEM */ - printk("Memory: %luk available (%dk kernel code, %dk data, %dk init, %ldk highmem)\n", + printk(KERN_INFO "Memory: %luk available (%dk kernel code, %dk data, %dk init, %ldk highmem)\n", (unsigned long)nr_free_pages()<< (PAGE_SHIFT-10), codepages<< (PAGE_SHIFT-10), datapages<< (PAGE_SHIFT-10), initpages<< (PAGE_SHIFT-10), diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/s390/config.in linux.19pre5-ac1/arch/s390/config.in --- linux.19p5/arch/s390/config.in Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/arch/s390/config.in Thu Mar 14 22:06:41 2002 @@ -75,3 +75,4 @@ bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ endmenu +source lib/Config.in diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/s390/kernel/entry.S linux.19pre5-ac1/arch/s390/kernel/entry.S --- linux.19p5/arch/s390/kernel/entry.S Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/arch/s390/kernel/entry.S Fri Mar 15 21:56:17 2002 @@ -254,13 +254,14 @@ ret_from_fork: basr %r13,0 l %r13,.Lentry_base-.(%r13) # setup base pointer to &entry_base + # not saving R14 here because we go to sysc_return ultimately + l %r1,BASED(.Lschedtail) + basr %r14,%r1 # call schedule_tail (unlock stuff) GET_CURRENT # load pointer to task_struct to R9 stosm 24(%r15),0x03 # reenable interrupts sr %r0,%r0 # child returns 0 st %r0,SP_R2(%r15) # store return value (change R2 on stack) - l %r1,BASED(.Lschedtail) - la %r14,BASED(sysc_return) - br %r1 # call schedule_tail, return to sysc_return + b BASED(sysc_return) # # clone, fork, vfork, exec and sigreturn need glue, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/s390/mm/init.c linux.19pre5-ac1/arch/s390/mm/init.c --- linux.19p5/arch/s390/mm/init.c Thu Apr 4 13:20:25 2002 +++ linux.19pre5-ac1/arch/s390/mm/init.c Fri Mar 15 22:07:36 2002 @@ -214,7 +214,7 @@ free_page(addr); totalram_pages++; } - printk ("Freeing unused kernel memory: %dk freed\n", + printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10); } @@ -222,7 +222,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) { if (start < end) - printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); + printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10); for (; start < end; start += PAGE_SIZE) { ClearPageReserved(virt_to_page(start)); set_page_count(virt_to_page(start), 1); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/s390x/config.in linux.19pre5-ac1/arch/s390x/config.in --- linux.19p5/arch/s390x/config.in Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/arch/s390x/config.in Thu Mar 14 22:06:56 2002 @@ -77,3 +77,4 @@ bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ endmenu +source lib/Config.in diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/s390x/kernel/entry.S linux.19pre5-ac1/arch/s390x/kernel/entry.S --- linux.19p5/arch/s390x/kernel/entry.S Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/arch/s390x/kernel/entry.S Fri Mar 15 21:56:17 2002 @@ -240,11 +240,11 @@ # .globl ret_from_fork ret_from_fork: + brasl %r14,schedule_tail GET_CURRENT # load pointer to task_struct to R9 stosm 48(%r15),0x03 # reenable interrupts xc SP_R2(8,%r15),SP_R2(%r15) # child returns 0 - larl %r14,sysc_return - jg schedule_tail # return to sysc_return + j sysc_return # # clone, fork, vfork, exec and sigreturn need glue, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/s390x/mm/init.c linux.19pre5-ac1/arch/s390x/mm/init.c --- linux.19p5/arch/s390x/mm/init.c Thu Apr 4 13:20:29 2002 +++ linux.19pre5-ac1/arch/s390x/mm/init.c Fri Mar 15 22:07:36 2002 @@ -226,7 +226,7 @@ free_page(addr); totalram_pages++; } - printk ("Freeing unused kernel memory: %ldk freed\n", + printk (KERN_INFO "Freeing unused kernel memory: %ldk freed\n", (&__init_end - &__init_begin) >> 10); } @@ -234,7 +234,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) { if (start < end) - printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); + printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10); for (; start < end; start += PAGE_SIZE) { ClearPageReserved(virt_to_page(start)); set_page_count(virt_to_page(start), 1); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/sh/config.in linux.19pre5-ac1/arch/sh/config.in --- linux.19p5/arch/sh/config.in Thu Apr 4 13:20:19 2002 +++ linux.19pre5-ac1/arch/sh/config.in Sat Mar 9 20:41:05 2002 @@ -386,3 +386,5 @@ bool 'Early printk support' CONFIG_SH_EARLY_PRINTK fi endmenu + +source lib/Config.in diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/sh/mm/init.c linux.19pre5-ac1/arch/sh/mm/init.c --- linux.19p5/arch/sh/mm/init.c Thu Apr 4 13:20:20 2002 +++ linux.19pre5-ac1/arch/sh/mm/init.c Fri Mar 15 22:07:36 2002 @@ -187,7 +187,7 @@ free_page(addr); totalram_pages++; } - printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10); + printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10); } #ifdef CONFIG_BLK_DEV_INITRD @@ -200,7 +200,7 @@ free_page(p); totalram_pages++; } - printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); + printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10); } #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/sparc/config.in linux.19pre5-ac1/arch/sparc/config.in --- linux.19p5/arch/sparc/config.in Thu Apr 4 13:19:54 2002 +++ linux.19pre5-ac1/arch/sparc/config.in Tue Mar 26 18:51:18 2002 @@ -211,6 +211,12 @@ dep_tristate ' PPP support for sync tty ports' CONFIG_PPP_SYNC_TTY $CONFIG_PPP dep_tristate ' PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP dep_tristate ' PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP m + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate ' PPP over Ethernet (EXPERIMENTAL)' CONFIG_PPPOE $CONFIG_PPP + if [ "$CONFIG_ATM" = "y" ]; then + dep_tristate ' PPP over ATM (EXPERIMENTAL)' CONFIG_PPPOATM $CONFIG_PPP + fi + fi fi tristate ' SLIP (serial line) support' CONFIG_SLIP if [ "$CONFIG_SLIP" != "n" ]; then @@ -266,3 +272,5 @@ bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ endmenu + +source lib/Config.in diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/sparc/kernel/sunos_ioctl.c linux.19pre5-ac1/arch/sparc/kernel/sunos_ioctl.c --- linux.19p5/arch/sparc/kernel/sunos_ioctl.c Thu Apr 4 13:19:54 2002 +++ linux.19pre5-ac1/arch/sparc/kernel/sunos_ioctl.c Mon Jan 28 19:39:48 2002 @@ -39,8 +39,12 @@ { int ret = -EBADF; - if (fd >= SUNOS_NR_OPEN || !fcheck(fd)) + read_lock(¤t->files->file_lock); + if (fd >= SUNOS_NR_OPEN || !fcheck(fd)) { + read_unlock(¤t->files->file_lock); goto out; + } + read_unlock(¤t->files->file_lock); /* First handle an easy compat. case for tty ldisc. */ if(cmd == TIOCSETD) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/sparc/mm/init.c linux.19pre5-ac1/arch/sparc/mm/init.c --- linux.19p5/arch/sparc/mm/init.c Thu Apr 4 13:19:56 2002 +++ linux.19pre5-ac1/arch/sparc/mm/init.c Fri Mar 15 22:07:36 2002 @@ -459,7 +459,7 @@ initpages = (((unsigned long) &__init_end) - ((unsigned long) &__init_begin)); initpages = PAGE_ALIGN(initpages) >> PAGE_SHIFT; - printk("Memory: %dk available (%dk kernel code, %dk data, %dk init, %ldk highmem) [%08lx,%08lx]\n", + printk(KERN_INFO "Memory: %dk available (%dk kernel code, %dk data, %dk init, %ldk highmem) [%08lx,%08lx]\n", nr_free_pages() << (PAGE_SHIFT-10), codepages << (PAGE_SHIFT-10), datapages << (PAGE_SHIFT-10), @@ -486,14 +486,14 @@ totalram_pages++; num_physpages++; } - printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10); + printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10); } #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { if (start < end) - printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); + printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10); for (; start < end; start += PAGE_SIZE) { struct page *p = virt_to_page(start); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/sparc/mm/srmmu.c linux.19pre5-ac1/arch/sparc/mm/srmmu.c --- linux.19p5/arch/sparc/mm/srmmu.c Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/arch/sparc/mm/srmmu.c Thu Apr 4 13:33:39 2002 @@ -1957,7 +1957,7 @@ iaddr = &(insn); \ daddr = &(dest); \ *iaddr = SPARC_BRANCH((unsigned long) daddr, (unsigned long) iaddr); \ - } while(0); + } while(0) static void __init patch_window_trap_handlers(void) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/sparc/mm/sun4c.c linux.19pre5-ac1/arch/sparc/mm/sun4c.c --- linux.19p5/arch/sparc/mm/sun4c.c Thu Apr 4 13:19:56 2002 +++ linux.19pre5-ac1/arch/sparc/mm/sun4c.c Wed Feb 13 00:25:35 2002 @@ -425,7 +425,7 @@ daddr = &(dst); \ iaddr = &(src); \ *daddr = *iaddr; \ - } while (0); + } while (0) static void patch_kernel_fault_handler(void) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/sparc64/config.in linux.19pre5-ac1/arch/sparc64/config.in --- linux.19p5/arch/sparc64/config.in Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/arch/sparc64/config.in Mon Mar 25 18:03:17 2002 @@ -310,3 +310,5 @@ fi endmenu + +source lib/Config.in diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/sparc64/kernel/binfmt_elf32.c linux.19pre5-ac1/arch/sparc64/kernel/binfmt_elf32.c --- linux.19p5/arch/sparc64/kernel/binfmt_elf32.c Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/arch/sparc64/kernel/binfmt_elf32.c Mon Mar 25 18:03:17 2002 @@ -43,7 +43,7 @@ dest[34] = (unsigned int) src->tnpc; \ dest[35] = src->y; \ dest[36] = dest[37] = 0; /* XXX */ \ -} while (0); +} while(0) typedef struct { union { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/sparc64/kernel/sunos_ioctl32.c linux.19pre5-ac1/arch/sparc64/kernel/sunos_ioctl32.c --- linux.19p5/arch/sparc64/kernel/sunos_ioctl32.c Thu Apr 4 13:20:14 2002 +++ linux.19pre5-ac1/arch/sparc64/kernel/sunos_ioctl32.c Mon Jan 28 19:39:48 2002 @@ -100,8 +100,12 @@ if(fd >= SUNOS_NR_OPEN) goto out; - if(!fcheck(fd)) + read_lock(¤t->files->file_lock); + if(!fcheck(fd)) { + read_unlock(¤t->files->file_lock); goto out; + } + read_unlock(¤t->files->file_lock); if(cmd == TIOCSETD) { mm_segment_t old_fs = get_fs(); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/sparc64/kernel/sys_sparc32.c linux.19pre5-ac1/arch/sparc64/kernel/sys_sparc32.c --- linux.19p5/arch/sparc64/kernel/sys_sparc32.c Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/arch/sparc64/kernel/sys_sparc32.c Mon Feb 25 23:35:55 2002 @@ -888,24 +888,24 @@ return sys32_fcntl(fd, cmd, arg); } -struct dqblk32 { - __u32 dqb_bhardlimit; - __u32 dqb_bsoftlimit; - __u32 dqb_curblocks; +struct mem_dqblk32 { __u32 dqb_ihardlimit; __u32 dqb_isoftlimit; __u32 dqb_curinodes; + __u32 dqb_bhardlimit; + __u32 dqb_bsoftlimit; + __u64 dqb_curspace; __kernel_time_t32 dqb_btime; __kernel_time_t32 dqb_itime; }; -extern asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr); +extern asmlinkage long sys_quotactl(int cmd, const char *special, int id, __kernel_caddr_t addr); asmlinkage int sys32_quotactl(int cmd, const char *special, int id, unsigned long addr) { int cmds = cmd >> SUBCMDSHIFT; int err; - struct dqblk d; + struct mem_dqblk d; mm_segment_t old_fs; char *spec; @@ -915,33 +915,35 @@ case Q_SETQUOTA: case Q_SETUSE: case Q_SETQLIM: - if (copy_from_user (&d, (struct dqblk32 *)addr, - sizeof (struct dqblk32))) + if (copy_from_user (&d, (struct mem_dqblk32 *)addr, + sizeof (struct mem_dqblk32))) return -EFAULT; - d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime; - d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime; + d.dqb_itime = ((struct mem_dqblk32 *)&d)->dqb_itime; + d.dqb_btime = ((struct mem_dqblk32 *)&d)->dqb_btime; break; default: return sys_quotactl(cmd, special, - id, (caddr_t)addr); + id, (__kernel_caddr_t)addr); } spec = getname (special); err = PTR_ERR(spec); if (IS_ERR(spec)) return err; old_fs = get_fs (); set_fs (KERNEL_DS); - err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d); + err = sys_quotactl(cmd, (const char *)spec, id, (__kernel_caddr_t)&d); set_fs (old_fs); putname (spec); + if (err) + return err; if (cmds == Q_GETQUOTA) { __kernel_time_t b = d.dqb_btime, i = d.dqb_itime; - ((struct dqblk32 *)&d)->dqb_itime = i; - ((struct dqblk32 *)&d)->dqb_btime = b; - if (copy_to_user ((struct dqblk32 *)addr, &d, - sizeof (struct dqblk32))) + ((struct mem_dqblk32 *)&d)->dqb_itime = i; + ((struct mem_dqblk32 *)&d)->dqb_btime = b; + if (copy_to_user ((struct mem_dqblk32 *)addr, &d, + sizeof (struct mem_dqblk32))) return -EFAULT; } - return err; + return 0; } static inline int put_statfs (struct statfs32 *ubuf, struct statfs *kbuf) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/sparc64/solaris/timod.c linux.19pre5-ac1/arch/sparc64/solaris/timod.c --- linux.19p5/arch/sparc64/solaris/timod.c Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/arch/sparc64/solaris/timod.c Thu Apr 4 13:34:11 2002 @@ -149,7 +149,9 @@ struct socket *sock; SOLD("wakeing socket"); + read_lock(¤t->files->file_lock); sock = ¤t->files->fd[fd]->f_dentry->d_inode->u.socket_i; + read_unlock(¤t->files->file_lock); wake_up_interruptible(&sock->wait); read_lock(&sock->sk->callback_lock); if (sock->fasync_list && !test_bit(SOCK_ASYNC_WAITDATA, &sock->flags)) @@ -163,7 +165,9 @@ struct sol_socket_struct *sock; SOLD("queuing primsg"); + read_lock(¤t->files->file_lock); sock = (struct sol_socket_struct *)current->files->fd[fd]->private_data; + read_unlock(¤t->files->file_lock); it->next = sock->pfirst; sock->pfirst = it; if (!sock->plast) @@ -177,7 +181,9 @@ struct sol_socket_struct *sock; SOLD("queuing primsg at end"); + read_lock(¤t->files->file_lock); sock = (struct sol_socket_struct *)current->files->fd[fd]->private_data; + read_unlock(¤t->files->file_lock); it->next = NULL; if (sock->plast) sock->plast->next = it; @@ -355,7 +361,11 @@ (int (*)(int, unsigned long *))SYS(socketcall); int (*sys_sendto)(int, void *, size_t, unsigned, struct sockaddr *, int) = (int (*)(int, void *, size_t, unsigned, struct sockaddr *, int))SYS(sendto); - filp = current->files->fd[fd]; + read_lock(¤t->files->file_lock); + filp = fcheck(fd); + read_unlock(¤t->files->file_lock); + if (!filp) + return -EBADF; ino = filp->f_dentry->d_inode; sock = (struct sol_socket_struct *)filp->private_data; SOLD("entry"); @@ -636,7 +646,11 @@ SOLD("entry"); SOLDD(("%u %p %d %p %p %d %p %d\n", fd, ctl_buf, ctl_maxlen, ctl_len, data_buf, data_maxlen, data_len, *flags_p)); - filp = current->files->fd[fd]; + read_lock(¤t->files->file_lock); + filp = fcheck(fd); + read_unlock(¤t->files->file_lock); + if (!filp) + return -EBADF; ino = filp->f_dentry->d_inode; sock = (struct sol_socket_struct *)filp->private_data; SOLDD(("%p %p\n", sock->pfirst, sock->pfirst ? sock->pfirst->next : NULL)); @@ -847,7 +861,9 @@ lock_kernel(); if(fd >= NR_OPEN) goto out; - filp = current->files->fd[fd]; + read_lock(¤t->files->file_lock); + filp = fcheck(fd); + read_unlock(¤t->files->file_lock); if(!filp) goto out; ino = filp->f_dentry->d_inode; @@ -914,7 +930,9 @@ lock_kernel(); if(fd >= NR_OPEN) goto out; - filp = current->files->fd[fd]; + read_lock(¤t->files->file_lock); + filp = fcheck(fd); + read_unlock(¤t->files->file_lock); if(!filp) goto out; ino = filp->f_dentry->d_inode; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/block/elevator.c linux.19pre5-ac1/drivers/block/elevator.c --- linux.19p5/drivers/block/elevator.c Thu Apr 4 13:19:02 2002 +++ linux.19pre5-ac1/drivers/block/elevator.c Wed Feb 13 01:06:43 2002 @@ -80,30 +80,38 @@ struct buffer_head *bh, int rw, int max_sectors) { - struct list_head *entry = &q->queue_head; - unsigned int count = bh->b_size >> 9, ret = ELEVATOR_NO_MERGE; - + struct list_head *entry; + unsigned int count = bh->b_size >> 9; + unsigned int ret = ELEVATOR_NO_MERGE; + int merge_only = 0; + const int max_bomb_segments = q->elevator.max_bomb_segments; + + entry = &q->queue_head; while ((entry = entry->prev) != head) { struct request *__rq = blkdev_entry_to_request(entry); - /* - * simply "aging" of requests in queue - */ - if (__rq->elevator_sequence-- <= 0) - break; - + if (__rq->elevator_sequence-- <= 0) { + /* + * OK, we've exceeded someone's latency limit. + * But we still continue to look for merges, + * because they're so much better than seeks. + */ + merge_only = 1; + } if (__rq->waiting) continue; if (__rq->rq_dev != bh->b_rdev) continue; - if (!*req && bh_rq_in_between(bh, __rq, &q->queue_head)) + if (!*req && !merge_only && + bh_rq_in_between(bh, __rq, &q->queue_head)) { *req = __rq; + } if (__rq->cmd != rw) continue; if (__rq->nr_sectors + count > max_sectors) continue; if (__rq->elevator_sequence < count) - break; + merge_only = 1; if (__rq->sector + __rq->nr_sectors == bh->b_rsector) { ret = ELEVATOR_BACK_MERGE; *req = __rq; @@ -116,6 +124,56 @@ } } + /* + * If we failed to merge a read anywhere in the request + * queue, we really don't want to place it at the end + * of the list, behind lots of writes. So place it near + * the front. + * + * We don't want to place it in front of _all_ writes: that + * would create lots of seeking, and isn't tunable. + * We try to avoid promoting this read in front of existing + * reads. + * + * max_bomb_sectors becomes the maximum number of write + * requests which we allow to remain in place in front of + * a newly introduced read. We weight things a little bit, + * so large writes are more expensive than small ones, but it's + * requests which count, not sectors. + */ + if (max_bomb_segments && rw == READ && ret == ELEVATOR_NO_MERGE) { + int cur_latency = 0; + struct request * const cur_request = *req; + + entry = head->next; + while (entry != &q->queue_head) { + struct request *__rq; + + if (entry == &q->queue_head) + BUG(); + if (entry == q->queue_head.next && + q->head_active && !q->plugged) + BUG(); + __rq = blkdev_entry_to_request(entry); + + if (__rq == cur_request) { + /* + * This is where the old algorithm placed it. + * There's no point pushing it further back, + * so leave it here, in sorted order. + */ + break; + } + if (__rq->cmd == WRITE) { + cur_latency += 1 + __rq->nr_sectors / 64; + if (cur_latency >= max_bomb_segments) { + *req = __rq; + break; + } + } + entry = entry->next; + } + } return ret; } @@ -188,7 +246,7 @@ output.queue_ID = elevator->queue_ID; output.read_latency = elevator->read_latency; output.write_latency = elevator->write_latency; - output.max_bomb_segments = 0; + output.max_bomb_segments = elevator->max_bomb_segments; if (copy_to_user(arg, &output, sizeof(blkelv_ioctl_arg_t))) return -EFAULT; @@ -207,9 +265,12 @@ return -EINVAL; if (input.write_latency < 0) return -EINVAL; + if (input.max_bomb_segments < 0) + return -EINVAL; elevator->read_latency = input.read_latency; elevator->write_latency = input.write_latency; + elevator->max_bomb_segments = input.max_bomb_segments; return 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/block/genhd.c linux.19pre5-ac1/drivers/block/genhd.c --- linux.19p5/drivers/block/genhd.c Thu Apr 4 13:19:02 2002 +++ linux.19pre5-ac1/drivers/block/genhd.c Sun Mar 10 01:29:03 2002 @@ -135,20 +135,39 @@ get_partition_list(char *page, char **start, off_t offset, int count) { struct gendisk *gp; + struct hd_struct *hd; char buf[64]; int len, n; - len = sprintf(page, "major minor #blocks name\n\n"); + len = sprintf(page, "major minor #blocks name " + "rio rmerge rsect ruse wio wmerge " + "wsect wuse running use aveq\n\n"); + + read_lock(&gendisk_lock); for (gp = gendisk_head; gp; gp = gp->next) { for (n = 0; n < (gp->nr_real << gp->minor_shift); n++) { if (gp->part[n].nr_sects == 0) continue; - len += snprintf(page + len, 63, - "%4d %4d %10d %s\n", + hd = &gp->part[n]; disk_round_stats(hd); + len += sprintf(page + len, + "%4d %4d %10d %s " + "%d %d %d %d %d %d %d %d %d %d %d\n", gp->major, n, gp->sizes[n], - disk_name(gp, n, buf)); + disk_name(gp, n, buf), + hd->rd_ios, hd->rd_merges, + hd->rd_sectors, +#define MSEC(x) ((x) * 1000 / HZ) + MSEC(hd->rd_ticks), + hd->wr_ios, hd->wr_merges, + hd->wr_sectors, + MSEC(hd->wr_ticks), + hd->ios_in_flight, + MSEC(hd->io_ticks), + MSEC(hd->aveq)); +#undef MSEC + if (len < offset) offset -= len, len = 0; else if (len >= offset + count) @@ -168,14 +187,10 @@ extern int blk_dev_init(void); -#ifdef CONFIG_FUSION_BOOT -extern int fusion_init(void); -#endif extern int net_dev_init(void); extern void console_map_init(void); extern int soc_probe(void); extern int atmdev_init(void); -extern int i2o_init(void); extern int cpqarray_init(void); int __init device_init(void) @@ -183,12 +198,6 @@ rwlock_init(&gendisk_lock); blk_dev_init(); sti(); -#ifdef CONFIG_I2O - i2o_init(); -#endif -#ifdef CONFIG_FUSION_BOOT - fusion_init(); -#endif #ifdef CONFIG_FC4_SOC /* This has to be done before scsi_dev_init */ soc_probe(); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/block/ll_rw_blk.c linux.19pre5-ac1/drivers/block/ll_rw_blk.c --- linux.19p5/drivers/block/ll_rw_blk.c Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/drivers/block/ll_rw_blk.c Thu Mar 21 01:02:08 2002 @@ -117,6 +117,23 @@ */ int * max_sectors[MAX_BLKDEV]; +/* + * blkdev_varyio indicates if variable size IO can be done on a device. + * + * Currently used for doing variable size IO on RAW devices. + */ +char * blkdev_varyio[MAX_BLKDEV]; + +/* + * The total number of requests in each queue. + */ +static int queue_nr_requests; + +/* + * The threshold around which we make wakeup decisions + */ +static int batch_requests; + static inline int get_max_sectors(kdev_t dev) { if (!max_sectors[MAJOR(dev)]) @@ -170,7 +187,7 @@ **/ void blk_cleanup_queue(request_queue_t * q) { - int count = q->nr_requests; + int count = queue_nr_requests; count -= __blk_cleanup_queue(&q->rq[READ]); count -= __blk_cleanup_queue(&q->rq[WRITE]); @@ -320,64 +337,31 @@ spin_unlock_irqrestore(&io_request_lock, flags); } -/** blk_grow_request_list - * @q: The &request_queue_t - * @nr_requests: how many requests are desired - * - * More free requests are added to the queue's free lists, bringing - * the total number of requests to @nr_requests. - * - * The requests are added equally to the request queue's read - * and write freelists. - * - * This function can sleep. - * - * Returns the (new) number of requests which the queue has available. - */ -int blk_grow_request_list(request_queue_t *q, int nr_requests) -{ - spin_lock_irq(&io_request_lock); - while (q->nr_requests < nr_requests) { - struct request *rq; - int rw; - - spin_unlock_irq(&io_request_lock); - rq = kmem_cache_alloc(request_cachep, SLAB_KERNEL); - spin_lock_irq(&io_request_lock); - if (rq == NULL) - break; - memset(rq, 0, sizeof(*rq)); - rq->rq_status = RQ_INACTIVE; - rw = q->nr_requests & 1; - list_add(&rq->queue, &q->rq[rw].free); - q->rq[rw].count++; - q->nr_requests++; - } - q->batch_requests = q->nr_requests / 4; - if (q->batch_requests > 32) - q->batch_requests = 32; - spin_unlock_irq(&io_request_lock); - return q->nr_requests; -} - static void blk_init_free_list(request_queue_t *q) { - struct sysinfo si; - int megs; /* Total memory, in megabytes */ - int nr_requests; + struct request *rq; + int i; INIT_LIST_HEAD(&q->rq[READ].free); INIT_LIST_HEAD(&q->rq[WRITE].free); q->rq[READ].count = 0; q->rq[WRITE].count = 0; - q->nr_requests = 0; - si_meminfo(&si); - megs = si.totalram >> (20 - PAGE_SHIFT); - nr_requests = 128; - if (megs < 32) - nr_requests /= 2; - blk_grow_request_list(q, nr_requests); + /* + * Divide requests in half between read and write + */ + for (i = 0; i < queue_nr_requests; i++) { + rq = kmem_cache_alloc(request_cachep, SLAB_KERNEL); + if (rq == NULL) { + /* We'll get a `leaked requests' message from blk_cleanup_queue */ + printk(KERN_EMERG "blk_init_free_list: error allocating requests\n"); + break; + } + memset(rq, 0, sizeof(struct request)); + rq->rq_status = RQ_INACTIVE; + list_add(&rq->queue, &q->rq[i&1].free); + q->rq[i&1].count++; + } init_waitqueue_head(&q->wait_for_requests[0]); init_waitqueue_head(&q->wait_for_requests[1]); @@ -591,6 +575,121 @@ printk(KERN_ERR "drive_stat_acct: cmd not R/W?\n"); } +/* Return up to two hd_structs on which to do IO accounting for a given + * request. On a partitioned device, we want to account both against + * the partition and against the whole disk. */ +static void locate_hd_struct(struct request *req, + struct hd_struct **hd1, + struct hd_struct **hd2) +{ + struct gendisk *gd; + + *hd1 = NULL; + *hd2 = NULL; + + gd = get_gendisk(req->rq_dev); + if (gd && gd->part) { + /* Mask out the partition bits: account for the entire disk */ + int devnr = MINOR(req->rq_dev) >> gd->minor_shift; + int whole_minor = devnr << gd->minor_shift; + *hd1 = &gd->part[whole_minor]; + if (whole_minor != MINOR(req->rq_dev)) + *hd2= &gd->part[MINOR(req->rq_dev)]; + } +} + +/* Round off the performance stats on an hd_struct. The average IO + * queue length and utilisation statistics are maintained by observing + * the current state of the queue length and the amount of time it has + * been in this state for. Normally, that accounting is done on IO + * completion, but that can result in more than a second's worth of IO + * being accounted for within any one second, leading to >100% + * utilisation. To deal with that, we do a round-off before returning + * the results when reading /proc/partitions, accounting immediately for + * all queue usage up to the current jiffies and restarting the counters + * again. */ +void disk_round_stats(struct hd_struct *hd) +{ + unsigned long now = jiffies; + + hd->aveq += (hd->ios_in_flight * (jiffies - hd->last_queue_change)); + hd->last_queue_change = now; + + if (hd->ios_in_flight) + hd->io_ticks += (now - hd->last_idle_time); + hd->last_idle_time = now; +} + + +static inline void down_ios(struct hd_struct *hd) +{ + disk_round_stats(hd); + --hd->ios_in_flight; +} + +static inline void up_ios(struct hd_struct *hd) +{ + disk_round_stats(hd); + ++hd->ios_in_flight; +} + +static void account_io_start(struct hd_struct *hd, struct request *req, + int merge, int sectors) +{ + switch (req->cmd) { + case READ: + if (merge) + hd->rd_merges++; + hd->rd_sectors += sectors; + break; + case WRITE: + if (merge) + hd->wr_merges++; + hd->wr_sectors += sectors; + break; + default: + } + if (!merge) + up_ios(hd); +} + +static void account_io_end(struct hd_struct *hd, struct request *req) +{ + unsigned long duration = jiffies - req->start_time; + switch (req->cmd) { + case READ: + hd->rd_ticks += duration; + hd->rd_ios++; + break; + case WRITE: + hd->wr_ticks += duration; + hd->wr_ios++; + break; + default: + } + down_ios(hd); +} + +void req_new_io(struct request *req, int merge, int sectors) +{ + struct hd_struct *hd1, *hd2; + locate_hd_struct(req, &hd1, &hd2); + if (hd1) + account_io_start(hd1, req, merge, sectors); + if (hd2) + account_io_start(hd2, req, merge, sectors); +} + +void req_finished_io(struct request *req) +{ + struct hd_struct *hd1, *hd2; + locate_hd_struct(req, &hd1, &hd2); + if (hd1) + account_io_end(hd1, req); + if (hd2) + account_io_end(hd2, req); +} + /* * add-request adds a request to the linked list. * io_request_lock is held and interrupts disabled, as we muck with the @@ -633,7 +732,7 @@ */ if (q) { list_add(&req->queue, &q->rq[rw].free); - if (++q->rq[rw].count >= q->batch_requests && + if (++q->rq[rw].count >= batch_requests && waitqueue_active(&q->wait_for_requests[rw])) wake_up(&q->wait_for_requests[rw]); } @@ -648,6 +747,7 @@ int max_segments) { struct request *next; + struct hd_struct *hd1, *hd2; next = blkdev_next_request(req); if (req->sector + req->nr_sectors != next->sector) @@ -671,6 +771,15 @@ req->bhtail = next->bhtail; req->nr_sectors = req->hard_nr_sectors += next->hard_nr_sectors; list_del(&next->queue); + + /* One last thing: we have removed a request, so we now have one + less expected IO to complete for accounting purposes. */ + + locate_hd_struct(req, &hd1, &hd2); + if (hd1) + down_ios(hd1); + if (hd2) + down_ios(hd2); blkdev_release_request(next); } @@ -778,6 +887,7 @@ req->nr_sectors = req->hard_nr_sectors += count; blk_started_io(count); drive_stat_acct(req->rq_dev, req->cmd, count, 0); + req_new_io(req, 1, count); attempt_back_merge(q, req, max_sectors, max_segments); goto out; @@ -791,10 +901,12 @@ req->bh = bh; req->buffer = bh->b_data; req->current_nr_sectors = count; + req->hard_cur_sectors = count; req->sector = req->hard_sector = sector; req->nr_sectors = req->hard_nr_sectors += count; blk_started_io(count); drive_stat_acct(req->rq_dev, req->cmd, count, 0); + req_new_io(req, 1, count); attempt_front_merge(q, head, req, max_sectors, max_segments); goto out; @@ -825,7 +937,7 @@ * See description above __get_request_wait() */ if (rw_ahead) { - if (q->rq[rw].count < q->batch_requests) { + if (q->rq[rw].count < batch_requests) { spin_unlock_irq(&io_request_lock); goto end_io; } @@ -849,6 +961,7 @@ req->hard_sector = req->sector = sector; req->hard_nr_sectors = req->nr_sectors = count; req->current_nr_sectors = count; + req->hard_cur_sectors = count; req->nr_segments = 1; /* Always 1 for a new request. */ req->nr_hw_segments = 1; /* Always 1 for a new request. */ req->buffer = bh->b_data; @@ -856,6 +969,8 @@ req->bh = bh; req->bhtail = bh; req->rq_dev = bh->b_rdev; + req->start_time = jiffies; + req_new_io(req, 0, count); blk_started_io(count); add_request(q, req, insert_here); out: @@ -981,7 +1096,6 @@ BUG(); set_bit(BH_Req, &bh->b_state); - set_bit(BH_Launder, &bh->b_state); /* * First step, 'identity mapping' - RAID or LVM might @@ -1002,6 +1116,38 @@ } } +/* + * submit_bh_blknr() - same as submit_bh() except that b_rsector is + * set to b_blocknr. Used for RAW VARY. + */ +void submit_bh_blknr(int rw, struct buffer_head * bh) +{ + int count = bh->b_size >> 9; + + if (!test_bit(BH_Lock, &bh->b_state)) + BUG(); + + set_bit(BH_Req, &bh->b_state); + + /* + * First step, 'identity mapping' - RAID or LVM might + * further remap this. + */ + bh->b_rdev = bh->b_dev; + bh->b_rsector = bh->b_blocknr; + + generic_make_request(rw, bh); + + switch (rw) { + case WRITE: + kstat.pgpgout += count; + break; + default: + kstat.pgpgin += count; + break; + } +} + /** * ll_rw_block: low-level access to block devices * @rw: whether to %READ or %WRITE or maybe %READA (readahead) @@ -1154,6 +1300,7 @@ req->nr_sectors = req->hard_nr_sectors; req->current_nr_sectors = bh->b_size >> 9; + req->hard_cur_sectors = req->current_nr_sectors; if (req->nr_sectors < req->current_nr_sectors) { req->nr_sectors = req->current_nr_sectors; printk("end_request: buffer-list destroyed\n"); @@ -1169,13 +1316,17 @@ { if (req->waiting != NULL) complete(req->waiting); + req_finished_io(req); blkdev_release_request(req); } +#define MB(kb) ((kb) << 10) + int __init blk_dev_init(void) { struct blk_dev_struct *dev; + int total_ram; /* kilobytes */ request_cachep = kmem_cache_create("blkdev_requests", sizeof(struct request), @@ -1191,6 +1342,24 @@ memset(max_readahead, 0, sizeof(max_readahead)); memset(max_sectors, 0, sizeof(max_sectors)); + total_ram = nr_free_pages() << (PAGE_SHIFT - 10); + + /* + * Free request slots per queue. + * (Half for reads, half for writes) + */ + queue_nr_requests = (total_ram >> 9) & ~15; /* One per half-megabyte */ + if (queue_nr_requests < 32) + queue_nr_requests = 32; + if (queue_nr_requests > 1024) + queue_nr_requests = 1024; + + /* + * Batch frees according to queue length + */ + batch_requests = queue_nr_requests/4; + printk("block: %d slots per queue, batch=%d\n", queue_nr_requests, batch_requests); + #ifdef CONFIG_AMIGA_Z2RAM z2_init(); #endif @@ -1301,7 +1470,6 @@ EXPORT_SYMBOL(io_request_lock); EXPORT_SYMBOL(end_that_request_first); EXPORT_SYMBOL(end_that_request_last); -EXPORT_SYMBOL(blk_grow_request_list); EXPORT_SYMBOL(blk_init_queue); EXPORT_SYMBOL(blk_get_queue); EXPORT_SYMBOL(blk_cleanup_queue); @@ -1309,4 +1477,5 @@ EXPORT_SYMBOL(blk_queue_make_request); EXPORT_SYMBOL(generic_make_request); EXPORT_SYMBOL(blkdev_release_request); +EXPORT_SYMBOL(req_finished_io); EXPORT_SYMBOL(generic_unplug_device); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/block/loop.c linux.19pre5-ac1/drivers/block/loop.c --- linux.19p5/drivers/block/loop.c Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/drivers/block/loop.c Wed Feb 27 18:32:03 2002 @@ -573,9 +573,6 @@ flush_signals(current); spin_unlock_irq(¤t->sigmask_lock); - current->policy = SCHED_OTHER; - current->nice = -20; - spin_lock_irq(&lo->lo_lock); lo->lo_state = Lo_bound; atomic_inc(&lo->lo_pending); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/block/paride/bpck6.c linux.19pre5-ac1/drivers/block/paride/bpck6.c --- linux.19p5/drivers/block/paride/bpck6.c Thu Apr 4 13:19:03 2002 +++ linux.19pre5-ac1/drivers/block/paride/bpck6.c Wed Apr 3 01:36:31 2002 @@ -17,13 +17,15 @@ Version 2.0.0 is the first to have source released Version 2.0.1 is the "Cox-ified" source code Version 2.0.2 - fixed version string usage, and made ppc functions static + Version 2.0.2ac - additional cleanup (privptr now not private to fix 64bit + platforms), use memset, rename clashing PPC define. */ /* PARAMETERS */ int verbose=0; /* set this to 1 to see debugging messages and whatnot */ -#define BACKPACK_VERSION "2.0.2" +#define BACKPACK_VERSION "2.0.2ac" #include #include @@ -40,7 +42,7 @@ -#define PPCSTRUCT(pi) ((PPC *)(pi->private)) +#define PPCSTRUCT(pi) ((PPC_STORAGE *)(pi->privptr)) /****************************************************************/ /* @@ -226,9 +228,9 @@ int i; /* allocate a state structure for this item */ - pi->private=(int)kmalloc(sizeof(PPC),GFP_KERNEL); + pi->privptr=kmalloc(sizeof(PPC_STORAGE),GFP_KERNEL); - if(pi->private==(int)NULL) + if(pi->privptr==NULL) { printk(KERN_ERR "%s: ERROR COULDN'T ALLOCATE MEMORY\n",pi->device); return; @@ -238,10 +240,7 @@ MOD_INC_USE_COUNT; } - for(i=0;iprivate))[i]=0; - } + memset(pi->privptr, 0, sizeof(PPC_STORAGE)); } static void bpck6_release_proto(PIA *pi) @@ -249,7 +248,7 @@ MOD_DEC_USE_COUNT; /* free after use count decremented so that we aren't using it when it is decremented */ - kfree((void *)(pi->private)); + kfree(pi->privptr); } struct pi_protocol bpck6 = { "bpck6", /* name for proto*/ @@ -290,7 +289,7 @@ #ifdef MODULE /*module information*/ -static int init_module(void) +int init_module(void) { printk(KERN_INFO "bpck6: BACKPACK Protocol Driver V"BACKPACK_VERSION"\n"); printk(KERN_INFO "bpck6: Copyright 2001 by Micro Solutions, Inc., DeKalb IL. USA\n"); @@ -303,7 +302,7 @@ return pi_register(&bpck6) - 1; } -void cleanup_module(void) +void cleanup_module(void) { pi_unregister(&bpck6); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/block/paride/paride.h linux.19pre5-ac1/drivers/block/paride/paride.h --- linux.19p5/drivers/block/paride/paride.h Thu Apr 4 13:19:02 2002 +++ linux.19pre5-ac1/drivers/block/paride/paride.h Wed Apr 3 01:34:41 2002 @@ -13,9 +13,10 @@ /* Changes: 1.01 GRG 1998.05.05 init_proto, release_proto + 1.01ac AGC 2002.04.03 added privptr */ -#define PARIDE_H_VERSION "1.01" +#define PARIDE_H_VERSION "1.01ac" /* Some adapters need to know what kind of device they are in @@ -46,7 +47,9 @@ int saved_r2; /* saved port state */ int reserved; /* number of ports reserved */ int private; /* for protocol module */ - + void *privptr; /* private pointer for protocol module */ + /* For 2.5 just make private a ulong but + for 2.4 fixups thats a bit risky.. */ wait_queue_head_t parq; /* semaphore for parport sharing */ void *pardev; /* pointer to pardevice */ char *parname; /* parport name */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/block/paride/ppc6lnx.c linux.19pre5-ac1/drivers/block/paride/ppc6lnx.c --- linux.19p5/drivers/block/paride/ppc6lnx.c Thu Apr 4 13:19:03 2002 +++ linux.19pre5-ac1/drivers/block/paride/ppc6lnx.c Wed Apr 3 00:32:24 2002 @@ -79,7 +79,7 @@ u8 org_data; // original LPT data port contents u8 org_ctrl; // original LPT control port contents u8 cur_ctrl; // current control port contents -} PPC; +} PPC_STORAGE; //*************************************************************************** @@ -101,25 +101,25 @@ //*************************************************************************** -static int ppc6_select(PPC *ppc); -static void ppc6_deselect(PPC *ppc); -static void ppc6_send_cmd(PPC *ppc, u8 cmd); -static void ppc6_wr_data_byte(PPC *ppc, u8 data); -static u8 ppc6_rd_data_byte(PPC *ppc); -static u8 ppc6_rd_port(PPC *ppc, u8 port); -static void ppc6_wr_port(PPC *ppc, u8 port, u8 data); -static void ppc6_rd_data_blk(PPC *ppc, u8 *data, long count); -static void ppc6_wait_for_fifo(PPC *ppc); -static void ppc6_wr_data_blk(PPC *ppc, u8 *data, long count); -static void ppc6_rd_port16_blk(PPC *ppc, u8 port, u8 *data, long length); -static void ppc6_wr_port16_blk(PPC *ppc, u8 port, u8 *data, long length); -static void ppc6_wr_extout(PPC *ppc, u8 regdata); -static int ppc6_open(PPC *ppc); -static void ppc6_close(PPC *ppc); +static int ppc6_select(PPC_STORAGE *ppc); +static void ppc6_deselect(PPC_STORAGE *ppc); +static void ppc6_send_cmd(PPC_STORAGE *ppc, u8 cmd); +static void ppc6_wr_data_byte(PPC_STORAGE *ppc, u8 data); +static u8 ppc6_rd_data_byte(PPC_STORAGE *ppc); +static u8 ppc6_rd_port(PPC_STORAGE *ppc, u8 port); +static void ppc6_wr_port(PPC_STORAGE *ppc, u8 port, u8 data); +static void ppc6_rd_data_blk(PPC_STORAGE *ppc, u8 *data, long count); +static void ppc6_wait_for_fifo(PPC_STORAGE *ppc); +static void ppc6_wr_data_blk(PPC_STORAGE *ppc, u8 *data, long count); +static void ppc6_rd_port16_blk(PPC_STORAGE *ppc, u8 port, u8 *data, long length); +static void ppc6_wr_port16_blk(PPC_STORAGE *ppc, u8 port, u8 *data, long length); +static void ppc6_wr_extout(PPC_STORAGE *ppc, u8 regdata); +static int ppc6_open(PPC_STORAGE *ppc); +static void ppc6_close(PPC_STORAGE *ppc); //*************************************************************************** -static int ppc6_select(PPC *ppc) +static int ppc6_select(PPC_STORAGE *ppc) { u8 i, j, k; @@ -205,7 +205,7 @@ //*************************************************************************** -static void ppc6_deselect(PPC *ppc) +static void ppc6_deselect(PPC_STORAGE *ppc) { if (ppc->mode & 4) // EPP ppc->cur_ctrl |= port_init; @@ -223,7 +223,7 @@ //*************************************************************************** -static void ppc6_send_cmd(PPC *ppc, u8 cmd) +static void ppc6_send_cmd(PPC_STORAGE *ppc, u8 cmd) { switch(ppc->mode) { @@ -254,7 +254,7 @@ //*************************************************************************** -static void ppc6_wr_data_byte(PPC *ppc, u8 data) +static void ppc6_wr_data_byte(PPC_STORAGE *ppc, u8 data) { switch(ppc->mode) { @@ -285,7 +285,7 @@ //*************************************************************************** -static u8 ppc6_rd_data_byte(PPC *ppc) +static u8 ppc6_rd_data_byte(PPC_STORAGE *ppc) { u8 data = 0; @@ -358,7 +358,7 @@ //*************************************************************************** -static u8 ppc6_rd_port(PPC *ppc, u8 port) +static u8 ppc6_rd_port(PPC_STORAGE *ppc, u8 port) { ppc6_send_cmd(ppc,(u8)(port | ACCESS_PORT | ACCESS_READ)); @@ -367,7 +367,7 @@ //*************************************************************************** -static void ppc6_wr_port(PPC *ppc, u8 port, u8 data) +static void ppc6_wr_port(PPC_STORAGE *ppc, u8 port, u8 data) { ppc6_send_cmd(ppc,(u8)(port | ACCESS_PORT | ACCESS_WRITE)); @@ -376,7 +376,7 @@ //*************************************************************************** -static void ppc6_rd_data_blk(PPC *ppc, u8 *data, long count) +static void ppc6_rd_data_blk(PPC_STORAGE *ppc, u8 *data, long count) { switch(ppc->mode) { @@ -512,7 +512,7 @@ //*************************************************************************** -static void ppc6_wait_for_fifo(PPC *ppc) +static void ppc6_wait_for_fifo(PPC_STORAGE *ppc) { int i; @@ -525,7 +525,7 @@ //*************************************************************************** -static void ppc6_wr_data_blk(PPC *ppc, u8 *data, long count) +static void ppc6_wr_data_blk(PPC_STORAGE *ppc, u8 *data, long count) { switch(ppc->mode) { @@ -644,7 +644,7 @@ //*************************************************************************** -static void ppc6_rd_port16_blk(PPC *ppc, u8 port, u8 *data, long length) +static void ppc6_rd_port16_blk(PPC_STORAGE *ppc, u8 port, u8 *data, long length) { length = length << 1; @@ -664,7 +664,7 @@ //*************************************************************************** -static void ppc6_wr_port16_blk(PPC *ppc, u8 port, u8 *data, long length) +static void ppc6_wr_port16_blk(PPC_STORAGE *ppc, u8 port, u8 *data, long length) { length = length << 1; @@ -684,7 +684,7 @@ //*************************************************************************** -static void ppc6_wr_extout(PPC *ppc, u8 regdata) +static void ppc6_wr_extout(PPC_STORAGE *ppc, u8 regdata) { ppc6_send_cmd(ppc,(REG_VERSION | ACCESS_REG | ACCESS_WRITE)); @@ -693,7 +693,7 @@ //*************************************************************************** -static int ppc6_open(PPC *ppc) +static int ppc6_open(PPC_STORAGE *ppc) { int ret; @@ -717,7 +717,7 @@ //*************************************************************************** -static void ppc6_close(PPC *ppc) +static void ppc6_close(PPC_STORAGE *ppc) { ppc6_deselect(ppc); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/Config.in linux.19pre5-ac1/drivers/char/Config.in --- linux.19p5/drivers/char/Config.in Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/drivers/char/Config.in Wed Apr 3 00:33:58 2002 @@ -177,18 +177,11 @@ bool 'Watchdog Timer Support' CONFIG_WATCHDOG if [ "$CONFIG_WATCHDOG" != "n" ]; then bool ' Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT - tristate ' Software Watchdog' CONFIG_SOFT_WATCHDOG - tristate ' WDT Watchdog timer' CONFIG_WDT - tristate ' WDT PCI Watchdog timer' CONFIG_WDTPCI - if [ "$CONFIG_WDT" != "n" ]; then - bool ' WDT501 features' CONFIG_WDT_501 - if [ "$CONFIG_WDT_501" = "y" ]; then - bool ' Fan Tachometer' CONFIG_WDT_501_FAN - fi - fi - tristate ' Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG tristate ' Acquire SBC Watchdog Timer' CONFIG_ACQUIRE_WDT tristate ' Advantech SBC Watchdog Timer' CONFIG_ADVANTECH_WDT + tristate ' ALi M7101 PMU Watchdog Timer' CONFIG_ALIM7101_WDT + tristate ' AMD "Elan" SC520 Watchdog Timer' CONFIG_SC520_WDT + tristate ' Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then tristate ' DC21285 watchdog' CONFIG_21285_WATCHDOG if [ "$CONFIG_ARCH_NETWINDER" = "y" ]; then @@ -197,14 +190,25 @@ fi tristate ' Eurotech CPU-1220/1410 Watchdog Timer' CONFIG_EUROTECH_WDT tristate ' IB700 SBC Watchdog Timer' CONFIG_IB700_WDT + tristate ' ICP ELectronics Wafer 5823 Watchdog' CONFIG_WAFER_WDT + if [ "$CONFIG_SGI_IP22" = "y" ]; then + dep_tristate ' Indy/I2 Hardware Watchdog' CONFIG_INDYDOG $CONFIG_SGI_IP22 + fi tristate ' Intel i810 TCO timer / Watchdog' CONFIG_I810_TCO tristate ' Mixcom Watchdog' CONFIG_MIXCOMWD tristate ' SBC-60XX Watchdog Timer' CONFIG_60XX_WDT + dep_tristate ' SC1200 Watchdog Timer (EXPERIMENTAL)' CONFIG_SC1200_WDT $CONFIG_EXPERIMENTAL + tristate ' Software Watchdog' CONFIG_SOFT_WATCHDOG tristate ' W83877F (EMACS) Watchdog Timer' CONFIG_W83877F_WDT - tristate ' ZF MachZ Watchdog' CONFIG_MACHZ_WDT - if [ "$CONFIG_SGI_IP22" = "y" ]; then - tristate ' Indy/I2 Hardware Watchdog' CONFIG_INDYDOG + tristate ' WDT Watchdog timer' CONFIG_WDT + tristate ' WDT PCI Watchdog timer' CONFIG_WDTPCI + if [ "$CONFIG_WDT" != "n" ]; then + bool ' WDT501 features' CONFIG_WDT_501 + if [ "$CONFIG_WDT_501" = "y" ]; then + bool ' Fan Tachometer' CONFIG_WDT_501_FAN + fi fi + tristate ' ZF MachZ Watchdog' CONFIG_MACHZ_WDT fi endmenu @@ -219,6 +223,7 @@ dep_tristate 'AMD 768 Random Number Generator support' CONFIG_AMD_RNG $CONFIG_PCI dep_tristate 'Intel i8x0 Random Number Generator support' CONFIG_INTEL_RNG $CONFIG_PCI +dep_tristate 'AMD 762/768 native power management' CONFIG_AMD_PM768 $CONFIG_PCI tristate '/dev/nvram support' CONFIG_NVRAM tristate 'Enhanced Real Time Clock Support' CONFIG_RTC if [ "$CONFIG_IA64" = "y" ]; then @@ -277,4 +282,8 @@ if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then tristate ' ITE GPIO' CONFIG_ITE_GPIO fi + +if [ "$CONFIG_X86" = "y" ]; then + tristate 'ACP Modem (Mwave) support' CONFIG_MWAVE +fi endmenu diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/Makefile linux.19pre5-ac1/drivers/char/Makefile --- linux.19p5/drivers/char/Makefile Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/drivers/char/Makefile Mon Mar 25 18:05:23 2002 @@ -213,6 +213,7 @@ obj-$(CONFIG_DS1620) += ds1620.o obj-$(CONFIG_INTEL_RNG) += i810_rng.o obj-$(CONFIG_AMD_RNG) += amd768_rng.o +obj-$(CONFIG_AMD_PM768) += amd768_pm.o obj-$(CONFIG_ITE_GPIO) += ite_gpio.o obj-$(CONFIG_AU1000_GPIO) += au1000_gpio.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/agp/agpgart_be.c linux.19pre5-ac1/drivers/char/agp/agpgart_be.c --- linux.19p5/drivers/char/agp/agpgart_be.c Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/drivers/char/agp/agpgart_be.c Fri Mar 1 21:28:20 2002 @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/amd768_pm.c linux.19pre5-ac1/drivers/char/amd768_pm.c --- linux.19p5/drivers/char/amd768_pm.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/char/amd768_pm.c Sun Feb 10 21:28:33 2002 @@ -0,0 +1,151 @@ +/* + * Native power management driver for the AMD 760MPx series + * + * (c) Copyright 2002, Red Hat Inc, + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static u32 pmbase; /* PMxx I/O base */ +static struct pci_dev *amd762; + +/* + * amd768pm_init_one - look for and attempt to init PM + */ +static int __init amd768pm_init_one (struct pci_dev *dev) +{ + u32 reg; + u8 rnen; + int i; + + amd762 = pci_find_device(0x1022, 0x700C, NULL); + if(amd762 == NULL) + return -ENODEV; + + pci_read_config_dword(amd762, 0x70, ®); + if(!(reg & (1<<18))) + { + printk(KERN_INFO "AMD768_pm: enabling self refresh.\n"); + reg |= (1<<18); /* Enable self refresh */ + pci_write_config_dword(amd762, 0x70, reg); + } + + pci_read_config_dword(amd762, 0x58, ®); + if(reg&(1<<19)) + { + printk(KERN_INFO "AMD768_pm: DRAM refresh enabled.\n"); + reg &= ~(1<<19); /* Disable to allow self refresh modes */ + pci_write_config_dword(amd762, 0x58, reg); + } + + for(i=0; i 2) + { + printk(KERN_ERR "Only single and dual processor AMD762/768 is supported.\n"); + return -ENODEV; + } + pci_for_each_dev(pdev) { + if (pci_match_device (amd768pm_pci_tbl, pdev) != NULL) + goto match; + } + + return -ENODEV; + +match: + rc = amd768pm_init_one (pdev); + if (rc) + return rc; + return 0; +} + + +/* + * amd768pm_cleanup - shutdown the AMD pm module + */ +static void __exit amd768pm_cleanup (void) +{ +} + + +module_init (amd768pm_init); +module_exit (amd768pm_cleanup); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/Config.in linux.19pre5-ac1/drivers/char/drm/Config.in --- linux.19p5/drivers/char/drm/Config.in Thu Apr 4 13:19:12 2002 +++ linux.19pre5-ac1/drivers/char/drm/Config.in Wed Feb 13 00:35:46 2002 @@ -10,5 +10,6 @@ tristate ' ATI Rage 128' CONFIG_DRM_R128 dep_tristate ' ATI Radeon' CONFIG_DRM_RADEON $CONFIG_AGP dep_tristate ' Intel I810' CONFIG_DRM_I810 $CONFIG_AGP +dep_tristate ' Intel 830M' CONFIG_DRM_I830 $CONFIG_AGP dep_tristate ' Matrox g200/g400' CONFIG_DRM_MGA $CONFIG_AGP dep_tristate ' SiS' CONFIG_DRM_SIS $CONFIG_AGP diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/Makefile linux.19pre5-ac1/drivers/char/drm/Makefile --- linux.19p5/drivers/char/drm/Makefile Thu Apr 4 13:19:11 2002 +++ linux.19pre5-ac1/drivers/char/drm/Makefile Wed Feb 13 00:36:27 2002 @@ -3,13 +3,15 @@ # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. O_TARGET := drm.o -list-multi := gamma.o tdfx.o r128.o mga.o i810.o radeon.o ffb.o sis.o +list-multi := gamma.o tdfx.o r128.o mga.o i810.o i830.o radeon.o ffb.o sis.o gamma-objs := gamma_drv.o gamma_dma.o tdfx-objs := tdfx_drv.o r128-objs := r128_drv.o r128_cce.o r128_state.o mga-objs := mga_drv.o mga_dma.o mga_state.o mga_warp.o i810-objs := i810_drv.o i810_dma.o +i830-objs := i830_drv.o i830_dma.o + radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o ffb-objs := ffb_drv.o ffb_context.o sis-objs := sis_drv.o sis_ds.o sis_mm.o @@ -20,6 +22,7 @@ obj-$(CONFIG_DRM_RADEON)+= radeon.o obj-$(CONFIG_DRM_MGA) += mga.o obj-$(CONFIG_DRM_I810) += i810.o +obj-$(CONFIG_DRM_I830) += i830.o obj-$(CONFIG_DRM_FFB) += ffb.o obj-$(CONFIG_DRM_SIS) += sis.o @@ -37,6 +40,9 @@ i810.o: $(i810-objs) $(lib) $(LD) -r -o $@ $(i810-objs) $(lib) +i830.o: $(i830-objs) $(lib) + $(LD) -r -o $@ $(i830-objs) $(lib) + r128.o: $(r128-objs) $(lib) $(LD) -r -o $@ $(r128-objs) $(lib) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/drm.h linux.19pre5-ac1/drivers/char/drm/drm.h --- linux.19p5/drivers/char/drm/drm.h Thu Apr 4 13:19:11 2002 +++ linux.19pre5-ac1/drivers/char/drm/drm.h Wed Feb 13 00:35:28 2002 @@ -104,9 +104,8 @@ #include "i810_drm.h" #include "r128_drm.h" #include "radeon_drm.h" -#if defined(CONFIG_DRM_SIS) || defined(CONFIG_DRM_SIS_MODULE) #include "sis_drm.h" -#endif +#include "i830_drm.h" typedef struct drm_version { int version_major; /* Major version */ @@ -449,6 +448,12 @@ #define DRM_IOCTL_I810_SWAP DRM_IO( 0x46) #define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t) #define DRM_IOCTL_I810_DOCOPY DRM_IO( 0x48) +#define DRM_IOCTL_I810_OV0INFO DRM_IOR( 0x49, drm_i810_overlay_t) +#define DRM_IOCTL_I810_FSTATUS DRM_IO ( 0x4a) +#define DRM_IOCTL_I810_OV0FLIP DRM_IO ( 0x4b) +#define DRM_IOCTL_I810_MC DRM_IOW( 0x4c, drm_i810_mc_t) +#define DRM_IOCTL_I810_RSTATUS DRM_IO ( 0x4d ) + /* Rage 128 specific ioctls */ #define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t) @@ -483,7 +488,6 @@ #define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t) #define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4e, drm_radeon_texture_t) -#if defined(CONFIG_DRM_SIS) || defined(CONFIG_DRM_SIS_MODULE) /* SiS specific ioctls */ #define SIS_IOCTL_FB_ALLOC DRM_IOWR(0x44, drm_sis_mem_t) #define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t) @@ -493,6 +497,16 @@ #define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t) #define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49) #define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50) -#endif + +/* I830 specific ioctls */ +#define DRM_IOCTL_I830_INIT DRM_IOW( 0x40, drm_i830_init_t) +#define DRM_IOCTL_I830_VERTEX DRM_IOW( 0x41, drm_i830_vertex_t) +#define DRM_IOCTL_I830_CLEAR DRM_IOW( 0x42, drm_i830_clear_t) +#define DRM_IOCTL_I830_FLUSH DRM_IO ( 0x43) +#define DRM_IOCTL_I830_GETAGE DRM_IO ( 0x44) +#define DRM_IOCTL_I830_GETBUF DRM_IOWR(0x45, drm_i830_dma_t) +#define DRM_IOCTL_I830_SWAP DRM_IO ( 0x46) +#define DRM_IOCTL_I830_COPY DRM_IOW( 0x47, drm_i830_copy_t) +#define DRM_IOCTL_I830_DOCOPY DRM_IO ( 0x48) #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/drmP.h linux.19pre5-ac1/drivers/char/drm/drmP.h --- linux.19p5/drivers/char/drm/drmP.h Thu Apr 4 13:19:11 2002 +++ linux.19pre5-ac1/drivers/char/drm/drmP.h Thu Apr 4 15:51:45 2002 @@ -66,13 +66,8 @@ #include #include #endif -#if LINUX_VERSION_CODE >= 0x020100 /* KERNEL_VERSION(2,1,0) */ #include #include -#endif -#if LINUX_VERSION_CODE < 0x020400 -#include "compat-pre24.h" -#endif #include #include "drm.h" @@ -81,12 +76,6 @@ #define page_to_bus(page) ((unsigned int)(virt_to_bus(page_address(page)))) #endif -/* We just use virt_to_bus for pci_map_single on older kernels */ -#if LINUX_VERSION_CODE < 0x020400 -#define pci_map_single(hwdev, ptr, size, direction) virt_to_bus(ptr) -#define pci_unmap_single(hwdev, dma_addr, size, direction) -#endif - /* DRM template customization defaults */ #ifndef __HAVE_AGP @@ -119,87 +108,6 @@ #define __REALLY_HAVE_MTRR (__HAVE_MTRR && defined(CONFIG_MTRR)) -/* Begin the DRM... - */ - -#define DRM_DEBUG_CODE 2 /* Include debugging code (if > 1, then - also include looping detection. */ - -#define DRM_HASH_SIZE 16 /* Size of key hash table */ -#define DRM_KERNEL_CONTEXT 0 /* Change drm_resctx if changed */ -#define DRM_RESERVED_CONTEXTS 1 /* Change drm_resctx if changed */ -#define DRM_LOOPING_LIMIT 5000000 -#define DRM_BSZ 1024 /* Buffer size for /dev/drm? output */ -#define DRM_TIME_SLICE (HZ/20) /* Time slice for GLXContexts */ -#define DRM_LOCK_SLICE 1 /* Time slice for lock, in jiffies */ - -#define DRM_FLAG_DEBUG 0x01 -#define DRM_FLAG_NOCTX 0x02 - -#define DRM_MEM_DMA 0 -#define DRM_MEM_SAREA 1 -#define DRM_MEM_DRIVER 2 -#define DRM_MEM_MAGIC 3 -#define DRM_MEM_IOCTLS 4 -#define DRM_MEM_MAPS 5 -#define DRM_MEM_VMAS 6 -#define DRM_MEM_BUFS 7 -#define DRM_MEM_SEGS 8 -#define DRM_MEM_PAGES 9 -#define DRM_MEM_FILES 10 -#define DRM_MEM_QUEUES 11 -#define DRM_MEM_CMDS 12 -#define DRM_MEM_MAPPINGS 13 -#define DRM_MEM_BUFLISTS 14 -#define DRM_MEM_AGPLISTS 15 -#define DRM_MEM_TOTALAGP 16 -#define DRM_MEM_BOUNDAGP 17 -#define DRM_MEM_CTXBITMAP 18 -#define DRM_MEM_STUB 19 -#define DRM_MEM_SGLISTS 20 - -#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8) - - /* Backward compatibility section */ - /* _PAGE_WT changed to _PAGE_PWT in 2.2.6 */ -#ifndef _PAGE_PWT -#define _PAGE_PWT _PAGE_WT -#endif - /* Wait queue declarations changed in 2.3.1 */ -#ifndef DECLARE_WAITQUEUE -#define DECLARE_WAITQUEUE(w,c) struct wait_queue w = { c, NULL } -typedef struct wait_queue *wait_queue_head_t; -#define init_waitqueue_head(q) *q = NULL; -#endif - - /* _PAGE_4M changed to _PAGE_PSE in 2.3.23 */ -#ifndef _PAGE_PSE -#define _PAGE_PSE _PAGE_4M -#endif - - /* vm_offset changed to vm_pgoff in 2.3.25 */ -#if LINUX_VERSION_CODE < 0x020319 -#define VM_OFFSET(vma) ((vma)->vm_offset) -#else -#define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT) -#endif - - /* *_nopage return values defined in 2.3.26 */ -#ifndef NOPAGE_SIGBUS -#define NOPAGE_SIGBUS 0 -#endif -#ifndef NOPAGE_OOM -#define NOPAGE_OOM 0 -#endif - - /* module_init/module_exit added in 2.3.13 */ -#ifndef module_init -#define module_init(x) int init_module(void) { return x(); } -#endif -#ifndef module_exit -#define module_exit(x) void cleanup_module(void) { x(); } -#endif - /* Generic cmpxchg added in 2.3.x */ #ifndef __HAVE_ARCH_CMPXCHG /* Include this here so that driver can be @@ -211,7 +119,7 @@ unsigned long prev, cmp; __asm__ __volatile__( - "1: ldl_l %0,%5\n" + "1: ldl_l %0,%2\n" " cmpeq %0,%3,%1\n" " beq %1,2f\n" " mov %4,%1\n" @@ -222,8 +130,7 @@ "3: br 1b\n" ".previous" : "=&r"(prev), "=&r"(cmp), "=m"(*m) - : "r"((long) old), "r"(new), "m"(*m) - : "memory" ); + : "r"((long) old), "r"(new), "m"(*m)); return prev; } @@ -234,7 +141,7 @@ unsigned long prev, cmp; __asm__ __volatile__( - "1: ldq_l %0,%5\n" + "1: ldq_l %0,%2\n" " cmpeq %0,%3,%1\n" " beq %1,2f\n" " mov %4,%1\n" @@ -245,8 +152,7 @@ "3: br 1b\n" ".previous" : "=&r"(prev), "=&r"(cmp), "=m"(*m) - : "r"((long) old), "r"(new), "m"(*m) - : "memory" ); + : "r"((long) old), "r"(new), "m"(*m)); return prev; } @@ -298,42 +204,54 @@ return old; } -#elif defined(__powerpc__) -extern void __cmpxchg_called_with_bad_pointer(void); -static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, - unsigned long new, int size) -{ - unsigned long prev; - - switch (size) { - case 4: - __asm__ __volatile__( - "sync;" - "0: lwarx %0,0,%1 ;" - " cmpl 0,%0,%3;" - " bne 1f;" - " stwcx. %2,0,%1;" - " bne- 0b;" - "1: " - "sync;" - : "=&r"(prev) - : "r"(ptr), "r"(new), "r"(old) - : "cr0", "memory"); - return prev; - } - __cmpxchg_called_with_bad_pointer(); - return old; -} - -#endif /* i386, powerpc & alpha */ - -#ifndef __alpha__ #define cmpxchg(ptr,o,n) \ ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o), \ (unsigned long)(n),sizeof(*(ptr)))) +#endif /* i386 & alpha */ #endif -#endif /* !__HAVE_ARCH_CMPXCHG */ +/* Begin the DRM... + */ + +#define DRM_DEBUG_CODE 2 /* Include debugging code (if > 1, then + also include looping detection. */ + +#define DRM_HASH_SIZE 16 /* Size of key hash table */ +#define DRM_KERNEL_CONTEXT 0 /* Change drm_resctx if changed */ +#define DRM_RESERVED_CONTEXTS 1 /* Change drm_resctx if changed */ +#define DRM_LOOPING_LIMIT 5000000 +#define DRM_BSZ 1024 /* Buffer size for /dev/drm? output */ +#define DRM_TIME_SLICE (HZ/20) /* Time slice for GLXContexts */ +#define DRM_LOCK_SLICE 1 /* Time slice for lock, in jiffies */ + +#define DRM_FLAG_DEBUG 0x01 +#define DRM_FLAG_NOCTX 0x02 + +#define DRM_MEM_DMA 0 +#define DRM_MEM_SAREA 1 +#define DRM_MEM_DRIVER 2 +#define DRM_MEM_MAGIC 3 +#define DRM_MEM_IOCTLS 4 +#define DRM_MEM_MAPS 5 +#define DRM_MEM_VMAS 6 +#define DRM_MEM_BUFS 7 +#define DRM_MEM_SEGS 8 +#define DRM_MEM_PAGES 9 +#define DRM_MEM_FILES 10 +#define DRM_MEM_QUEUES 11 +#define DRM_MEM_CMDS 12 +#define DRM_MEM_MAPPINGS 13 +#define DRM_MEM_BUFLISTS 14 +#define DRM_MEM_AGPLISTS 15 +#define DRM_MEM_TOTALAGP 16 +#define DRM_MEM_BOUNDAGP 17 +#define DRM_MEM_CTXBITMAP 18 +#define DRM_MEM_STUB 19 +#define DRM_MEM_SGLISTS 20 + +#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8) + +#define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT) /* Macros to make printk easier */ #define DRM_ERROR(fmt, arg...) \ @@ -778,34 +696,18 @@ struct poll_table_struct *wait); /* Mapping support (drm_vm.h) */ -#if LINUX_VERSION_CODE < 0x020317 -extern unsigned long DRM(vm_nopage)(struct vm_area_struct *vma, - unsigned long address, - int unused); -extern unsigned long DRM(vm_shm_nopage)(struct vm_area_struct *vma, - unsigned long address, - int unused); -extern unsigned long DRM(vm_dma_nopage)(struct vm_area_struct *vma, - unsigned long address, - int unused); -extern unsigned long DRM(vm_sg_nopage)(struct vm_area_struct *vma, - unsigned long address, - int unused); -#else - /* Return type changed in 2.3.23 */ extern struct page *DRM(vm_nopage)(struct vm_area_struct *vma, unsigned long address, - int unused); + int write_access); extern struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma, unsigned long address, - int unused); + int write_access); extern struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma, unsigned long address, - int unused); + int write_access); extern struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma, unsigned long address, - int unused); -#endif + int write_access); extern void DRM(vm_open)(struct vm_area_struct *vma); extern void DRM(vm_close)(struct vm_area_struct *vma); extern void DRM(vm_shm_close)(struct vm_area_struct *vma); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/drm_agpsupport.h linux.19pre5-ac1/drivers/char/drm/drm_agpsupport.h --- linux.19p5/drivers/char/drm/drm_agpsupport.h Thu Apr 4 13:19:11 2002 +++ linux.19pre5-ac1/drivers/char/drm/drm_agpsupport.h Thu Apr 4 15:51:47 2002 @@ -35,12 +35,8 @@ #if __REALLY_HAVE_AGP -#if LINUX_VERSION_CODE < 0x020400 -#include "agpsupport-pre24.h" -#else #define DRM_AGP_GET (drm_agp_t *)inter_module_get("drm_agp") #define DRM_AGP_PUT inter_module_put("drm_agp") -#endif static const drm_agp_t *drm_agp = NULL; @@ -271,24 +267,24 @@ case INTEL_GX: head->chipset = "Intel 440GX"; break; case INTEL_I810: head->chipset = "Intel i810"; break; -#if LINUX_VERSION_CODE >= 0x020400 case INTEL_I815: head->chipset = "Intel i815"; break; +#if LINUX_VERSION_CODE >= 0x020415 case INTEL_I820: head->chipset = "Intel i820"; break; +#endif case INTEL_I840: head->chipset = "Intel i840"; break; +#if LINUX_VERSION_CODE >= 0x020415 case INTEL_I845: head->chipset = "Intel i845"; break; - case INTEL_I850: head->chipset = "Intel i850"; break; #endif + case INTEL_I850: head->chipset = "Intel i850"; break; case VIA_GENERIC: head->chipset = "VIA"; break; case VIA_VP3: head->chipset = "VIA VP3"; break; case VIA_MVP3: head->chipset = "VIA MVP3"; break; -#if LINUX_VERSION_CODE >= 0x020400 case VIA_MVP4: head->chipset = "VIA MVP4"; break; case VIA_APOLLO_KX133: head->chipset = "VIA Apollo KX133"; break; case VIA_APOLLO_KT133: head->chipset = "VIA Apollo KT133"; break; -#endif case VIA_APOLLO_PRO: head->chipset = "VIA Apollo Pro"; break; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/drm_bufs.h linux.19pre5-ac1/drivers/char/drm/drm_bufs.h --- linux.19p5/drivers/char/drm/drm_bufs.h Thu Apr 4 13:19:11 2002 +++ linux.19pre5-ac1/drivers/char/drm/drm_bufs.h Thu Apr 4 15:51:45 2002 @@ -229,11 +229,7 @@ DRM(free)(list, sizeof(*list), DRM_MEM_MAPS); for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) { -#if LINUX_VERSION_CODE >= 0x020300 if (pt->vma->vm_private_data == map) found_maps++; -#else - if (pt->vma->vm_pte == map) found_maps++; -#endif } if(!found_maps) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/drm_drv.h linux.19pre5-ac1/drivers/char/drm/drm_drv.h --- linux.19p5/drivers/char/drm/drm_drv.h Thu Apr 4 13:19:12 2002 +++ linux.19pre5-ac1/drivers/char/drm/drm_drv.h Wed Feb 13 00:35:28 2002 @@ -113,7 +113,6 @@ #define DRIVER_IOCTLS #endif #ifndef DRIVER_FOPS -#if LINUX_VERSION_CODE >= 0x020400 #define DRIVER_FOPS \ static struct file_operations DRM(fops) = { \ owner: THIS_MODULE, \ @@ -126,19 +125,6 @@ fasync: DRM(fasync), \ poll: DRM(poll), \ } -#else -#define DRIVER_FOPS \ -static struct file_operations DRM(fops) = { \ - open: DRM(open), \ - flush: DRM(flush), \ - release: DRM(release), \ - ioctl: DRM(ioctl), \ - mmap: DRM(mmap), \ - read: DRM(read), \ - fasync: DRM(fasync), \ - poll: DRM(poll), \ -} -#endif #endif @@ -234,7 +220,9 @@ MODULE_AUTHOR( DRIVER_AUTHOR ); MODULE_DESCRIPTION( DRIVER_DESC ); MODULE_PARM( drm_opts, "s" ); +#ifdef MODULE_LICENSE MODULE_LICENSE("GPL and additional rights"); +#endif static int DRM(setup)( drm_device_t *dev ) { @@ -732,9 +720,6 @@ retcode = DRM(open_helper)( inode, filp, dev ); if ( !retcode ) { -#if LINUX_VERSION_CODE < 0x020333 - MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */ -#endif atomic_inc( &dev->counts[_DRM_STAT_OPENS] ); spin_lock( &dev->count_lock ); if ( !dev->open_count++ ) { @@ -853,9 +838,6 @@ * End inline drm_release */ -#if LINUX_VERSION_CODE < 0x020333 - MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */ -#endif atomic_inc( &dev->counts[_DRM_STAT_CLOSES] ); spin_lock( &dev->count_lock ); if ( !--dev->open_count ) { @@ -1047,25 +1029,6 @@ atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] ); -#if __HAVE_KERNEL_CTX_SWITCH - /* We no longer really hold it, but if we are the next - * agent to request it then we should just be able to - * take it immediately and not eat the ioctl. - */ - dev->lock.pid = 0; - { - __volatile__ unsigned int *plock = &dev->lock.hw_lock->lock; - unsigned int old, new, prev, ctx; - - ctx = lock.context; - do { - old = *plock; - new = ctx; - prev = cmpxchg(plock, old, new); - } while (prev != old); - } - wake_up_interruptible(&dev->lock.lock_queue); -#else DRM(lock_transfer)( dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT ); #if __HAVE_DMA_SCHEDULE @@ -1080,7 +1043,6 @@ DRM_ERROR( "\n" ); } } -#endif /* !__HAVE_KERNEL_CTX_SWITCH */ unblock_all_signals(); return 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/drm_fops.h linux.19pre5-ac1/drivers/char/drm/drm_fops.h --- linux.19p5/drivers/char/drm/drm_fops.h Thu Apr 4 13:19:12 2002 +++ linux.19pre5-ac1/drivers/char/drm/drm_fops.h Thu Apr 4 15:51:45 2002 @@ -125,21 +125,31 @@ int avail; int send; int cur; + DECLARE_WAITQUEUE(wait, current); DRM_DEBUG("%p, %p\n", dev->buf_rp, dev->buf_wp); + add_wait_queue(&dev->buf_readers, &wait); + set_current_state(TASK_INTERRUPTIBLE); while (dev->buf_rp == dev->buf_wp) { DRM_DEBUG(" sleeping\n"); if (filp->f_flags & O_NONBLOCK) { + remove_wait_queue(&dev->buf_readers, &wait); + set_current_state(TASK_RUNNING); return -EAGAIN; } - interruptible_sleep_on(&dev->buf_readers); + schedule(); /* wait for dev->buf_readers */ if (signal_pending(current)) { DRM_DEBUG(" interrupted\n"); + remove_wait_queue(&dev->buf_readers, &wait); + set_current_state(TASK_RUNNING); return -ERESTARTSYS; } DRM_DEBUG(" awake\n"); + set_current_state(TASK_INTERRUPTIBLE); } + remove_wait_queue(&dev->buf_readers, &wait); + set_current_state(TASK_RUNNING); left = (dev->buf_rp + DRM_BSZ - dev->buf_wp) % DRM_BSZ; avail = DRM_BSZ - left; @@ -191,24 +201,8 @@ send -= count; } -#if LINUX_VERSION_CODE < 0x020315 && !defined(KILLFASYNCHASTHREEPARAMETERS) - /* The extra parameter to kill_fasync was added in 2.3.21, and is - _not_ present in _stock_ 2.2.14 and 2.2.15. However, some - distributions patch 2.2.x kernels to add this parameter. The - Makefile.linux attempts to detect this addition and defines - KILLFASYNCHASTHREEPARAMETERS if three parameters are found. */ - if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO); -#else - - /* Parameter added in 2.3.21. */ -#if LINUX_VERSION_CODE < 0x020400 - if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO, POLL_IN); -#else - /* Type of first parameter changed in - Linux 2.4.0-test2... */ if (dev->buf_async) kill_fasync(&dev->buf_async, SIGIO, POLL_IN); -#endif -#endif + DRM_DEBUG("waking\n"); wake_up_interruptible(&dev->buf_readers); return 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/drm_memory.h linux.19pre5-ac1/drivers/char/drm/drm_memory.h --- linux.19p5/drivers/char/drm/drm_memory.h Thu Apr 4 13:19:12 2002 +++ linux.19pre5-ac1/drivers/char/drm/drm_memory.h Thu Apr 4 15:51:45 2002 @@ -85,12 +85,7 @@ } si_meminfo(&si); -#if LINUX_VERSION_CODE < 0x020317 - /* Changed to page count in 2.3.23 */ - DRM(ram_available) = si.totalram >> PAGE_SHIFT; -#else DRM(ram_available) = si.totalram; -#endif DRM(ram_used) = 0; } @@ -257,12 +252,7 @@ for (addr = address, sz = bytes; sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { -#if LINUX_VERSION_CODE >= 0x020400 - /* Argument type changed in 2.4.0-test6/pre8 */ mem_map_reserve(virt_to_page(addr)); -#else - mem_map_reserve(MAP_NR(addr)); -#endif } return address; @@ -283,12 +273,7 @@ for (addr = address, sz = bytes; sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { -#if LINUX_VERSION_CODE >= 0x020400 - /* Argument type changed in 2.4.0-test6/pre8 */ mem_map_unreserve(virt_to_page(addr)); -#else - mem_map_unreserve(MAP_NR(addr)); -#endif } free_pages(address, order); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/drm_stub.h linux.19pre5-ac1/drivers/char/drm/drm_stub.h --- linux.19p5/drivers/char/drm/drm_stub.h Thu Apr 4 13:19:12 2002 +++ linux.19pre5-ac1/drivers/char/drm/drm_stub.h Thu Apr 4 15:51:45 2002 @@ -31,10 +31,6 @@ #define __NO_VERSION__ #include "drmP.h" -#if LINUX_VERSION_CODE < 0x020400 -#include "stubsupport-pre24.h" -#endif - #define DRM_STUB_MAXCARDS 16 /* Enough for one machine */ static struct drm_stub_list { @@ -70,9 +66,7 @@ } static struct file_operations DRM(stub_fops) = { -#if LINUX_VERSION_CODE >= 0x020400 owner: THIS_MODULE, -#endif open: DRM(stub_open) }; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/drm_vm.h linux.19pre5-ac1/drivers/char/drm/drm_vm.h --- linux.19p5/drivers/char/drm/drm_vm.h Thu Apr 4 13:19:12 2002 +++ linux.19pre5-ac1/drivers/char/drm/drm_vm.h Thu Apr 4 15:51:45 2002 @@ -56,16 +56,9 @@ close: DRM(vm_close), }; -#if LINUX_VERSION_CODE < 0x020317 -unsigned long DRM(vm_nopage)(struct vm_area_struct *vma, - unsigned long address, - int unused) -#else - /* Return type changed in 2.3.23 */ struct page *DRM(vm_nopage)(struct vm_area_struct *vma, unsigned long address, - int unused) -#endif + int write_access) { #if __REALLY_HAVE_AGP drm_file_t *priv = vma->vm_file->private_data; @@ -122,11 +115,7 @@ DRM_DEBUG("baddr = 0x%lx page = 0x%p, offset = 0x%lx\n", baddr, __va(agpmem->memory->memory[offset]), offset); -#if LINUX_VERSION_CODE < 0x020317 - return page_address(page); -#else return page; -#endif } vm_nopage_error: #endif /* __REALLY_HAVE_AGP */ @@ -134,22 +123,11 @@ return NOPAGE_SIGBUS; /* Disallow mremap */ } -#if LINUX_VERSION_CODE < 0x020317 -unsigned long DRM(vm_shm_nopage)(struct vm_area_struct *vma, - unsigned long address, - int unused) -#else - /* Return type changed in 2.3.23 */ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma, unsigned long address, - int unused) -#endif + int write_access) { -#if LINUX_VERSION_CODE >= 0x020300 drm_map_t *map = (drm_map_t *)vma->vm_private_data; -#else - drm_map_t *map = (drm_map_t *)vma->vm_pte; -#endif unsigned long offset; unsigned long i; pgd_t *pgd; @@ -175,12 +153,8 @@ page = pte_page(*pte); get_page(page); - DRM_DEBUG("shm_nopage 0x%lx\n", address); -#if LINUX_VERSION_CODE < 0x020317 - return page_address(page); -#else + DRM_DEBUG("0x%08lx => 0x%08x\n", address, page_to_bus(page)); return page; -#endif } /* Special close routine which deletes map information if we are the last @@ -199,25 +173,14 @@ DRM_DEBUG("0x%08lx,0x%08lx\n", vma->vm_start, vma->vm_end - vma->vm_start); -#if LINUX_VERSION_CODE < 0x020333 - MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */ -#endif atomic_dec(&dev->vma_count); -#if LINUX_VERSION_CODE >= 0x020300 map = vma->vm_private_data; -#else - map = vma->vm_pte; -#endif down(&dev->struct_sem); for (pt = dev->vmalist, prev = NULL; pt; pt = next) { next = pt->next; -#if LINUX_VERSION_CODE >= 0x020300 if (pt->vma->vm_private_data == map) found_maps++; -#else - if (pt->vma->vm_pte == map) found_maps++; -#endif if (pt->vma == vma) { if (prev) { prev->next = pt->next; @@ -270,16 +233,9 @@ up(&dev->struct_sem); } -#if LINUX_VERSION_CODE < 0x020317 -unsigned long DRM(vm_dma_nopage)(struct vm_area_struct *vma, - unsigned long address, - int unused) -#else - /* Return type changed in 2.3.23 */ struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma, unsigned long address, - int unused) -#endif + int write_access) { drm_file_t *priv = vma->vm_file->private_data; drm_device_t *dev = priv->dev; @@ -299,30 +255,16 @@ get_page(page); - DRM_DEBUG("dma_nopage 0x%lx (page %lu)\n", address, page_nr); -#if LINUX_VERSION_CODE < 0x020317 - return page_address(page); -#else + DRM_DEBUG("0x%08lx (page %lu) => 0x%08x\n", address, page_nr, + page_to_bus(page)); return page; -#endif } -#if LINUX_VERSION_CODE < 0x020317 -unsigned long DRM(vm_sg_nopage)(struct vm_area_struct *vma, - unsigned long address, - int unused) -#else - /* Return type changed in 2.3.23 */ struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma, unsigned long address, - int unused) -#endif + int write_access) { -#if LINUX_VERSION_CODE >= 0x020300 drm_map_t *map = (drm_map_t *)vma->vm_private_data; -#else - drm_map_t *map = (drm_map_t *)vma->vm_pte; -#endif drm_file_t *priv = vma->vm_file->private_data; drm_device_t *dev = priv->dev; drm_sg_mem_t *entry = dev->sg; @@ -342,11 +284,7 @@ page = entry->pagelist[page_offset]; get_page(page); -#if LINUX_VERSION_CODE < 0x020317 - return page_address(page); -#else return page; -#endif } void DRM(vm_open)(struct vm_area_struct *vma) @@ -358,10 +296,6 @@ DRM_DEBUG("0x%08lx,0x%08lx\n", vma->vm_start, vma->vm_end - vma->vm_start); atomic_inc(&dev->vma_count); -#if LINUX_VERSION_CODE < 0x020333 - /* The map can exist after the fd is closed. */ - MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */ -#endif vma_entry = DRM(alloc)(sizeof(*vma_entry), DRM_MEM_VMAS); if (vma_entry) { @@ -382,9 +316,6 @@ DRM_DEBUG("0x%08lx,0x%08lx\n", vma->vm_start, vma->vm_end - vma->vm_start); -#if LINUX_VERSION_CODE < 0x020333 - MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */ -#endif atomic_dec(&dev->vma_count); down(&dev->struct_sem); @@ -423,13 +354,13 @@ unlock_kernel(); vma->vm_ops = &DRM(vm_dma_ops); - vma->vm_flags |= VM_RESERVED; /* Don't swap */ -#if LINUX_VERSION_CODE < 0x020203 /* KERNEL_VERSION(2,2,3) */ - /* In Linux 2.2.3 and above, this is - handled in do_mmap() in mm/mmap.c. */ - ++filp->f_count; +#if LINUX_VERSION_CODE <= 0x020414 + vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */ +#else + vma->vm_flags |= VM_RESERVED; /* Don't swap */ #endif + vma->vm_file = filp; /* Needed for drm_vm_open() */ DRM(vm_open)(vma); return 0; @@ -531,17 +462,10 @@ vma->vm_flags |= VM_IO; /* not in core dump */ } offset = DRIVER_GET_REG_OFS(); -#ifdef __sparc__ - if (io_remap_page_range(vma->vm_start, - VM_OFFSET(vma) + offset, - vma->vm_end - vma->vm_start, - vma->vm_page_prot, 0)) -#else if (remap_page_range(vma->vm_start, VM_OFFSET(vma) + offset, vma->vm_end - vma->vm_start, vma->vm_page_prot)) -#endif return -EAGAIN; DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx," " offset = 0x%lx\n", @@ -551,34 +475,33 @@ break; case _DRM_SHM: vma->vm_ops = &DRM(vm_shm_ops); -#if LINUX_VERSION_CODE >= 0x020300 vma->vm_private_data = (void *)map; -#else - vma->vm_pte = (unsigned long)map; -#endif /* Don't let this area swap. Change when DRM_KERNEL advisory is supported. */ +#if LINUX_VERSION_CODE <= 0x020414 + vma->vm_flags |= VM_LOCKED; +#else vma->vm_flags |= VM_RESERVED; +#endif break; case _DRM_SCATTER_GATHER: vma->vm_ops = &DRM(vm_sg_ops); -#if LINUX_VERSION_CODE >= 0x020300 vma->vm_private_data = (void *)map; +#if LINUX_VERSION_CODE <= 0x020414 + vma->vm_flags |= VM_LOCKED; #else - vma->vm_pte = (unsigned long)map; + vma->vm_flags |= VM_RESERVED; #endif - vma->vm_flags |= VM_RESERVED; break; default: return -EINVAL; /* This should never happen. */ } +#if LINUX_VERSION_CODE <= 0x020414 + vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */ +#else vma->vm_flags |= VM_RESERVED; /* Don't swap */ - -#if LINUX_VERSION_CODE < 0x020203 /* KERNEL_VERSION(2,2,3) */ - /* In Linux 2.2.3 and above, this is - handled in do_mmap() in mm/mmap.c. */ - ++filp->f_count; #endif + vma->vm_file = filp; /* Needed for drm_vm_open() */ DRM(vm_open)(vma); return 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/i810_dma.c linux.19pre5-ac1/drivers/char/drm/i810_dma.c --- linux.19p5/drivers/char/drm/i810_dma.c Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/drivers/char/drm/i810_dma.c Tue Mar 19 16:02:05 2002 @@ -35,6 +35,7 @@ #include "drmP.h" #include "i810_drv.h" #include /* For task queue support */ +#include /* in case we don't have a 2.3.99-pre6 kernel or later: */ #ifndef VM_DONTCOPY @@ -73,7 +74,7 @@ *(volatile unsigned int *)(virt + outring) = n; \ outring += 4; \ outring &= ringmask; \ -} while (0); +} while (0) static inline void i810_print_status_page(drm_device_t *dev) { @@ -86,6 +87,7 @@ DRM_DEBUG( "hw_status: LpRing Head ptr : %x\n", temp[1]); DRM_DEBUG( "hw_status: IRing Head ptr : %x\n", temp[2]); DRM_DEBUG( "hw_status: Reserved : %x\n", temp[3]); + DRM_DEBUG( "hw_status: Last Render: %x\n", temp[4]); DRM_DEBUG( "hw_status: Driver Counter : %d\n", temp[5]); for(i = 6; i < dma->buf_count + 6; i++) { DRM_DEBUG( "buffer status idx : %d used: %d\n", i - 6, temp[i]); @@ -227,14 +229,9 @@ #else down_write( ¤t->mm->mmap_sem ); #endif -#if LINUX_VERSION_CODE < 0x020399 - retcode = do_munmap((unsigned long)buf_priv->virtual, - (size_t) buf->total); -#else retcode = do_munmap(current->mm, (unsigned long)buf_priv->virtual, - (size_t) buf->total); -#endif + (size_t) buf->total, 1); #if LINUX_VERSION_CODE <= 0x020402 up( ¤t->mm->mmap_sem ); #else @@ -474,6 +471,9 @@ dev_priv->back_offset = init->back_offset; dev_priv->depth_offset = init->depth_offset; + dev_priv->overlay_offset = init->overlay_offset; + dev_priv->overlay_physical = init->overlay_physical; + dev_priv->front_di1 = init->front_offset | init->pitch_bits; dev_priv->back_di1 = init->back_offset | init->pitch_bits; dev_priv->zi1 = init->depth_offset | init->pitch_bits; @@ -1262,3 +1262,156 @@ if(VM_DONTCOPY == 0) return 1; return 0; } + +static void i810_dma_dispatch_mc(drm_device_t *dev, drm_buf_t *buf, int used, + unsigned int last_render) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_buf_priv_t *buf_priv = buf->dev_private; + drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; + unsigned long address = (unsigned long)buf->bus_address; + unsigned long start = address - dev->agp->base; + int u; + RING_LOCALS; + + i810_kernel_lost_context(dev); + + u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, + I810_BUF_HARDWARE); + if(u != I810_BUF_CLIENT) { + DRM_DEBUG("MC found buffer that isn't mine!\n"); + } + + if (used > 4*1024) + used = 0; + + sarea_priv->dirty = 0x7f; + + DRM_DEBUG("dispatch mc addr 0x%lx, used 0x%x\n", + address, used); + + dev_priv->counter++; + DRM_DEBUG("dispatch counter : %ld\n", dev_priv->counter); + DRM_DEBUG("i810_dma_dispatch_mc\n"); + DRM_DEBUG("start : %lx\n", start); + DRM_DEBUG("used : %d\n", used); + DRM_DEBUG("start + used - 4 : %ld\n", start + used - 4); + + if (buf_priv->currently_mapped == I810_BUF_MAPPED) { + if (used & 4) { + *(u32 *)((u32)buf_priv->virtual + used) = 0; + used += 4; + } + + i810_unmap_buffer(buf); + } + BEGIN_LP_RING(4); + OUT_RING( CMD_OP_BATCH_BUFFER ); + OUT_RING( start | BB1_PROTECTED ); + OUT_RING( start + used - 4 ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + + + BEGIN_LP_RING(8); + OUT_RING( CMD_STORE_DWORD_IDX ); + OUT_RING( buf_priv->my_use_idx ); + OUT_RING( I810_BUF_FREE ); + OUT_RING( 0 ); + + OUT_RING( CMD_STORE_DWORD_IDX ); + OUT_RING( 16 ); + OUT_RING( last_render ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); +} + +int i810_dma_mc(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_device_dma_t *dma = dev->dma; + drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + u32 *hw_status = (u32 *)dev_priv->hw_status_page; + drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) + dev_priv->sarea_priv; + drm_i810_mc_t mc; + + if (copy_from_user(&mc, (drm_i810_mc_t *)arg, sizeof(mc))) + return -EFAULT; + + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_dma_mc called without lock held\n"); + return -EINVAL; + } + + i810_dma_dispatch_mc(dev, dma->buflist[mc.idx], mc.used, + mc.last_render ); + + atomic_add(mc.used, &dev->counts[_DRM_STAT_SECONDARY]); + atomic_inc(&dev->counts[_DRM_STAT_DMA]); + sarea_priv->last_enqueue = dev_priv->counter-1; + sarea_priv->last_dispatch = (int) hw_status[5]; + + return 0; +} + +int i810_rstatus(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + + return (int)(((u32 *)(dev_priv->hw_status_page))[4]); +} + +int i810_ov0_info(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + drm_i810_overlay_t data; + + data.offset = dev_priv->overlay_offset; + data.physical = dev_priv->overlay_physical; + copy_to_user((drm_i810_overlay_t *)arg,&data,sizeof(data)); + return 0; +} + +int i810_fstatus(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_fstatus called without lock held\n"); + return -EINVAL; + } + return I810_READ(0x30008); +} + +int i810_ov0_flip(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_ov0_flip called without lock held\n"); + return -EINVAL; + } + + //Tell the overlay to update + I810_WRITE(0x30000,dev_priv->overlay_physical | 0x80000000); + + return 0; +} + + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/i810_drm.h linux.19pre5-ac1/drivers/char/drm/i810_drm.h --- linux.19p5/drivers/char/drm/i810_drm.h Thu Apr 4 13:19:12 2002 +++ linux.19pre5-ac1/drivers/char/drm/i810_drm.h Wed Feb 13 00:35:28 2002 @@ -112,6 +112,8 @@ unsigned int front_offset; unsigned int back_offset; unsigned int depth_offset; + unsigned int overlay_offset; + unsigned int overlay_physical; unsigned int w; unsigned int h; unsigned int pitch; @@ -196,4 +198,18 @@ int granted; } drm_i810_dma_t; +typedef struct _drm_i810_overlay_t { + unsigned int offset; /* Address of the Overlay Regs */ + unsigned int physical; +} drm_i810_overlay_t; + +typedef struct _drm_i810_mc { + int idx; /* buffer index */ + int used; /* nr bytes in use */ + int num_blocks; /* number of GFXBlocks */ + int *length; /* List of lengths for GFXBlocks (FUTURE)*/ + unsigned int last_render; /* Last Render Request */ +} drm_i810_mc_t; + + #endif /* _I810_DRM_H_ */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/i810_drv.c linux.19pre5-ac1/drivers/char/drm/i810_drv.c --- linux.19p5/drivers/char/drm/i810_drv.c Thu Apr 4 13:19:12 2002 +++ linux.19pre5-ac1/drivers/char/drm/i810_drv.c Wed Feb 13 00:35:28 2002 @@ -39,10 +39,10 @@ #define DRIVER_NAME "i810" #define DRIVER_DESC "Intel i810" -#define DRIVER_DATE "20010616" +#define DRIVER_DATE "20010920" #define DRIVER_MAJOR 1 -#define DRIVER_MINOR 1 +#define DRIVER_MINOR 2 #define DRIVER_PATCHLEVEL 0 #define DRIVER_IOCTLS \ @@ -54,7 +54,12 @@ [DRM_IOCTL_NR(DRM_IOCTL_I810_GETBUF)] = { i810_getbuf, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_I810_SWAP)] = { i810_swap_bufs, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_I810_COPY)] = { i810_copybuf, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_OV0INFO)] = { i810_ov0_info, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_FSTATUS)] = { i810_fstatus, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_OV0FLIP)] = { i810_ov0_flip, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_MC)] = { i810_dma_mc, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_RSTATUS)] = { i810_rstatus, 1, 0 } #define __HAVE_COUNTERS 4 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/i810_drv.h linux.19pre5-ac1/drivers/char/drm/i810_drv.h --- linux.19p5/drivers/char/drm/i810_drv.h Thu Apr 4 13:19:12 2002 +++ linux.19pre5-ac1/drivers/char/drm/i810_drv.h Wed Feb 13 00:35:28 2002 @@ -73,6 +73,8 @@ int back_offset; int depth_offset; + int overlay_offset; + int overlay_physical; int w, h; int pitch; } drm_i810_private_t; @@ -94,6 +96,18 @@ extern int i810_docopy(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); +extern int i810_rstatus(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int i810_ov0_info(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int i810_fstatus(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int i810_ov0_flip(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int i810_dma_mc(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + + extern void i810_dma_quiescent(drm_device_t *dev); #define I810_VERBOSE 0 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/i830.h linux.19pre5-ac1/drivers/char/drm/i830.h --- linux.19p5/drivers/char/drm/i830.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/char/drm/i830.h Wed Feb 13 00:35:28 2002 @@ -0,0 +1,116 @@ +/* i830.h -- Intel I830 DRM template customization -*- linux-c -*- + * Created: Thu Feb 15 00:01:12 2001 by gareth@valinux.com + * + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Gareth Hughes + */ + +#ifndef __I830_H__ +#define __I830_H__ + +/* This remains constant for all DRM template files. + */ +#define DRM(x) i830_##x + +/* General customization: + */ +#define __HAVE_AGP 1 +#define __MUST_HAVE_AGP 1 +#define __HAVE_MTRR 1 +#define __HAVE_CTX_BITMAP 1 + +/* Driver customization: + */ +#define __HAVE_RELEASE 1 +#define DRIVER_RELEASE() do { \ + i830_reclaim_buffers( dev, priv->pid ); \ +} while (0) + +/* DMA customization: + */ +#define __HAVE_DMA 1 +#define __HAVE_DMA_QUEUE 1 +#define __HAVE_DMA_WAITLIST 1 +#define __HAVE_DMA_RECLAIM 1 + +#define __HAVE_DMA_QUIESCENT 1 +#define DRIVER_DMA_QUIESCENT() do { \ + i830_dma_quiescent( dev ); \ +} while (0) + +#define __HAVE_DMA_IRQ 1 +#define __HAVE_DMA_IRQ_BH 1 +#define __HAVE_SHARED_IRQ 1 +#define DRIVER_PREINSTALL() do { \ + drm_i830_private_t *dev_priv = \ + (drm_i830_private_t *)dev->dev_private; \ + u16 tmp; \ + tmp = I830_READ16( I830REG_HWSTAM ); \ + tmp = tmp & 0x6000; \ + I830_WRITE16( I830REG_HWSTAM, tmp ); \ + \ + tmp = I830_READ16( I830REG_INT_MASK_R ); \ + tmp = tmp & 0x6000; /* Unmask interrupts */ \ + I830_WRITE16( I830REG_INT_MASK_R, tmp ); \ + tmp = I830_READ16( I830REG_INT_ENABLE_R ); \ + tmp = tmp & 0x6000; /* Disable all interrupts */ \ + I830_WRITE16( I830REG_INT_ENABLE_R, tmp ); \ +} while (0) + +#define DRIVER_POSTINSTALL() do { \ + drm_i830_private_t *dev_priv = \ + (drm_i830_private_t *)dev->dev_private; \ + u16 tmp; \ + tmp = I830_READ16( I830REG_INT_ENABLE_R ); \ + tmp = tmp & 0x6000; \ + tmp = tmp | 0x0003; /* Enable bp & user interrupts */ \ + I830_WRITE16( I830REG_INT_ENABLE_R, tmp ); \ +} while (0) + +#define DRIVER_UNINSTALL() do { \ + drm_i830_private_t *dev_priv = \ + (drm_i830_private_t *)dev->dev_private; \ + u16 tmp; \ + if ( dev_priv ) { \ + tmp = I830_READ16( I830REG_INT_IDENTITY_R ); \ + tmp = tmp & ~(0x6000); /* Clear all interrupts */ \ + if ( tmp != 0 ) \ + I830_WRITE16( I830REG_INT_IDENTITY_R, tmp ); \ + \ + tmp = I830_READ16( I830REG_INT_ENABLE_R ); \ + tmp = tmp & 0x6000; /* Disable all interrupts */ \ + I830_WRITE16( I830REG_INT_ENABLE_R, tmp ); \ + } \ +} while (0) + +/* Buffer customization: + */ + +#define DRIVER_BUF_PRIV_T drm_i830_buf_priv_t + +#define DRIVER_AGP_BUFFERS_MAP( dev ) \ + ((drm_i830_private_t *)((dev)->dev_private))->buffer_map + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/i830_dma.c linux.19pre5-ac1/drivers/char/drm/i830_dma.c --- linux.19p5/drivers/char/drm/i830_dma.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/char/drm/i830_dma.c Tue Mar 19 16:03:21 2002 @@ -0,0 +1,1405 @@ +/* i830_dma.c -- DMA support for the I830 -*- linux-c -*- + * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com + * + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: Rickard E. (Rik) Faith + * Jeff Hartmann + * Keith Whitwell + * Abraham vd Merwe + * + */ + +#define __NO_VERSION__ +#include "i830.h" +#include "drmP.h" +#include "i830_drv.h" +#include /* For task queue support */ +#include +/* in case we don't have a 2.3.99-pre6 kernel or later: */ +#ifndef VM_DONTCOPY +#define VM_DONTCOPY 0 +#endif + +#define I830_BUF_FREE 2 +#define I830_BUF_CLIENT 1 +#define I830_BUF_HARDWARE 0 + +#define I830_BUF_UNMAPPED 0 +#define I830_BUF_MAPPED 1 + +#define RING_LOCALS unsigned int outring, ringmask; volatile char *virt; + + +#define DO_IDLE_WORKAROUND() \ +do { \ + int _head; \ + int _tail; \ + int _i; \ + do { \ + _head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; \ + _tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR; \ + udelay(1); \ + } while(_head != _tail); \ +} while(0) + +#define I830_SYNC_WORKAROUND 0 + +#define BEGIN_LP_RING(n) do { \ + if (I830_VERBOSE) \ + DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", \ + n, __FUNCTION__); \ + if (I830_SYNC_WORKAROUND) \ + DO_IDLE_WORKAROUND(); \ + if (dev_priv->ring.space < n*4) \ + i830_wait_ring(dev, n*4); \ + dev_priv->ring.space -= n*4; \ + outring = dev_priv->ring.tail; \ + ringmask = dev_priv->ring.tail_mask; \ + virt = dev_priv->ring.virtual_start; \ +} while (0) + +#define ADVANCE_LP_RING() do { \ + if (I830_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \ + dev_priv->ring.tail = outring; \ + I830_WRITE(LP_RING + RING_TAIL, outring); \ +} while(0) + +#define OUT_RING(n) do { \ + if (I830_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ + *(volatile unsigned int *)(virt + outring) = n; \ + outring += 4; \ + outring &= ringmask; \ +} while (0); + +static inline void i830_print_status_page(drm_device_t *dev) +{ + drm_device_dma_t *dma = dev->dma; + drm_i830_private_t *dev_priv = dev->dev_private; + u32 *temp = (u32 *)dev_priv->hw_status_page; + int i; + + DRM_DEBUG( "hw_status: Interrupt Status : %x\n", temp[0]); + DRM_DEBUG( "hw_status: LpRing Head ptr : %x\n", temp[1]); + DRM_DEBUG( "hw_status: IRing Head ptr : %x\n", temp[2]); + DRM_DEBUG( "hw_status: Reserved : %x\n", temp[3]); + DRM_DEBUG( "hw_status: Driver Counter : %d\n", temp[5]); + for(i = 9; i < dma->buf_count + 9; i++) { + DRM_DEBUG( "buffer status idx : %d used: %d\n", i - 9, temp[i]); + } +} + +static drm_buf_t *i830_freelist_get(drm_device_t *dev) +{ + drm_device_dma_t *dma = dev->dma; + int i; + int used; + + /* Linear search might not be the best solution */ + + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[ i ]; + drm_i830_buf_priv_t *buf_priv = buf->dev_private; + /* In use is already a pointer */ + used = cmpxchg(buf_priv->in_use, I830_BUF_FREE, + I830_BUF_CLIENT); + if(used == I830_BUF_FREE) { + return buf; + } + } + return NULL; +} + +/* This should only be called if the buffer is not sent to the hardware + * yet, the hardware updates in use for us once its on the ring buffer. + */ + +static int i830_freelist_put(drm_device_t *dev, drm_buf_t *buf) +{ + drm_i830_buf_priv_t *buf_priv = buf->dev_private; + int used; + + /* In use is already a pointer */ + used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, I830_BUF_FREE); + if(used != I830_BUF_CLIENT) { + DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx); + return -EINVAL; + } + + return 0; +} + +static struct file_operations i830_buffer_fops = { + open: DRM(open), + flush: DRM(flush), + release: DRM(release), + ioctl: DRM(ioctl), + mmap: i830_mmap_buffers, + read: DRM(read), + fasync: DRM(fasync), + poll: DRM(poll), +}; + +int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev; + drm_i830_private_t *dev_priv; + drm_buf_t *buf; + drm_i830_buf_priv_t *buf_priv; + + lock_kernel(); + dev = priv->dev; + dev_priv = dev->dev_private; + buf = dev_priv->mmap_buffer; + buf_priv = buf->dev_private; + + vma->vm_flags |= (VM_IO | VM_DONTCOPY); + vma->vm_file = filp; + + buf_priv->currently_mapped = I830_BUF_MAPPED; + unlock_kernel(); + + if (remap_page_range(vma->vm_start, + VM_OFFSET(vma), + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) return -EAGAIN; + return 0; +} + +static int i830_map_buffer(drm_buf_t *buf, struct file *filp) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i830_buf_priv_t *buf_priv = buf->dev_private; + drm_i830_private_t *dev_priv = dev->dev_private; + struct file_operations *old_fops; + int retcode = 0; + + if(buf_priv->currently_mapped == I830_BUF_MAPPED) return -EINVAL; + + if(VM_DONTCOPY != 0) { +#if LINUX_VERSION_CODE <= 0x020402 + down( ¤t->mm->mmap_sem ); +#else + down_write( ¤t->mm->mmap_sem ); +#endif + old_fops = filp->f_op; + filp->f_op = &i830_buffer_fops; + dev_priv->mmap_buffer = buf; + buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total, + PROT_READ|PROT_WRITE, + MAP_SHARED, + buf->bus_address); + dev_priv->mmap_buffer = NULL; + filp->f_op = old_fops; + if ((unsigned long)buf_priv->virtual > -1024UL) { + /* Real error */ + DRM_DEBUG("mmap error\n"); + retcode = (signed int)buf_priv->virtual; + buf_priv->virtual = 0; + } +#if LINUX_VERSION_CODE <= 0x020402 + up( ¤t->mm->mmap_sem ); +#else + up_write( ¤t->mm->mmap_sem ); +#endif + } else { + buf_priv->virtual = buf_priv->kernel_virtual; + buf_priv->currently_mapped = I830_BUF_MAPPED; + } + return retcode; +} + +static int i830_unmap_buffer(drm_buf_t *buf) +{ + drm_i830_buf_priv_t *buf_priv = buf->dev_private; + int retcode = 0; + + if(VM_DONTCOPY != 0) { + if(buf_priv->currently_mapped != I830_BUF_MAPPED) + return -EINVAL; + down_write( ¤t->mm->mmap_sem ); + retcode = do_munmap(current->mm, + (unsigned long)buf_priv->virtual, + (size_t) buf->total, 1); + up_write( ¤t->mm->mmap_sem ); + } + buf_priv->currently_mapped = I830_BUF_UNMAPPED; + buf_priv->virtual = 0; + + return retcode; +} + +static int i830_dma_get_buffer(drm_device_t *dev, drm_i830_dma_t *d, + struct file *filp) +{ + drm_file_t *priv = filp->private_data; + drm_buf_t *buf; + drm_i830_buf_priv_t *buf_priv; + int retcode = 0; + + buf = i830_freelist_get(dev); + if (!buf) { + retcode = -ENOMEM; + DRM_DEBUG("retcode=%d\n", retcode); + return retcode; + } + + retcode = i830_map_buffer(buf, filp); + if(retcode) { + i830_freelist_put(dev, buf); + DRM_DEBUG("mapbuf failed, retcode %d\n", retcode); + return retcode; + } + buf->pid = priv->pid; + buf_priv = buf->dev_private; + d->granted = 1; + d->request_idx = buf->idx; + d->request_size = buf->total; + d->virtual = buf_priv->virtual; + + return retcode; +} + +static unsigned long i830_alloc_page(drm_device_t *dev) +{ + unsigned long address; + + address = __get_free_page(GFP_KERNEL); + if(address == 0UL) + return 0; + + atomic_inc(&virt_to_page(address)->count); + set_bit(PG_locked, &virt_to_page(address)->flags); + + return address; +} + +static void i830_free_page(drm_device_t *dev, unsigned long page) +{ + if(page == 0UL) + return; + + atomic_dec(&virt_to_page(page)->count); + clear_bit(PG_locked, &virt_to_page(page)->flags); + wake_up_page(virt_to_page(page)); + free_page(page); + return; +} + +static int i830_dma_cleanup(drm_device_t *dev) +{ + drm_device_dma_t *dma = dev->dma; + + if(dev->dev_private) { + int i; + drm_i830_private_t *dev_priv = + (drm_i830_private_t *) dev->dev_private; + + if(dev_priv->ring.virtual_start) { + DRM(ioremapfree)((void *) dev_priv->ring.virtual_start, + dev_priv->ring.Size); + } + if(dev_priv->hw_status_page != 0UL) { + i830_free_page(dev, dev_priv->hw_status_page); + /* Need to rewrite hardware status page */ + I830_WRITE(0x02080, 0x1ffff000); + } + DRM(free)(dev->dev_private, sizeof(drm_i830_private_t), + DRM_MEM_DRIVER); + dev->dev_private = NULL; + + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[ i ]; + drm_i830_buf_priv_t *buf_priv = buf->dev_private; + DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total); + } + } + return 0; +} + +static int i830_wait_ring(drm_device_t *dev, int n) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_ring_buffer_t *ring = &(dev_priv->ring); + int iters = 0; + unsigned long end; + unsigned int last_head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; + + end = jiffies + (HZ*3); + while (ring->space < n) { + int i; + + ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; + ring->space = ring->head - (ring->tail+8); + if (ring->space < 0) ring->space += ring->Size; + + if (ring->head != last_head) { + end = jiffies + (HZ*3); + last_head = ring->head; + } + + iters++; + if(time_before(end,jiffies)) { + DRM_ERROR("space: %d wanted %d\n", ring->space, n); + DRM_ERROR("lockup\n"); + goto out_wait_ring; + } + + udelay(1); + } + +out_wait_ring: + return iters; +} + +static void i830_kernel_lost_context(drm_device_t *dev) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_ring_buffer_t *ring = &(dev_priv->ring); + + ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; + ring->tail = I830_READ(LP_RING + RING_TAIL); + ring->space = ring->head - (ring->tail+8); + if (ring->space < 0) ring->space += ring->Size; +} + +static int i830_freelist_init(drm_device_t *dev, drm_i830_private_t *dev_priv) +{ + drm_device_dma_t *dma = dev->dma; + int my_idx = 36; + u32 *hw_status = (u32 *)(dev_priv->hw_status_page + my_idx); + int i; + + if(dma->buf_count > 1019) { + /* Not enough space in the status page for the freelist */ + return -EINVAL; + } + + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[ i ]; + drm_i830_buf_priv_t *buf_priv = buf->dev_private; + + buf_priv->in_use = hw_status++; + buf_priv->my_use_idx = my_idx; + my_idx += 4; + + *buf_priv->in_use = I830_BUF_FREE; + + buf_priv->kernel_virtual = DRM(ioremap)(buf->bus_address, + buf->total); + } + return 0; +} + +static int i830_dma_initialize(drm_device_t *dev, + drm_i830_private_t *dev_priv, + drm_i830_init_t *init) +{ + struct list_head *list; + + memset(dev_priv, 0, sizeof(drm_i830_private_t)); + + list_for_each(list, &dev->maplist->head) { + drm_map_list_t *r_list = (drm_map_list_t *)list; + if( r_list->map && + r_list->map->type == _DRM_SHM && + r_list->map->flags & _DRM_CONTAINS_LOCK ) { + dev_priv->sarea_map = r_list->map; + break; + } + } + + if(!dev_priv->sarea_map) { + dev->dev_private = (void *)dev_priv; + i830_dma_cleanup(dev); + DRM_ERROR("can not find sarea!\n"); + return -EINVAL; + } + DRM_FIND_MAP( dev_priv->mmio_map, init->mmio_offset ); + if(!dev_priv->mmio_map) { + dev->dev_private = (void *)dev_priv; + i830_dma_cleanup(dev); + DRM_ERROR("can not find mmio map!\n"); + return -EINVAL; + } + DRM_FIND_MAP( dev_priv->buffer_map, init->buffers_offset ); + if(!dev_priv->buffer_map) { + dev->dev_private = (void *)dev_priv; + i830_dma_cleanup(dev); + DRM_ERROR("can not find dma buffer map!\n"); + return -EINVAL; + } + + dev_priv->sarea_priv = (drm_i830_sarea_t *) + ((u8 *)dev_priv->sarea_map->handle + + init->sarea_priv_offset); + + atomic_set(&dev_priv->flush_done, 0); + init_waitqueue_head(&dev_priv->flush_queue); + + dev_priv->ring.Start = init->ring_start; + dev_priv->ring.End = init->ring_end; + dev_priv->ring.Size = init->ring_size; + + dev_priv->ring.virtual_start = DRM(ioremap)(dev->agp->base + + init->ring_start, + init->ring_size); + + if (dev_priv->ring.virtual_start == NULL) { + dev->dev_private = (void *) dev_priv; + i830_dma_cleanup(dev); + DRM_ERROR("can not ioremap virtual address for" + " ring buffer\n"); + return -ENOMEM; + } + + dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; + + dev_priv->w = init->w; + dev_priv->h = init->h; + dev_priv->pitch = init->pitch; + dev_priv->back_offset = init->back_offset; + dev_priv->depth_offset = init->depth_offset; + + dev_priv->front_di1 = init->front_offset | init->pitch_bits; + dev_priv->back_di1 = init->back_offset | init->pitch_bits; + dev_priv->zi1 = init->depth_offset | init->pitch_bits; + + dev_priv->cpp = init->cpp; + /* We are using seperate values as placeholders for mechanisms for + * private backbuffer/depthbuffer usage. + */ + + dev_priv->back_pitch = init->back_pitch; + dev_priv->depth_pitch = init->depth_pitch; + + /* Program Hardware Status Page */ + dev_priv->hw_status_page = i830_alloc_page(dev); + if(dev_priv->hw_status_page == 0UL) { + dev->dev_private = (void *)dev_priv; + i830_dma_cleanup(dev); + DRM_ERROR("Can not allocate hardware status page\n"); + return -ENOMEM; + } + memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE); + DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page); + + I830_WRITE(0x02080, virt_to_bus((void *)dev_priv->hw_status_page)); + DRM_DEBUG("Enabled hardware status page\n"); + + /* Now we need to init our freelist */ + if(i830_freelist_init(dev, dev_priv) != 0) { + dev->dev_private = (void *)dev_priv; + i830_dma_cleanup(dev); + DRM_ERROR("Not enough space in the status page for" + " the freelist\n"); + return -ENOMEM; + } + dev->dev_private = (void *)dev_priv; + + return 0; +} + +int i830_dma_init(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i830_private_t *dev_priv; + drm_i830_init_t init; + int retcode = 0; + + if (copy_from_user(&init, (drm_i830_init_t *)arg, sizeof(init))) + return -EFAULT; + + switch(init.func) { + case I830_INIT_DMA: + dev_priv = DRM(alloc)(sizeof(drm_i830_private_t), + DRM_MEM_DRIVER); + if(dev_priv == NULL) return -ENOMEM; + retcode = i830_dma_initialize(dev, dev_priv, &init); + break; + case I830_CLEANUP_DMA: + retcode = i830_dma_cleanup(dev); + break; + default: + retcode = -EINVAL; + break; + } + + return retcode; +} + +/* Most efficient way to verify state for the i830 is as it is + * emitted. Non-conformant state is silently dropped. + * + * Use 'volatile' & local var tmp to force the emitted values to be + * identical to the verified ones. + */ +static void i830EmitContextVerified( drm_device_t *dev, + volatile unsigned int *code ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + int i, j = 0; + unsigned int tmp; + RING_LOCALS; + + BEGIN_LP_RING( I830_CTX_SETUP_SIZE ); + for ( i = 0 ; i < I830_CTX_SETUP_SIZE ; i++ ) { + tmp = code[i]; + +#if 0 + if ((tmp & (7<<29)) == (3<<29) && + (tmp & (0x1f<<24)) < (0x1d<<24)) { + OUT_RING( tmp ); + j++; + } else { + printk("Skipping %d\n", i); + } +#else + OUT_RING( tmp ); + j++; +#endif + } + + if (j & 1) + OUT_RING( 0 ); + + ADVANCE_LP_RING(); +} + +static void i830EmitTexVerified( drm_device_t *dev, + volatile unsigned int *code ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + int i, j = 0; + unsigned int tmp; + RING_LOCALS; + + BEGIN_LP_RING( I830_TEX_SETUP_SIZE ); + + OUT_RING( GFX_OP_MAP_INFO ); + OUT_RING( code[I830_TEXREG_MI1] ); + OUT_RING( code[I830_TEXREG_MI2] ); + OUT_RING( code[I830_TEXREG_MI3] ); + OUT_RING( code[I830_TEXREG_MI4] ); + OUT_RING( code[I830_TEXREG_MI5] ); + + for ( i = 6 ; i < I830_TEX_SETUP_SIZE ; i++ ) { + tmp = code[i]; + OUT_RING( tmp ); + j++; + } + + if (j & 1) + OUT_RING( 0 ); + + ADVANCE_LP_RING(); +} + +static void i830EmitTexBlendVerified( drm_device_t *dev, + volatile unsigned int *code, + volatile unsigned int num) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + int i, j = 0; + unsigned int tmp; + RING_LOCALS; + + BEGIN_LP_RING( num ); + + for ( i = 0 ; i < num ; i++ ) { + tmp = code[i]; + OUT_RING( tmp ); + j++; + } + + if (j & 1) + OUT_RING( 0 ); + + ADVANCE_LP_RING(); +} + +static void i830EmitTexPalette( drm_device_t *dev, + unsigned int *palette, + int number, + int is_shared ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + int i; + RING_LOCALS; + + BEGIN_LP_RING( 258 ); + + if(is_shared == 1) { + OUT_RING(CMD_OP_MAP_PALETTE_LOAD | + MAP_PALETTE_NUM(0) | + MAP_PALETTE_BOTH); + } else { + OUT_RING(CMD_OP_MAP_PALETTE_LOAD | MAP_PALETTE_NUM(number)); + } + for(i = 0; i < 256; i++) { + OUT_RING(palette[i]); + } + OUT_RING(0); +} + +/* Need to do some additional checking when setting the dest buffer. + */ +static void i830EmitDestVerified( drm_device_t *dev, + volatile unsigned int *code ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + unsigned int tmp; + RING_LOCALS; + + BEGIN_LP_RING( I830_DEST_SETUP_SIZE + 6 ); + + tmp = code[I830_DESTREG_CBUFADDR]; + if (tmp == dev_priv->front_di1) { + /* Don't use fence when front buffer rendering */ + OUT_RING( CMD_OP_DESTBUFFER_INFO ); + OUT_RING( BUF_3D_ID_COLOR_BACK | + BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) ); + OUT_RING( tmp ); + + OUT_RING( CMD_OP_DESTBUFFER_INFO ); + OUT_RING( BUF_3D_ID_DEPTH | + BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp)); + OUT_RING( dev_priv->zi1 ); + } else if(tmp == dev_priv->back_di1) { + OUT_RING( CMD_OP_DESTBUFFER_INFO ); + OUT_RING( BUF_3D_ID_COLOR_BACK | + BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) | + BUF_3D_USE_FENCE); + OUT_RING( tmp ); + + OUT_RING( CMD_OP_DESTBUFFER_INFO ); + OUT_RING( BUF_3D_ID_DEPTH | BUF_3D_USE_FENCE | + BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp)); + OUT_RING( dev_priv->zi1 ); + } else { + DRM_DEBUG("bad di1 %x (allow %x or %x)\n", + tmp, dev_priv->front_di1, dev_priv->back_di1); + } + + /* invarient: + */ + + + OUT_RING( GFX_OP_DESTBUFFER_VARS ); + OUT_RING( code[I830_DESTREG_DV1] ); + + OUT_RING( GFX_OP_DRAWRECT_INFO ); + OUT_RING( code[I830_DESTREG_DR1] ); + OUT_RING( code[I830_DESTREG_DR2] ); + OUT_RING( code[I830_DESTREG_DR3] ); + OUT_RING( code[I830_DESTREG_DR4] ); + + /* Need to verify this */ + tmp = code[I830_DESTREG_SENABLE]; + if((tmp & ~0x3) == GFX_OP_SCISSOR_ENABLE) { + OUT_RING( tmp ); + } else { + DRM_DEBUG("bad scissor enable\n"); + OUT_RING( 0 ); + } + + OUT_RING( code[I830_DESTREG_SENABLE] ); + + OUT_RING( GFX_OP_SCISSOR_RECT ); + OUT_RING( code[I830_DESTREG_SR1] ); + OUT_RING( code[I830_DESTREG_SR2] ); + + ADVANCE_LP_RING(); +} + +static void i830EmitState( drm_device_t *dev ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; + unsigned int dirty = sarea_priv->dirty; + + if (dirty & I830_UPLOAD_BUFFERS) { + i830EmitDestVerified( dev, sarea_priv->BufferState ); + sarea_priv->dirty &= ~I830_UPLOAD_BUFFERS; + } + + if (dirty & I830_UPLOAD_CTX) { + i830EmitContextVerified( dev, sarea_priv->ContextState ); + sarea_priv->dirty &= ~I830_UPLOAD_CTX; + } + + if (dirty & I830_UPLOAD_TEX0) { + i830EmitTexVerified( dev, sarea_priv->TexState[0] ); + sarea_priv->dirty &= ~I830_UPLOAD_TEX0; + } + + if (dirty & I830_UPLOAD_TEX1) { + i830EmitTexVerified( dev, sarea_priv->TexState[1] ); + sarea_priv->dirty &= ~I830_UPLOAD_TEX1; + } + + if (dirty & I830_UPLOAD_TEXBLEND0) { + i830EmitTexBlendVerified( dev, sarea_priv->TexBlendState[0], + sarea_priv->TexBlendStateWordsUsed[0]); + sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND0; + } + + if (dirty & I830_UPLOAD_TEXBLEND1) { + i830EmitTexBlendVerified( dev, sarea_priv->TexBlendState[1], + sarea_priv->TexBlendStateWordsUsed[1]); + sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND1; + } + + if (dirty & I830_UPLOAD_TEX_PALETTE_SHARED) { + i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 1); + } else { + if (dirty & I830_UPLOAD_TEX_PALETTE_N(0)) { + i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 0); + sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(0); + } + if (dirty & I830_UPLOAD_TEX_PALETTE_N(1)) { + i830EmitTexPalette(dev, sarea_priv->Palette[1], 1, 0); + sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(1); + } + } +} + +static void i830_dma_dispatch_clear( drm_device_t *dev, int flags, + unsigned int clear_color, + unsigned int clear_zval, + unsigned int clear_depthmask) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; + int nbox = sarea_priv->nbox; + drm_clip_rect_t *pbox = sarea_priv->boxes; + int pitch = dev_priv->pitch; + int cpp = dev_priv->cpp; + int i; + unsigned int BR13, CMD, D_CMD; + RING_LOCALS; + + i830_kernel_lost_context(dev); + + switch(cpp) { + case 2: + BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24); + D_CMD = CMD = XY_COLOR_BLT_CMD; + break; + case 4: + BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24) | (1<<25); + CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA | + XY_COLOR_BLT_WRITE_RGB); + D_CMD = XY_COLOR_BLT_CMD; + if(clear_depthmask & 0x00ffffff) + D_CMD |= XY_COLOR_BLT_WRITE_RGB; + if(clear_depthmask & 0xff000000) + D_CMD |= XY_COLOR_BLT_WRITE_ALPHA; + break; + default: + BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24); + D_CMD = CMD = XY_COLOR_BLT_CMD; + break; + } + + if (nbox > I830_NR_SAREA_CLIPRECTS) + nbox = I830_NR_SAREA_CLIPRECTS; + + for (i = 0 ; i < nbox ; i++, pbox++) { + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > dev_priv->w || + pbox->y2 > dev_priv->h) + continue; + + if ( flags & I830_FRONT ) { + DRM_DEBUG("clear front\n"); + BEGIN_LP_RING( 6 ); + OUT_RING( CMD ); + OUT_RING( BR13 ); + OUT_RING( (pbox->y1 << 16) | pbox->x1 ); + OUT_RING( (pbox->y2 << 16) | pbox->x2 ); + OUT_RING( 0 ); + OUT_RING( clear_color ); + ADVANCE_LP_RING(); + } + + if ( flags & I830_BACK ) { + DRM_DEBUG("clear back\n"); + BEGIN_LP_RING( 6 ); + OUT_RING( CMD ); + OUT_RING( BR13 ); + OUT_RING( (pbox->y1 << 16) | pbox->x1 ); + OUT_RING( (pbox->y2 << 16) | pbox->x2 ); + OUT_RING( dev_priv->back_offset ); + OUT_RING( clear_color ); + ADVANCE_LP_RING(); + } + + if ( flags & I830_DEPTH ) { + DRM_DEBUG("clear depth\n"); + BEGIN_LP_RING( 6 ); + OUT_RING( D_CMD ); + OUT_RING( BR13 ); + OUT_RING( (pbox->y1 << 16) | pbox->x1 ); + OUT_RING( (pbox->y2 << 16) | pbox->x2 ); + OUT_RING( dev_priv->depth_offset ); + OUT_RING( clear_zval ); + ADVANCE_LP_RING(); + } + } +} + +static void i830_dma_dispatch_swap( drm_device_t *dev ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; + int nbox = sarea_priv->nbox; + drm_clip_rect_t *pbox = sarea_priv->boxes; + int pitch = dev_priv->pitch; + int cpp = dev_priv->cpp; + int ofs = dev_priv->back_offset; + int i; + unsigned int CMD, BR13; + RING_LOCALS; + + DRM_DEBUG("swapbuffers\n"); + + switch(cpp) { + case 2: + BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24); + CMD = XY_SRC_COPY_BLT_CMD; + break; + case 4: + BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24) | (1<<25); + CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + break; + default: + BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24); + CMD = XY_SRC_COPY_BLT_CMD; + break; + } + + i830_kernel_lost_context(dev); + + if (nbox > I830_NR_SAREA_CLIPRECTS) + nbox = I830_NR_SAREA_CLIPRECTS; + + for (i = 0 ; i < nbox; i++, pbox++) + { + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > dev_priv->w || + pbox->y2 > dev_priv->h) + continue; + + DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n", + pbox->x1, pbox->y1, + pbox->x2, pbox->y2); + + BEGIN_LP_RING( 8 ); + OUT_RING( CMD ); + OUT_RING( BR13 ); + + OUT_RING( (pbox->y1 << 16) | + pbox->x1 ); + OUT_RING( (pbox->y2 << 16) | + pbox->x2 ); + + OUT_RING( 0 /* front ofs always zero */ ); + OUT_RING( (pbox->y1 << 16) | + pbox->x1 ); + + OUT_RING( BR13 & 0xffff ); + OUT_RING( ofs ); + + ADVANCE_LP_RING(); + } +} + + +static void i830_dma_dispatch_vertex(drm_device_t *dev, + drm_buf_t *buf, + int discard, + int used) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_buf_priv_t *buf_priv = buf->dev_private; + drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_clip_rect_t *box = sarea_priv->boxes; + int nbox = sarea_priv->nbox; + unsigned long address = (unsigned long)buf->bus_address; + unsigned long start = address - dev->agp->base; + int i = 0, u; + RING_LOCALS; + + i830_kernel_lost_context(dev); + + if (nbox > I830_NR_SAREA_CLIPRECTS) + nbox = I830_NR_SAREA_CLIPRECTS; + + if (discard) { + u = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, + I830_BUF_HARDWARE); + if(u != I830_BUF_CLIENT) { + DRM_DEBUG("xxxx 2\n"); + } + } + + if (used > 4*1024) + used = 0; + + if (sarea_priv->dirty) + i830EmitState( dev ); + + DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n", + address, used, nbox); + + dev_priv->counter++; + DRM_DEBUG( "dispatch counter : %ld\n", dev_priv->counter); + DRM_DEBUG( "i830_dma_dispatch\n"); + DRM_DEBUG( "start : %lx\n", start); + DRM_DEBUG( "used : %d\n", used); + DRM_DEBUG( "start + used - 4 : %ld\n", start + used - 4); + + if (buf_priv->currently_mapped == I830_BUF_MAPPED) { + *(u32 *)buf_priv->virtual = (GFX_OP_PRIMITIVE | + sarea_priv->vertex_prim | + ((used/4)-2)); + + if (used & 4) { + *(u32 *)((u32)buf_priv->virtual + used) = 0; + used += 4; + } + + i830_unmap_buffer(buf); + } + + if (used) { + do { + if (i < nbox) { + BEGIN_LP_RING(6); + OUT_RING( GFX_OP_DRAWRECT_INFO ); + OUT_RING( sarea_priv->BufferState[I830_DESTREG_DR1] ); + OUT_RING( box[i].x1 | (box[i].y1<<16) ); + OUT_RING( box[i].x2 | (box[i].y2<<16) ); + OUT_RING( sarea_priv->BufferState[I830_DESTREG_DR4] ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + } + + BEGIN_LP_RING(4); + + OUT_RING( MI_BATCH_BUFFER ); + OUT_RING( start | MI_BATCH_NON_SECURE ); + OUT_RING( start + used - 4 ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + + } while (++i < nbox); + } + + BEGIN_LP_RING(10); + OUT_RING( CMD_STORE_DWORD_IDX ); + OUT_RING( 20 ); + OUT_RING( dev_priv->counter ); + OUT_RING( 0 ); + + if (discard) { + OUT_RING( CMD_STORE_DWORD_IDX ); + OUT_RING( buf_priv->my_use_idx ); + OUT_RING( I830_BUF_FREE ); + OUT_RING( 0 ); + } + + OUT_RING( CMD_REPORT_HEAD ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); +} + +/* Interrupts are only for flushing */ +void i830_dma_service(int irq, void *device, struct pt_regs *regs) +{ + drm_device_t *dev = (drm_device_t *)device; + drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; + u16 temp; + + temp = I830_READ16(I830REG_INT_IDENTITY_R); + temp = temp & ~(0x6000); + if(temp != 0) I830_WRITE16(I830REG_INT_IDENTITY_R, + temp); /* Clear all interrupts */ + else + return; + + queue_task(&dev->tq, &tq_immediate); + mark_bh(IMMEDIATE_BH); +} + +void DRM(dma_immediate_bh)(void *device) +{ + drm_device_t *dev = (drm_device_t *) device; + drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; + + atomic_set(&dev_priv->flush_done, 1); + wake_up_interruptible(&dev_priv->flush_queue); +} + +static inline void i830_dma_emit_flush(drm_device_t *dev) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + i830_kernel_lost_context(dev); + + BEGIN_LP_RING(2); + OUT_RING( CMD_REPORT_HEAD ); + OUT_RING( GFX_OP_USER_INTERRUPT ); + ADVANCE_LP_RING(); + + i830_wait_ring( dev, dev_priv->ring.Size - 8 ); + atomic_set(&dev_priv->flush_done, 1); + wake_up_interruptible(&dev_priv->flush_queue); +} + +static inline void i830_dma_quiescent_emit(drm_device_t *dev) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + i830_kernel_lost_context(dev); + + BEGIN_LP_RING(4); + OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE ); + OUT_RING( CMD_REPORT_HEAD ); + OUT_RING( 0 ); + OUT_RING( GFX_OP_USER_INTERRUPT ); + ADVANCE_LP_RING(); + + i830_wait_ring( dev, dev_priv->ring.Size - 8 ); + atomic_set(&dev_priv->flush_done, 1); + wake_up_interruptible(&dev_priv->flush_queue); +} + +void i830_dma_quiescent(drm_device_t *dev) +{ + DECLARE_WAITQUEUE(entry, current); + drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; + unsigned long end; + + if(dev_priv == NULL) { + return; + } + atomic_set(&dev_priv->flush_done, 0); + add_wait_queue(&dev_priv->flush_queue, &entry); + end = jiffies + (HZ*3); + + for (;;) { + current->state = TASK_INTERRUPTIBLE; + i830_dma_quiescent_emit(dev); + if (atomic_read(&dev_priv->flush_done) == 1) break; + if(time_before(end, jiffies)) { + DRM_ERROR("lockup\n"); + break; + } + schedule_timeout(HZ*3); + if (signal_pending(current)) { + break; + } + } + + current->state = TASK_RUNNING; + remove_wait_queue(&dev_priv->flush_queue, &entry); + + return; +} + +static int i830_flush_queue(drm_device_t *dev) +{ + DECLARE_WAITQUEUE(entry, current); + drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; + drm_device_dma_t *dma = dev->dma; + unsigned long end; + int i, ret = 0; + + if(dev_priv == NULL) { + return 0; + } + atomic_set(&dev_priv->flush_done, 0); + add_wait_queue(&dev_priv->flush_queue, &entry); + end = jiffies + (HZ*3); + for (;;) { + current->state = TASK_INTERRUPTIBLE; + i830_dma_emit_flush(dev); + if (atomic_read(&dev_priv->flush_done) == 1) break; + if(time_before(end, jiffies)) { + DRM_ERROR("lockup\n"); + break; + } + schedule_timeout(HZ*3); + if (signal_pending(current)) { + ret = -EINTR; /* Can't restart */ + break; + } + } + + current->state = TASK_RUNNING; + remove_wait_queue(&dev_priv->flush_queue, &entry); + + + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[ i ]; + drm_i830_buf_priv_t *buf_priv = buf->dev_private; + + int used = cmpxchg(buf_priv->in_use, I830_BUF_HARDWARE, + I830_BUF_FREE); + + if (used == I830_BUF_HARDWARE) + DRM_DEBUG("reclaimed from HARDWARE\n"); + if (used == I830_BUF_CLIENT) + DRM_DEBUG("still on client HARDWARE\n"); + } + + return ret; +} + +/* Must be called with the lock held */ +void i830_reclaim_buffers(drm_device_t *dev, pid_t pid) +{ + drm_device_dma_t *dma = dev->dma; + int i; + + if (!dma) return; + if (!dev->dev_private) return; + if (!dma->buflist) return; + + i830_flush_queue(dev); + + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[ i ]; + drm_i830_buf_priv_t *buf_priv = buf->dev_private; + + if (buf->pid == pid && buf_priv) { + int used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, + I830_BUF_FREE); + + if (used == I830_BUF_CLIENT) + DRM_DEBUG("reclaimed from client\n"); + if(buf_priv->currently_mapped == I830_BUF_MAPPED) + buf_priv->currently_mapped = I830_BUF_UNMAPPED; + } + } +} + +int i830_flush_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + + DRM_DEBUG("i830_flush_ioctl\n"); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i830_flush_ioctl called without lock held\n"); + return -EINVAL; + } + + i830_flush_queue(dev); + return 0; +} + +int i830_dma_vertex(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_device_dma_t *dma = dev->dma; + drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; + u32 *hw_status = (u32 *)dev_priv->hw_status_page; + drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) + dev_priv->sarea_priv; + drm_i830_vertex_t vertex; + + if (copy_from_user(&vertex, (drm_i830_vertex_t *)arg, sizeof(vertex))) + return -EFAULT; + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i830_dma_vertex called without lock held\n"); + return -EINVAL; + } + + DRM_DEBUG("i830 dma vertex, idx %d used %d discard %d\n", + vertex.idx, vertex.used, vertex.discard); + + if(vertex.idx < 0 || vertex.idx > dma->buf_count) return -EINVAL; + + i830_dma_dispatch_vertex( dev, + dma->buflist[ vertex.idx ], + vertex.discard, vertex.used ); + + sarea_priv->last_enqueue = dev_priv->counter-1; + sarea_priv->last_dispatch = (int) hw_status[5]; + + return 0; +} + +int i830_clear_bufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i830_clear_t clear; + + if (copy_from_user(&clear, (drm_i830_clear_t *)arg, sizeof(clear))) + return -EFAULT; + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i830_clear_bufs called without lock held\n"); + return -EINVAL; + } + + /* GH: Someone's doing nasty things... */ + if (!dev->dev_private) { + return -EINVAL; + } + + i830_dma_dispatch_clear( dev, clear.flags, + clear.clear_color, + clear.clear_depth, + clear.clear_depthmask); + return 0; +} + +int i830_swap_bufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + + DRM_DEBUG("i830_swap_bufs\n"); + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i830_swap_buf called without lock held\n"); + return -EINVAL; + } + + i830_dma_dispatch_swap( dev ); + return 0; +} + +int i830_getage(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; + u32 *hw_status = (u32 *)dev_priv->hw_status_page; + drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) + dev_priv->sarea_priv; + + sarea_priv->last_dispatch = (int) hw_status[5]; + return 0; +} + +int i830_getbuf(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + int retcode = 0; + drm_i830_dma_t d; + drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; + u32 *hw_status = (u32 *)dev_priv->hw_status_page; + drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) + dev_priv->sarea_priv; + + DRM_DEBUG("getbuf\n"); + if (copy_from_user(&d, (drm_i830_dma_t *)arg, sizeof(d))) + return -EFAULT; + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i830_dma called without lock held\n"); + return -EINVAL; + } + + d.granted = 0; + + retcode = i830_dma_get_buffer(dev, &d, filp); + + DRM_DEBUG("i830_dma: %d returning %d, granted = %d\n", + current->pid, retcode, d.granted); + + if (copy_to_user((drm_dma_t *)arg, &d, sizeof(d))) + return -EFAULT; + sarea_priv->last_dispatch = (int) hw_status[5]; + + return retcode; +} + +int i830_copybuf(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i830_copy_t d; + drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; + u32 *hw_status = (u32 *)dev_priv->hw_status_page; + drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) + dev_priv->sarea_priv; + drm_buf_t *buf; + drm_i830_buf_priv_t *buf_priv; + drm_device_dma_t *dma = dev->dma; + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i830_dma called without lock held\n"); + return -EINVAL; + } + + if (copy_from_user(&d, (drm_i830_copy_t *)arg, sizeof(d))) + return -EFAULT; + + if(d.idx < 0 || d.idx > dma->buf_count) return -EINVAL; + buf = dma->buflist[ d.idx ]; + buf_priv = buf->dev_private; + if (buf_priv->currently_mapped != I830_BUF_MAPPED) return -EPERM; + + if(d.used < 0 || d.used > buf->total) return -EINVAL; + + if (copy_from_user(buf_priv->virtual, d.address, d.used)) + return -EFAULT; + + sarea_priv->last_dispatch = (int) hw_status[5]; + + return 0; +} + +int i830_docopy(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + if(VM_DONTCOPY == 0) return 1; + return 0; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/i830_drm.h linux.19pre5-ac1/drivers/char/drm/i830_drm.h --- linux.19p5/drivers/char/drm/i830_drm.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/char/drm/i830_drm.h Wed Feb 13 00:35:28 2002 @@ -0,0 +1,238 @@ +#ifndef _I830_DRM_H_ +#define _I830_DRM_H_ + +/* WARNING: These defines must be the same as what the Xserver uses. + * if you change them, you must change the defines in the Xserver. + */ + +#ifndef _I830_DEFINES_ +#define _I830_DEFINES_ + +#define I830_DMA_BUF_ORDER 12 +#define I830_DMA_BUF_SZ (1< + * Jeff Hartmann + * Gareth Hughes + * Abraham vd Merwe + */ + +#include +#include "i830.h" +#include "drmP.h" +#include "i830_drv.h" + +#define DRIVER_AUTHOR "VA Linux Systems Inc." + +#define DRIVER_NAME "i830" +#define DRIVER_DESC "Intel 830M" +#define DRIVER_DATE "20011004" + +#define DRIVER_MAJOR 1 +#define DRIVER_MINOR 2 +#define DRIVER_PATCHLEVEL 0 + +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_INIT)] = { i830_dma_init, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_VERTEX)] = { i830_dma_vertex, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_CLEAR)] = { i830_clear_bufs, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_FLUSH)] = { i830_flush_ioctl, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_GETAGE)] = { i830_getage, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_GETBUF)] = { i830_getbuf, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_SWAP)] = { i830_swap_bufs, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_COPY)] = { i830_copybuf, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_DOCOPY)] = { i830_docopy, 1, 0 }, + +#define __HAVE_COUNTERS 4 +#define __HAVE_COUNTER6 _DRM_STAT_IRQ +#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY +#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY +#define __HAVE_COUNTER9 _DRM_STAT_DMA + + +#include "drm_agpsupport.h" +#include "drm_auth.h" +#include "drm_bufs.h" +#include "drm_context.h" +#include "drm_dma.h" +#include "drm_drawable.h" +#include "drm_drv.h" + +#ifndef MODULE +/* DRM(options) is called by the kernel to parse command-line options + * passed via the boot-loader (e.g., LILO). It calls the insmod option + * routine, drm_parse_drm. + */ + +/* JH- We have to hand expand the string ourselves because of the cpp. If + * anyone can think of a way that we can fit into the __setup macro without + * changing it, then please send the solution my way. + */ +static int __init i830_options( char *str ) +{ + DRM(parse_options)( str ); + return 1; +} + +__setup( DRIVER_NAME "=", i830_options ); +#endif + +#include "drm_fops.h" +#include "drm_init.h" +#include "drm_ioctl.h" +#include "drm_lock.h" +#include "drm_lists.h" +#include "drm_memory.h" +#include "drm_proc.h" +#include "drm_vm.h" +#include "drm_stub.h" diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/i830_drv.h linux.19pre5-ac1/drivers/char/drm/i830_drv.h --- linux.19p5/drivers/char/drm/i830_drv.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/char/drm/i830_drv.h Wed Feb 13 00:35:28 2002 @@ -0,0 +1,213 @@ +/* i830_drv.h -- Private header for the I830 driver -*- linux-c -*- + * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com + * + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: Rickard E. (Rik) Faith + * Jeff Hartmann + * + */ + +#ifndef _I830_DRV_H_ +#define _I830_DRV_H_ + +typedef struct drm_i830_buf_priv { + u32 *in_use; + int my_use_idx; + int currently_mapped; + void *virtual; + void *kernel_virtual; + int map_count; + struct vm_area_struct *vma; +} drm_i830_buf_priv_t; + +typedef struct _drm_i830_ring_buffer{ + int tail_mask; + unsigned long Start; + unsigned long End; + unsigned long Size; + u8 *virtual_start; + int head; + int tail; + int space; +} drm_i830_ring_buffer_t; + +typedef struct drm_i830_private { + drm_map_t *sarea_map; + drm_map_t *buffer_map; + drm_map_t *mmio_map; + + drm_i830_sarea_t *sarea_priv; + drm_i830_ring_buffer_t ring; + + unsigned long hw_status_page; + unsigned long counter; + + atomic_t flush_done; + wait_queue_head_t flush_queue; /* Processes waiting until flush */ + drm_buf_t *mmap_buffer; + + u32 front_di1, back_di1, zi1; + + int back_offset; + int depth_offset; + int w, h; + int pitch; + int back_pitch; + int depth_pitch; + unsigned int cpp; +} drm_i830_private_t; + + /* i830_dma.c */ +extern int i830_dma_schedule(drm_device_t *dev, int locked); +extern int i830_getbuf(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int i830_dma_init(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int i830_flush_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern void i830_reclaim_buffers(drm_device_t *dev, pid_t pid); +extern int i830_getage(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg); +extern int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma); +extern int i830_copybuf(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int i830_docopy(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + +extern void i830_dma_quiescent(drm_device_t *dev); + +extern int i830_dma_vertex(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + +extern int i830_swap_bufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + +extern int i830_clear_bufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + +#define I830_VERBOSE 0 + +#define I830_BASE(reg) ((unsigned long) \ + dev_priv->mmio_map->handle) +#define I830_ADDR(reg) (I830_BASE(reg) + reg) +#define I830_DEREF(reg) *(__volatile__ int *)I830_ADDR(reg) +#define I830_READ(reg) I830_DEREF(reg) +#define I830_WRITE(reg,val) do { I830_DEREF(reg) = val; } while (0) +#define I830_DEREF16(reg) *(__volatile__ u16 *)I830_ADDR(reg) +#define I830_READ16(reg) I830_DEREF16(reg) +#define I830_WRITE16(reg,val) do { I830_DEREF16(reg) = val; } while (0) + +#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) +#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) +#define CMD_REPORT_HEAD (7<<23) +#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1) +#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1) + +#define INST_PARSER_CLIENT 0x00000000 +#define INST_OP_FLUSH 0x02000000 +#define INST_FLUSH_MAP_CACHE 0x00000001 + + +#define BB1_START_ADDR_MASK (~0x7) +#define BB1_PROTECTED (1<<0) +#define BB1_UNPROTECTED (0<<0) +#define BB2_END_ADDR_MASK (~0x7) + +#define I830REG_HWSTAM 0x02098 +#define I830REG_INT_IDENTITY_R 0x020a4 +#define I830REG_INT_MASK_R 0x020a8 +#define I830REG_INT_ENABLE_R 0x020a0 + +#define LP_RING 0x2030 +#define HP_RING 0x2040 +#define RING_TAIL 0x00 +#define TAIL_ADDR 0x000FFFF8 +#define RING_HEAD 0x04 +#define HEAD_WRAP_COUNT 0xFFE00000 +#define HEAD_WRAP_ONE 0x00200000 +#define HEAD_ADDR 0x001FFFFC +#define RING_START 0x08 +#define START_ADDR 0x00FFFFF8 +#define RING_LEN 0x0C +#define RING_NR_PAGES 0x000FF000 +#define RING_REPORT_MASK 0x00000006 +#define RING_REPORT_64K 0x00000002 +#define RING_REPORT_128K 0x00000004 +#define RING_NO_REPORT 0x00000000 +#define RING_VALID_MASK 0x00000001 +#define RING_VALID 0x00000001 +#define RING_INVALID 0x00000000 + +#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19)) +#define SC_UPDATE_SCISSOR (0x1<<1) +#define SC_ENABLE_MASK (0x1<<0) +#define SC_ENABLE (0x1<<0) + +#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1)) +#define SCI_YMIN_MASK (0xffff<<16) +#define SCI_XMIN_MASK (0xffff<<0) +#define SCI_YMAX_MASK (0xffff<<16) +#define SCI_XMAX_MASK (0xffff<<0) + +#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19)) +#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1) +#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0) +#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) +#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4) +#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0) +#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3)) +#define GFX_OP_PRIMITIVE ((0x3<<29)|(0x1f<<24)) + +#define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1) + + +#define BR00_BITBLT_CLIENT 0x40000000 +#define BR00_OP_COLOR_BLT 0x10000000 +#define BR00_OP_SRC_COPY_BLT 0x10C00000 +#define BR13_SOLID_PATTERN 0x80000000 + +#define BUF_3D_ID_COLOR_BACK (0x3<<24) +#define BUF_3D_ID_DEPTH (0x7<<24) +#define BUF_3D_USE_FENCE (1<<23) +#define BUF_3D_PITCH(x) (((x)/4)<<2) + +#define CMD_OP_MAP_PALETTE_LOAD ((3<<29)|(0x1d<<24)|(0x82<<16)|255) +#define MAP_PALETTE_NUM(x) ((x<<8) & (1<<8)) +#define MAP_PALETTE_BOTH (1<<11) + +#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4) +#define XY_COLOR_BLT_WRITE_ALPHA (1<<21) +#define XY_COLOR_BLT_WRITE_RGB (1<<20) + +#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) +#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) +#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) + +#define MI_BATCH_BUFFER ((0x30<<23)|1) +#define MI_BATCH_NON_SECURE (1) + + +#endif + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/picker.c linux.19pre5-ac1/drivers/char/drm/picker.c --- linux.19p5/drivers/char/drm/picker.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/char/drm/picker.c Wed Feb 13 00:35:28 2002 @@ -0,0 +1,30 @@ + +#include +#include + +#ifndef CONFIG_SMP +#define CONFIG_SMP 0 +#endif + +#ifndef CONFIG_MODULES +#define CONFIG_MODULES 0 +#endif + +#ifndef CONFIG_MODVERSIONS +#define CONFIG_MODVERSIONS 0 +#endif + +#ifndef CONFIG_AGP_MODULE +#define CONFIG_AGP_MODULE 0 +#endif + +#ifndef CONFIG_AGP +#define CONFIG_AGP 0 +#endif + +SMP = CONFIG_SMP +MODULES = CONFIG_MODULES +MODVERSIONS = CONFIG_MODVERSIONS +AGP = CONFIG_AGP +AGP_MODULE = CONFIG_AGP_MODULE +RELEASE = UTS_RELEASE diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/r128_drv.c linux.19pre5-ac1/drivers/char/drm/r128_drv.c --- linux.19p5/drivers/char/drm/r128_drv.c Thu Apr 4 13:19:12 2002 +++ linux.19pre5-ac1/drivers/char/drm/r128_drv.c Wed Feb 13 00:35:28 2002 @@ -39,11 +39,11 @@ #define DRIVER_NAME "r128" #define DRIVER_DESC "ATI Rage 128" -#define DRIVER_DATE "20010405" +#define DRIVER_DATE "20010917" #define DRIVER_MAJOR 2 -#define DRIVER_MINOR 1 -#define DRIVER_PATCHLEVEL 6 +#define DRIVER_MINOR 2 +#define DRIVER_PATCHLEVEL 0 #define DRIVER_IOCTLS \ [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { r128_cce_buffers, 1, 0 }, \ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/r128_state.c linux.19pre5-ac1/drivers/char/drm/r128_state.c --- linux.19p5/drivers/char/drm/r128_state.c Thu Apr 4 13:19:12 2002 +++ linux.19pre5-ac1/drivers/char/drm/r128_state.c Wed Feb 13 00:35:28 2002 @@ -1519,10 +1519,75 @@ { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; + drm_r128_private_t *dev_priv = dev->dev_private; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; + drm_r128_buf_priv_t *buf_priv; + drm_r128_indirect_t indirect; +#if 0 + RING_LOCALS; +#endif LOCK_TEST_WITH_RETURN( dev ); - /* Indirect buffer firing is not supported at this time. + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + if ( copy_from_user( &indirect, (drm_r128_indirect_t *)arg, + sizeof(indirect) ) ) + return -EFAULT; + + DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n", + indirect.idx, indirect.start, + indirect.end, indirect.discard ); + + if ( indirect.idx < 0 || indirect.idx >= dma->buf_count ) { + DRM_ERROR( "buffer index %d (of %d max)\n", + indirect.idx, dma->buf_count - 1 ); + return -EINVAL; + } + + buf = dma->buflist[indirect.idx]; + buf_priv = buf->dev_private; + + if ( buf->pid != current->pid ) { + DRM_ERROR( "process %d using buffer owned by %d\n", + current->pid, buf->pid ); + return -EINVAL; + } + if ( buf->pending ) { + DRM_ERROR( "sending pending buffer %d\n", indirect.idx ); + return -EINVAL; + } + + if ( indirect.start < buf->used ) { + DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n", + indirect.start, buf->used ); + return -EINVAL; + } + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + VB_AGE_TEST_WITH_RETURN( dev_priv ); + + buf->used = indirect.end; + buf_priv->discard = indirect.discard; + +#if 0 + /* Wait for the 3D stream to idle before the indirect buffer + * containing 2D acceleration commands is processed. */ - return -EINVAL; + BEGIN_RING( 2 ); + RADEON_WAIT_UNTIL_3D_IDLE(); + ADVANCE_RING(); +#endif + + /* Dispatch the indirect buffer full of commands from the + * X server. This is insecure and is thus only available to + * privileged clients. + */ + r128_cce_dispatch_indirect( dev, buf, indirect.start, indirect.end ); + + return 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm-4.0/ffb_drv.c linux.19pre5-ac1/drivers/char/drm-4.0/ffb_drv.c --- linux.19p5/drivers/char/drm-4.0/ffb_drv.c Thu Apr 4 13:19:13 2002 +++ linux.19pre5-ac1/drivers/char/drm-4.0/ffb_drv.c Wed Feb 27 18:32:03 2002 @@ -710,8 +710,7 @@ /* Contention */ atomic_inc(&dev->total_sleeps); current->state = TASK_INTERRUPTIBLE; - current->policy |= SCHED_YIELD; - schedule(); + yield(); if (signal_pending(current)) { ret = -ERESTARTSYS; break; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm-4.0/i810_dma.c linux.19pre5-ac1/drivers/char/drm-4.0/i810_dma.c --- linux.19p5/drivers/char/drm-4.0/i810_dma.c Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/drivers/char/drm-4.0/i810_dma.c Tue Mar 19 16:02:17 2002 @@ -83,7 +83,7 @@ *(volatile unsigned int *)(virt + outring) = n; \ outring += 4; \ outring &= ringmask; \ -} while (0); +} while (0) static inline void i810_print_status_page(drm_device_t *dev) { @@ -231,7 +231,7 @@ #else retcode = do_munmap(current->mm, (unsigned long)buf_priv->virtual, - (size_t) buf->total); + (size_t) buf->total, 1); #endif up_write(¤t->mm->mmap_sem); } @@ -279,7 +279,7 @@ address = __get_free_page(GFP_KERNEL); if(address == 0UL) return 0; - + get_page(virt_to_page(address)); LockPage(virt_to_page(address)); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm-4.0/tdfx_drv.c linux.19pre5-ac1/drivers/char/drm-4.0/tdfx_drv.c --- linux.19p5/drivers/char/drm-4.0/tdfx_drv.c Thu Apr 4 13:19:13 2002 +++ linux.19pre5-ac1/drivers/char/drm-4.0/tdfx_drv.c Wed Feb 27 18:32:03 2002 @@ -554,7 +554,6 @@ lock.context, current->pid, j, dev->lock.lock_time, jiffies); current->state = TASK_INTERRUPTIBLE; - current->policy |= SCHED_YIELD; schedule_timeout(DRM_LOCK_SLICE-j); DRM_DEBUG("jiffies=%d\n", jiffies); } @@ -578,10 +577,7 @@ /* Contention */ atomic_inc(&dev->total_sleeps); -#if 1 - current->policy |= SCHED_YIELD; -#endif - schedule(); + yield(); if (signal_pending(current)) { ret = -ERESTARTSYS; break; @@ -604,8 +600,7 @@ when dev->last_context == lock.context NOTE WE HOLD THE LOCK THROUGHOUT THIS TIME! */ - current->policy |= SCHED_YIELD; - schedule(); + yield(); current->state = TASK_RUNNING; remove_wait_queue(&dev->context_wait, &entry); if (signal_pending(current)) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/indydog.c linux.19pre5-ac1/drivers/char/indydog.c --- linux.19p5/drivers/char/indydog.c Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/drivers/char/indydog.c Tue Mar 26 18:44:55 2002 @@ -24,7 +24,7 @@ #include #include -static int indydog_alive; +static unsigned long indydog_alive; static struct sgimc_misc_ctrl *mcmisc_regs; static void indydog_ping() @@ -41,7 +41,7 @@ { u32 mc_ctrl0; - if(indydog_alive) + if( test_and_set_bit(0,&indydog_alive) ) return -EBUSY; #ifdef CONFIG_WATCHDOG_NOWAYOUT MOD_INC_USE_COUNT; @@ -55,7 +55,6 @@ mcmisc_regs->cpuctrl0 = mc_ctrl0; indydog_ping(); - indydog_alive=1; printk("Started watchdog timer.\n"); return 0; } @@ -66,7 +65,6 @@ * Shut off the timer. * Lock it in if it's a module and we defined ...NOWAYOUT */ - lock_kernel(); #ifndef CONFIG_WATCHDOG_NOWAYOUT { u32 mc_ctrl0 = mcmisc_regs->cpuctrl0; @@ -75,8 +73,7 @@ printk("Stopped watchdog timer.\n"); } #endif - indydog_alive=0; - unlock_kernel(); + clear_bit(0,&indydog_alive); return 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/mwave/mwavedd.c linux.19pre5-ac1/drivers/char/mwave/mwavedd.c --- linux.19p5/drivers/char/mwave/mwavedd.c Thu Apr 4 13:19:09 2002 +++ linux.19pre5-ac1/drivers/char/mwave/mwavedd.c Wed Feb 27 18:32:03 2002 @@ -279,7 +279,6 @@ pDrvData->IPCs[ipcnum].bIsHere = FALSE; pDrvData->IPCs[ipcnum].bIsEnabled = TRUE; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - current->nice = -20; /* boost to provide priority timing */ #else current->priority = 0x28; /* boost to provide priority timing */ #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/pc_keyb.c linux.19pre5-ac1/drivers/char/pc_keyb.c --- linux.19p5/drivers/char/pc_keyb.c Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/drivers/char/pc_keyb.c Thu Mar 14 22:08:13 2002 @@ -1066,6 +1066,9 @@ static int open_aux(struct inode * inode, struct file * file) { + unsigned long flags; + int cnt, status; + if (aux_count++) { return 0; } @@ -1077,7 +1080,30 @@ kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE); /* Enable the auxiliary port on controller. */ - aux_write_ack(AUX_ENABLE_DEV); /* Enable aux device */ + + spin_lock_irqsave(&kbd_controller_lock, flags); + __aux_write_ack(AUX_ENABLE_DEV); /* Enable aux device */ + for(cnt = 50; cnt > 0; --cnt) { + status = handle_kbd_event(); + if (mouse_reply_expected == 0 || + (status & (KBD_STAT_GTO | KBD_STAT_PERR))) + break; + set_current_state(TASK_UNINTERRUPTIBLE); + spin_unlock_irqrestore(&kbd_controller_lock, flags); + schedule_timeout(2); + spin_lock_irqsave(&kbd_controller_lock, flags); + set_current_state(TASK_RUNNING); + } + if (cnt == 0 || (status & (KBD_STAT_GTO | KBD_STAT_PERR))) { + --aux_count; + spin_unlock_irqrestore(&kbd_controller_lock, flags); + kbd_write_cmd(AUX_INTS_OFF); + kbd_write_command_w(KBD_CCMD_MOUSE_DISABLE); + aux_free_irq(AUX_DEV); + return -ENXIO; + } + spin_unlock_irqrestore(&kbd_controller_lock, flags); + kbd_write_cmd(AUX_INTS_ON); /* Enable controller ints */ mdelay(2); /* Ensure we follow the kbc access delay rules.. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/random.c linux.19pre5-ac1/drivers/char/random.c --- linux.19p5/drivers/char/random.c Thu Apr 4 13:19:03 2002 +++ linux.19pre5-ac1/drivers/char/random.c Tue Feb 26 23:21:52 2002 @@ -1643,7 +1643,7 @@ return -EINVAL; if (size > random_state->poolinfo.poolwords) size = random_state->poolinfo.poolwords; - if (copy_to_user(p, random_state->pool, size * 4)) + if (copy_to_user(p, random_state->pool, size * sizeof(__u32))) return -EFAULT; return 0; case RNDADDENTROPY: diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/raw.c linux.19pre5-ac1/drivers/char/raw.c --- linux.19p5/drivers/char/raw.c Thu Apr 4 13:19:09 2002 +++ linux.19pre5-ac1/drivers/char/raw.c Tue Feb 12 15:57:47 2002 @@ -23,6 +23,7 @@ struct block_device *binding; int inuse, sector_size, sector_bits; struct semaphore mutex; + int can_do_vary; } raw_device_data_t; static raw_device_data_t raw_devices[256]; @@ -117,6 +118,8 @@ if (raw_devices[minor].inuse++) goto out; + raw_devices[minor].can_do_vary = + get_blkdev_varyio(MAJOR(rdev), MINOR(rdev)); /* * Don't interfere with mounted devices: we cannot safely set * the blocksize on a device which is already mounted. @@ -126,6 +129,7 @@ if (is_mounted(rdev)) { if (blksize_size[MAJOR(rdev)]) sector_size = blksize_size[MAJOR(rdev)][MINOR(rdev)]; + raw_devices[minor].can_do_vary = 0; } else { if (hardsect_size[MAJOR(rdev)]) sector_size = hardsect_size[MAJOR(rdev)][MINOR(rdev)]; @@ -133,6 +137,7 @@ set_blocksize(rdev, sector_size); raw_devices[minor].sector_size = sector_size; + filp->f_iobuf->dovary = raw_devices[minor].can_do_vary; for (sector_bits = 0; !(sector_size & 1); ) sector_size>>=1, sector_bits++; @@ -301,6 +306,7 @@ if (err) goto out; new_iobuf = 1; + iobuf->dovary = raw_devices[minor].can_do_vary; } dev = to_kdev_t(raw_devices[minor].binding->bd_dev); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/rtc.c linux.19pre5-ac1/drivers/char/rtc.c --- linux.19p5/drivers/char/rtc.c Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/drivers/char/rtc.c Mon Mar 25 18:05:32 2002 @@ -67,6 +67,7 @@ #include #include #include +#include #include #include @@ -138,6 +139,7 @@ static unsigned long rtc_status = 0; /* bitmapped status byte. */ static unsigned long rtc_freq = 0; /* Current periodic IRQ rate */ static unsigned long rtc_irq_data = 0; /* our output to the world */ +static unsigned long rtc_max_user_freq = 64; /* > this, need CAP_SYS_RESOURCE */ /* * If this driver ever becomes modularised, it will be really nice @@ -187,6 +189,38 @@ #endif /* + * sysctl-tuning infrastructure. + */ +static ctl_table rtc_table[] = { + { 1, "max-user-freq", &rtc_max_user_freq, sizeof(int), 0644, NULL, + &proc_dointvec, NULL, }, + { 0, } +}; + +static ctl_table rtc_root[] = { + { 1, "rtc", NULL, 0, 0555, rtc_table, }, + { 0, } +}; + +static ctl_table dev_root[] = { + { CTL_DEV, "dev", NULL, 0, 0555, rtc_root, }, + { 0, } +}; + +static struct ctl_table_header *sysctl_header; + +static int __init init_sysctl(void) +{ + sysctl_header = register_sysctl_table(dev_root, 0); + return 0; +} + +static void __exit cleanup_sysctl(void) +{ + unregister_sysctl_table(sysctl_header); +} + +/* * Now all the various file operations that we export. */ @@ -295,7 +329,8 @@ * We don't really want Joe User enabling more * than 64Hz of interrupts on a multi-user machine. */ - if ((rtc_freq > 64) && (!capable(CAP_SYS_RESOURCE))) + if ((rtc_freq > rtc_max_user_freq) && + (!capable(CAP_SYS_RESOURCE))) return -EACCES; if (!(rtc_status & RTC_TIMER_ON)) { @@ -493,7 +528,7 @@ * We don't really want Joe User generating more * than 64Hz of interrupts on a multi-user machine. */ - if ((arg > 64) && (!capable(CAP_SYS_RESOURCE))) + if ((arg > rtc_max_user_freq) && (!capable(CAP_SYS_RESOURCE))) return -EACCES; while (arg > (1< #include #include +#include #if (LINUX_VERSION_CODE >= 131343) #include #endif @@ -1221,7 +1222,7 @@ if (!page) return -ENOMEM; - save_flags(flags); cli(); + spin_lock_irqsave( &info->irq_spinlock, flags); if (info->flags & ASYNC_INITIALIZED) { free_page(page); @@ -1459,11 +1460,11 @@ change_speed(info, 0); info->flags |= ASYNC_INITIALIZED; - restore_flags(flags); + spin_unlock_irqrestore( &info->irq_spinlock, flags); return 0; errout: - restore_flags(flags); + spin_unlock_irqrestore( &info->irq_spinlock, flags); return retval; } @@ -1487,7 +1488,7 @@ state->irq); #endif - save_flags(flags); cli(); /* Disable interrupts */ + spin_lock_irqsave( &info->irq_spinlock, flags); /* * clear delta_msr_wait queue to avoid mem leaks: we may free the irq @@ -1495,41 +1496,6 @@ */ wake_up_interruptible(&info->delta_msr_wait); - /* - * First unlink the serial port from the IRQ chain... - */ - if (info->next_port) - info->next_port->prev_port = info->prev_port; - if (info->prev_port) - info->prev_port->next_port = info->next_port; - else - IRQ_ports[state->irq] = info->next_port; - figure_IRQ_timeout(state->irq); - - /* - * Free the IRQ, if necessary - */ - if (state->irq && (!IRQ_ports[state->irq] || - !IRQ_ports[state->irq]->next_port)) { - if (IRQ_ports[state->irq]) { - free_irq(state->irq, &IRQ_ports[state->irq]); - retval = request_irq(state->irq, rs_interrupt_single, - SA_SHIRQ, "serial", - &IRQ_ports[state->irq]); - - if (retval) - printk("serial shutdown: request_irq: error %d" - " Couldn't reacquire IRQ.\n", retval); - } else - free_irq(state->irq, &IRQ_ports[state->irq]); - } - - if (info->xmit.buf) { - unsigned long pg = (unsigned long) info->xmit.buf; - info->xmit.buf = 0; - free_page(pg); - } - info->IER = 0; serial_outp(info, UART_IER, 0x00); /* disable all intrs */ #ifdef CONFIG_SERIAL_MANY_PORTS @@ -1586,7 +1552,43 @@ serial_outp(info, UART_IER, UART_IERX_SLEEP); } info->flags &= ~ASYNC_INITIALIZED; - restore_flags(flags); + + /* + * First unlink the serial port from the IRQ chain... + */ + if (info->next_port) + info->next_port->prev_port = info->prev_port; + if (info->prev_port) + info->prev_port->next_port = info->next_port; + else + IRQ_ports[state->irq] = info->next_port; + figure_IRQ_timeout(state->irq); + + /* + * Free the IRQ, if necessary + */ + if (state->irq && (!IRQ_ports[state->irq] || + !IRQ_ports[state->irq]->next_port)) { + if (IRQ_ports[state->irq]) { + free_irq(state->irq, &IRQ_ports[state->irq]); + retval = request_irq(state->irq, rs_interrupt_single, + SA_SHIRQ, "serial", + &IRQ_ports[state->irq]); + + if (retval) + printk("serial shutdown: request_irq: error %d" + " Couldn't reacquire IRQ.\n", retval); + } else + free_irq(state->irq, &IRQ_ports[state->irq]); + } + + if (info->xmit.buf) { + unsigned long pg = (unsigned long) info->xmit.buf; + info->xmit.buf = 0; + free_page(pg); + } + + spin_unlock_irqrestore( &info->irq_spinlock, flags); } #if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */ @@ -3130,6 +3132,7 @@ info->tqueue.routine = do_softint; info->tqueue.data = info; info->state = sstate; + spin_lock_init(&info->irq_spinlock); if (sstate->info) { kfree(info); *ret_info = sstate->info; @@ -3654,6 +3657,7 @@ info->io_type = state->io_type; info->iomem_base = state->iomem_base; info->iomem_reg_shift = state->iomem_reg_shift; + info->irq_spinlock= (spinlock_t) SPIN_LOCK_UNLOCKED; save_flags(flags); cli(); @@ -3906,7 +3910,14 @@ case 6: /* BAR 4*/ case 7: base_idx=idx-2; /* BAR 5*/ } - + + /* AFAVLAB uses a different mixture of BARs and offsets */ + /* Not that ugly ;) -- HW */ + if (dev->vendor == PCI_VENDOR_ID_AFAVLAB && idx >= 4) { + base_idx = 4; + offset = (idx - 4) * 8; + } + /* Some Titan cards are also a little weird */ if (dev->vendor == PCI_VENDOR_ID_TITAN && (dev->device == PCI_DEVICE_ID_TITAN_400L || @@ -4253,8 +4264,10 @@ pbn_b0_bt_1_115200, pbn_b0_bt_2_115200, + pbn_b0_bt_8_115200, pbn_b0_bt_1_460800, pbn_b0_bt_2_460800, + pbn_b0_bt_4_460800, pbn_b1_1_115200, pbn_b1_2_115200, @@ -4331,8 +4344,10 @@ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, /* pbn_b0_bt_1_115200 */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, /* pbn_b0_bt_2_115200 */ + { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 8, 115200 }, /* pbn_b0_bt_8_115200 */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 460800 }, /* pbn_b0_bt_1_460800 */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 460800 }, /* pbn_b0_bt_2_460800 */ + { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 4, 460800 }, /* pbn_b0_bt_4_460800 */ { SPCI_FL_BASE1, 1, 115200 }, /* pbn_b1_1_115200 */ { SPCI_FL_BASE1, 2, 115200 }, /* pbn_b1_2_115200 */ @@ -4840,6 +4855,12 @@ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b0_bt_2_460800 }, + { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_OCTO_A, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_b0_bt_4_460800 }, + { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_OCTO_B, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_b0_bt_4_460800 }, { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_SSERIAL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b0_bt_1_115200 }, @@ -4852,6 +4873,11 @@ PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b2_bt_2_115200 }, + /* AFAVLAB serial card, from Harald Welte */ + { PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_P028, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_b0_bt_8_115200 }, + /* EKF addition for i960 Boards form EKF with serial port */ { PCI_VENDOR_ID_INTEL, 0x1960, 0xE4BF, PCI_ANY_ID, 0, 0, @@ -5630,6 +5656,7 @@ info->io_type = req->io_type; info->iomem_base = req->iomem_base; info->iomem_reg_shift = req->iomem_reg_shift; + info->irq_spinlock= (spinlock_t) SPIN_LOCK_UNLOCKED; } autoconfig(state); if (state->type == PORT_UNKNOWN) { @@ -5966,6 +5993,7 @@ info->io_type = state->io_type; info->iomem_base = state->iomem_base; info->iomem_reg_shift = state->iomem_reg_shift; + info->irq_spinlock= (spinlock_t) SPIN_LOCK_UNLOCKED; quot = state->baud_base / baud; cval = cflag & (CSIZE | CSTOPB); #if defined(__powerpc__) || defined(__alpha__) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/serial_tx3912.h linux.19pre5-ac1/drivers/char/serial_tx3912.h --- linux.19p5/drivers/char/serial_tx3912.h Thu Apr 4 13:21:11 2002 +++ linux.19pre5-ac1/drivers/char/serial_tx3912.h Fri Mar 1 18:54:28 2002 @@ -12,6 +12,27 @@ #include #include +/* UART Interrupt (Interrupt 2) bits (UARTA,UARTB) */ +#define UART_RX_INT 9 /* receiver holding register full (31, 21) */ +#define UART_RXOVERRUN_INT 8 /* receiver overrun error (30, 20) */ +#define UART_FRAMEERR_INT 7 /* receiver frame error (29, 19) */ +#define UART_BREAK_INT 6 /* received break signal (28, 18) */ +#define UART_PARITYERR_INT 5 /* receiver parity error (27, 17) */ +#define UART_TX_INT 4 /* transmit holding register empty (26, 16) */ +#define UART_TXOVERRUN_INT 3 /* transmit overrun error (25, 15) */ +#define UART_EMPTY_INT 2 /* both trans/recv regs empty (24, 14) */ +#define UART_DMAFULL_INT 1 /* DMA at end of buffer (23, 13) */ +#define UART_DMAHALF_INT 0 /* DMA halfway through buffer (22, 12) */ + +#define UARTA_SHIFT 22 +#define UARTB_SHIFT 12 + +#define INTTYPE(interrupttype) (1 << interrupttype) + +/* + * This driver can spew a whole lot of debugging output at you. If you + * need maximum performance, you should disable the DEBUG define. + */ #undef TX3912_UART_DEBUG #ifdef TX3912_UART_DEBUG diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/sonypi.c linux.19pre5-ac1/drivers/char/sonypi.c --- linux.19p5/drivers/char/sonypi.c Thu Apr 4 13:19:13 2002 +++ linux.19pre5-ac1/drivers/char/sonypi.c Thu Mar 14 23:00:23 2002 @@ -50,6 +50,7 @@ static int fnkeyinit; /* = 0 */ static int camera; /* = 0 */ static int compat; /* = 0 */ +static int nojogdial; /* = 0 */ /* Inits the queue */ static inline void sonypi_initq(void) { @@ -310,24 +311,28 @@ int i; u8 sonypi_jogger_ev, sonypi_fnkey_ev; u8 sonypi_capture_ev, sonypi_bluetooth_ev; + u8 sonypi_pkey_ev; if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) { sonypi_jogger_ev = SONYPI_TYPE2_JOGGER_EV; sonypi_fnkey_ev = SONYPI_TYPE2_FNKEY_EV; sonypi_capture_ev = SONYPI_TYPE2_CAPTURE_EV; sonypi_bluetooth_ev = SONYPI_TYPE2_BLUETOOTH_EV; + sonypi_pkey_ev = nojogdial ? SONYPI_TYPE2_PKEY_EV + : SONYPI_TYPE1_PKEY_EV; } else { sonypi_jogger_ev = SONYPI_TYPE1_JOGGER_EV; sonypi_fnkey_ev = SONYPI_TYPE1_FNKEY_EV; sonypi_capture_ev = SONYPI_TYPE1_CAPTURE_EV; sonypi_bluetooth_ev = SONYPI_TYPE1_BLUETOOTH_EV; + sonypi_pkey_ev = SONYPI_TYPE1_PKEY_EV; } v1 = inb_p(sonypi_device.ioport1); v2 = inb_p(sonypi_device.ioport2); - if ((v2 & SONYPI_TYPE1_PKEY_EV) == SONYPI_TYPE1_PKEY_EV) { + if ((v2 & sonypi_pkey_ev) == sonypi_pkey_ev) { for (i = 0; sonypi_pkeyev[i].event; i++) if (sonypi_pkeyev[i].data == v1) { event = sonypi_pkeyev[i].event; @@ -713,11 +718,12 @@ SONYPI_DRIVER_MAJORVERSION, SONYPI_DRIVER_MINORVERSION); printk(KERN_INFO "sonypi: detected %s model, " - "camera = %s, compat = %s\n", + "camera = %s, compat = %s, nojogdial = %s\n", (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) ? "type1" : "type2", camera ? "on" : "off", - compat ? "on" : "off"); + compat ? "on" : "off", + nojogdial ? "on" : "off"); printk(KERN_INFO "sonypi: enabled at irq=%d, port1=0x%x, port2=0x%x\n", sonypi_device.irq, sonypi_device.ioport1, sonypi_device.ioport2); @@ -791,6 +797,9 @@ if (ints[0] == 4) goto out; compat = ints[5]; + if (ints[0] == 5) + goto out; + nojogdial = ints[6]; out: return 1; } @@ -817,5 +826,7 @@ MODULE_PARM_DESC(camera, "set this if you have a MotionEye camera (PictureBook series)"); MODULE_PARM(compat,"i"); MODULE_PARM_DESC(compat, "set this if you want to enable backward compatibility mode"); +MODULE_PARM(nojogdial, "i"); +MODULE_PARM_DESC(nojogdial, "set this if you have a Vaio without a jogdial (like the fx series)"); EXPORT_SYMBOL(sonypi_camera_command); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/sonypi.h linux.19pre5-ac1/drivers/char/sonypi.h --- linux.19p5/drivers/char/sonypi.h Thu Apr 4 13:19:13 2002 +++ linux.19pre5-ac1/drivers/char/sonypi.h Thu Apr 4 15:51:29 2002 @@ -35,7 +35,7 @@ #ifdef __KERNEL__ #define SONYPI_DRIVER_MAJORVERSION 1 -#define SONYPI_DRIVER_MINORVERSION 10 +#define SONYPI_DRIVER_MINORVERSION 11 #include #include @@ -141,6 +141,7 @@ #define SONYPI_TYPE1_BLUETOOTH_EV 0x30 #define SONYPI_TYPE2_BLUETOOTH_EV 0x08 #define SONYPI_TYPE1_PKEY_EV 0x40 +#define SONYPI_TYPE2_PKEY_EV 0x08 #define SONYPI_BACK_EV 0x08 #define SONYPI_LID_EV 0x38 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/sx.c linux.19pre5-ac1/drivers/char/sx.c --- linux.19p5/drivers/char/sx.c Thu Apr 4 13:19:08 2002 +++ linux.19pre5-ac1/drivers/char/sx.c Thu Mar 28 22:51:48 2002 @@ -353,9 +353,11 @@ 0xc8000, 0xd8000, 0xe8000}; static int si_probe_addrs[]= {0xc0000, 0xd0000, 0xe0000, 0xc8000, 0xd8000, 0xe8000, 0xa0000}; +static int si1_probe_addrs[]= { 0xd0000}; #define NR_SX_ADDRS (sizeof(sx_probe_addrs)/sizeof (int)) #define NR_SI_ADDRS (sizeof(si_probe_addrs)/sizeof (int)) +#define NR_SI1_ADDRS (sizeof(si1_probe_addrs)/sizeof (int)) /* Set the mask to all-ones. This alas, only supports 32 interrupts. @@ -582,6 +584,8 @@ } } else if (IS_EISA_BOARD(board)) { outb(board->irq<<4, board->eisa_base+0xc02); + } else if (IS_SI1_BOARD(board)) { + write_sx_byte (board, SI1_ISA_RESET, 0); // value does not matter } else { /* Gory details of the SI/ISA board */ write_sx_byte (board, SI2_ISA_RESET, SI2_ISA_RESET_SET); @@ -656,6 +660,9 @@ } else if (IS_EISA_BOARD(board)) { write_sx_byte(board, SI2_EISA_OFF, SI2_EISA_VAL); outb((board->irq<<4)|4, board->eisa_base+0xc02); + } else if (IS_SI1_BOARD(board)) { + write_sx_byte (board, SI1_ISA_RESET_CLEAR, 0); + write_sx_byte (board, SI1_ISA_INTCL, 0); } else { /* Don't bug me about the clear_set. I haven't the foggiest idea what it's about -- REW */ @@ -681,6 +688,9 @@ SX_CONF_HOSTIRQ); } else if (IS_EISA_BOARD(board)) { inb(board->eisa_base+0xc03); + } else if (IS_SI1_BOARD(board)) { + write_sx_byte (board, SI1_ISA_INTCL,0); + write_sx_byte (board, SI1_ISA_INTCL_CLEAR,0); } else { switch (board->irq) { case 11:write_sx_byte (board, SI2_ISA_IRQ11, SI2_ISA_IRQ11_SET);break; @@ -1690,6 +1700,7 @@ if (IS_SX_BOARD (board)) rc = SX_TYPE_SX; if (IS_CF_BOARD (board)) rc = SX_TYPE_CF; if (IS_SI_BOARD (board)) rc = SX_TYPE_SI; + if (IS_SI1_BOARD (board)) rc = SX_TYPE_SI; if (IS_EISA_BOARD (board)) rc = SX_TYPE_SI; sx_dprintk (SX_DEBUG_FIRMWARE, "returning type= %d\n", rc); break; @@ -2181,13 +2192,20 @@ int i; func_enter(); - sx_dprintk (SX_DEBUG_PROBE, "Going to verify SI signature %lx.\n", + sx_dprintk (SX_DEBUG_PROBE, "Going to verify SI signature hw %lx at %lx.\n", board->hw_base, board->base + SI2_ISA_ID_BASE); if (sx_debug & SX_DEBUG_PROBE) my_hd ((char *)(board->base + SI2_ISA_ID_BASE), 0x8); - if (!IS_EISA_BOARD(board)) { + if (!IS_EISA_BOARD(board) ) { + if( IS_SI1_BOARD(board) ) + { + for (i=0;i<8;i++) { + write_sx_byte (board, SI2_ISA_ID_BASE+7-i,i); + + } + } for (i=0;i<8;i++) { if ((read_sx_byte (board, SI2_ISA_ID_BASE+7-i) & 7) != i) { return 0; @@ -2203,7 +2221,7 @@ board->nports = -1; - /* This resets the processor, and keeps it off the bus. */ + /* This resets the processor, and keeps it off the bus. */ if (!sx_reset (board)) return 0; sx_dprintk (SX_DEBUG_INIT, "reset the board...\n"); @@ -2554,6 +2572,21 @@ board->irq = sx_irqmask ?-1:0; if (probe_si (board)) { + found++; + } else { + my_iounmap (board->hw_base, board->base); + } + } + for (i=0;ihw_base = si1_probe_addrs[i]; + board->base2 = + board->base = (ulong) ioremap(board->hw_base, SI1_ISA_WINDOW_LEN); + board->flags &= ~SX_BOARD_TYPE; + board->flags |= SI1_ISA_BOARD; + board->irq = sx_irqmask ?-1:0; + + if (probe_si (board)) { found++; } else { my_iounmap (board->hw_base, board->base); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/sx.h linux.19pre5-ac1/drivers/char/sx.h --- linux.19p5/drivers/char/sx.h Thu Apr 4 13:19:08 2002 +++ linux.19pre5-ac1/drivers/char/sx.h Thu Mar 28 22:51:46 2002 @@ -73,6 +73,7 @@ #define SX_CFPCI_BOARD 0x00000008 #define SX_CFISA_BOARD 0x00000010 #define SI_EISA_BOARD 0x00000020 +#define SI1_ISA_BOARD 0x00000040 #define SX_BOARD_PRESENT 0x00001000 #define SX_BOARD_INITIALIZED 0x00002000 @@ -84,6 +85,7 @@ SX_ISA_BOARD | SX_CFISA_BOARD)) #define IS_SI_BOARD(board) (board->flags & SI_ISA_BOARD) +#define IS_SI1_BOARD(board) (board->flags & SI1_ISA_BOARD) #define IS_EISA_BOARD(board) (board->flags & SI_EISA_BOARD) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/sxboards.h linux.19pre5-ac1/drivers/char/sxboards.h --- linux.19p5/drivers/char/sxboards.h Thu Apr 4 13:19:10 2002 +++ linux.19pre5-ac1/drivers/char/sxboards.h Thu Mar 28 22:51:51 2002 @@ -46,12 +46,36 @@ #define CARD_BUS(type) ((type>>4)&0xF) #define CARD_PHASE(type) (type&0xF) +#define TYPE_SI1_ISA CARD_TYPE(BUS_ISA,SI1_Z280) #define TYPE_SI2_ISA CARD_TYPE(BUS_ISA,SI2_Z280) #define TYPE_SI2_EISA CARD_TYPE(BUS_EISA,SI2_Z280) #define TYPE_SI2_PCI CARD_TYPE(BUS_PCI,SI2_Z280) #define TYPE_SX_ISA CARD_TYPE(BUS_ISA,SI3_T225) #define TYPE_SX_PCI CARD_TYPE(BUS_PCI,SI3_T225) +/***************************************************************************** +****************************** ****************************** +****************************** Phase 1 Z280 ****************************** +****************************** ****************************** +*****************************************************************************/ + +/* ISA board details... */ +#define SI1_ISA_WINDOW_LEN 0x10000 /* 64 Kbyte shared memory window */ +//#define SI1_ISA_MEMORY_LEN 0x8000 /* Usable memory - unused define*/ +//#define SI1_ISA_ADDR_LOW 0x0A0000 /* Lowest address = 640 Kbyte */ +//#define SI1_ISA_ADDR_HIGH 0xFF8000 /* Highest address = 16Mbyte - 32Kbyte */ +//#define SI2_ISA_ADDR_STEP SI2_ISA_WINDOW_LEN/* ISA board address step */ +//#define SI2_ISA_IRQ_MASK 0x9800 /* IRQs 15,12,11 */ + +/* ISA board, register definitions... */ +//#define SI2_ISA_ID_BASE 0x7FF8 /* READ: Board ID string */ +#define SI1_ISA_RESET 0x8000 /* WRITE: Host Reset */ +#define SI1_ISA_RESET_CLEAR 0xc000 /* WRITE: Host Reset clear*/ +#define SI1_ISA_WAIT 0x9000 /* WRITE: Host wait */ +#define SI1_ISA_WAIT_CLEAR 0xd000 /* WRITE: Host wait clear */ +#define SI1_ISA_INTCL 0xa000 /* WRITE: Host Reset */ +#define SI1_ISA_INTCL_CLEAR 0xe000 /* WRITE: Host Reset */ + /***************************************************************************** ****************************** ****************************** diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/tty_io.c linux.19pre5-ac1/drivers/char/tty_io.c --- linux.19p5/drivers/char/tty_io.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/char/tty_io.c Fri Mar 1 18:56:48 2002 @@ -1849,9 +1849,6 @@ for_each_task(p) { if ((p->tty == tty) || ((session > 0) && (p->session == session))) { - printk(KERN_NOTICE "SAK: killed process %d" - " (%s): p->session==tty->session\n", - p->pid, p->comm); send_sig(SIGKILL, p, 1); continue; } @@ -1862,9 +1859,6 @@ filp = fcheck_files(p->files, i); if (filp && (filp->f_op == &tty_fops) && (filp->private_data == tty)) { - printk(KERN_NOTICE "SAK: killed process %d" - " (%s): fd#%d opened to the tty\n", - p->pid, p->comm, i); send_sig(SIGKILL, p, 1); break; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/wdt285.c linux.19pre5-ac1/drivers/char/wdt285.c --- linux.19p5/drivers/char/wdt285.c Thu Apr 4 13:19:08 2002 +++ linux.19pre5-ac1/drivers/char/wdt285.c Thu Mar 28 22:58:17 2002 @@ -138,11 +138,9 @@ default: return -ENOTTY; case WDIOC_GETSUPPORT: - i = verify_area(VERIFY_WRITE, (void*) arg, sizeof(struct watchdog_info)); - if (i) - return i; - else - return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)); + if(copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))) + return -EFAULT; + return 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: return put_user(0,(int *)arg); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/hotplug/ibmphp_core.c linux.19pre5-ac1/drivers/hotplug/ibmphp_core.c --- linux.19p5/drivers/hotplug/ibmphp_core.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/hotplug/ibmphp_core.c Tue Mar 26 18:47:21 2002 @@ -56,7 +56,7 @@ MODULE_DESCRIPTION (DRIVER_DESC); static int *ops[MAX_OPS + 1]; -static struct pci_ops *ibmphp_pci_root_ops; +struct pci_ops *ibmphp_pci_root_ops; static int max_slots; static int irqs[16]; /* PIC mode IRQ's we're using so far (in case MPS tables don't provide default info for empty slots */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/Config.in linux.19pre5-ac1/drivers/ide/Config.in --- linux.19p5/drivers/ide/Config.in Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/ide/Config.in Thu Apr 4 13:42:03 2002 @@ -34,7 +34,7 @@ dep_tristate ' SCSI emulation support' CONFIG_BLK_DEV_IDESCSI $CONFIG_BLK_DEV_IDE $CONFIG_SCSI bool ' IDE Taskfile Access' CONFIG_IDE_TASK_IOCTL -# bool ' IDE Taskfile IO' CONFIG_IDE_TASKFILE_IO + bool ' IDE Taskfile IO' CONFIG_IDE_TASKFILE_IO comment 'IDE chipset support/bugfixes' if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/Makefile linux.19pre5-ac1/drivers/ide/Makefile --- linux.19p5/drivers/ide/Makefile Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/ide/Makefile Thu Mar 21 01:02:18 2002 @@ -10,7 +10,7 @@ O_TARGET := idedriver.o -export-objs := ide.o ide-features.o ide-probe.o ide-taskfile.o ataraid.o +export-objs := ide-taskfile.o ide.o ide-features.o ide-probe.o ataraid.o list-multi := ide-mod.o ide-probe-mod.o obj-y := @@ -46,6 +46,7 @@ ide-obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o ide-obj-$(CONFIG_BLK_DEV_ADMA) += ide-adma.o ide-obj-$(CONFIG_BLK_DEV_IDEDMA_PCI) += ide-dma.o +ide-obj-$(CONFIG_BLK_DEV_MPC8xx_IDE) += ide-m8xx.o ide-obj-$(CONFIG_BLK_DEV_IDEPCI) += ide-pci.o ide-obj-$(CONFIG_BLK_DEV_ISAPNP) += ide-pnp.o ide-obj-$(CONFIG_BLK_DEV_IDE_PMAC) += ide-pmac.o @@ -67,7 +68,6 @@ ide-obj-$(CONFIG_BLK_DEV_TRM290) += trm290.o ide-obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o ide-obj-$(CONFIG_BLK_DEV_VIA82CXXX) += via82cxxx.o -ide-obj-$(CONFIG_BLK_DEV_MPC8xx_IDE) += ide-m8xx.o # The virtualised raid layers MUST come after the ide itself or bad stuff # will happen. @@ -77,7 +77,7 @@ ide-obj-$(CONFIG_PROC_FS) += ide-proc.o -ide-mod-objs := ide.o ide-features.o ide-taskfile.o $(ide-obj-y) +ide-mod-objs := ide-taskfile.o ide.o ide-features.o $(ide-obj-y) ide-probe-mod-objs := ide-probe.o ide-geometry.o include $(TOPDIR)/Rules.make diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/alim15x3.c linux.19pre5-ac1/drivers/ide/alim15x3.c --- linux.19p5/drivers/ide/alim15x3.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/ide/alim15x3.c Wed Apr 3 00:59:32 2002 @@ -248,7 +248,7 @@ byte s_clc, a_clc, r_clc; unsigned long flags; int bus_speed = system_bus_clock(); - int port = hwif->index ? 0x5c : 0x58; + int port = hwif->channel ? 0x5c : 0x58; int portFIFO = hwif->channel ? 0x55 : 0x54; byte cd_dma_fifo = 0; @@ -405,7 +405,7 @@ if (!drive->init_speed) drive->init_speed = speed; - rval = (int)( ((id->dma_ultra >> 11) & 3) ? ide_dma_on : + rval = (int)( ((id->dma_ultra >> 11) & 7) ? ide_dma_on : ((id->dma_ultra >> 8) & 7) ? ide_dma_on : ((id->dma_mword >> 8) & 7) ? ide_dma_on : ((id->dma_1word >> 8) & 7) ? ide_dma_on : @@ -453,7 +453,7 @@ } dma_func = ide_dma_off_quietly; if ((id->field_valid & 4) && (m5229_revision >= 0xC2)) { - if (id->dma_ultra & 0x003F) { + if (id->dma_ultra & 0x002F) { /* Force if Capable UltraDMA */ dma_func = config_chipset_for_dma(drive, can_ultra_dma); if ((id->field_valid & 2) && diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/amd74xx.c linux.19pre5-ac1/drivers/ide/amd74xx.c --- linux.19p5/drivers/ide/amd74xx.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/ide/amd74xx.c Thu Mar 21 01:02:18 2002 @@ -346,6 +346,8 @@ struct hd_driveid *id = drive->id; ide_dma_action_t dma_func = ide_dma_on; + config_chipset_for_pio(drive); + if (id && (id->capability & 1) && HWIF(drive)->autodma) { /* Consult the list of known "bad" drives */ if (ide_dmaproc(ide_dma_bad_drive, drive)) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ataraid.c linux.19pre5-ac1/drivers/ide/ataraid.c --- linux.19p5/drivers/ide/ataraid.c Thu Apr 4 13:19:32 2002 +++ linux.19pre5-ac1/drivers/ide/ataraid.c Wed Feb 27 18:32:03 2002 @@ -123,8 +123,7 @@ ptr=kmalloc(sizeof(struct buffer_head),GFP_NOIO); if (!ptr) { __set_current_state(TASK_RUNNING); - current->policy |= SCHED_YIELD; - schedule(); + yield(); } } return ptr; @@ -139,8 +138,7 @@ ptr=kmalloc(sizeof(struct ataraid_bh_private),GFP_NOIO); if (!ptr) { __set_current_state(TASK_RUNNING); - current->policy |= SCHED_YIELD; - schedule(); + yield(); } } return ptr; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/cmd640.c linux.19pre5-ac1/drivers/ide/cmd640.c --- linux.19p5/drivers/ide/cmd640.c Thu Apr 4 13:19:32 2002 +++ linux.19pre5-ac1/drivers/ide/cmd640.c Mon Apr 1 17:38:53 2002 @@ -692,6 +692,44 @@ #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ +static int pci_conf1(void) +{ + u32 tmp; + unsigned long flags; + + save_flags(flags); + __cli(); + outb(0x01, 0xCFB); + tmp = inl(0xCF8); + outl(0x80000000, 0xCF8); + if(inl(0xCF8) == 0x80000000) + { + outl(tmp, 0xCF8); + __restore_flags(flags); + return 1; + } + outl(tmp, 0xCF8); + return 0; +} + +static int pci_conf2(void) +{ + unsigned long flags; + + save_flags(flags); + __cli(); + outb(0x00, 0xCFB); + outb(0x00, 0xCF8); + outb(0x00, 0xCFA); + if(inb(0xCF8) == 0x00 && inb(0xCF8) == 0x00) + { + restore_flags(flags); + return 1; + } + restore_flags(flags); + return 0; +} + /* * Probe for a cmd640 chipset, and initialize it if found. Called from ide.c */ @@ -709,9 +747,11 @@ bus_type = "VLB"; } else { cmd640_vlb = 0; - if (probe_for_cmd640_pci1()) + /* Find out what kind of PCI probing is supported otherwise + Justin Gibbs will sulk.. */ + if (pci_conf1() && probe_for_cmd640_pci1()) bus_type = "PCI (type1)"; - else if (probe_for_cmd640_pci2()) + else if (pci_conf2() && probe_for_cmd640_pci2()) bus_type = "PCI (type2)"; else return 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/cmd64x.c linux.19pre5-ac1/drivers/ide/cmd64x.c --- linux.19p5/drivers/ide/cmd64x.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/ide/cmd64x.c Thu Mar 21 01:02:18 2002 @@ -538,6 +538,11 @@ if ((speed == XFER_UDMA_6) && (scsc & 0x30) == 0x00) { pci_write_config_byte(dev, 0x8A, scsc|0x01); pci_read_config_byte(dev, 0x8A, &scsc); +#if 0 + /* if 133 clock fails, switch to 2xbus clock */ + if (!(scsc & 0x01)) + pci_write_config_byte(dev, 0x8A, scsc|0x10); +#endif } switch(speed) { @@ -975,6 +980,13 @@ pci_write_config_byte(dev, 0x84, 0x00); pci_read_config_byte(dev, 0x8A, &tmpbyte); pci_write_config_byte(dev, 0x8A, tmpbyte|0x01); +#if 0 + /* if 133 clock fails, switch to 2xbus clock */ + if (!(tmpbyte & 0x01)) { + pci_read_config_byte(dev, 0x8A, &tmpbyte); + pci_write_config_byte(dev, 0x8A, tmpbyte|0x10); + } +#endif pci_write_config_word(dev, 0xA2, 0x328A); pci_write_config_dword(dev, 0xA4, 0x328A); pci_write_config_dword(dev, 0xA8, 0x4392); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/hpt34x.c linux.19pre5-ac1/drivers/ide/hpt34x.c --- linux.19p5/drivers/ide/hpt34x.c Thu Apr 4 13:19:32 2002 +++ linux.19pre5-ac1/drivers/ide/hpt34x.c Thu Mar 21 01:02:27 2002 @@ -255,6 +255,8 @@ struct hd_driveid *id = drive->id; ide_dma_action_t dma_func = ide_dma_on; + config_chipset_for_pio(drive); + if (id && (id->capability & 1) && HWIF(drive)->autodma) { /* Consult the list of known "bad" drives */ if (ide_dmaproc(ide_dma_bad_drive, drive)) { @@ -335,9 +337,28 @@ drive->waiting_for_dma = 1; if (drive->media != ide_disk) return 0; - ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */ - OUT_BYTE((reading == 9) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); - return 0; + ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); + /* issue cmd to drive */ + /* + * FIX ME to use only ACB ide_task_t args Struct + */ +#if 0 + { + ide_task_t *args = HWGROUP(drive)->rq->special; + OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG); + } +#else + if ((HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE) && + (drive->addressing == 1)) { + ide_task_t *args = HWGROUP(drive)->rq->special; + OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG); + } else if (drive->addressing) { + OUT_BYTE((reading == 9) ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG); + } else { + OUT_BYTE((reading == 9) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); + } +#endif + return HWIF(drive)->dmaproc(ide_dma_begin, drive); case ide_dma_end: /* returns 1 on error, 0 otherwise */ drive->waiting_for_dma = 0; outb(inb(dma_base)&~1, dma_base); /* stop DMA */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/hpt366.c linux.19pre5-ac1/drivers/ide/hpt366.c --- linux.19p5/drivers/ide/hpt366.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/ide/hpt366.c Thu Mar 21 01:03:56 2002 @@ -67,8 +67,8 @@ /* various tuning parameters */ #define HPT_RESET_STATE_ENGINE -/*#define HPT_DELAY_INTERRUPT*/ -/*#define HPT_SERIALIZE_IO*/ +#undef HPT_DELAY_INTERRUPT +#undef HPT_SERIALIZE_IO #if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) #include @@ -166,8 +166,7 @@ * PIO. * 31 FIFO enable. */ -struct chipset_bus_clock_list_entry forty_base [] = { - +struct chipset_bus_clock_list_entry forty_base_hpt366[] = { { XFER_UDMA_4, 0x900fd943 }, { XFER_UDMA_3, 0x900ad943 }, { XFER_UDMA_2, 0x900bd943 }, @@ -186,7 +185,7 @@ { 0, 0x0120d9d9 } }; -struct chipset_bus_clock_list_entry thirty_three_base [] = { +struct chipset_bus_clock_list_entry thirty_three_base_hpt366[] = { { XFER_UDMA_4, 0x90c9a731 }, { XFER_UDMA_3, 0x90cfa731 }, @@ -206,8 +205,7 @@ { 0, 0x0120a7a7 } }; -struct chipset_bus_clock_list_entry twenty_five_base [] = { - +struct chipset_bus_clock_list_entry twenty_five_base_hpt366[] = { { XFER_UDMA_4, 0x90c98521 }, { XFER_UDMA_3, 0x90cf8521 }, { XFER_UDMA_2, 0x90cf8521 }, @@ -226,7 +224,6 @@ { 0, 0x01208585 } }; -#if 1 /* these are the current (4 sep 2001) timings from highpoint */ struct chipset_bus_clock_list_entry thirty_three_base_hpt370[] = { { XFER_UDMA_5, 0x12446231 }, @@ -268,9 +265,9 @@ { XFER_PIO_0, 0x0d02bf5f }, { 0, 0x0d02bf5f } }; -#else + /* from highpoint documentation. these are old values */ -struct chipset_bus_clock_list_entry thirty_three_base_hpt370[] = { +struct chipset_bus_clock_list_entry thirty_three_base_old_hpt370[] = { { XFER_UDMA_5, 0x16454e31 }, { XFER_UDMA_4, 0x16454e31 }, { XFER_UDMA_3, 0x166d4e31 }, @@ -290,7 +287,7 @@ { 0, 0x06514e57 } }; -struct chipset_bus_clock_list_entry sixty_six_base_hpt370[] = { +struct chipset_bus_clock_list_entry sixty_six_base_old_hpt370[] = { { XFER_UDMA_5, 0x14846231 }, { XFER_UDMA_4, 0x14886231 }, { XFER_UDMA_3, 0x148c6231 }, @@ -309,7 +306,6 @@ { XFER_PIO_0, 0x06914e57 }, { 0, 0x06514e57 } }; -#endif struct chipset_bus_clock_list_entry fifty_base_hpt370[] = { { XFER_UDMA_5, 0x12848242 }, @@ -331,6 +327,144 @@ { 0, 0x0ac1f48a } }; +struct chipset_bus_clock_list_entry thirty_three_base_hpt372[] = { + { XFER_UDMA_6, 0x1c81dc62 }, + { XFER_UDMA_5, 0x1c6ddc62 }, + { XFER_UDMA_4, 0x1c8ddc62 }, + { XFER_UDMA_3, 0x1c8edc62 }, /* checkme */ + { XFER_UDMA_2, 0x1c91dc62 }, + { XFER_UDMA_1, 0x1c9adc62 }, /* checkme */ + { XFER_UDMA_0, 0x1c82dc62 }, /* checkme */ + + { XFER_MW_DMA_2, 0x2c829262 }, + { XFER_MW_DMA_1, 0x2c829266 }, /* checkme */ + { XFER_MW_DMA_0, 0x2c82922e }, /* checkme */ + + { XFER_PIO_4, 0x0c829c62 }, + { XFER_PIO_3, 0x0c829c84 }, + { XFER_PIO_2, 0x0c829ca6 }, + { XFER_PIO_1, 0x0d029d26 }, + { XFER_PIO_0, 0x0d029d5e }, + { 0, 0x0d029d5e } +}; + +struct chipset_bus_clock_list_entry fifty_base_hpt372[] = { + { XFER_UDMA_5, 0x12848242 }, + { XFER_UDMA_4, 0x12ac8242 }, + { XFER_UDMA_3, 0x128c8242 }, + { XFER_UDMA_2, 0x120c8242 }, + { XFER_UDMA_1, 0x12148254 }, + { XFER_UDMA_0, 0x121882ea }, + + { XFER_MW_DMA_2, 0x22808242 }, + { XFER_MW_DMA_1, 0x22808254 }, + { XFER_MW_DMA_0, 0x228082ea }, + + { XFER_PIO_4, 0x0a81f442 }, + { XFER_PIO_3, 0x0a81f443 }, + { XFER_PIO_2, 0x0a81f454 }, + { XFER_PIO_1, 0x0ac1f465 }, + { XFER_PIO_0, 0x0ac1f48a }, + { 0, 0x0a81f443 } +}; + +struct chipset_bus_clock_list_entry sixty_six_base_hpt372[] = { + { XFER_UDMA_6, 0x1c869c62 }, + { XFER_UDMA_5, 0x1cae9c62 }, + { XFER_UDMA_4, 0x1c8a9c62 }, + { XFER_UDMA_3, 0x1c8e9c62 }, + { XFER_UDMA_2, 0x1c929c62 }, + { XFER_UDMA_1, 0x1c9a9c62 }, + { XFER_UDMA_0, 0x1c829c62 }, + + { XFER_MW_DMA_2, 0x2c829c62 }, + { XFER_MW_DMA_1, 0x2c829c66 }, + { XFER_MW_DMA_0, 0x2c829d2e }, + + { XFER_PIO_4, 0x0c829c62 }, + { XFER_PIO_3, 0x0c829c84 }, + { XFER_PIO_2, 0x0c829ca6 }, + { XFER_PIO_1, 0x0d029d26 }, + { XFER_PIO_0, 0x0d029d5e }, + { 0, 0x0d029d26 } +}; + +struct chipset_bus_clock_list_entry thirty_three_base_hpt374[] = { + { XFER_UDMA_6, 0x12808242 }, + { XFER_UDMA_5, 0x12848242 }, + { XFER_UDMA_4, 0x12ac8242 }, + { XFER_UDMA_3, 0x128c8242 }, + { XFER_UDMA_2, 0x120c8242 }, + { XFER_UDMA_1, 0x12148254 }, + { XFER_UDMA_0, 0x121882ea }, + + { XFER_MW_DMA_2, 0x22808242 }, + { XFER_MW_DMA_1, 0x22808254 }, + { XFER_MW_DMA_0, 0x228082ea }, + + { XFER_PIO_4, 0x0a81f442 }, + { XFER_PIO_3, 0x0a81f443 }, + { XFER_PIO_2, 0x0a81f454 }, + { XFER_PIO_1, 0x0ac1f465 }, + { XFER_PIO_0, 0x0ac1f48a }, + { 0, 0x06814e93 } +}; + +#if 0 +struct chipset_bus_clock_list_entry fifty_base_hpt374[] = { + { XFER_UDMA_6, }, + { XFER_UDMA_5, }, + { XFER_UDMA_4, }, + { XFER_UDMA_3, }, + { XFER_UDMA_2, }, + { XFER_UDMA_1, }, + { XFER_UDMA_0, }, + { XFER_MW_DMA_2, }, + { XFER_MW_DMA_1, }, + { XFER_MW_DMA_0, }, + { XFER_PIO_4, }, + { XFER_PIO_3, }, + { XFER_PIO_2, }, + { XFER_PIO_1, }, + { XFER_PIO_0, }, + { 0, } +}; +#endif +#if 0 +struct chipset_bus_clock_list_entry sixty_six_base_hpt374[] = { + { XFER_UDMA_6, 0x12406231 }, /* checkme */ + { XFER_UDMA_5, 0x12446231 }, + 0x14846231 + { XFER_UDMA_4, 0x16814ea7 }, + 0x14886231 + { XFER_UDMA_3, 0x16814ea7 }, + 0x148c6231 + { XFER_UDMA_2, 0x16814ea7 }, + 0x148c6231 + { XFER_UDMA_1, 0x16814ea7 }, + 0x14906231 + { XFER_UDMA_0, 0x16814ea7 }, + 0x14986231 + { XFER_MW_DMA_2, 0x16814ea7 }, + 0x26514e21 + { XFER_MW_DMA_1, 0x16814ea7 }, + 0x26514e97 + { XFER_MW_DMA_0, 0x16814ea7 }, + 0x26514e97 + { XFER_PIO_4, 0x06814ea7 }, + 0x06514e21 + { XFER_PIO_3, 0x06814ea7 }, + 0x06514e22 + { XFER_PIO_2, 0x06814ea7 }, + 0x06514e33 + { XFER_PIO_1, 0x06814ea7 }, + 0x06914e43 + { XFER_PIO_0, 0x06814ea7 }, + 0x06914e57 + { 0, 0x06814ea7 } +}; +#endif + #define HPT366_DEBUG_DRIVE_INFO 0 #define HPT370_ALLOW_ATA100_5 1 #define HPT366_ALLOW_ATA66_4 1 @@ -345,8 +479,11 @@ static struct pci_dev *hpt_devs[HPT366_MAX_DEVS]; static int n_hpt_devs; -static unsigned int pci_rev_check_hpt3xx(struct pci_dev *dev); static unsigned int pci_rev2_check_hpt3xx(struct pci_dev *dev); +static unsigned int pci_rev3_check_hpt3xx(struct pci_dev *dev); +static unsigned int pci_rev5_check_hpt3xx(struct pci_dev *dev); +static unsigned int pci_rev7_check_hpt3xx(struct pci_dev *dev); + byte hpt366_proc = 0; byte hpt363_shared_irq; byte hpt363_shared_pin; @@ -360,11 +497,13 @@ static int hpt366_get_info (char *buffer, char **addr, off_t offset, int count) { char *p = buffer; - char *chipset_nums[] = {"366", "366", "368", "370", "370A"}; + char *chipset_nums[] = {"366", "366", "368", + "370", "370A", "372", + "??", "374" }; int i; p += sprintf(p, "\n " - "HighPoint HPT366/368/370\n"); + "HighPoint HPT366/368/370/372/374\n"); for (i = 0; i < n_hpt_devs; i++) { struct pci_dev *dev = hpt_devs[i]; unsigned long iobase = dev->resource[4].start; @@ -373,9 +512,14 @@ pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; + + if(class_rev >= sizeof(chipset_nums)/sizeof(char *)) p += sprintf(p, "\nController: %d\n", i); - p += sprintf(p, "Chipset: HPT%s\n", chipset_nums[class_rev]); + if(class_rev >= sizeof(chipset_nums)/sizeof(char *)) + p += sprintf(p, "Chipset: UNKNOWN\n"); + else + p += sprintf(p, "Chipset: HPT%s\n", chipset_nums[class_rev]); p += sprintf(p, "--------------- Primary Channel " "--------------- Secondary Channel " "--------------\n"); @@ -388,7 +532,7 @@ (c0 & 0x80) ? "no" : "yes", (c1 & 0x80) ? "no" : "yes"); - if (pci_rev_check_hpt3xx(dev)) { + if (pci_rev3_check_hpt3xx(dev)) { u8 cbl; cbl = inb_p(iobase + 0x7b); outb_p(cbl | 1, iobase + 0x7b); @@ -437,7 +581,19 @@ } #endif /* defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) */ -static unsigned int pci_rev_check_hpt3xx (struct pci_dev *dev) +/* + * fixme: it really needs to be a switch. + */ + +static unsigned int pci_rev2_check_hpt3xx (struct pci_dev *dev) +{ + unsigned int class_rev; + pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); + class_rev &= 0xff; + return ((int) (class_rev > 0x01) ? 1 : 0); +} + +static unsigned int pci_rev3_check_hpt3xx (struct pci_dev *dev) { unsigned int class_rev; pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); @@ -445,12 +601,20 @@ return ((int) (class_rev > 0x02) ? 1 : 0); } -static unsigned int pci_rev2_check_hpt3xx (struct pci_dev *dev) +static unsigned int pci_rev5_check_hpt3xx (struct pci_dev *dev) { unsigned int class_rev; pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; - return ((int) (class_rev > 0x01) ? 1 : 0); + return ((int) (class_rev > 0x04) ? 1 : 0); +} + +static unsigned int pci_rev7_check_hpt3xx (struct pci_dev *dev) +{ + unsigned int class_rev; + pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); + class_rev &= 0xff; + return ((int) (class_rev > 0x06) ? 1 : 0); } static int check_in_drive_lists (ide_drive_t *drive, const char **list) @@ -484,54 +648,31 @@ static void hpt366_tune_chipset (ide_drive_t *drive, byte speed) { - byte regtime = (drive->select.b.unit & 0x01) ? 0x44 : 0x40; + struct pci_dev *dev = HWIF(drive)->pci_dev; + byte drive_pci = (drive->select.b.unit & 0x01) ? 0x44 : 0x40; byte regfast = (HWIF(drive)->channel) ? 0x55 : 0x51; - /* - * since the channel is always 0 it does not matter. - */ - - unsigned int reg1 = 0; - unsigned int reg2 = 0; byte drive_fast = 0; - - /* - * Disable the "fast interrupt" prediction. - */ - pci_read_config_byte(HWIF(drive)->pci_dev, regfast, &drive_fast); + unsigned int list_conf = 0; + unsigned int drive_conf = 0; + unsigned int conf_mask = (speed >= XFER_MW_DMA_0) ? 0xc0000000 : 0x30070000; + + /* Disable the "fast interrupt" prediction. */ + pci_read_config_byte(dev, regfast, &drive_fast); if (drive_fast & 0x02) - pci_write_config_byte(HWIF(drive)->pci_dev, regfast, drive_fast & ~0x20); - - pci_read_config_dword(HWIF(drive)->pci_dev, regtime, ®1); - /* detect bus speed by looking at control reg timing: */ - switch((reg1 >> 8) & 7) { - case 5: - reg2 = pci_bus_clock_list(speed, forty_base); - break; - case 9: - reg2 = pci_bus_clock_list(speed, twenty_five_base); - break; - default: - case 7: - reg2 = pci_bus_clock_list(speed, thirty_three_base); - break; - } -#if 0 - /* this is a nice idea ... */ + pci_write_config_byte(dev, regfast, drive_fast & ~0x20); list_conf = pci_bus_clock_list(speed, (struct chipset_bus_clock_list_entry *) dev->sysdata); -#endif - /* - * Disable on-chip PIO FIFO/buffer (to avoid problems handling I/O errors later) - */ - if (speed >= XFER_MW_DMA_0) { - reg2 = (reg2 & ~0xc0000000) | (reg1 & 0xc0000000); - } else { - reg2 = (reg2 & ~0x30070000) | (reg1 & 0x30070000); - } - reg2 &= ~0x80000000; + pci_read_config_dword(dev, drive_pci, &drive_conf); + list_conf = (list_conf & ~conf_mask) | (drive_conf & conf_mask); + if (speed < XFER_MW_DMA_0) + list_conf &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */ + pci_write_config_dword(dev, drive_pci, list_conf); +} - pci_write_config_dword(HWIF(drive)->pci_dev, regtime, reg2); +static void hpt368_tune_chipset (ide_drive_t *drive, byte speed) +{ + hpt366_tune_chipset(drive, speed); } static void hpt370_tune_chipset (ide_drive_t *drive, byte speed) @@ -577,6 +718,39 @@ pci_write_config_dword(dev, drive_pci, list_conf); } +static void hpt372_tune_chipset (ide_drive_t *drive, byte speed) +{ + byte regfast = (HWIF(drive)->channel) ? 0x55 : 0x51; + unsigned int list_conf = 0; + unsigned int drive_conf = 0; + unsigned int conf_mask = (speed >= XFER_MW_DMA_0) ? 0xc0000000 : 0x30070000; + byte drive_pci = 0x40 + (drive->dn * 4); + byte drive_fast = 0; + struct pci_dev *dev = HWIF(drive)->pci_dev; + + /* + * Disable the "fast interrupt" prediction. + * don't holdoff on interrupts. (== 0x01 despite what the docs say) + */ + pci_read_config_byte(dev, regfast, &drive_fast); + drive_fast &= ~0x07; + pci_write_config_byte(HWIF(drive)->pci_dev, regfast, drive_fast); + + list_conf = pci_bus_clock_list(speed, + (struct chipset_bus_clock_list_entry *) + dev->sysdata); + pci_read_config_dword(dev, drive_pci, &drive_conf); + list_conf = (list_conf & ~conf_mask) | (drive_conf & conf_mask); + if (speed < XFER_MW_DMA_0) + list_conf &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */ + pci_write_config_dword(dev, drive_pci, list_conf); +} + +static void hpt374_tune_chipset (ide_drive_t *drive, byte speed) +{ + hpt372_tune_chipset(drive, speed); +} + static int hpt3xx_tune_chipset (ide_drive_t *drive, byte speed) { if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0)) @@ -585,9 +759,15 @@ if (!drive->init_speed) drive->init_speed = speed; - if (pci_rev_check_hpt3xx(HWIF(drive)->pci_dev)) { + if (pci_rev7_check_hpt3xx(HWIF(drive)->pci_dev)) { + hpt374_tune_chipset(drive, speed); + } else if (pci_rev5_check_hpt3xx(HWIF(drive)->pci_dev)) { + hpt372_tune_chipset(drive, speed); + } else if (pci_rev3_check_hpt3xx(HWIF(drive)->pci_dev)) { hpt370_tune_chipset(drive, speed); - } else { + } else if (pci_rev2_check_hpt3xx(HWIF(drive)->pci_dev)) { + hpt368_tune_chipset(drive, speed); + } else { hpt366_tune_chipset(drive, speed); } drive->current_speed = speed; @@ -664,13 +844,19 @@ byte ultra66 = eighty_ninty_three(drive); int rval; + config_chipset_for_pio(drive); + if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0)) return ((int) ide_dma_off_quietly); - if ((id->dma_ultra & 0x0020) && + if ((id->dma_ultra & 0x0040) && + (pci_rev5_check_hpt3xx(HWIF(drive)->pci_dev)) && + (ultra66)) { + speed = XFER_UDMA_6; + } else if ((id->dma_ultra & 0x0020) && (!check_in_drive_lists(drive, bad_ata100_5)) && (HPT370_ALLOW_ATA100_5) && - (pci_rev_check_hpt3xx(HWIF(drive)->pci_dev)) && + (pci_rev3_check_hpt3xx(HWIF(drive)->pci_dev)) && (ultra66)) { speed = XFER_UDMA_5; } else if ((id->dma_ultra & 0x0010) && @@ -703,7 +889,8 @@ (void) hpt3xx_tune_chipset(drive, speed); - rval = (int)( ((id->dma_ultra >> 11) & 7) ? ide_dma_on : + rval = (int)( ((id->dma_ultra >> 14) & 3) ? ide_dma_on : + ((id->dma_ultra >> 11) & 7) ? ide_dma_on : ((id->dma_ultra >> 8) & 7) ? ide_dma_on : ((id->dma_mword >> 8) & 7) ? ide_dma_on : ide_dma_off_quietly); @@ -717,17 +904,16 @@ void hpt3xx_intrproc (ide_drive_t *drive) { - if (drive->quirk_list) { - /* drives in the quirk_list may not like intr setups/cleanups */ - } else { - OUT_BYTE((drive)->ctl|2, HWIF(drive)->io_ports[IDE_CONTROL_OFFSET]); - } + /* drives in the quirk_list may not like intr setups/cleanups */ + if (drive->quirk_list) + return; + OUT_BYTE((drive)->ctl|2, HWIF(drive)->io_ports[IDE_CONTROL_OFFSET]); } void hpt3xx_maskproc (ide_drive_t *drive, int mask) { if (drive->quirk_list) { - if (pci_rev_check_hpt3xx(HWIF(drive)->pci_dev)) { + if (pci_rev3_check_hpt3xx(HWIF(drive)->pci_dev)) { byte reg5a = 0; pci_read_config_byte(HWIF(drive)->pci_dev, 0x5a, ®5a); if (((reg5a & 0x10) >> 4) != mask) @@ -758,7 +944,7 @@ } dma_func = ide_dma_off_quietly; if (id->field_valid & 4) { - if (id->dma_ultra & 0x002F) { + if (id->dma_ultra & 0x007F) { /* Force if Capable UltraDMA */ dma_func = config_chipset_for_dma(drive); if ((id->field_valid & 2) && @@ -821,8 +1007,10 @@ reg50h, reg52h, reg5ah); if (reg5ah & 0x10) pci_write_config_byte(HWIF(drive)->pci_dev, 0x5a, reg5ah & ~0x10); +#if 1 + /* how about we flush and reset, mmmkay? */ + pci_write_config_byte(HWIF(drive)->pci_dev, 0x51, 0x1F); /* fall through to a reset */ -#if 0 case ide_dma_begin: case ide_dma_end: /* reset the chips state over and over.. */ @@ -889,6 +1077,44 @@ } return ide_dmaproc(func, drive); /* use standard DMA stuff */ } + +int hpt374_dmaproc (ide_dma_action_t func, ide_drive_t *drive) +{ + ide_hwif_t *hwif = HWIF(drive); + unsigned long dma_base = hwif->dma_base; + byte mscreg = hwif->channel ? 0x54 : 0x50; +// byte reginfo = hwif->channel ? 0x56 : 0x52; + byte dma_stat; + + switch (func) { + case ide_dma_check: + return config_drive_xfer_rate(drive); + case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */ + dma_stat = inb(dma_base+2); +#if 0 /* do not set unless you know what you are doing */ + if (dma_stat & 4) { + byte stat = GET_STAT(); + outb(dma_base+2, dma_stat & 0xE4); + } +#endif + /* return 1 if INTR asserted */ + return (dma_stat & 4) == 4; + case ide_dma_end: + { + byte bwsr_mask = hwif->channel ? 0x02 : 0x01; + byte bwsr_stat, msc_stat; + pci_read_config_byte(hwif->pci_dev, 0x6a, &bwsr_stat); + pci_read_config_byte(hwif->pci_dev, mscreg, &msc_stat); + if ((bwsr_stat & bwsr_mask) == bwsr_mask) + pci_write_config_byte(hwif->pci_dev, mscreg, msc_stat|0x30); + } + default: + break; + } + return ide_dmaproc(func, drive); /* use standard DMA stuff */ +} + + #endif /* CONFIG_BLK_DEV_IDEDMA */ /* @@ -1006,6 +1232,184 @@ return 0; } +static void __init init_hpt374(struct pci_dev *dev) +{ + int adjust, i; + u16 freq; + u32 pll; + byte reg5bh; + + /* + * default to pci clock. make sure MA15/16 are set to output + * to prevent drives having problems with 40-pin cables. + */ + pci_write_config_byte(dev, 0x5b, 0x23); + + /* + * set up the PLL. we need to adjust it so that it's stable. + * freq = Tpll * 192 / Tpci + */ + pci_read_config_word(dev, 0x78, &freq); + freq &= 0x1FF; + if (freq < 0x9c) { + pll = F_LOW_PCI_33; + dev->sysdata = (void *) thirty_three_base_hpt374; + printk("HPT374: using 33MHz PCI clock\n"); + } else if (freq < 0xb0) { + pll = F_LOW_PCI_40; + } else if (freq < 0xc8) { + pll = F_LOW_PCI_50; +// dev->sysdata = (void *) fifty_base_hpt374; + printk("HPT374: using 50MHz PCI clock\n"); + } else { + pll = F_LOW_PCI_66; +// dev->sysdata = (void *) sixty_six_base_hpt374; + printk("HPT374: using 66MHz PCI clock\n"); + } + + /* + * only try the pll if we don't have a table for the clock + * speed that we're running at. NOTE: the internal PLL will + * result in slow reads when using a 33MHz PCI clock. we also + * don't like to use the PLL because it will cause glitches + * on PRST/SRST when the HPT state engine gets reset. + */ + if (dev->sysdata) + goto init_hpt374_done; + + /* + * adjust PLL based upon PCI clock, enable it, and wait for + * stabilization. + */ + adjust = 0; + freq = (pll < F_LOW_PCI_50) ? 2 : 4; + while (adjust++ < 6) { + pci_write_config_dword(dev, 0x5c, (freq + pll) << 16 | + pll | 0x100); + + /* wait for clock stabilization */ + for (i = 0; i < 0x50000; i++) { + pci_read_config_byte(dev, 0x5b, ®5bh); + if (reg5bh & 0x80) { + /* spin looking for the clock to destabilize */ + for (i = 0; i < 0x1000; ++i) { + pci_read_config_byte(dev, 0x5b, + ®5bh); + if ((reg5bh & 0x80) == 0) + goto pll_recal; + } + pci_read_config_dword(dev, 0x5c, &pll); + pci_write_config_dword(dev, 0x5c, + pll & ~0x100); + pci_write_config_byte(dev, 0x5b, 0x21); +// dev->sysdata = (void *) fifty_base_hpt374; + printk("HPT374: using 50MHz internal PLL\n"); + goto init_hpt374_done; + } + } +pll_recal: + if (adjust & 1) + pll -= (adjust >> 1); + else + pll += (adjust >> 1); + } + +init_hpt374_done: + /* reset state engine */ + pci_write_config_byte(dev, 0x50, 0x36); + pci_write_config_byte(dev, 0x54, 0x36); + udelay(100); +} + +static void __init init_hpt372(struct pci_dev *dev) +{ + int adjust, i; + u16 freq; + u32 pll; + byte reg5bh; + + /* + * default to pci clock. make sure MA15/16 are set to output + * to prevent drives having problems with 40-pin cables. + */ + pci_write_config_byte(dev, 0x5b, 0x23); + + /* + * set up the PLL. we need to adjust it so that it's stable. + * freq = Tpll * 192 / Tpci + */ + pci_read_config_word(dev, 0x78, &freq); + freq &= 0x1FF; + if (freq < 0x9c) { + pll = F_LOW_PCI_33; + dev->sysdata = (void *) thirty_three_base_hpt372; + printk("HPT372: using 33MHz PCI clock\n"); + } else if (freq < 0xb0) { + pll = F_LOW_PCI_40; + } else if (freq < 0xc8) { + pll = F_LOW_PCI_50; + dev->sysdata = (void *) fifty_base_hpt372; + printk("HPT372: using 50MHz PCI clock\n"); + } else { + pll = F_LOW_PCI_66; + dev->sysdata = (void *) sixty_six_base_hpt372; + printk("HPT372: using 66MHz PCI clock\n"); + } + + /* + * only try the pll if we don't have a table for the clock + * speed that we're running at. NOTE: the internal PLL will + * result in slow reads when using a 33MHz PCI clock. we also + * don't like to use the PLL because it will cause glitches + * on PRST/SRST when the HPT state engine gets reset. + */ + if (dev->sysdata) + goto init_hpt372_done; + + /* + * adjust PLL based upon PCI clock, enable it, and wait for + * stabilization. + */ + adjust = 0; + freq = (pll < F_LOW_PCI_50) ? 2 : 4; + while (adjust++ < 6) { + pci_write_config_dword(dev, 0x5c, (freq + pll) << 16 | + pll | 0x100); + + /* wait for clock stabilization */ + for (i = 0; i < 0x50000; i++) { + pci_read_config_byte(dev, 0x5b, ®5bh); + if (reg5bh & 0x80) { + /* spin looking for the clock to destabilize */ + for (i = 0; i < 0x1000; ++i) { + pci_read_config_byte(dev, 0x5b, + ®5bh); + if ((reg5bh & 0x80) == 0) + goto pll_recal; + } + pci_read_config_dword(dev, 0x5c, &pll); + pci_write_config_dword(dev, 0x5c, + pll & ~0x100); + pci_write_config_byte(dev, 0x5b, 0x21); + dev->sysdata = (void *) fifty_base_hpt372; + printk("HPT372: using 50MHz internal PLL\n"); + goto init_hpt372_done; + } + } +pll_recal: + if (adjust & 1) + pll -= (adjust >> 1); + else + pll += (adjust >> 1); + } + +init_hpt372_done: + /* reset state engine */ + pci_write_config_byte(dev, 0x50, 0x37); + pci_write_config_byte(dev, 0x54, 0x37); + udelay(100); +} + static void __init init_hpt370(struct pci_dev *dev) { int adjust, i; @@ -1095,6 +1499,34 @@ udelay(100); } +static void __init init_hpt366 (struct pci_dev *dev) +{ + unsigned int reg1 = 0; + byte drive_fast = 0; + + /* + * Disable the "fast interrupt" prediction. + */ + pci_read_config_byte(dev, 0x51, &drive_fast); + if (drive_fast & 0x02) + pci_write_config_byte(dev, 0x51, drive_fast & ~0x20); + pci_read_config_dword(dev, 0x40, ®1); + + /* detect bus speed by looking at control reg timing: */ + switch((reg1 >> 8) & 7) { + case 5: + dev->sysdata = (void *) forty_base_hpt366; + break; + case 9: + dev->sysdata = (void *) twenty_five_base_hpt366; + break; + case 7: + default: + dev->sysdata = (void *) thirty_three_base_hpt366; + break; + } +} + unsigned int __init pci_init_hpt366 (struct pci_dev *dev, const char *name) { byte test = 0; @@ -1118,13 +1550,29 @@ if (test != 0x08) pci_write_config_byte(dev, PCI_MAX_LAT, 0x08); - if (pci_rev_check_hpt3xx(dev)) { - init_hpt370(dev); - hpt_devs[n_hpt_devs++] = dev; - } else { - hpt_devs[n_hpt_devs++] = dev; + if(n_hpt_devs < HPT366_MAX_DEVS) + { + if (pci_rev7_check_hpt3xx(dev)) { + init_hpt374(dev); + hpt_devs[n_hpt_devs++] = dev; + } else if (pci_rev5_check_hpt3xx(dev)) { + init_hpt372(dev); + hpt_devs[n_hpt_devs++] = dev; + } else if (pci_rev3_check_hpt3xx(dev)) { + init_hpt370(dev); + hpt_devs[n_hpt_devs++] = dev; + } else { + if (dev->device == PCI_DEVICE_ID_TTI_HPT372) { + init_hpt372(dev); + hpt_devs[n_hpt_devs++] = dev; + } else { + init_hpt366(dev); + hpt_devs[n_hpt_devs++] = dev; + } + } } - + else printk(KERN_ERR "hpt366: Too many highpoint controllers.\n"); + #if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) if (!hpt366_proc) { hpt366_proc = 1; @@ -1151,8 +1599,6 @@ void __init ide_init_hpt366 (ide_hwif_t *hwif) { - int hpt_rev; - hwif->tuneproc = &hpt3xx_tune_drive; hwif->speedproc = &hpt3xx_tune_chipset; hwif->quirkproc = &hpt3xx_quirkproc; @@ -1165,47 +1611,61 @@ hwif->serialized = hwif->mate->serialized = 1; #endif - hpt_rev = pci_rev_check_hpt3xx(hwif->pci_dev); - if (hpt_rev) { - /* set up ioctl for power status. note: power affects both - * drives on each channel */ - hwif->busproc = &hpt370_busproc; - } - - if (pci_rev2_check_hpt3xx(hwif->pci_dev)) { - /* do nothing now but will split device types */ - hwif->resetproc = &hpt3xx_reset; -/* - * don't do until we can parse out the cobalt box argh ... - * hwif->busproc = &hpt3xx_tristate; - */ - } - #ifdef CONFIG_BLK_DEV_IDEDMA - if (hwif->dma_base) { - if (hpt_rev) { + if ((pci_rev3_check_hpt3xx(hwif->pci_dev)) || + (hwif->pci_dev->device == PCI_DEVICE_ID_TTI_HPT372)) { + if (hwif->dma_base) { byte reg5ah = 0; pci_read_config_byte(hwif->pci_dev, 0x5a, ®5ah); - if (reg5ah & 0x10) /* interrupt force enable */ - pci_write_config_byte(hwif->pci_dev, 0x5a, reg5ah & ~0x10); - hwif->dmaproc = &hpt370_dmaproc; - } else { - hwif->dmaproc = &hpt366_dmaproc; + reg5ah &= ~0x10; + pci_write_config_byte(hwif->pci_dev, 0x5a, reg5ah); } - if (!noautodma) - hwif->autodma = 1; - else - hwif->autodma = 0; + } +#endif /* CONFIG_BLK_DEV_IDEDMA */ + + if (pci_rev7_check_hpt3xx(hwif->pci_dev)) { + hwif->resetproc = &hpt3xx_reset; + hwif->busproc = &hpt370_busproc; +#ifdef CONFIG_BLK_DEV_IDEDMA + if (hwif->dma_base) + hwif->dmaproc = &hpt374_dmaproc; +#endif /* CONFIG_BLK_DEV_IDEDMA */ + } else if (pci_rev5_check_hpt3xx(hwif->pci_dev)) { + hwif->resetproc = &hpt3xx_reset; + hwif->busproc = &hpt370_busproc; +#ifdef CONFIG_BLK_DEV_IDEDMA + if (hwif->dma_base) + hwif->dmaproc = &hpt374_dmaproc; +#endif /* CONFIG_BLK_DEV_IDEDMA */ + } else if (pci_rev3_check_hpt3xx(hwif->pci_dev)) { + /* + * set up ioctl for power status. note: power affects both + * drives on each channel + */ + hwif->resetproc = &hpt3xx_reset; + hwif->busproc = &hpt370_busproc; +#ifdef CONFIG_BLK_DEV_IDEDMA + if (hwif->dma_base) + hwif->dmaproc = &hpt370_dmaproc; +#endif /* CONFIG_BLK_DEV_IDEDMA */ + } else if (hwif->pci_dev->device == PCI_DEVICE_ID_TTI_HPT372) { + hwif->resetproc = &hpt3xx_reset; + hwif->busproc = &hpt370_busproc; +#ifdef CONFIG_BLK_DEV_IDEDMA + if (hwif->dma_base) + hwif->dmaproc = &hpt370_dmaproc; +#endif /* CONFIG_BLK_DEV_IDEDMA */ } else { - hwif->autodma = 0; - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; - } -#else /* !CONFIG_BLK_DEV_IDEDMA */ - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; - hwif->autodma = 0; + /* do nothing now but will split device types */ + hwif->resetproc = &hpt3xx_reset; + hwif->busproc = &hpt3xx_tristate; +#ifdef CONFIG_BLK_DEV_IDEDMA + if (hwif->dma_base) + hwif->dmaproc = &hpt366_dmaproc; #endif /* CONFIG_BLK_DEV_IDEDMA */ + } + hwif->drives[0].autotune = (hwif->autodma) ? 0 : 1; + hwif->drives[1].autotune = (hwif->autodma) ? 0 : 1; } void __init ide_dmacapable_hpt366 (ide_hwif_t *hwif, unsigned long dmabase) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/icside.c linux.19pre5-ac1/drivers/ide/icside.c --- linux.19p5/drivers/ide/icside.c Thu Apr 4 13:19:32 2002 +++ linux.19pre5-ac1/drivers/ide/icside.c Thu Mar 21 01:02:27 2002 @@ -334,7 +334,7 @@ rq = HWGROUP(drive)->rq; for (i = rq->nr_sectors; i > 0;) { i -= rq->current_nr_sectors; - ide_end_request(1, HWGROUP(drive)); + ide_end_request(drive, 1); } return ide_stopped; } @@ -535,9 +535,26 @@ return 0; ide_set_handler(drive, &icside_dmaintr, WAIT_CMD, NULL); - OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, - IDE_COMMAND_REG); - + /* + * FIX ME to use only ACB ide_task_t args Struct + */ +#if 0 + { + ide_task_t *args = HWGROUP(drive)->rq->special; + OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG); + } +#else + if ((HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE) && + (drive->addressing == 1)) { + ide_task_t *args = HWGROUP(drive)->rq->special; + OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG); + } else if (drive->addressing) { + OUT_BYTE(reading ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG); + } else { + OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); + } +#endif +// return HWIF(drive)->dmaproc(ide_dma_begin, drive); case ide_dma_begin: enable_dma(hwif->hw.dma); return 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ide-cd.c linux.19pre5-ac1/drivers/ide/ide-cd.c --- linux.19p5/drivers/ide/ide-cd.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/ide/ide-cd.c Fri Mar 22 16:33:53 2002 @@ -540,7 +540,7 @@ } -static void cdrom_end_request (int uptodate, ide_drive_t *drive) +static void cdrom_end_request (ide_drive_t *drive, int uptodate) { struct request *rq = HWGROUP(drive)->rq; @@ -554,7 +554,7 @@ if (!rq->current_nr_sectors) uptodate = 1; - ide_end_request (uptodate, HWGROUP(drive)); + ide_end_request(drive, uptodate); } @@ -591,7 +591,7 @@ pc = (struct packet_command *) rq->buffer; pc->stat = 1; - cdrom_end_request (1, drive); + cdrom_end_request(drive, 1); *startstop = ide_error (drive, "request sense failure", stat); return 1; @@ -628,7 +628,7 @@ } pc->stat = 1; - cdrom_end_request (1, drive); + cdrom_end_request(drive, 1); if ((stat & ERR_STAT) != 0) cdrom_queue_request_sense(drive, wait, pc->sense, pc); @@ -641,7 +641,7 @@ /* Fail the request. */ printk ("%s: tray open\n", drive->name); - cdrom_end_request (0, drive); + cdrom_end_request(drive, 0); } else if (sense_key == UNIT_ATTENTION) { /* Media change. */ cdrom_saw_media_change (drive); @@ -650,13 +650,13 @@ But be sure to give up if we've retried too many times. */ if (++rq->errors > ERROR_MAX) - cdrom_end_request (0, drive); + cdrom_end_request(drive, 0); } else if (sense_key == ILLEGAL_REQUEST || sense_key == DATA_PROTECT) { /* No point in retrying after an illegal request or data protect error.*/ ide_dump_status (drive, "command error", stat); - cdrom_end_request (0, drive); + cdrom_end_request(drive, 0); } else if ((err & ~ABRT_ERR) != 0) { /* Go to the default handler for other errors. */ @@ -664,7 +664,7 @@ return 1; } else if ((++rq->errors > ERROR_MAX)) { /* We've racked up too many retries. Abort. */ - cdrom_end_request (0, drive); + cdrom_end_request(drive, 0); } /* If we got a CHECK_CONDITION status, @@ -786,6 +786,9 @@ return startstop; } + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); + /* Arm the interrupt handler. */ ide_set_handler (drive, handler, timeout, cdrom_timer_expiry); @@ -879,7 +882,7 @@ drive->name, ireason); } - cdrom_end_request (0, drive); + cdrom_end_request(drive, 0); return -1; } @@ -910,7 +913,7 @@ if (!dma_error) { for (i = rq->nr_sectors; i > 0;) { i -= rq->current_nr_sectors; - ide_end_request(1, HWGROUP(drive)); + ide_end_request(drive, 1); } return ide_stopped; } else @@ -928,9 +931,9 @@ if (rq->current_nr_sectors > 0) { printk ("%s: cdrom_read_intr: data underrun (%ld blocks)\n", drive->name, rq->current_nr_sectors); - cdrom_end_request (0, drive); + cdrom_end_request(drive, 0); } else - cdrom_end_request (1, drive); + cdrom_end_request(drive, 1); return ide_stopped; } @@ -950,7 +953,7 @@ printk (" Trying to limit transfer sizes\n"); CDROM_CONFIG_FLAGS (drive)->limit_nframes = 1; } - cdrom_end_request (0, drive); + cdrom_end_request(drive, 0); return ide_stopped; } @@ -979,7 +982,7 @@ /* If we've filled the present buffer but there's another chained buffer after it, move on. */ if (rq->current_nr_sectors == 0 && rq->nr_sectors) - cdrom_end_request (1, drive); + cdrom_end_request(drive, 1); /* If the buffers are full, cache the rest of the data in our internal buffer. */ @@ -1007,6 +1010,9 @@ } } + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); + /* Done moving data! Wait for another interrupt. */ ide_set_handler(drive, &cdrom_read_intr, WAIT_CMD, NULL); @@ -1031,7 +1037,7 @@ rq->sector >= info->sector_buffered && rq->sector < info->sector_buffered + info->nsectors_buffered) { if (rq->current_nr_sectors == 0) - cdrom_end_request (1, drive); + cdrom_end_request(drive, 1); memcpy (rq->buffer, info->buffer + @@ -1046,13 +1052,13 @@ /* If we've satisfied the current request, terminate it successfully. */ if (rq->nr_sectors == 0) { - cdrom_end_request (1, drive); + cdrom_end_request(drive, 1); return -1; } /* Move on to the next buffer if needed. */ if (rq->current_nr_sectors == 0) - cdrom_end_request (1, drive); + cdrom_end_request(drive, 1); /* If this condition does not hold, then the kluge i use to represent the number of sectors to skip at the start of a transfer @@ -1062,7 +1068,7 @@ (rq->sector % SECTORS_PER_FRAME) != 0) { printk ("%s: cdrom_read_from_buffer: buffer botch (%ld)\n", drive->name, rq->sector); - cdrom_end_request (0, drive); + cdrom_end_request(drive, 0); return -1; } @@ -1101,7 +1107,7 @@ (rq->sector % CD_FRAMESIZE != 0)) { printk ("%s: cdrom_start_read_continuation: buffer botch (%lu)\n", drive->name, rq->current_nr_sectors); - cdrom_end_request (0, drive); + cdrom_end_request(drive, 0); return ide_stopped; } sector -= nskip; @@ -1147,7 +1153,7 @@ return startstop; CDROM_CONFIG_FLAGS(drive)->seeking = 1; - if (retry && jiffies - info->start_seek > IDECD_SEEK_TIMER) { + if (retry && time_after(jiffies, info->start_seek + IDECD_SEEK_TIMER)) { if (--retry == 0) { /* * this condition is far too common, to bother @@ -1337,7 +1343,7 @@ } if (pc->buflen == 0) - cdrom_end_request (1, drive); + cdrom_end_request(drive, 1); else { /* Comment this out, because this always happens right after a reset occurs, and it is annoying to @@ -1347,7 +1353,7 @@ drive->name, pc->buflen); */ pc->stat = 1; - cdrom_end_request (1, drive); + cdrom_end_request(drive, 1); } return ide_stopped; } @@ -1398,6 +1404,9 @@ pc->stat = 1; } + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); + /* Now we wait for another interrupt. */ ide_set_handler (drive, &cdrom_pc_intr, WAIT_CMD, cdrom_timer_expiry); return ide_started; @@ -1522,7 +1531,7 @@ drive->name, ireason); } - cdrom_end_request(0, drive); + cdrom_end_request(drive, 0); return 1; } @@ -1559,7 +1568,7 @@ rq = HWGROUP(drive)->rq; for (i = rq->nr_sectors; i > 0;) { i -= rq->current_nr_sectors; - ide_end_request(1, HWGROUP(drive)); + ide_end_request(drive, 1); } return ide_stopped; } @@ -1579,7 +1588,7 @@ drive->name, rq->current_nr_sectors); uptodate = 0; } - cdrom_end_request(uptodate, drive); + cdrom_end_request(drive, uptodate); return ide_stopped; } @@ -1620,9 +1629,12 @@ * current buffer complete, move on */ if (rq->current_nr_sectors == 0 && rq->nr_sectors) - cdrom_end_request (1, drive); + cdrom_end_request(drive, 1); } + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); + /* re-arm handler */ ide_set_handler(drive, &cdrom_write_intr, 5 * WAIT_CMD, NULL); return ide_started; @@ -1662,7 +1674,7 @@ * writes *must* be 2kB frame aligned */ if ((rq->nr_sectors & 3) || (rq->sector & 3)) { - cdrom_end_request(0, drive); + cdrom_end_request(drive, 0); return ide_stopped; } @@ -1698,11 +1710,10 @@ case WRITE: case READ: { if (CDROM_CONFIG_FLAGS(drive)->seeking) { - unsigned long elpased = jiffies - info->start_seek; int stat = GET_STAT(); if ((stat & SEEK_STAT) != SEEK_STAT) { - if (elpased < IDECD_SEEK_TIMEOUT) { + if (time_before(jiffies, info->start_seek + IDECD_SEEK_TIMEOUT)) { ide_stall_queue(drive, IDECD_SEEK_TIMER); return ide_stopped; } @@ -1728,13 +1739,13 @@ } case RESET_DRIVE_COMMAND: { - cdrom_end_request(1, drive); + cdrom_end_request(drive, 1); return ide_do_reset(drive); } default: { printk("ide-cd: bad cmd %d\n", rq->cmd); - cdrom_end_request(0, drive); + cdrom_end_request(drive, 0); return ide_stopped; } } @@ -2961,6 +2972,7 @@ return 0; } +int ide_cdrom_init(void); int ide_cdrom_reinit (ide_drive_t *drive); static ide_driver_t ide_cdrom_driver = { @@ -2968,7 +2980,11 @@ version: IDECD_VERSION, media: ide_cdrom, busy: 0, +#ifdef CONFIG_IDEDMA_ONLYDISK + supports_dma: 0, +#else supports_dma: 1, +#endif supports_dsc_overlap: 1, cleanup: ide_cdrom_cleanup, standby: NULL, @@ -2984,12 +3000,12 @@ capacity: ide_cdrom_capacity, special: NULL, proc: NULL, + init: ide_cdrom_init, reinit: ide_cdrom_reinit, ata_prebuilder: NULL, atapi_prebuilder: NULL, }; -int ide_cdrom_init(void); static ide_module_t ide_cdrom_module = { IDE_DRIVER_MODULE, ide_cdrom_init, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ide-disk.c linux.19pre5-ac1/drivers/ide/ide-disk.c --- linux.19p5/drivers/ide/ide-disk.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/ide/ide-disk.c Thu Mar 21 01:02:27 2002 @@ -62,42 +62,11 @@ #endif #ifdef CONFIG_IDE_TASKFILE_IO -# undef __TASKFILE__IO /* define __TASKFILE__IO */ +# define __TASKFILE__IO #else /* CONFIG_IDE_TASKFILE_IO */ # undef __TASKFILE__IO #endif /* CONFIG_IDE_TASKFILE_IO */ -#ifndef __TASKFILE__IO - -static void idedisk_bswap_data (void *buffer, int wcount) -{ - u16 *p = buffer; - - while (wcount--) { - *p = *p << 8 | *p >> 8; p++; - *p = *p << 8 | *p >> 8; p++; - } -} - -static inline void idedisk_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount) -{ - ide_input_data(drive, buffer, wcount); - if (drive->bswap) - idedisk_bswap_data(buffer, wcount); -} - -static inline void idedisk_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount) -{ - if (drive->bswap) { - idedisk_bswap_data(buffer, wcount); - ide_output_data(drive, buffer, wcount); - idedisk_bswap_data(buffer, wcount); - } else - ide_output_data(drive, buffer, wcount); -} - -#endif /* __TASKFILE__IO */ - /* * lba_capacity_is_ok() performs a sanity check on the claimed "lba_capacity" * value for this drive (from its reported identification information). @@ -166,6 +135,8 @@ return ide_error(drive, "read_intr", stat); } /* no data yet, so wait for another interrupt */ + if (HWGROUP(drive)->handler != NULL) + BUG(); ide_set_handler(drive, &read_intr, WAIT_CMD, NULL); return ide_started; } @@ -179,7 +150,7 @@ msect -= nsect; } else nsect = 1; - idedisk_input_data(drive, rq->buffer, nsect * SECTOR_WORDS); + taskfile_input_data(drive, rq->buffer, nsect * SECTOR_WORDS); #ifdef DEBUG printk("%s: read: sectors(%ld-%ld), buffer=0x%08lx, remaining=%ld\n", drive->name, rq->sector, rq->sector+nsect-1, @@ -190,11 +161,18 @@ rq->errors = 0; i = (rq->nr_sectors -= nsect); if (((long)(rq->current_nr_sectors -= nsect)) <= 0) - ide_end_request(1, HWGROUP(drive)); + ide_end_request(drive, 1); + /* + * Another BH Page walker and DATA INTERGRITY Questioned on ERROR. + * If passed back up on multimode read, BAD DATA could be ACKED + * to FILE SYSTEMS above ... + */ if (i > 0) { if (msect) goto read_next; - ide_set_handler (drive, &read_intr, WAIT_CMD, NULL); + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); + ide_set_handler(drive, &read_intr, WAIT_CMD, NULL); return ide_started; } return ide_stopped; @@ -225,10 +203,12 @@ i = --rq->nr_sectors; --rq->current_nr_sectors; if (((long)rq->current_nr_sectors) <= 0) - ide_end_request(1, hwgroup); + ide_end_request(drive, 1); if (i > 0) { - idedisk_output_data (drive, rq->buffer, SECTOR_WORDS); - ide_set_handler (drive, &write_intr, WAIT_CMD, NULL); + taskfile_output_data(drive, rq->buffer, SECTOR_WORDS); + if (HWGROUP(drive)->handler != NULL) + BUG(); + ide_set_handler(drive, &write_intr, WAIT_CMD, NULL); return ide_started; } return ide_stopped; @@ -248,6 +228,11 @@ * and IRQ context. The IRQ can happen any time after we've output the * full "mcount" number of sectors, so we must make sure we update the * state _before_ we output the final part of the data! + * + * The update and return to BH is a BLOCK Layer Fakey to get more data + * to satisfy the hardware atomic segment. If the hardware atomic segment + * is shorter or smaller than the BH segment then we should be OKAY. + * This is only valid if we can rewind the rq->current_nr_sectors counter. */ int ide_multwrite (ide_drive_t *drive, unsigned int mcount) { @@ -286,7 +271,7 @@ * Ok, we're all setup for the interrupt * re-entering us on the last transfer. */ - idedisk_output_data(drive, buffer, nsect<<7); + taskfile_output_data(drive, buffer, nsect<<7); } while (mcount); return 0; @@ -311,7 +296,9 @@ if (rq->nr_sectors) { if (ide_multwrite(drive, drive->mult_count)) return ide_stopped; - ide_set_handler (drive, &multwrite_intr, WAIT_CMD, NULL); + if (HWGROUP(drive)->handler != NULL) + BUG(); + ide_set_handler(drive, &multwrite_intr, WAIT_CMD, NULL); return ide_started; } } else { @@ -323,7 +310,7 @@ rq = hwgroup->rq; for (i = rq->nr_sectors; i > 0;){ i -= rq->current_nr_sectors; - ide_end_request(1, hwgroup); + ide_end_request(drive, 1); } return ide_stopped; } @@ -353,7 +340,7 @@ goto good_command; printk(KERN_ERR "%s: bad command: %d\n", drive->name, rq->cmd); - ide_end_request(0, HWGROUP(drive)); + ide_end_request(drive, 0); return ide_stopped; good_command: @@ -434,12 +421,9 @@ args.command_type = ide_cmd_type_parser(&args); args.prehandler = ide_pre_handler_parser(&taskfile, &hobfile); args.handler = ide_handler_parser(&taskfile, &hobfile); - args.posthandler = NULL; + args.posthandler = ide_post_handler_parser(&taskfile, &hobfile); args.rq = (struct request *) rq; - args.block = block; - rq->special = NULL; rq->special = (ide_task_t *)&args; - return do_rw_taskfile(drive, &args); } @@ -448,7 +432,6 @@ struct hd_drive_task_hdr taskfile; struct hd_drive_hob_hdr hobfile; ide_task_t args; - task_ioreg_t command = get_command(drive, rq->cmd); memset(&taskfile, 0, sizeof(task_struct_t)); @@ -462,7 +445,6 @@ taskfile.device_head |= drive->select.all; taskfile.command = command; - #ifdef DEBUG printk("%s: %sing: ", drive->name, (rq->cmd==READ) ? "read" : "writ"); if (lba) printk("LBAsect=%lld, ", block); @@ -476,12 +458,9 @@ args.command_type = ide_cmd_type_parser(&args); args.prehandler = ide_pre_handler_parser(&taskfile, &hobfile); args.handler = ide_handler_parser(&taskfile, &hobfile); - args.posthandler = NULL; + args.posthandler = ide_post_handler_parser(&taskfile, &hobfile); args.rq = (struct request *) rq; - args.block = block; - rq->special = NULL; rq->special = (ide_task_t *)&args; - return do_rw_taskfile(drive, &args); } @@ -496,20 +475,16 @@ struct hd_drive_task_hdr taskfile; struct hd_drive_hob_hdr hobfile; ide_task_t args; + int sectors; task_ioreg_t command = get_command(drive, rq->cmd); memset(&taskfile, 0, sizeof(task_struct_t)); memset(&hobfile, 0, sizeof(hob_struct_t)); - taskfile.sector_count = rq->nr_sectors; - hobfile.sector_count = (rq->nr_sectors>>8); - - if (rq->nr_sectors == 65536) { - taskfile.sector_count = 0x00; - hobfile.sector_count = 0x00; - } - + sectors = (rq->nr_sectors == 65536) ? 0 : rq->nr_sectors; + taskfile.sector_count = sectors; + hobfile.sector_count = sectors >> 8; taskfile.sector_number = block; /* low lba */ taskfile.low_cylinder = (block>>=8); /* mid lba */ taskfile.high_cylinder = (block>>=8); /* hi lba */ @@ -534,12 +509,9 @@ args.command_type = ide_cmd_type_parser(&args); args.prehandler = ide_pre_handler_parser(&taskfile, &hobfile); args.handler = ide_handler_parser(&taskfile, &hobfile); - args.posthandler = NULL; + args.posthandler = ide_post_handler_parser(&taskfile, &hobfile); args.rq = (struct request *) rq; - args.block = block; - rq->special = NULL; rq->special = (ide_task_t *)&args; - return do_rw_taskfile(drive, &args); } @@ -647,6 +619,8 @@ if (drive->using_dma && !(HWIF(drive)->dmaproc(ide_dma_read, drive))) return ide_started; #endif /* CONFIG_BLK_DEV_IDEDMA */ + if (HWGROUP(drive)->handler != NULL) + BUG(); ide_set_handler(drive, &read_intr, WAIT_CMD, NULL); if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing)) { OUT_BYTE(drive->mult_count ? WIN_MULTREAD_EXT : WIN_READ_EXT, IDE_COMMAND_REG); @@ -683,8 +657,12 @@ * before returning. Fortunately, this NEVER happens (right?). * * Except when you get an error it seems... + * + * MAJOR DATA INTEGRITY BUG !!! only if we error */ hwgroup->wrq = *rq; /* scratchpad */ + if (HWGROUP(drive)->handler != NULL) + BUG(); ide_set_handler(drive, &multwrite_intr, WAIT_CMD, NULL); if (ide_multwrite(drive, drive->mult_count)) { unsigned long flags; @@ -695,13 +673,15 @@ return ide_stopped; } } else { - ide_set_handler (drive, &write_intr, WAIT_CMD, NULL); - idedisk_output_data(drive, rq->buffer, SECTOR_WORDS); + if (HWGROUP(drive)->handler != NULL) + BUG(); + ide_set_handler(drive, &write_intr, WAIT_CMD, NULL); + taskfile_output_data(drive, rq->buffer, SECTOR_WORDS); } return ide_started; } printk(KERN_ERR "%s: bad command: %d\n", drive->name, rq->cmd); - ide_end_request(0, HWGROUP(drive)); + ide_end_request(drive, 0); return ide_stopped; } @@ -949,6 +929,7 @@ drive->name, set_max_ext, capacity_2); #endif /* CONFIG_IDEDISK_STROKE */ } + drive->cyl = (unsigned int) capacity_2 / (drive->head * drive->sect); drive->bios_cyl = drive->cyl; drive->capacity48 = capacity_2; drive->capacity = (unsigned long) capacity_2; @@ -979,7 +960,7 @@ drive->capacity = capacity; if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400)) { - drive->capacity48 = id->lba_capacity_2; + drive->capacity48 = id->lba_capacity_2; drive->head = 255; drive->sect = 63; drive->cyl = (unsigned long)(drive->capacity48) / (drive->head * drive->sect); @@ -1038,7 +1019,7 @@ memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr)); taskfile.sector_count = drive->mult_req; taskfile.command = WIN_SETMULT; - do_taskfile(drive, &taskfile, &hobfile, ide_handler_parser(&taskfile, &hobfile)); + do_taskfile(drive, &taskfile, &hobfile, &set_multmode_intr); } } else if (s->all) { int special = s->all; @@ -1175,23 +1156,12 @@ #endif /* CONFIG_PROC_FS */ +/* + * This is tightly woven into the driver->do_special can not touch. + * DON'T do it again until a total personality rewrite is committed. + */ static int set_multcount(ide_drive_t *drive, int arg) { -#ifdef __TASKFILE__IO - struct hd_drive_task_hdr taskfile; - struct hd_drive_hob_hdr hobfile; - - if (drive->special.b.set_multmode) - return -EBUSY; - - memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr)); - memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr)); - taskfile.sector_count = drive->mult_req; - taskfile.command = WIN_SETMULT; - drive->mult_req = arg; - drive->special.b.set_multmode = 1; - ide_wait_taskfile(drive, &taskfile, &hobfile, NULL); -#else /* !__TASKFILE__IO */ struct request rq; if (drive->special.b.set_multmode) @@ -1201,7 +1171,6 @@ drive->mult_req = arg; drive->special.b.set_multmode = 1; (void) ide_do_drive_cmd (drive, &rq, ide_wait); -#endif /* __TASKFILE__IO */ return (drive->mult_count == arg) ? 0 : -EIO; } @@ -1414,7 +1383,13 @@ drive->no_io_32bit = id->dword_io ? 1 : 0; if (drive->id->cfs_enable_2 & 0x3000) write_cache(drive, (id->cfs_enable_2 & 0x3000)); +#if 1 (void) probe_lba_addressing(drive, 1); +#else + /* if using 48-bit addressing bump the request size up */ + if (probe_lba_addressing(drive, 1)) + blk_queue_max_sectors(&drive->queue, 2048); +#endif } static int idedisk_cleanup (ide_drive_t *drive) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ide-dma.c linux.19pre5-ac1/drivers/ide/ide-dma.c --- linux.19p5/drivers/ide/ide-dma.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/ide/ide-dma.c Thu Mar 21 01:02:27 2002 @@ -123,7 +123,6 @@ { "WDC AC11000H" , "ALL" }, { "WDC AC22100H" , "ALL" }, - { "WDC AC31000H" , "ALL" }, { "WDC AC32500H" , "ALL" }, { "WDC AC33100H" , "ALL" }, { "WDC AC31600H" , "ALL" }, @@ -238,7 +237,7 @@ rq = HWGROUP(drive)->rq; for (i = rq->nr_sectors; i > 0;) { i -= rq->current_nr_sectors; - ide_end_request(1, HWGROUP(drive)); + ide_end_request(drive, 1); } return ide_stopped; } @@ -291,8 +290,6 @@ unsigned char *virt_addr = rq->buffer; int sector_count = rq->nr_sectors; -// if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_WRITEDMA) || -// (args->tfRegister[IDE_COMMAND_OFFSET] == WIN_WRITEDMA_EXT)) if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE) hwif->sg_dma_direction = PCI_DMA_TODEVICE; else @@ -498,16 +495,10 @@ static int config_drive_for_dma (ide_drive_t *drive) { - int config_allows_dma = 1; struct hd_driveid *id = drive->id; ide_hwif_t *hwif = HWIF(drive); -#ifdef CONFIG_IDEDMA_ONLYDISK - if (drive->media != ide_disk) - config_allows_dma = 0; -#endif - - if (id && (id->capability & 1) && hwif->autodma && config_allows_dma) { + if (id && (id->capability & 1) && hwif->autodma) { /* Consult the list of known "bad" drives */ if (ide_dmaproc(ide_dma_bad_drive, drive)) return hwif->dmaproc(ide_dma_off, drive); @@ -535,7 +526,7 @@ return hwif->dmaproc(ide_dma_off_quietly, drive); } -#ifndef CONFIG_BLK_DEV_IDEDMA_TIMEOUT +#ifndef __IDEDMA_TIMEOUT /* * 1 dmaing, 2 error, 4 intr */ @@ -559,30 +550,46 @@ return WAIT_CMD; return 0; } -#else /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */ -static ide_startstop_t ide_dma_timeout_revovery (ide_drive_t *drive) +#else /* __IDEDMA_TIMEOUT */ +static int ide_dma_timeout_recovery (ide_drive_t *drive) { - ide_hwgroup_t *hwgroup = HWGROUP(drive); - ide_hwif_t *hwif = HWIF(drive); + struct request *rq = HWGROUP(drive)->rq; int enable_dma = drive->using_dma; + int speed = drive->current_speed; unsigned long flags; - ide_startstop_t startstop; spin_lock_irqsave(&io_request_lock, flags); - hwgroup->handler = NULL; - del_timer(&hwgroup->timer); + HWGROUP(drive)->handler = NULL; + del_timer(&HWGROUP(drive)->timer); + HWGROUP(drive)->expiry = NULL; + HWGROUP(drive)->rq = NULL; spin_unlock_irqrestore(&io_request_lock, flags); + (void) HWIF(drive)->dmaproc(ide_dma_off, drive); drive->waiting_for_dma = 0; - startstop = ide_do_reset(drive); + (void) ide_do_reset(drive); + + if (!(drive_is_ready(drive))) { + /* FIXME: Replace hard-coded 100, error handling? */ + int i; + for (i=0; i<100; i++) { + if (drive_is_ready(drive)) + break; + } + } + + if ((HWIF(drive)->speedproc) != NULL) { + HWIF(drive)->speedproc(drive, speed); + drive->current_speed = speed; + } if ((enable_dma) && !(drive->using_dma)) - (void) hwif->dmaproc(ide_dma_on, drive); + (void) HWIF(drive)->dmaproc(ide_dma_on, drive); - return startstop; + return restart_request(drive, rq); } -#endif /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */ +#endif /* __IDEDMA_TIMEOUT */ /* * ide_dmaproc() initiates/aborts DMA read/write operations on a drive. @@ -602,7 +609,6 @@ */ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive) { -// ide_hwgroup_t *hwgroup = HWGROUP(drive); ide_hwif_t *hwif = HWIF(drive); unsigned long dma_base = hwif->dma_base; byte unit = (drive->select.b.unit & 0x01); @@ -626,18 +632,32 @@ case ide_dma_write: SELECT_READ_WRITE(hwif,drive,func); if (!(count = ide_build_dmatable(drive, func))) - return 1; /* try PIO instead of DMA */ - outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */ - outb(reading, dma_base); /* specify r/w */ - outb(inb(dma_base+2)|6, dma_base+2); /* clear INTR & ERROR flags */ + /* try PIO instead of DMA */ + return 1; + /* PRD table */ + outl(hwif->dmatable_dma, dma_base + 4); + /* specify r/w */ + outb(reading, dma_base); + /* clear INTR & ERROR flags */ + outb(inb(dma_base+2)|6, dma_base+2); drive->waiting_for_dma = 1; if (drive->media != ide_disk) return 0; -#ifdef CONFIG_BLK_DEV_IDEDMA_TIMEOUT - ide_set_handler(drive, &ide_dma_intr, 2*WAIT_CMD, NULL); /* issue cmd to drive */ -#else /* !CONFIG_BLK_DEV_IDEDMA_TIMEOUT */ - ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, dma_timer_expiry); /* issue cmd to drive */ -#endif /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */ +#ifndef __IDEDMA_TIMEOUT + ide_set_handler(drive, &ide_dma_intr, 2*WAIT_CMD, dma_timer_expiry); +#else /* __IDEDMA_TIMEOUT */ + ide_set_handler(drive, &ide_dma_intr, 2*WAIT_CMD, NULL); +#endif /* __IDEDMA_TIMEOUT */ + /* issue cmd to drive */ + /* + * FIX ME to use only ACB ide_task_t args Struct + */ +#if 0 + { + ide_task_t *args = HWGROUP(drive)->rq->special; + OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG); + } +#else if ((HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE) && (drive->addressing == 1)) { ide_task_t *args = HWGROUP(drive)->rq->special; @@ -647,6 +667,7 @@ } else { OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); } +#endif return HWIF(drive)->dmaproc(ide_dma_begin, drive); case ide_dma_begin: /* Note that this is done *after* the cmd has @@ -654,15 +675,20 @@ * The Promise Ultra33 doesn't work correctly when * we do this part before issuing the drive cmd. */ - outb(inb(dma_base)|1, dma_base); /* start DMA */ + outb(inb(dma_base)|1, dma_base); /* start DMA */ return 0; case ide_dma_end: /* returns 1 on error, 0 otherwise */ drive->waiting_for_dma = 0; - outb(inb(dma_base)&~1, dma_base); /* stop DMA */ - dma_stat = inb(dma_base+2); /* get DMA status */ - outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */ - ide_destroy_dmatable(drive); /* purge DMA mappings */ - return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; /* verify good DMA status */ + /* stop DMA */ + outb(inb(dma_base)&~1, dma_base); + /* get DMA status */ + dma_stat = inb(dma_base+2); + /* clear the INTR & ERROR bits */ + outb(dma_stat|6, dma_base+2); + /* purge DMA mappings */ + ide_destroy_dmatable(drive); + /* verify good DMA status */ + return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */ dma_stat = inb(dma_base+2); #if 0 /* do not set unless you know what you are doing */ @@ -671,48 +697,51 @@ outb(dma_base+2, dma_stat & 0xE4); } #endif - return (dma_stat & 4) == 4; /* return 1 if INTR asserted */ + /* return 1 if INTR asserted */ + return (dma_stat & 4) == 4; case ide_dma_bad_drive: case ide_dma_good_drive: return check_drive_lists(drive, (func == ide_dma_good_drive)); case ide_dma_verbose: return report_drive_dmaing(drive); case ide_dma_timeout: - // FIXME: Many IDE chipsets do not permit command file register access - // FIXME: while the bus-master function is still active. - // FIXME: To prevent deadlock with those chipsets, we must be extremely - // FIXME: careful here (and in ide_intr() as well) to NOT access any - // FIXME: registers from the 0x1Fx/0x17x sets before terminating the - // FIXME: bus-master operation via the bus-master control reg. - // FIXME: Otherwise, chipset deadlock will occur, and some systems will - // FIXME: lock up completely!! -#ifdef CONFIG_BLK_DEV_IDEDMA_TIMEOUT + // FIXME: Many IDE chipsets do not permit command file register access + // FIXME: while the bus-master function is still active. + // FIXME: To prevent deadlock with those chipsets, we must be extremely + // FIXME: careful here (and in ide_intr() as well) to NOT access any + // FIXME: registers from the 0x1Fx/0x17x sets before terminating the + // FIXME: bus-master operation via the bus-master control reg. + // FIXME: Otherwise, chipset deadlock will occur, and some systems will + // FIXME: lock up completely!! +#ifdef __IDEDMA_TIMEOUT /* * Have to issue an abort and requeue the request * DMA engine got turned off by a goofy ASIC, and * we have to clean up the mess, and here is as good * as any. Do it globally for all chipsets. */ - outb(0x00, dma_base); /* stop DMA */ - dma_stat = inb(dma_base+2); /* get DMA status */ - outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */ +#if 0 + dma_stat = HWIF(drive)->dmaproc(ide_dma_end, drive); +#else + drive->waiting_for_dma = 0; + /* stop DMA */ + outb(inb(dma_base)&~1, dma_base); +// outb(0x00, dma_base); + /* get DMA status */ + dma_stat = inb(dma_base+2); + /* clear the INTR & ERROR bits */ + outb(dma_stat|6, dma_base+2); + /* purge DMA mappings */ + ide_destroy_dmatable(drive); +#endif printk("%s: %s: Lets do it again!" \ "stat = 0x%02x, dma_stat = 0x%02x\n", drive->name, ide_dmafunc_verbose(func), GET_STAT(), dma_stat); if (dma_stat & 0xF0) - return ide_dma_timeout_revovery(drive); - - printk("%s: %s: (restart_request) Lets do it again!" \ - "stat = 0x%02x, dma_stat = 0x%02x\n", - drive->name, ide_dmafunc_verbose(func), - GET_STAT(), dma_stat); - - return restart_request(drive); // BUG: return types do not match!! -//#else -// return HWGROUP(drive)->handler(drive); -#endif /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */ + return ide_dma_timeout_recovery(drive); +#endif /* __IDEDMA_TIMEOUT */ case ide_dma_retune: case ide_dma_lostirq: printk("ide_dmaproc: chipset supported %s func only: %d\n", ide_dmafunc_verbose(func), func); @@ -746,7 +775,7 @@ } /* - * This can be called for a dynamically installed interface. Don't __init it + * This can be called for a dynamically installed interface. Don't __init it */ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_ports) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ide-features.c linux.19pre5-ac1/drivers/ide/ide-features.c --- linux.19p5/drivers/ide/ide-features.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/ide/ide-features.c Thu Mar 21 01:02:27 2002 @@ -157,7 +157,7 @@ OUT_BYTE(WIN_IDENTIFY, IDE_COMMAND_REG); timeout = jiffies + WAIT_WORSTCASE; do { - if (0 < (signed long)(jiffies - timeout)) { + if (time_after(jiffies, timeout)) { SELECT_MASK(HWIF(drive), drive, 0); return 0; /* drive timed-out */ } @@ -177,7 +177,7 @@ __restore_flags(flags); /* local CPU only */ return 0; } - ide_input_data(drive, id, SECTOR_WORDS); + ata_input_data(drive, id, SECTOR_WORDS); (void) GET_STAT(); /* clear drive IRQ */ ide__sti(); /* local CPU only */ __restore_flags(flags); /* local CPU only */ @@ -305,7 +305,7 @@ ide__sti(); /* local CPU only -- for jiffies */ timeout = jiffies + WAIT_CMD; while ((stat = GET_STAT()) & BUSY_STAT) { - if (0 < (signed long)(jiffies - timeout)) + if (time_after(jiffies, timeout)) break; } __restore_flags(flags); /* local CPU only */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ide-floppy.c linux.19pre5-ac1/drivers/ide/ide-floppy.c --- linux.19p5/drivers/ide/ide-floppy.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/ide/ide-floppy.c Thu Mar 21 01:02:27 2002 @@ -685,11 +685,10 @@ * For read/write requests, we will call ide_end_request to pass to the * next buffer. */ -static void idefloppy_end_request (byte uptodate, ide_hwgroup_t *hwgroup) +static int idefloppy_end_request (ide_drive_t *drive, int uptodate) { - ide_drive_t *drive = hwgroup->drive; idefloppy_floppy_t *floppy = drive->driver_data; - struct request *rq = hwgroup->rq; + struct request *rq = HWGROUP(drive)->rq; int error; #if IDEFLOPPY_DEBUG_LOG @@ -705,13 +704,14 @@ floppy->failed_pc = NULL; /* Why does this happen? */ if (!rq) - return; + return 0; if (!IDEFLOPPY_RQ_CMD (rq->cmd)) { - ide_end_request (uptodate, hwgroup); - return; + ide_end_request(drive, uptodate); + return 0; } rq->errors = error; ide_end_drive_cmd (drive, 0, 0); + return 0; } static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount) @@ -724,7 +724,7 @@ if (pc->b_count == bh->b_size) { rq->sector += rq->current_nr_sectors; rq->nr_sectors -= rq->current_nr_sectors; - idefloppy_end_request (1, HWGROUP(drive)); + idefloppy_end_request(drive, 1); if ((bh = rq->bh) != NULL) pc->b_count = 0; } @@ -749,7 +749,7 @@ if (!pc->b_count) { rq->sector += rq->current_nr_sectors; rq->nr_sectors -= rq->current_nr_sectors; - idefloppy_end_request (1, HWGROUP(drive)); + idefloppy_end_request(drive, 1); if ((bh = rq->bh) != NULL) { pc->b_data = bh->b_data; pc->b_count = bh->b_size; @@ -773,7 +773,7 @@ struct buffer_head *bh = rq->bh; while ((bh = rq->bh) != NULL) - idefloppy_end_request (1, HWGROUP(drive)); + idefloppy_end_request(drive, 1); } #endif /* CONFIG_BLK_DEV_IDEDMA */ @@ -836,10 +836,10 @@ #endif /* IDEFLOPPY_DEBUG_LOG */ if (!floppy->pc->error) { idefloppy_analyze_error (drive,(idefloppy_request_sense_result_t *) floppy->pc->buffer); - idefloppy_end_request (1,HWGROUP (drive)); + idefloppy_end_request(drive, 1); } else { printk (KERN_ERR "Error in REQUEST SENSE itself - Aborting request!\n"); - idefloppy_end_request (0,HWGROUP (drive)); + idefloppy_end_request(drive, 0); } } @@ -854,7 +854,7 @@ printk (KERN_INFO "ide-floppy: Reached idefloppy_pc_callback\n"); #endif /* IDEFLOPPY_DEBUG_LOG */ - idefloppy_end_request (floppy->pc->error ? 0:1, HWGROUP(drive)); + idefloppy_end_request(drive, floppy->pc->error ? 0 : 1); } /* @@ -985,7 +985,9 @@ if (temp > pc->buffer_size) { printk (KERN_ERR "ide-floppy: The floppy wants to send us more data than expected - discarding data\n"); idefloppy_discard_data (drive,bcount.all); - ide_set_handler (drive,&idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL); + if (HWGROUP(drive)->handler != NULL) + BUG(); + ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); return ide_started; } #if IDEFLOPPY_DEBUG_LOG @@ -1007,7 +1009,9 @@ pc->actually_transferred+=bcount.all; /* Update the current position */ pc->current_position+=bcount.all; - ide_set_handler (drive,&idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL); /* And set the interrupt handler again */ + if (HWGROUP(drive)->handler != NULL) + BUG(); + ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* And set the interrupt handler again */ return ide_started; } @@ -1031,7 +1035,9 @@ printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n"); return ide_do_reset (drive); } - ide_set_handler (drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* Set the interrupt routine */ + if (HWGROUP(drive)->handler != NULL) + BUG(); + ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* Set the interrupt routine */ atapi_output_bytes (drive, floppy->pc->c, 12); /* Send the actual packet */ return ide_started; } @@ -1079,9 +1085,11 @@ * 25msec is too short, 40 and 50msec work well. idefloppy_pc_intr will * not be actually used until after the packet is moved in about 50 msec. */ - ide_set_handler (drive, + if (HWGROUP(drive)->handler != NULL) + BUG(); + ide_set_handler(drive, &idefloppy_pc_intr, /* service routine for packet command */ - floppy->ticks, /* wait this long before "failing" */ + floppy->ticks, /* wait this long before "failing" */ &idefloppy_transfer_pc2); /* fail == transfer_pc2 */ return ide_started; } @@ -1162,7 +1170,9 @@ } if (test_bit (IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags)) { - ide_set_handler (drive, pkt_xfer_routine, IDEFLOPPY_WAIT_CMD, NULL); + if (HWGROUP(drive)->handler != NULL) + BUG(); + ide_set_handler(drive, pkt_xfer_routine, IDEFLOPPY_WAIT_CMD, NULL); OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* Issue the packet command */ return ide_started; } else { @@ -1177,7 +1187,7 @@ printk (KERN_INFO "ide-floppy: Reached idefloppy_rw_callback\n"); #endif /* IDEFLOPPY_DEBUG_LOG */ - idefloppy_end_request(1, HWGROUP(drive)); + idefloppy_end_request(drive, 1); return; } @@ -1310,7 +1320,7 @@ drive->name, floppy->failed_pc->c[0], floppy->sense_key, floppy->asc, floppy->ascq); else printk (KERN_ERR "ide-floppy: %s: I/O error\n", drive->name); - idefloppy_end_request (0, HWGROUP(drive)); + idefloppy_end_request(drive, 0); return ide_stopped; } switch (rq->cmd) { @@ -1318,7 +1328,7 @@ case WRITE: if (rq->sector % floppy->bs_factor || rq->nr_sectors % floppy->bs_factor) { printk ("%s: unsupported r/w request size\n", drive->name); - idefloppy_end_request (0, HWGROUP(drive)); + idefloppy_end_request(drive, 0); return ide_stopped; } pc = idefloppy_next_pc_storage (drive); @@ -1329,7 +1339,7 @@ break; default: printk (KERN_ERR "ide-floppy: unsupported command %x in request queue\n", rq->cmd); - idefloppy_end_request (0,HWGROUP (drive)); + idefloppy_end_request(drive, 0); return ide_stopped; } pc->rq = rq; @@ -2089,6 +2099,7 @@ #endif /* CONFIG_PROC_FS */ +int idefloppy_init (void); int idefloppy_reinit(ide_drive_t *drive); /* @@ -2099,7 +2110,11 @@ version: IDEFLOPPY_VERSION, media: ide_floppy, busy: 0, +#ifdef CONFIG_IDEDMA_ONLYDISK + supports_dma: 0, +#else supports_dma: 1, +#endif supports_dsc_overlap: 0, cleanup: idefloppy_cleanup, standby: NULL, @@ -2115,12 +2130,12 @@ capacity: idefloppy_capacity, special: NULL, proc: idefloppy_proc, + init: idefloppy_init, reinit: idefloppy_reinit, ata_prebuilder: NULL, atapi_prebuilder: NULL, }; -int idefloppy_init (void); static ide_module_t idefloppy_module = { IDE_DRIVER_MODULE, idefloppy_init, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ide-pci.c linux.19pre5-ac1/drivers/ide/ide-pci.c --- linux.19p5/drivers/ide/ide-pci.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/ide/ide-pci.c Tue Mar 26 18:39:35 2002 @@ -55,6 +55,7 @@ #define DEVID_PDC20268 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268}) #define DEVID_PDC20268R ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268R}) #define DEVID_PDC20269 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20269}) +#define DEVID_PDC20271 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20271}) #define DEVID_PDC20275 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20275}) #define DEVID_PDC20276 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20276}) #define DEVID_RZ1000 ((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000}) @@ -83,6 +84,8 @@ #define DEVID_UM8886BF ((ide_pci_devid_t){PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886BF}) #define DEVID_HPT34X ((ide_pci_devid_t){PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT343}) #define DEVID_HPT366 ((ide_pci_devid_t){PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT366}) +#define DEVID_HPT372 ((ide_pci_devid_t){PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372}) +#define DEVID_HPT374 ((ide_pci_devid_t){PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT374}) #define DEVID_ALI15X3 ((ide_pci_devid_t){PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229}) #define DEVID_CY82C693 ((ide_pci_devid_t){PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693}) #define DEVID_HINT ((ide_pci_devid_t){0x3388, 0x8013}) @@ -281,7 +284,7 @@ #else #define PCI_IT8172 NULL #define ATA66_IT8172 NULL -#define INIT_IT8172 NULL +#define INIT_IT8172 IDE_NO_DRIVER #endif #ifdef CONFIG_BLK_DEV_RZ1000 @@ -419,6 +422,7 @@ prevent Linux detecting it and using our own raid code. We want to detect it for the ataraid drivers, so we have to list both here.. */ {DEVID_PDC20268R,"PDC20270", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, + {DEVID_PDC20271,"PDC20271", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, {DEVID_PDC20269,"PDC20269", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, {DEVID_PDC20275,"PDC20275", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, {DEVID_PDC20276,"PDC20276", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, @@ -451,6 +455,13 @@ {DEVID_UM8886BF,"UM8886BF", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_HPT34X, "HPT34X", PCI_HPT34X, NULL, INIT_HPT34X, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, NEVER_BOARD, 16 }, {DEVID_HPT366, "HPT366", PCI_HPT366, ATA66_HPT366, INIT_HPT366, DMA_HPT366, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 240 }, +#if 1 + {DEVID_HPT372, "HPT372", PCI_HPT366, ATA66_HPT366, INIT_HPT366, DMA_HPT366, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, + {DEVID_HPT374, "HPT374", PCI_HPT366, ATA66_HPT366, INIT_HPT366, DMA_HPT366, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, +#else + {DEVID_HPT372, "HPT372", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, + {DEVID_HPT374, "HPT374", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, +#endif {DEVID_ALI15X3, "ALI15X3", PCI_ALI15X3, ATA66_ALI15X3, INIT_ALI15X3, DMA_ALI15X3, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_CY82C693,"CY82C693", PCI_CY82C693, NULL, INIT_CY82C693, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_HINT, "HINT_IDE", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, @@ -475,6 +486,7 @@ { switch(dev->device) { case PCI_DEVICE_ID_TTI_HPT366: + case PCI_DEVICE_ID_TTI_HPT374: case PCI_DEVICE_ID_PROMISE_20246: case PCI_DEVICE_ID_PROMISE_20262: case PCI_DEVICE_ID_PROMISE_20265: @@ -812,6 +824,7 @@ IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20268) || IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20268R) || IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20269) || + IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20271) || IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20275) || IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20276) || IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6210) || @@ -819,6 +832,7 @@ IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260R) || IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X) || IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366) || + IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT374) || IDE_PCI_DEVID_EQ(d->devid, DEVID_CS5530) || IDE_PCI_DEVID_EQ(d->devid, DEVID_CY82C693) || IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD646) || @@ -901,6 +915,44 @@ ide_setup_pci_device(dev2, d2); } +static void __init hpt374_device_order_fixup (struct pci_dev *dev, ide_pci_device_t *d) +{ + struct pci_dev *dev2 = NULL, *findev; + ide_pci_device_t *d2; + + if (PCI_FUNC(dev->devfn) & 1) + return; + + pci_for_each_dev(findev) { + if ((findev->vendor == dev->vendor) && + (findev->device == dev->device) && + ((findev->devfn - dev->devfn) == 1) && + (PCI_FUNC(findev->devfn) & 1)) { + dev2 = findev; + break; + } + } + + printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn); + ide_setup_pci_device(dev, d); + if (!dev2) { + return; + } else { + byte irq = 0, irq2 = 0; + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); + pci_read_config_byte(dev2, PCI_INTERRUPT_LINE, &irq2); + if (irq != irq2) { + pci_write_config_byte(dev2, PCI_INTERRUPT_LINE, irq); + dev2->irq = dev->irq; + printk("%s: pci-config space interrupt fixed.\n", d->name); + } + } + d2 = d; + printk("%s: IDE controller on PCI bus %02x dev %02x\n", d2->name, dev2->bus->number, dev2->devfn); + ide_setup_pci_device(dev2, d2); + +} + static void __init hpt366_device_order_fixup (struct pci_dev *dev, ide_pci_device_t *d) { struct pci_dev *dev2 = NULL, *findev; @@ -914,12 +966,11 @@ pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; - if (class_rev > 5) - class_rev = 5; - + strcpy(d->name, chipset_names[class_rev]); switch(class_rev) { + case 5: case 4: case 3: printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn); ide_setup_pci_device(dev, d); @@ -940,7 +991,7 @@ if (hpt363_shared_pin && hpt363_shared_irq) { d->bootable = ON_BOARD; printk("%s: onboard version of chipset, pin1=%d pin2=%d\n", d->name, pin1, pin2); -#if 0 +#if 1 /* I forgot why I did this once, but it fixed something. */ pci_write_config_byte(dev2, PCI_INTERRUPT_PIN, dev->irq); printk("PCI: %s: Fixing interrupt %d pin %d to ZERO \n", d->name, dev2->irq, pin2); @@ -983,6 +1034,8 @@ return; /* UM8886A/BF pair */ else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366)) hpt366_device_order_fixup(dev, d); + else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT374)) + hpt374_device_order_fixup(dev, d); else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20268R)) pdc20270_device_order_fixup(dev, d); else if (!IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL) || (dev->class >> 8) == PCI_CLASS_STORAGE_IDE) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ide-pmac.c linux.19pre5-ac1/drivers/ide/ide-pmac.c --- linux.19p5/drivers/ide/ide-pmac.c Thu Apr 4 13:19:32 2002 +++ linux.19pre5-ac1/drivers/ide/ide-pmac.c Thu Mar 21 01:04:05 2002 @@ -351,42 +351,6 @@ (void)in_le32((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG + _IO_BASE)); } - -/* Note: We don't use the generic routine here because for some - * yet unexplained reasons, it cause some media-bay CD-ROMs to - * lockup the bus. Strangely, this new version of the code is - * almost identical to the generic one and works, I've not yet - * managed to figure out what bit is causing the lockup in the - * generic code, possibly a timing issue... - * - * --BenH - */ -static int __pmac -wait_for_ready(ide_drive_t *drive) -{ - /* Timeout bumped for some powerbooks */ - int timeout = 2000; - byte stat; - - while(--timeout) { - stat = GET_STAT(); - if(!(stat & BUSY_STAT)) { - if (drive->ready_stat == 0) - break; - else if((stat & drive->ready_stat) || (stat & ERR_STAT)) - break; - } - mdelay(1); - } - if((stat & ERR_STAT) || timeout <= 0) { - if (stat & ERR_STAT) { - printk(KERN_ERR "ide_pmac: wait_for_ready, error status: %x\n", stat); - } - return 1; - } - return 0; -} - static int __pmac pmac_ide_do_setfeature(ide_drive_t *drive, byte command) { @@ -400,7 +364,7 @@ SELECT_MASK(HWIF(drive), drive, 0); udelay(1); (void)GET_STAT(); /* Get rid of pending error state */ - if(wait_for_ready(drive)) { + if(wait_for_ready(drive, 2000)) { /* Timeout bumped for some powerbooks */ printk(KERN_ERR "pmac_ide_do_setfeature disk not ready before SET_FEATURE!\n"); goto out; } @@ -412,7 +376,7 @@ udelay(1); __save_flags(flags); /* local CPU only */ ide__sti(); /* local CPU only -- for jiffies */ - result = wait_for_ready(drive); + result = wait_for_ready(drive, 2000); /* Timeout bumped for some powerbooks */ __restore_flags(flags); /* local CPU only */ OUT_BYTE(drive->ctl, IDE_CONTROL_REG); if (result) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ide-probe.c linux.19pre5-ac1/drivers/ide/ide-probe.c --- linux.19p5/drivers/ide/ide-probe.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/ide/ide-probe.c Thu Mar 21 01:04:05 2002 @@ -62,8 +62,18 @@ printk(KERN_WARNING "(ide-probe::do_identify) Out of memory.\n"); goto err_kmalloc; } - - ide_input_data(drive, id, SECTOR_WORDS); /* read 512 bytes of id info */ + /* read 512 bytes of id info */ +#if 1 + ata_input_data(drive, id, SECTOR_WORDS); /* read 512 bytes of id info */ +#else + { + unsigned long *ptr = (unsigned long *)id ; + unsigned long lcount = 256/2 ; + // printk("IDE_DATA_REG = %#lx",IDE_DATA_REG); + while( lcount-- ) + *ptr++ = inl(IDE_DATA_REG); + } +#endif ide__sti(); /* local CPU only */ ide_fix_driveid(id); @@ -235,7 +245,7 @@ timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2; timeout += jiffies; do { - if (0 < (signed long)(jiffies - timeout)) { + if (time_after(jiffies, timeout)) { return 1; /* drive timed-out */ } ide_delay_50ms(); /* give drive a breather */ @@ -557,7 +567,7 @@ do { ide_delay_50ms(); stat = IN_BYTE(hwif->io_ports[IDE_STATUS_OFFSET]); - } while ((stat & BUSY_STAT) && 0 < (signed long)(timeout - jiffies)); + } while ((stat & BUSY_STAT) && time_after(timeout, jiffies)); } __restore_flags(flags); /* local CPU only */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ide-proc.c linux.19pre5-ac1/drivers/ide/ide-proc.c --- linux.19p5/drivers/ide/ide-proc.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/ide/ide-proc.c Thu Mar 21 01:04:05 2002 @@ -193,7 +193,7 @@ cli(); /* all CPUs; ensure all writes are done together */ while (mygroup->busy || (mategroup && mategroup->busy)) { sti(); /* all CPUs */ - if (0 < (signed long)(jiffies - timeout)) { + if (time_after(jiffies, timeout)) { printk("/proc/ide/%s/config: channel(s) busy, cannot write\n", hwif->name); restore_flags(flags); /* all CPUs */ return -EBUSY; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ide-tape.c linux.19pre5-ac1/drivers/ide/ide-tape.c --- linux.19p5/drivers/ide/ide-tape.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/ide/ide-tape.c Thu Mar 21 01:04:05 2002 @@ -1835,10 +1835,9 @@ * idetape_end_request is used to finish servicing a request, and to * insert a pending pipeline request into the main device queue. */ -static void idetape_end_request (byte uptodate, ide_hwgroup_t *hwgroup) +static int idetape_end_request (ide_drive_t *drive, int uptodate) { - ide_drive_t *drive = hwgroup->drive; - struct request *rq = hwgroup->rq; + struct request *rq = HWGROUP(drive)->rq; idetape_tape_t *tape = drive->driver_data; unsigned long flags; int error; @@ -1932,6 +1931,7 @@ if (tape->active_data_request == NULL) clear_bit(IDETAPE_PIPELINE_ACTIVE, &tape->flags); spin_unlock_irqrestore(&tape->spinlock, flags); + return 0; } static ide_startstop_t idetape_request_sense_callback (ide_drive_t *drive) @@ -1944,10 +1944,10 @@ #endif /* IDETAPE_DEBUG_LOG */ if (!tape->pc->error) { idetape_analyze_error (drive, (idetape_request_sense_result_t *) tape->pc->buffer); - idetape_end_request (1, HWGROUP (drive)); + idetape_end_request(drive, 1); } else { printk (KERN_ERR "ide-tape: Error in REQUEST SENSE itself - Aborting request!\n"); - idetape_end_request (0, HWGROUP (drive)); + idetape_end_request(drive, 0); } return ide_stopped; } @@ -2348,7 +2348,7 @@ printk (KERN_INFO "ide-tape: Reached idetape_pc_callback\n"); #endif /* IDETAPE_DEBUG_LOG */ - idetape_end_request (tape->pc->error ? 0 : 1, HWGROUP(drive)); + idetape_end_request(drive, tape->pc->error ? 0 : 1); return ide_stopped; } @@ -2397,7 +2397,7 @@ if (tape->debug_level >= 1) printk(KERN_INFO "ide-tape: buffer fill callback, %d/%d\n", tape->cur_frames, tape->max_frames); #endif - idetape_end_request (tape->pc->error ? 0 : 1, HWGROUP(drive)); + idetape_end_request(drive, tape->pc->error ? 0 : 1); return ide_stopped; } @@ -2517,9 +2517,9 @@ rq->current_nr_sectors -= blocks; if (!tape->pc->error) - idetape_end_request (1, HWGROUP (drive)); + idetape_end_request(drive, 1); else - idetape_end_request (tape->pc->error, HWGROUP (drive)); + idetape_end_request(drive, tape->pc->error); return ide_stopped; } @@ -2628,7 +2628,7 @@ * We do not support buffer cache originated requests. */ printk (KERN_NOTICE "ide-tape: %s: Unsupported command in request queue (%d)\n", drive->name, rq->cmd); - ide_end_request (0, HWGROUP (drive)); /* Let the common code handle it */ + ide_end_request(drive, 0); /* Let the common code handle it */ return ide_stopped; } @@ -2642,7 +2642,7 @@ if (postponed_rq != NULL) if (rq != postponed_rq) { printk (KERN_ERR "ide-tape: ide-tape.c bug - Two DSC requests were queued\n"); - idetape_end_request (0, HWGROUP (drive)); + idetape_end_request(drive, 0); return ide_stopped; } #endif /* IDETAPE_DEBUG_BUGS */ @@ -2770,7 +2770,7 @@ break; case IDETAPE_ABORTED_WRITE_RQ: rq->cmd = IDETAPE_WRITE_RQ; - idetape_end_request (IDETAPE_ERROR_EOD, HWGROUP(drive)); + idetape_end_request(drive, IDETAPE_ERROR_EOD); return ide_stopped; case IDETAPE_ABORTED_READ_RQ: #if IDETAPE_DEBUG_LOG @@ -2778,7 +2778,7 @@ printk(KERN_INFO "ide-tape: %s: detected aborted read rq\n", tape->name); #endif rq->cmd = IDETAPE_READ_RQ; - idetape_end_request (IDETAPE_ERROR_EOD, HWGROUP(drive)); + idetape_end_request(drive, IDETAPE_ERROR_EOD); return ide_stopped; case IDETAPE_PC_RQ1: pc = (idetape_pc_t *) rq->buffer; @@ -2789,7 +2789,7 @@ return ide_stopped; default: printk (KERN_ERR "ide-tape: bug in IDETAPE_RQ_CMD macro\n"); - idetape_end_request (0, HWGROUP (drive)); + idetape_end_request(drive, 0); return ide_stopped; } return idetape_issue_packet_command (drive, pc); @@ -3112,7 +3112,7 @@ if (result->bpu) { printk (KERN_INFO "ide-tape: Block location is unknown to the tape\n"); clear_bit (IDETAPE_ADDRESS_VALID, &tape->flags); - idetape_end_request (0, HWGROUP (drive)); + idetape_end_request(drive, 0); } else { #if IDETAPE_DEBUG_LOG if (tape->debug_level >= 2) @@ -3123,10 +3123,10 @@ tape->last_frame_position = ntohl (result->last_block); tape->blocks_in_buffer = result->blocks_in_buffer[2]; set_bit (IDETAPE_ADDRESS_VALID, &tape->flags); - idetape_end_request (1, HWGROUP (drive)); + idetape_end_request(drive, 1); } } else { - idetape_end_request (0, HWGROUP (drive)); + idetape_end_request(drive, 0); } return ide_stopped; } @@ -6132,6 +6132,7 @@ #endif +int idetape_init (void); int idetape_reinit(ide_drive_t *drive); /* @@ -6142,7 +6143,11 @@ version: IDETAPE_VERSION, media: ide_tape, busy: 1, +#ifdef CONFIG_IDEDMA_ONLYDISK + supports_dma: 0, +#else supports_dma: 1, +#endif supports_dsc_overlap: 1, cleanup: idetape_cleanup, standby: NULL, @@ -6157,6 +6162,7 @@ pre_reset: idetape_pre_reset, capacity: NULL, proc: idetape_proc, + init: idetape_init, reinit: idetape_reinit, ata_prebuilder: NULL, atapi_prebuilder: NULL, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ide-taskfile.c linux.19pre5-ac1/drivers/ide/ide-taskfile.c --- linux.19p5/drivers/ide/ide-taskfile.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/ide/ide-taskfile.c Thu Mar 21 01:04:19 2002 @@ -1,8 +1,11 @@ /* - * linux/drivers/ide/ide-taskfile.c Version 0.20 Oct 11, 2000 + * linux/drivers/ide/ide-taskfile.c Version 0.25 Jan 17, 2001 * - * Copyright (C) 2000 Michael Cornwell - * Copyright (C) 2000 Andre Hedrick + * Copyright (C) 2000-2002 Michael Cornwell + * Copyright (C) 2000-2002 Andre Hedrick + * + * BIO Glue Layer into 2.5.3-pre1,pre2 + * Jens Axboe * * May be copied or modified under the terms of the GNU General Public License * @@ -34,20 +37,41 @@ #include #include -#ifdef CONFIG_IDE_TASKFILE_IO -# define __TASKFILE__IO -#else /* CONFIG_IDE_TASKFILE_IO */ -# undef __TASKFILE__IO -#endif /* CONFIG_IDE_TASKFILE_IO */ - #define DEBUG_TASKFILE 0 /* unset when fixed */ #if DEBUG_TASKFILE -#define DTF(x...) printk(##x) +#define DTF(x...) printk(x) #else #define DTF(x...) #endif +/* + * + */ +#define task_rq_offset(rq) \ + (((rq)->nr_sectors - (rq)->current_nr_sectors) * SECTOR_SIZE) + +/* + * for now, taskfile requests are special :/ + * + * However, upon the creation of the atapi version of packet_command + * data-phase ISR plus it own diagnostics and extensions for direct access + * (ioctl,read,write,rip,stream -- atapi), the kmap/kunmap for PIO will + * come localized. + */ +inline char *task_map_rq (struct request *rq, unsigned long *flags) +{ + if (rq->bh) + return ide_map_buffer(rq, flags); + return rq->buffer + task_rq_offset(rq); +} + +inline void task_unmap_rq (struct request *rq, char *buf, unsigned long *flags) +{ + if (rq->bh) + ide_unmap_buffer(buf, flags); +} + inline u32 task_read_24 (ide_drive_t *drive) { return (IN_BYTE(IDE_HCYL_REG)<<16) | @@ -74,9 +98,9 @@ * to ensure that the reads all happen together. */ static inline void task_vlb_sync (ide_ioreg_t port) { - (void) inb (port); - (void) inb (port); - (void) inb (port); + (void) IN_BYTE (port); + (void) IN_BYTE (port); + (void) IN_BYTE (port); } #endif /* SUPPORT_VLB_SYNC */ @@ -85,7 +109,19 @@ */ void ata_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount) { - byte io_32bit = drive->io_32bit; + byte io_32bit; + + /* + * first check if this controller has defined a special function + * for handling polled ide transfers + */ + + if (HWIF(drive)->ideproc) { + HWIF(drive)->ideproc(ideproc_ide_input_data, drive, buffer, wcount); + return; + } + + io_32bit = drive->io_32bit; if (io_32bit) { #if SUPPORT_VLB_SYNC @@ -118,7 +154,14 @@ */ void ata_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount) { - byte io_32bit = drive->io_32bit; + byte io_32bit; + + if (HWIF(drive)->ideproc) { + HWIF(drive)->ideproc(ideproc_ide_output_data, drive, buffer, wcount); + return; + } + + io_32bit = drive->io_32bit; if (io_32bit) { #if SUPPORT_VLB_SYNC @@ -146,15 +189,61 @@ } } +/* + * The following routines are mainly used by the ATAPI drivers. + * + * These routines will round up any request for an odd number of bytes, + * so if an odd bytecount is specified, be sure that there's at least one + * extra byte allocated for the buffer. + */ +void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount) +{ + if (HWIF(drive)->ideproc) { + HWIF(drive)->ideproc(ideproc_atapi_input_bytes, drive, buffer, bytecount); + return; + } + + ++bytecount; +#if defined(CONFIG_ATARI) || defined(CONFIG_Q40) + if (MACH_IS_ATARI || MACH_IS_Q40) { + /* Atari has a byte-swapped IDE interface */ + insw_swapw(IDE_DATA_REG, buffer, bytecount / 2); + return; + } +#endif /* CONFIG_ATARI */ + ata_input_data (drive, buffer, bytecount / 4); + if ((bytecount & 0x03) >= 2) + insw (IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1); +} + +void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount) +{ + if (HWIF(drive)->ideproc) { + HWIF(drive)->ideproc(ideproc_atapi_output_bytes, drive, buffer, bytecount); + return; + } + + ++bytecount; +#if defined(CONFIG_ATARI) || defined(CONFIG_Q40) + if (MACH_IS_ATARI || MACH_IS_Q40) { + /* Atari has a byte-swapped IDE interface */ + outsw_swapw(IDE_DATA_REG, buffer, bytecount / 2); + return; + } +#endif /* CONFIG_ATARI */ + ata_output_data (drive, buffer, bytecount / 4); + if ((bytecount & 0x03) >= 2) + outsw (IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1); +} -static inline void taskfile_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount) +void taskfile_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount) { ata_input_data(drive, buffer, wcount); if (drive->bswap) ata_bswap_data(buffer, wcount); } -static inline void taskfile_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount) +void taskfile_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount) { if (drive->bswap) { ata_bswap_data(buffer, wcount); @@ -165,6 +254,63 @@ } } +/* + * Needed for PCI irq sharing + */ +int drive_is_ready (ide_drive_t *drive) +{ + byte stat = 0; + if (drive->waiting_for_dma) + return HWIF(drive)->dmaproc(ide_dma_test_irq, drive); +#if 0 + /* need to guarantee 400ns since last command was issued */ + udelay(1); +#endif + +#ifdef CONFIG_IDEPCI_SHARE_IRQ + /* + * We do a passive status test under shared PCI interrupts on + * cards that truly share the ATA side interrupt, but may also share + * an interrupt with another pci card/device. We make no assumptions + * about possible isa-pnp and pci-pnp issues yet. + */ + if (IDE_CONTROL_REG) + stat = GET_ALTSTAT(); + else +#endif /* CONFIG_IDEPCI_SHARE_IRQ */ + stat = GET_STAT(); /* Note: this may clear a pending IRQ!! */ + + if (stat & BUSY_STAT) + return 0; /* drive busy: definitely not interrupting */ + return 1; /* drive ready: *might* be interrupting */ +} + +/* + * Global for All, and taken from ide-pmac.c + */ +int wait_for_ready (ide_drive_t *drive, int timeout) +{ + byte stat = 0; + + while(--timeout) { + stat = GET_STAT(); + if(!(stat & BUSY_STAT)) { + if (drive->ready_stat == 0) + break; + else if((stat & drive->ready_stat) || (stat & ERR_STAT)) + break; + } + mdelay(1); + } + if((stat & ERR_STAT) || timeout <= 0) { + if (stat & ERR_STAT) { + printk(KERN_ERR "%s: wait_for_ready, error status: %x\n", drive->name, stat); + } + return 1; + } + return 0; +} + ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) { task_struct_t *taskfile = (task_struct_t *) task->tfRegister; @@ -172,12 +318,9 @@ struct hd_driveid *id = drive->id; byte HIHI = (drive->addressing) ? 0xE0 : 0xEF; - /* (ks/hs): Moved to start, do not use for multiple out commands */ - if (task->handler != task_mulout_intr) { - if (IDE_CONTROL_REG) - OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */ - SELECT_MASK(HWIF(drive), drive, 0); - } + if (IDE_CONTROL_REG) + OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */ + SELECT_MASK(HWIF(drive), drive, 0); if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400) && @@ -199,49 +342,11 @@ OUT_BYTE((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG); if (task->handler != NULL) { -#if 0 ide_set_handler (drive, task->handler, WAIT_CMD, NULL); OUT_BYTE(taskfile->command, IDE_COMMAND_REG); - /* - * warning check for race between handler and prehandler for - * writing first block of data. however since we are well - * inside the boundaries of the seek, we should be okay. - */ if (task->prehandler != NULL) { return task->prehandler(drive, task->rq); } -#else - ide_startstop_t startstop; - - ide_set_handler (drive, task->handler, WAIT_CMD, NULL); - OUT_BYTE(taskfile->command, IDE_COMMAND_REG); - - if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) { - printk(KERN_ERR "%s: no DRQ after issuing %s\n", - drive->name, - drive->mult_count ? "MULTWRITE" : "WRITE"); - return startstop; - } - /* (ks/hs): Fixed Multi Write */ - if ((taskfile->command != WIN_MULTWRITE) && - (taskfile->command != WIN_MULTWRITE_EXT)) { - struct request *rq = HWGROUP(drive)->rq; - /* For Write_sectors we need to stuff the first sector */ - taskfile_output_data(drive, rq->buffer, SECTOR_WORDS); - rq->current_nr_sectors--; - } else { - /* Stuff first sector(s) by implicitly calling the handler */ - if (!(drive_is_ready(drive))) { - /* FIXME: Replace hard-coded 100, error handling? */ - int i; - for (i=0; i<100; i++) { - if (drive_is_ready(drive)) - break; - } - } - return task->handler(drive); - } -#endif } else { /* for dma commands we down set the handler */ if (drive->using_dma && !(HWIF(drive)->dmaproc(((taskfile->command == WIN_WRITEDMA) || (taskfile->command == WIN_WRITEDMA_EXT)) ? ide_dma_write : ide_dma_read, drive))); @@ -255,12 +360,9 @@ struct hd_driveid *id = drive->id; byte HIHI = (drive->addressing) ? 0xE0 : 0xEF; - /* (ks/hs): Moved to start, do not use for multiple out commands */ - if (*handler != task_mulout_intr) { - if (IDE_CONTROL_REG) - OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */ - SELECT_MASK(HWIF(drive), drive, 0); - } + if (IDE_CONTROL_REG) + OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */ + SELECT_MASK(HWIF(drive), drive, 0); if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400) && @@ -366,54 +468,11 @@ */ OUT_BYTE(taskfile->device_head | drive->select.all, IDE_SELECT_REG); if (task->handler != NULL) { -#if 0 ide_set_handler (drive, task->handler, WAIT_CMD, NULL); OUT_BYTE(taskfile->command, IDE_COMMAND_REG); - /* - * warning check for race between handler and prehandler for - * writing first block of data. however since we are well - * inside the boundaries of the seek, we should be okay. - */ if (task->prehandler != NULL) { return task->prehandler(drive, task->rq); } -#else - ide_startstop_t startstop; - - ide_set_handler (drive, task->handler, WAIT_CMD, NULL); - - /* - * (KS) The drive command register is also mandatory. - * Don't care about the out flags ! - */ - OUT_BYTE(taskfile->command, IDE_COMMAND_REG); - - if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) { - printk(KERN_ERR "%s: no DRQ after issuing %s\n", - drive->name, - drive->mult_count ? "MULTWRITE" : "WRITE"); - return startstop; - } - /* (ks/hs): Fixed Multi Write */ - if ((taskfile->command != WIN_MULTWRITE) && - (taskfile->command != WIN_MULTWRITE_EXT)) { - struct request *rq = HWGROUP(drive)->rq; - /* For Write_sectors we need to stuff the first sector */ - taskfile_output_data(drive, rq->buffer, SECTOR_WORDS); - rq->current_nr_sectors--; - } else { - /* Stuff first sector(s) by implicitly calling the handler */ - if (!(drive_is_ready(drive))) { - /* FIXME: Replace hard-coded 100, error handling? */ - int i; - for (i=0; i<100; i++) { - if (drive_is_ready(drive)) - break; - } - } - return task->handler(drive); - } -#endif } else { /* for dma commands we down set the handler */ if (drive->using_dma && !(HWIF(drive)->dmaproc(((taskfile->command == WIN_WRITEDMA) || (taskfile->command == WIN_WRITEDMA_EXT)) ? ide_dma_write : ide_dma_read, drive))); @@ -609,9 +668,9 @@ if (rq->errors >= ERROR_MAX) { if (drive->driver != NULL) - DRIVER(drive)->end_request(0, HWGROUP(drive)); + DRIVER(drive)->end_request(drive, 0); else - ide_end_request(0, HWGROUP(drive)); + ide_end_request(drive, 0); } else { if ((rq->errors & ERROR_RESET) == ERROR_RESET) { ++rq->errors; @@ -686,8 +745,8 @@ ide__sti(); /* local CPU only */ if (!OK_STAT(stat, READY_STAT, BAD_STAT)) - return ide_error(drive, "task_no_data_intr", stat); /* calls ide_end_drive_cmd */ - + return ide_error(drive, "task_no_data_intr", stat); + /* calls ide_end_drive_cmd */ if (args) ide_end_drive_cmd (drive, stat, GET_ERR()); @@ -695,7 +754,7 @@ } /* - * Handler for command with PIO data-in phase + * Handler for command with PIO data-in phase, READ */ ide_startstop_t task_in_intr (ide_drive_t *drive) { @@ -703,34 +762,54 @@ byte io_32bit = drive->io_32bit; struct request *rq = HWGROUP(drive)->rq; char *pBuf = NULL; + unsigned long flags; if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) { if (stat & (ERR_STAT|DRQ_STAT)) { + DTF("%s: attempting to recover last " \ + "sector counter status=0x%02x\n", + drive->name, stat); + rq->current_nr_sectors++; return ide_error(drive, "task_in_intr", stat); } if (!(stat & BUSY_STAT)) { DTF("task_in_intr to Soon wait for next interrupt\n"); - ide_set_handler(drive, &task_in_intr, WAIT_CMD, NULL); + if (HWGROUP(drive)->handler == NULL) + ide_set_handler(drive, &task_in_intr, WAIT_CMD, NULL); return ide_started; } } - DTF("stat: %02x\n", stat); - pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE); - DTF("Read: %p, rq->current_nr_sectors: %d\n", pBuf, (int) rq->current_nr_sectors); +#if 0 + + if (!OK_STAT(stat,DRIVE_READY,drive->bad_wstat)) { + DTF("%s: READ attempting to recover last " \ + "sector counter status=0x%02x\n", + drive->name, stat); + rq->current_nr_sectors++; + return ide_error(drive, "task_in_intr", stat); + } + if (!rq->current_nr_sectors) + if (!ide_end_request(drive, 1)) + return ide_stopped; + + if (--rq->current_nr_sectors <= 0) + if (!ide_end_request(drive, 1)) + return ide_stopped; +#endif + pBuf = task_map_rq(rq, &flags); + DTF("Read: %p, rq->current_nr_sectors: %d, stat: %02x\n", + pBuf, (int) rq->current_nr_sectors, stat); drive->io_32bit = 0; taskfile_input_data(drive, pBuf, SECTOR_WORDS); + task_unmap_rq(rq, pBuf, &flags); drive->io_32bit = io_32bit; - - if (--rq->current_nr_sectors <= 0) { - /* (hs): swapped next 2 lines */ - DTF("Request Ended stat: %02x\n", GET_STAT()); - ide_end_request(1, HWGROUP(drive)); - } else { + if (--rq->current_nr_sectors <= 0) + if (!ide_end_request(drive, 1)) + return ide_stopped; + if (HWGROUP(drive)->handler == NULL) ide_set_handler(drive, &task_in_intr, WAIT_CMD, NULL); - return ide_started; - } - return ide_stopped; + return ide_started; } #undef ALTSTAT_SCREW_UP @@ -778,30 +857,31 @@ */ ide_startstop_t task_mulin_intr (ide_drive_t *drive) { - unsigned int msect, nsect; - #ifdef ALTSTAT_SCREW_UP byte stat = altstat_multi_busy(drive, GET_ALTSTAT(), "read"); #else byte stat = GET_STAT(); #endif /* ALTSTAT_SCREW_UP */ - byte io_32bit = drive->io_32bit; struct request *rq = HWGROUP(drive)->rq; char *pBuf = NULL; + unsigned int msect = drive->mult_count; + unsigned int nsect; + unsigned long flags; if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) { if (stat & (ERR_STAT|DRQ_STAT)) { + printk("%s: MULTI-READ assume all data transfered " \ + "is bad status=0x%02x\n", + drive->name, stat); return ide_error(drive, "task_mulin_intr", stat); } /* no data yet, so wait for another interrupt */ - ide_set_handler(drive, &task_mulin_intr, WAIT_CMD, NULL); + if (HWGROUP(drive)->handler == NULL) + ide_set_handler(drive, &task_mulin_intr, WAIT_CMD, NULL); return ide_started; } - /* (ks/hs): Fixed Multi-Sector transfer */ - msect = drive->mult_count; - #ifdef ALTSTAT_SCREW_UP /* * Screw the request we do not support bad data-phase setups! @@ -814,78 +894,71 @@ */ nsect = 1; while (rq->current_nr_sectors) { - pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE); - DTF("Multiread: %p, nsect: %d, rq->current_nr_sectors: %ld\n", pBuf, nsect, rq->current_nr_sectors); + pBuf = task_map_rq(rq, &flags); + DTF("Multiread: %p, nsect: %d, " \ + "rq->current_nr_sectors: %ld\n", + pBuf, nsect, rq->current_nr_sectors); drive->io_32bit = 0; taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS); + task_unmap_rq(rq, pBuf, &flags); drive->io_32bit = io_32bit; rq->errors = 0; rq->current_nr_sectors -= nsect; stat = altstat_multi_poll(drive, GET_ALTSTAT(), "read"); } - ide_end_request(1, HWGROUP(drive)); + ide_end_request(drive, 1); return ide_stopped; } #endif /* ALTSTAT_SCREW_UP */ - nsect = (rq->current_nr_sectors > msect) ? msect : rq->current_nr_sectors; - pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE); - - DTF("Multiread: %p, nsect: %d , rq->current_nr_sectors: %ld\n", - pBuf, nsect, rq->current_nr_sectors); - drive->io_32bit = 0; - taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS); - drive->io_32bit = io_32bit; - rq->errors = 0; - rq->current_nr_sectors -= nsect; - if (rq->current_nr_sectors != 0) { + do { + nsect = rq->current_nr_sectors; + if (nsect > msect) + nsect = msect; + pBuf = task_map_rq(rq, &flags); + DTF("Multiread: %p, nsect: %d, msect: %d, " \ + " rq->current_nr_sectors: %d\n", + pBuf, nsect, msect, rq->current_nr_sectors); + drive->io_32bit = 0; + taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS); + task_unmap_rq(rq, pBuf, &flags); + drive->io_32bit = io_32bit; + rq->errors = 0; + rq->current_nr_sectors -= nsect; + msect -= nsect; + if (!rq->current_nr_sectors) { + if (!ide_end_request(drive, 1)) + return ide_stopped; + } + } while (msect); + if (HWGROUP(drive)->handler == NULL) ide_set_handler(drive, &task_mulin_intr, WAIT_CMD, NULL); - return ide_started; - } - ide_end_request(1, HWGROUP(drive)); - return ide_stopped; + return ide_started; } ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq) { - ide_task_t *args = rq->special; + char *pBuf = NULL; + unsigned long flags; ide_startstop_t startstop; - if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) { - printk(KERN_ERR "%s: no DRQ after issuing %s\n", drive->name, drive->mult_count ? "MULTWRITE" : "WRITE"); + if (ide_wait_stat(&startstop, drive, DATA_READY, + drive->bad_wstat, WAIT_DRQ)) { + printk(KERN_ERR "%s: no DRQ after issuing %s\n", + drive->name, + drive->addressing ? "WRITE_EXT" : "WRITE"); return startstop; } - - /* (ks/hs): Fixed Multi Write */ - if ((args->tfRegister[IDE_COMMAND_OFFSET] != WIN_MULTWRITE) && - (args->tfRegister[IDE_COMMAND_OFFSET] != WIN_MULTWRITE_EXT)) { - /* For Write_sectors we need to stuff the first sector */ - taskfile_output_data(drive, rq->buffer, SECTOR_WORDS); - rq->current_nr_sectors--; - return ide_started; - } else { - /* - * (ks/hs): Stuff the first sector(s) - * by implicitly calling the handler - */ - if (!(drive_is_ready(drive))) { - int i; - /* - * (ks/hs): FIXME: Replace hard-coded - * 100, error handling? - */ - for (i=0; i<100; i++) { - if (drive_is_ready(drive)) - break; - } - } - return args->handler(drive); - } + /* For Write_sectors we need to stuff the first sector */ + pBuf = task_map_rq(rq, &flags); + taskfile_output_data(drive, pBuf, SECTOR_WORDS); + rq->current_nr_sectors--; + task_unmap_rq(rq, pBuf, &flags); return ide_started; } /* - * Handler for command with PIO data-out phase + * Handler for command with PIO data-out phase WRITE */ ide_startstop_t task_out_intr (ide_drive_t *drive) { @@ -893,33 +966,67 @@ byte io_32bit = drive->io_32bit; struct request *rq = HWGROUP(drive)->rq; char *pBuf = NULL; - - if (!rq->current_nr_sectors) { - ide_end_request(1, HWGROUP(drive)); - return ide_stopped; - } + unsigned long flags; if (!OK_STAT(stat,DRIVE_READY,drive->bad_wstat)) { + DTF("%s: WRITE attempting to recover last " \ + "sector counter status=0x%02x\n", + drive->name, stat); + rq->current_nr_sectors++; return ide_error(drive, "task_out_intr", stat); } + if (!rq->current_nr_sectors) + if (!ide_end_request(drive, 1)) + return ide_stopped; if ((rq->current_nr_sectors==1) ^ (stat & DRQ_STAT)) { rq = HWGROUP(drive)->rq; - pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE); - DTF("write: %p, rq->current_nr_sectors: %d\n", pBuf, (int) rq->current_nr_sectors); + pBuf = task_map_rq(rq, &flags); + DTF("write: %p, rq->current_nr_sectors: %d\n", + pBuf, (int) rq->current_nr_sectors); drive->io_32bit = 0; taskfile_output_data(drive, pBuf, SECTOR_WORDS); + task_unmap_rq(rq, pBuf, &flags); drive->io_32bit = io_32bit; rq->errors = 0; rq->current_nr_sectors--; } - - if (rq->current_nr_sectors <= 0) { - ide_end_request(1, HWGROUP(drive)); - } else { + if (HWGROUP(drive)->handler == NULL) ide_set_handler(drive, &task_out_intr, WAIT_CMD, NULL); - return ide_started; + return ide_started; +} + +ide_startstop_t pre_task_mulout_intr (ide_drive_t *drive, struct request *rq) +{ + ide_task_t *args = rq->special; + ide_startstop_t startstop; + +#if 0 + /* + * assign private copy for multi-write + */ + memcpy(&HWGROUP(drive)->wrq, rq, sizeof(struct request)); +#endif + + if (ide_wait_stat(&startstop, drive, DATA_READY, + drive->bad_wstat, WAIT_DRQ)) { + printk(KERN_ERR "%s: no DRQ after issuing %s\n", + drive->name, + drive->addressing ? "MULTWRITE_EXT" : "MULTWRITE"); + return startstop; } - return ide_stopped; +#if 0 + if (wait_for_ready(drive, 100)) + IDE_DEBUG(__LINE__); //BUG(); +#else + if (!(drive_is_ready(drive))) { + int i; + for (i=0; i<100; i++) { + if (drive_is_ready(drive)) + break; + } + } +#endif + return args->handler(drive); } /* @@ -929,42 +1036,55 @@ */ ide_startstop_t task_mulout_intr (ide_drive_t *drive) { - unsigned int msect, nsect; - #ifdef ALTSTAT_SCREW_UP byte stat = altstat_multi_busy(drive, GET_ALTSTAT(), "write"); #else byte stat = GET_STAT(); #endif /* ALTSTAT_SCREW_UP */ - byte io_32bit = drive->io_32bit; - struct request *rq = HWGROUP(drive)->rq; - ide_hwgroup_t *hwgroup = HWGROUP(drive); - char *pBuf = NULL; + byte io_32bit = drive->io_32bit; + struct request *rq = HWGROUP(drive)->rq; + char *pBuf = NULL; + ide_startstop_t startstop = ide_stopped; + unsigned int msect = drive->mult_count; + unsigned int nsect; + unsigned long flags; /* * (ks/hs): Handle last IRQ on multi-sector transfer, - * occurs after all data was sent + * occurs after all data was sent in this chunk */ if (rq->current_nr_sectors == 0) { - if (stat & (ERR_STAT|DRQ_STAT)) + if (stat & (ERR_STAT|DRQ_STAT)) { + printk("%s: MULTI-WRITE assume all data transfered " \ + "is bad status=0x%02x\n", + drive->name, stat); return ide_error(drive, "task_mulout_intr", stat); - ide_end_request(1, HWGROUP(drive)); - return ide_stopped; + } + if (!rq->bh) + ide_end_request(drive, 1); + return startstop; } - if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) { if (stat & (ERR_STAT|DRQ_STAT)) { + printk("%s: MULTI-WRITE assume all data transfered " \ + "is bad status=0x%02x\n", + drive->name, stat); return ide_error(drive, "task_mulout_intr", stat); } /* no data yet, so wait for another interrupt */ - if (hwgroup->handler == NULL) + if (HWGROUP(drive)->handler == NULL) ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL); return ide_started; } - /* (ks/hs): See task_mulin_intr */ - msect = drive->mult_count; + if (HWGROUP(drive)->handler != NULL) { + unsigned long lflags; + spin_lock_irqsave(&io_request_lock, lflags); + HWGROUP(drive)->handler = NULL; + del_timer(&HWGROUP(drive)->timer); + spin_unlock_irqrestore(&io_request_lock, lflags); + } #ifdef ALTSTAT_SCREW_UP /* @@ -974,30 +1094,45 @@ if (!msect) { nsect = 1; while (rq->current_nr_sectors) { - pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE); - DTF("Multiwrite: %p, nsect: %d, rq->current_nr_sectors: %ld\n", pBuf, nsect, rq->current_nr_sectors); + pBuf = task_map_rq(rq, &flags); + DTF("Multiwrite: %p, nsect: %d, " \ + "rq->current_nr_sectors: %d\n", + pBuf, nsect, rq->current_nr_sectors); drive->io_32bit = 0; taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS); + task_unmap_rq(pBuf, &flags); drive->io_32bit = io_32bit; rq->errors = 0; rq->current_nr_sectors -= nsect; stat = altstat_multi_poll(drive, GET_ALTSTAT(), "write"); } - ide_end_request(1, HWGROUP(drive)); + ide_end_request(drive, 1); return ide_stopped; } #endif /* ALTSTAT_SCREW_UP */ - nsect = (rq->current_nr_sectors > msect) ? msect : rq->current_nr_sectors; - pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE); - DTF("Multiwrite: %p, nsect: %d , rq->current_nr_sectors: %ld\n", - pBuf, nsect, rq->current_nr_sectors); - drive->io_32bit = 0; - taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS); - drive->io_32bit = io_32bit; + do { + nsect = rq->current_nr_sectors; + if (nsect > msect) + nsect = msect; + pBuf = task_map_rq(rq, &flags); + DTF("Multiwrite: %p, nsect: %d, msect: %d, " \ + "rq->current_nr_sectors: %ld\n", + pBuf, nsect, msect, rq->current_nr_sectors); + msect -= nsect; + drive->io_32bit = 0; + taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS); + task_unmap_rq(rq, pBuf, &flags); + rq->current_nr_sectors -= nsect; + drive->io_32bit = io_32bit; + if (!rq->current_nr_sectors) { + if (!ide_end_request(drive, 1)) + if (!rq->bh) + return ide_stopped; + } + } while (msect); rq->errors = 0; - rq->current_nr_sectors -= nsect; - if (hwgroup->handler == NULL) + if (HWGROUP(drive)->handler == NULL) ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL); return ide_started; } @@ -1010,12 +1145,10 @@ case CFA_WRITE_MULTI_WO_ERASE: case WIN_MULTWRITE: case WIN_MULTWRITE_EXT: -// case WIN_WRITEDMA: -// case WIN_WRITEDMA_QUEUED: -// case WIN_WRITEDMA_EXT: -// case WIN_WRITEDMA_QUEUED_EXT: + return &pre_task_mulout_intr; /* IDE_DRIVE_TASK_OUT */ case WIN_WRITE: + case WIN_WRITE_EXT: case WIN_WRITE_VERIFY: case WIN_WRITE_BUFFER: case CFA_WRITE_SECT_WO_ERASE: @@ -1025,6 +1158,11 @@ case WIN_SMART: if (taskfile->feature == SMART_WRITE_LOG_SECTOR) return &pre_task_out_intr; + case WIN_WRITEDMA: + case WIN_WRITEDMA_QUEUED: + case WIN_WRITEDMA_EXT: + case WIN_WRITEDMA_QUEUED_EXT: + /* IDE_DRIVE_TASK_OUT */ default: break; } @@ -1130,14 +1268,26 @@ } } +ide_post_handler_t * ide_post_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile) +{ + switch(taskfile->command) { + case WIN_SPECIFY: /* set_geometry_intr */ + case WIN_RESTORE: /* recal_intr */ + case WIN_SETMULT: /* set_multmode_intr */ + default: + return(NULL); + } +} + /* Called by ioctl to feature out type of command being called */ int ide_cmd_type_parser (ide_task_t *args) { struct hd_drive_task_hdr *taskfile = (struct hd_drive_task_hdr *) args->tfRegister; struct hd_drive_hob_hdr *hobfile = (struct hd_drive_hob_hdr *) args->hobRegister; - args->prehandler = ide_pre_handler_parser(taskfile, hobfile); - args->handler = ide_handler_parser(taskfile, hobfile); + args->prehandler = ide_pre_handler_parser(taskfile, hobfile); + args->handler = ide_handler_parser(taskfile, hobfile); + args->posthandler = ide_post_handler_parser(taskfile, hobfile); switch(args->tfRegister[IDE_COMMAND_OFFSET]) { case WIN_IDENTIFY: @@ -1145,18 +1295,22 @@ return IDE_DRIVE_TASK_IN; case CFA_TRANSLATE_SECTOR: case WIN_READ: + case WIN_READ_EXT: case WIN_READ_BUFFER: return IDE_DRIVE_TASK_IN; case WIN_WRITE: + case WIN_WRITE_EXT: case WIN_WRITE_VERIFY: case WIN_WRITE_BUFFER: case CFA_WRITE_SECT_WO_ERASE: case WIN_DOWNLOAD_MICROCODE: return IDE_DRIVE_TASK_RAW_WRITE; case WIN_MULTREAD: + case WIN_MULTREAD_EXT: return IDE_DRIVE_TASK_IN; case CFA_WRITE_MULTI_WO_ERASE: case WIN_MULTWRITE: + case WIN_MULTWRITE_EXT: return IDE_DRIVE_TASK_RAW_WRITE; case WIN_SECURITY_DISABLE: case WIN_SECURITY_ERASE_UNIT: @@ -1299,6 +1453,7 @@ args.command_type = ide_cmd_type_parser (&args); if (args.command_type != IDE_DRIVE_TASK_NO_DATA) rq.current_nr_sectors = rq.nr_sectors = (hobfile->sector_count << 8) | taskfile->sector_count; + /* rq.hard_cur_sectors */ rq.cmd = IDE_DRIVE_TASKFILE; rq.buffer = buf; @@ -1315,6 +1470,14 @@ if (args->command_type != IDE_DRIVE_TASK_NO_DATA) rq.current_nr_sectors = rq.nr_sectors = (args->hobRegister[IDE_NSECTOR_OFFSET_HOB] << 8) | args->tfRegister[IDE_NSECTOR_OFFSET]; + /* rq.hard_cur_sectors */ + + /* + * clean up kernel settings to keep the driver sane, regardless. + */ + args->posthandler = ide_post_handler_parser( + (struct hd_drive_task_hdr *) args->tfRegister, + (struct hd_drive_hob_hdr *) args->hobRegister); rq.special = args; return ide_do_drive_cmd(drive, &rq, ide_wait); @@ -1333,41 +1496,6 @@ } #endif /* CONFIG_IDE_TASK_IOCTL_DEBUG */ -/* - * The taskfile glue table - * - * reqtask.data_phase reqtask.req_cmd - * args.command_type args.handler - * - * TASKFILE_P_OUT_DMAQ ?? ?? - * TASKFILE_P_IN_DMAQ ?? ?? - * TASKFILE_P_OUT_DMA ?? ?? - * TASKFILE_P_IN_DMA ?? ?? - * TASKFILE_P_OUT ?? ?? - * TASKFILE_P_IN ?? ?? - * - * TASKFILE_OUT_DMAQ IDE_DRIVE_TASK_RAW_WRITE NULL - * TASKFILE_IN_DMAQ IDE_DRIVE_TASK_IN NULL - * - * TASKFILE_OUT_DMA IDE_DRIVE_TASK_RAW_WRITE NULL - * TASKFILE_IN_DMA IDE_DRIVE_TASK_IN NULL - * - * TASKFILE_IN_OUT ?? ?? - * - * TASKFILE_MULTI_OUT IDE_DRIVE_TASK_RAW_WRITE task_mulout_intr - * TASKFILE_MULTI_IN IDE_DRIVE_TASK_IN task_mulin_intr - * - * TASKFILE_OUT IDE_DRIVE_TASK_RAW_WRITE task_out_intr - * TASKFILE_OUT IDE_DRIVE_TASK_OUT task_out_intr - * - * TASKFILE_IN IDE_DRIVE_TASK_IN task_in_intr - * TASKFILE_NO_DATA IDE_DRIVE_TASK_NO_DATA task_no_data_intr - * - * IDE_DRIVE_TASK_SET_XFER task_no_data_intr - * IDE_DRIVE_TASK_INVALID - * - */ - #define MAX_DMA (256*SECTOR_WORDS) int ide_taskfile_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) @@ -1472,7 +1600,7 @@ #endif case TASKFILE_MULTI_OUT: if (drive->mult_count) { - args.prehandler = &pre_task_out_intr; + args.prehandler = &pre_task_mulout_intr; args.handler = &task_mulout_intr; args.posthandler = NULL; err = ide_raw_taskfile(drive, &args, outbuf); @@ -1558,7 +1686,82 @@ return err; } +int ide_cmd_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + int err = 0; + byte args[4], *argbuf = args; + byte xfer_rate = 0; + int argsize = 4; + ide_task_t tfargs; + + if (NULL == (void *) arg) { + struct request rq; + ide_init_drive_cmd(&rq); + return ide_do_drive_cmd(drive, &rq, ide_wait); + } + if (copy_from_user(args, (void *)arg, 4)) + return -EFAULT; + + tfargs.tfRegister[IDE_FEATURE_OFFSET] = args[2]; + tfargs.tfRegister[IDE_NSECTOR_OFFSET] = args[3]; + tfargs.tfRegister[IDE_SECTOR_OFFSET] = args[1]; + tfargs.tfRegister[IDE_LCYL_OFFSET] = 0x00; + tfargs.tfRegister[IDE_HCYL_OFFSET] = 0x00; + tfargs.tfRegister[IDE_SELECT_OFFSET] = 0x00; + tfargs.tfRegister[IDE_COMMAND_OFFSET] = args[0]; + + if (args[3]) { + argsize = 4 + (SECTOR_WORDS * 4 * args[3]); + argbuf = kmalloc(argsize, GFP_KERNEL); + if (argbuf == NULL) + return -ENOMEM; + memcpy(argbuf, args, 4); + } + if (set_transfer(drive, &tfargs)) { + xfer_rate = args[1]; + if (ide_ata66_check(drive, &tfargs)) + goto abort; + } + + err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf); + + if (!err && xfer_rate) { + /* active-retuning-calls future */ + if ((HWIF(drive)->speedproc) != NULL) + HWIF(drive)->speedproc(drive, xfer_rate); + ide_driveid_update(drive); + } +abort: + if (copy_to_user((void *)arg, argbuf, argsize)) + err = -EFAULT; + if (argsize > 4) + kfree(argbuf); + return err; +} + +int ide_task_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + int err = 0; + byte args[7], *argbuf = args; + int argsize = 7; + + if (copy_from_user(args, (void *)arg, 7)) + return -EFAULT; + err = ide_wait_cmd_task(drive, argbuf); + if (copy_to_user((void *)arg, argbuf, argsize)) + err = -EFAULT; + return err; +} + +EXPORT_SYMBOL(drive_is_ready); +EXPORT_SYMBOL(wait_for_ready); EXPORT_SYMBOL(task_read_24); +EXPORT_SYMBOL(ata_input_data); +EXPORT_SYMBOL(ata_output_data); +EXPORT_SYMBOL(atapi_input_bytes); +EXPORT_SYMBOL(atapi_output_bytes); +EXPORT_SYMBOL(taskfile_input_data); +EXPORT_SYMBOL(taskfile_output_data); EXPORT_SYMBOL(do_rw_taskfile); EXPORT_SYMBOL(do_taskfile); // EXPORT_SYMBOL(flagged_taskfile); @@ -1574,6 +1777,7 @@ EXPORT_SYMBOL(task_mulin_intr); EXPORT_SYMBOL(pre_task_out_intr); EXPORT_SYMBOL(task_out_intr); +EXPORT_SYMBOL(pre_task_mulout_intr); EXPORT_SYMBOL(task_mulout_intr); EXPORT_SYMBOL(ide_init_drive_taskfile); @@ -1581,8 +1785,12 @@ EXPORT_SYMBOL(ide_raw_taskfile); EXPORT_SYMBOL(ide_pre_handler_parser); EXPORT_SYMBOL(ide_handler_parser); +EXPORT_SYMBOL(ide_post_handler_parser); EXPORT_SYMBOL(ide_cmd_type_parser); EXPORT_SYMBOL(ide_taskfile_ioctl); +EXPORT_SYMBOL(ide_cmd_ioctl); +EXPORT_SYMBOL(ide_task_ioctl); + #ifdef CONFIG_PKT_TASK_IOCTL diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ide.c linux.19pre5-ac1/drivers/ide/ide.c --- linux.19p5/drivers/ide/ide.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/ide/ide.c Thu Mar 21 01:04:19 2002 @@ -373,198 +373,17 @@ return system_bus_speed; } -#if SUPPORT_VLB_SYNC -/* - * Some localbus EIDE interfaces require a special access sequence - * when using 32-bit I/O instructions to transfer data. We call this - * the "vlb_sync" sequence, which consists of three successive reads - * of the sector count register location, with interrupts disabled - * to ensure that the reads all happen together. - */ -static inline void do_vlb_sync (ide_ioreg_t port) { - (void) inb (port); - (void) inb (port); - (void) inb (port); -} -#endif /* SUPPORT_VLB_SYNC */ - -/* - * This is used for most PIO data transfers *from* the IDE interface - */ -void ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount) -{ - byte io_32bit; - - /* first check if this controller has defined a special function - * for handling polled ide transfers - */ - - if(HWIF(drive)->ideproc) { - HWIF(drive)->ideproc(ideproc_ide_input_data, - drive, buffer, wcount); - return; - } - - io_32bit = drive->io_32bit; - - if (io_32bit) { -#if SUPPORT_VLB_SYNC - if (io_32bit & 2) { - unsigned long flags; - __save_flags(flags); /* local CPU only */ - __cli(); /* local CPU only */ - do_vlb_sync(IDE_NSECTOR_REG); - insl(IDE_DATA_REG, buffer, wcount); - __restore_flags(flags); /* local CPU only */ - } else -#endif /* SUPPORT_VLB_SYNC */ - insl(IDE_DATA_REG, buffer, wcount); - } else { -#if SUPPORT_SLOW_DATA_PORTS - if (drive->slow) { - unsigned short *ptr = (unsigned short *) buffer; - while (wcount--) { - *ptr++ = inw_p(IDE_DATA_REG); - *ptr++ = inw_p(IDE_DATA_REG); - } - } else -#endif /* SUPPORT_SLOW_DATA_PORTS */ - insw(IDE_DATA_REG, buffer, wcount<<1); - } -} - -/* - * This is used for most PIO data transfers *to* the IDE interface - */ -void ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount) -{ - byte io_32bit; - - if(HWIF(drive)->ideproc) { - HWIF(drive)->ideproc(ideproc_ide_output_data, - drive, buffer, wcount); - return; - } - - io_32bit = drive->io_32bit; - - if (io_32bit) { -#if SUPPORT_VLB_SYNC - if (io_32bit & 2) { - unsigned long flags; - __save_flags(flags); /* local CPU only */ - __cli(); /* local CPU only */ - do_vlb_sync(IDE_NSECTOR_REG); - outsl(IDE_DATA_REG, buffer, wcount); - __restore_flags(flags); /* local CPU only */ - } else -#endif /* SUPPORT_VLB_SYNC */ - outsl(IDE_DATA_REG, buffer, wcount); - } else { -#if SUPPORT_SLOW_DATA_PORTS - if (drive->slow) { - unsigned short *ptr = (unsigned short *) buffer; - while (wcount--) { - outw_p(*ptr++, IDE_DATA_REG); - outw_p(*ptr++, IDE_DATA_REG); - } - } else -#endif /* SUPPORT_SLOW_DATA_PORTS */ - outsw(IDE_DATA_REG, buffer, wcount<<1); - } -} - -/* - * The following routines are mainly used by the ATAPI drivers. - * - * These routines will round up any request for an odd number of bytes, - * so if an odd bytecount is specified, be sure that there's at least one - * extra byte allocated for the buffer. - */ -void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount) -{ - if(HWIF(drive)->ideproc) { - HWIF(drive)->ideproc(ideproc_atapi_input_bytes, - drive, buffer, bytecount); - return; - } - - ++bytecount; -#if defined(CONFIG_ATARI) || defined(CONFIG_Q40) - if (MACH_IS_ATARI || MACH_IS_Q40) { - /* Atari has a byte-swapped IDE interface */ - insw_swapw(IDE_DATA_REG, buffer, bytecount / 2); - return; - } -#endif /* CONFIG_ATARI */ - ide_input_data (drive, buffer, bytecount / 4); - if ((bytecount & 0x03) >= 2) - insw (IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1); -} - -void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount) -{ - if(HWIF(drive)->ideproc) { - HWIF(drive)->ideproc(ideproc_atapi_output_bytes, - drive, buffer, bytecount); - return; - } - - ++bytecount; -#if defined(CONFIG_ATARI) || defined(CONFIG_Q40) - if (MACH_IS_ATARI || MACH_IS_Q40) { - /* Atari has a byte-swapped IDE interface */ - outsw_swapw(IDE_DATA_REG, buffer, bytecount / 2); - return; - } -#endif /* CONFIG_ATARI */ - ide_output_data (drive, buffer, bytecount / 4); - if ((bytecount & 0x03) >= 2) - outsw (IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1); -} - -/* - * Needed for PCI irq sharing - */ -//static inline -int drive_is_ready (ide_drive_t *drive) -{ - byte stat = 0; - if (drive->waiting_for_dma) - return HWIF(drive)->dmaproc(ide_dma_test_irq, drive); -#if 0 - udelay(1); /* need to guarantee 400ns since last command was issued */ -#endif - -#ifdef CONFIG_IDEPCI_SHARE_IRQ - /* - * We do a passive status test under shared PCI interrupts on - * cards that truly share the ATA side interrupt, but may also share - * an interrupt with another pci card/device. We make no assumptions - * about possible isa-pnp and pci-pnp issues yet. - */ - if (IDE_CONTROL_REG) - stat = GET_ALTSTAT(); - else -#endif /* CONFIG_IDEPCI_SHARE_IRQ */ - stat = GET_STAT(); /* Note: this may clear a pending IRQ!! */ - - if (stat & BUSY_STAT) - return 0; /* drive busy: definitely not interrupting */ - return 1; /* drive ready: *might* be interrupting */ -} - /* * This is our end_request replacement function. */ -void ide_end_request (byte uptodate, ide_hwgroup_t *hwgroup) +int ide_end_request (ide_drive_t *drive, int uptodate) { struct request *rq; unsigned long flags; - ide_drive_t *drive = hwgroup->drive; + int ret = 1; spin_lock_irqsave(&io_request_lock, flags); - rq = hwgroup->rq; + rq = HWGROUP(drive)->rq; /* * decide whether to reenable DMA -- 3 is a random magic for now, @@ -572,16 +391,18 @@ */ if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) { drive->state = 0; - hwgroup->hwif->dmaproc(ide_dma_on, drive); + HWGROUP(drive)->hwif->dmaproc(ide_dma_on, drive); } - if (!end_that_request_first(rq, uptodate, hwgroup->drive->name)) { + if (!end_that_request_first(rq, uptodate, drive->name)) { add_blkdev_randomness(MAJOR(rq->rq_dev)); blkdev_dequeue_request(rq); - hwgroup->rq = NULL; + HWGROUP(drive)->rq = NULL; end_that_request_last(rq); + ret = 0; } spin_unlock_irqrestore(&io_request_lock, flags); + return ret; } /* @@ -666,7 +487,7 @@ if (OK_STAT(stat=GET_STAT(), 0, BUSY_STAT)) { printk("%s: ATAPI reset complete\n", drive->name); } else { - if (0 < (signed long)(hwgroup->poll_timeout - jiffies)) { + if (time_before(jiffies, hwgroup->poll_timeout)) { ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20, NULL); return ide_started; /* continue polling */ } @@ -691,7 +512,7 @@ byte tmp; if (!OK_STAT(tmp=GET_STAT(), 0, BUSY_STAT)) { - if (0 < (signed long)(hwgroup->poll_timeout - jiffies)) { + if (time_before(jiffies, hwgroup->poll_timeout)) { ide_set_handler (drive, &reset_pollfunc, HZ/20, NULL); return ide_started; /* continue polling */ } @@ -1035,7 +856,7 @@ u32 buffer[16]; unsigned int wcount = (i > 16) ? 16 : i; i -= wcount; - ide_input_data (drive, buffer, wcount); + ata_input_data (drive, buffer, wcount); } } @@ -1086,9 +907,9 @@ if (rq->errors >= ERROR_MAX) { if (drive->driver != NULL) - DRIVER(drive)->end_request(0, HWGROUP(drive)); + DRIVER(drive)->end_request(drive, 0); else - ide_end_request(0, HWGROUP(drive)); + ide_end_request(drive, 0); } else { if ((rq->errors & ERROR_RESET) == ERROR_RESET) { ++rq->errors; @@ -1129,7 +950,7 @@ if ((stat & DRQ_STAT) && args && args[3]) { byte io_32bit = drive->io_32bit; drive->io_32bit = 0; - ide_input_data(drive, &args[4], args[3] * SECTOR_WORDS); + ata_input_data(drive, &args[4], args[3] * SECTOR_WORDS); drive->io_32bit = io_32bit; while (((stat = GET_STAT()) & BUSY_STAT) && retries--) udelay(100); @@ -1194,7 +1015,7 @@ ide__sti(); /* local CPU only */ timeout += jiffies; while ((stat = GET_STAT()) & BUSY_STAT) { - if (0 < (signed long)(jiffies - timeout)) { + if (time_after(jiffies, timeout)) { __restore_flags(flags); /* local CPU only */ *startstop = ide_error(drive, "status timeout", stat); return 1; @@ -1408,25 +1229,16 @@ return do_special(drive); kill_rq: if (drive->driver != NULL) - DRIVER(drive)->end_request(0, HWGROUP(drive)); + DRIVER(drive)->end_request(drive, 0); else - ide_end_request(0, HWGROUP(drive)); + ide_end_request(drive, 0); return ide_stopped; } -ide_startstop_t restart_request (ide_drive_t *drive) +int restart_request (ide_drive_t *drive, struct request *rq) { - ide_hwgroup_t *hwgroup = HWGROUP(drive); - unsigned long flags; - struct request *rq; - - spin_lock_irqsave(&io_request_lock, flags); - hwgroup->handler = NULL; - del_timer(&hwgroup->timer); - rq = hwgroup->rq; - spin_unlock_irqrestore(&io_request_lock, flags); - - return start_request(drive, rq); + (void) start_request(drive, rq); + return 0; } /* @@ -1453,7 +1265,7 @@ best = NULL; drive = hwgroup->drive; do { - if (!list_empty(&drive->queue.queue_head) && (!drive->sleep || 0 <= (signed long)(jiffies - drive->sleep))) { + if (!list_empty(&drive->queue.queue_head) && (!drive->sleep || time_after_eq(jiffies, drive->sleep))) { if (!best || (drive->sleep && (!best->sleep || 0 < (signed long)(best->sleep - drive->sleep))) || (!best->sleep && 0 < (signed long)(WAKEUP(best) - WAKEUP(drive)))) @@ -1546,13 +1358,13 @@ sleep = drive->sleep; } while ((drive = drive->next) != hwgroup->drive); if (sleep) { - /* - * Take a short snooze, and then wake up this hwgroup again. - * This gives other hwgroups on the same a chance to - * play fairly with us, just in case there are big differences - * in relative throughputs.. don't want to hog the cpu too much. - */ - if (0 < (signed long)(jiffies + WAIT_MIN_SLEEP - sleep)) + /* + * Take a short snooze, and then wake up this hwgroup again. + * This gives other hwgroups on the same a chance to + * play fairly with us, just in case there are big differences + * in relative throughputs.. don't want to hog the cpu too much. + */ + if (time_before(sleep, jiffies + WAIT_MIN_SLEEP)) sleep = jiffies + WAIT_MIN_SLEEP; #if 1 if (timer_pending(&hwgroup->timer)) @@ -1621,6 +1433,7 @@ ide_do_request(q->queuedata, 0); } +#ifndef __IDEDMA_TIMEOUT /* * un-busy the hwgroup etc, and clear any pending DMA status. we want to * retry the current request in pio mode instead of risking tossing it @@ -1663,6 +1476,7 @@ rq->current_nr_sectors = rq->bh->b_size >> 9; rq->buffer = rq->bh->b_data; } +#endif /* * ide_timer_expiry() is our timeout function for all drive operations. @@ -1737,8 +1551,14 @@ startstop = handler(drive); } else { if (drive->waiting_for_dma) { +#ifndef __IDEDMA_TIMEOUT startstop = ide_stopped; ide_dma_timeout_retry(drive); +#else /* __IDEDMA_TIMEOUT */ + (void) hwgroup->hwif->dmaproc(ide_dma_end, drive); + printk("%s: timeout waiting for DMA\n", drive->name); + (void) hwgroup->hwif->dmaproc(ide_dma_timeout, drive); +#endif /* __IDEDMA_TIMEOUT */ } else startstop = ide_error(drive, "irq timeout", GET_STAT()); } @@ -1792,7 +1612,7 @@ /* Try to not flood the console with msgs */ static unsigned long last_msgtime, count; ++count; - if (0 < (signed long)(jiffies - (last_msgtime + HZ))) { + if (time_after(jiffies, last_msgtime + HZ)) { last_msgtime = jiffies; printk("%s%s: unexpected interrupt, status=0x%02x, count=%ld\n", hwif->name, (hwif->next == hwgroup->hwif) ? "" : "(?)", stat, count); @@ -2274,7 +2094,7 @@ g = g->next; } while (g != hwgroup->hwif); if (irq_count == 1) - free_irq(hwif->irq, hwgroup); + ide_free_irq(hwif->irq, hwgroup); /* * Note that we only release the standard ports, @@ -2595,7 +2415,7 @@ spin_unlock_irq(&io_request_lock); __save_flags(lflags); /* local CPU only */ __sti(); /* local CPU only; needed for jiffies */ - if (0 < (signed long)(jiffies - timeout)) { + if (time_after(jiffies, timeout)) { __restore_flags(lflags); /* local CPU only */ printk("%s: channel busy\n", drive->name); return -EBUSY; @@ -2695,8 +2515,8 @@ ide_add_setting(drive, "unmaskirq", drive->no_unmask ? SETTING_READ : SETTING_RW, HDIO_GET_UNMASKINTR, HDIO_SET_UNMASKINTR, TYPE_BYTE, 0, 1, 1, 1, &drive->unmask, NULL); ide_add_setting(drive, "using_dma", SETTING_RW, HDIO_GET_DMA, HDIO_SET_DMA, TYPE_BYTE, 0, 1, 1, 1, &drive->using_dma, set_using_dma); ide_add_setting(drive, "ide_scsi", SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->scsi, NULL); - ide_add_setting(drive, "init_speed", SETTING_RW, -1, -1, TYPE_BYTE, 0, 69, 1, 1, &drive->init_speed, NULL); - ide_add_setting(drive, "current_speed", SETTING_RW, -1, -1, TYPE_BYTE, 0, 69, 1, 1, &drive->current_speed, NULL); + ide_add_setting(drive, "init_speed", SETTING_RW, -1, -1, TYPE_BYTE, 0, 70, 1, 1, &drive->init_speed, NULL); + ide_add_setting(drive, "current_speed", SETTING_RW, -1, -1, TYPE_BYTE, 0, 70, 1, 1, &drive->current_speed, NULL); ide_add_setting(drive, "number", SETTING_RW, -1, -1, TYPE_BYTE, 0, 3, 1, 1, &drive->dn, NULL); } @@ -2916,68 +2736,15 @@ #endif /* CONFIG_IDE_TASK_IOCTL */ case HDIO_DRIVE_CMD: - { - byte args[4], *argbuf = args; - byte xfer_rate = 0; - int argsize = 4; - ide_task_t tfargs; - if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) return -EACCES; - if (NULL == (void *) arg) - return ide_do_drive_cmd(drive, &rq, ide_wait); - if (copy_from_user(args, (void *)arg, 4)) - return -EFAULT; + return ide_cmd_ioctl(drive, inode, file, cmd, arg); - tfargs.tfRegister[IDE_FEATURE_OFFSET] = args[2]; - tfargs.tfRegister[IDE_NSECTOR_OFFSET] = args[3]; - tfargs.tfRegister[IDE_SECTOR_OFFSET] = args[1]; - tfargs.tfRegister[IDE_LCYL_OFFSET] = 0x00; - tfargs.tfRegister[IDE_HCYL_OFFSET] = 0x00; - tfargs.tfRegister[IDE_SELECT_OFFSET] = 0x00; - tfargs.tfRegister[IDE_COMMAND_OFFSET] = args[0]; - - if (args[3]) { - argsize = 4 + (SECTOR_WORDS * 4 * args[3]); - argbuf = kmalloc(argsize, GFP_KERNEL); - if (argbuf == NULL) - return -ENOMEM; - memcpy(argbuf, args, 4); - } - - if (set_transfer(drive, &tfargs)) { - xfer_rate = args[1]; - if (ide_ata66_check(drive, &tfargs)) - goto abort; - } - - err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf); - - if (!err && xfer_rate) { - /* active-retuning-calls future */ - if ((HWIF(drive)->speedproc) != NULL) - HWIF(drive)->speedproc(drive, xfer_rate); - ide_driveid_update(drive); - } - abort: - if (copy_to_user((void *)arg, argbuf, argsize)) - err = -EFAULT; - if (argsize > 4) - kfree(argbuf); - return err; - } case HDIO_DRIVE_TASK: - { - byte args[7], *argbuf = args; - int argsize = 7; - if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) return -EACCES; - if (copy_from_user(args, (void *)arg, 7)) - return -EFAULT; - err = ide_wait_cmd_task(drive, argbuf); - if (copy_to_user((void *)arg, argbuf, argsize)) - err = -EFAULT; - return err; - } + if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) + return -EACCES; + return ide_task_ioctl(drive, inode, file, cmd, arg); + case HDIO_SCAN_HWIF: { int args[3]; @@ -3741,13 +3508,13 @@ static ide_startstop_t default_do_request(ide_drive_t *drive, struct request *rq, unsigned long block) { - ide_end_request(0, HWGROUP(drive)); + ide_end_request(drive, 0); return ide_stopped; } - -static void default_end_request (byte uptodate, ide_hwgroup_t *hwgroup) + +static int default_end_request (ide_drive_t *drive, int uptodate) { - ide_end_request(uptodate, hwgroup); + return ide_end_request(drive, uptodate); } static int default_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, @@ -3789,6 +3556,11 @@ return ide_stopped; } +static int default_init (void) +{ + return 0; +} + static int default_reinit (ide_drive_t *drive) { printk(KERN_ERR "%s: does not support hotswap of device class !\n", drive->name); @@ -3812,6 +3584,7 @@ if (d->pre_reset == NULL) d->pre_reset = default_pre_reset; if (d->capacity == NULL) d->capacity = default_capacity; if (d->special == NULL) d->special = default_special; + if (d->init == NULL) d->init = default_init; if (d->reinit == NULL) d->reinit = default_reinit; } @@ -3953,11 +3726,6 @@ EXPORT_SYMBOL(ide_register_subdriver); EXPORT_SYMBOL(ide_unregister_subdriver); EXPORT_SYMBOL(ide_replace_subdriver); -EXPORT_SYMBOL(ide_input_data); -EXPORT_SYMBOL(ide_output_data); -EXPORT_SYMBOL(atapi_input_bytes); -EXPORT_SYMBOL(atapi_output_bytes); -EXPORT_SYMBOL(drive_is_ready); EXPORT_SYMBOL(ide_set_handler); EXPORT_SYMBOL(ide_dump_status); EXPORT_SYMBOL(ide_error); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/pdc202xx.c linux.19pre5-ac1/drivers/ide/pdc202xx.c --- linux.19p5/drivers/ide/pdc202xx.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/ide/pdc202xx.c Wed Apr 3 00:33:12 2002 @@ -221,6 +221,9 @@ case PCI_DEVICE_ID_PROMISE_20275: p += sprintf(p, "\n PDC20275 Chipset.\n"); break; + case PCI_DEVICE_ID_PROMISE_20271: + p += sprintf(p, "\n PDC20271 Chipset.\n"); + break; case PCI_DEVICE_ID_PROMISE_20269: p += sprintf(p, "\n PDC20269 TX2 Chipset.\n"); break; @@ -241,6 +244,7 @@ switch(bmide_dev->device) { case PCI_DEVICE_ID_PROMISE_20276: case PCI_DEVICE_ID_PROMISE_20275: + case PCI_DEVICE_ID_PROMISE_20271: case PCI_DEVICE_ID_PROMISE_20269: case PCI_DEVICE_ID_PROMISE_20268: case PCI_DEVICE_ID_PROMISE_20268R: @@ -725,16 +729,12 @@ byte mask = hwif->channel ? 0x08 : 0x02; unsigned short c_mask = hwif->channel ? (1<<11) : (1<<10); - byte ultra_66 = ((id->dma_ultra & 0x0010) || - (id->dma_ultra & 0x0008)) ? 1 : 0; - byte ultra_100 = ((id->dma_ultra & 0x0020) || - (ultra_66)) ? 1 : 0; - byte ultra_133 = ((id->dma_ultra & 0x0040) || - (ultra_100)) ? 1 : 0; + byte fast_ultra = id->dma_ultra & 0x0078; switch(dev->device) { case PCI_DEVICE_ID_PROMISE_20276: case PCI_DEVICE_ID_PROMISE_20275: + case PCI_DEVICE_ID_PROMISE_20271: case PCI_DEVICE_ID_PROMISE_20269: udma_133 = (udma_66) ? 1 : 0; udma_100 = (udma_66) ? 1 : 0; @@ -787,7 +787,7 @@ * parameters. */ - if (((ultra_66) || (ultra_100) || (ultra_133)) && (cable)) { + if (fast_ultra && cable) { #ifdef DEBUG printk("ULTRA66: %s channel of Ultra 66 requires an 80-pin cable for Ultra66 operation.\n", hwif->channel ? "Secondary" : "Primary"); printk(" Switching to Ultra33 mode.\n"); @@ -800,17 +800,13 @@ printk("%s reduced to Ultra33 mode.\n", drive->name); udma_66 = 0; udma_100 = 0; udma_133 = 0; } else { - if ((ultra_66) || (ultra_100) || (ultra_133)) { + if (fast_ultra) { /* * check to make sure drive on same channel * is u66 capable */ if (hwif->drives[!(drive->dn%2)].id) { - if ((hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0040) || - (hwif->drives[!(drive->dn%2)].id->dma_ultra -& 0x0020) || - (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0010) || - (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0008)) { + if (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0078) { if (!jumpbit) OUT_BYTE(CLKSPD | mask, (high_16 + 0x11)); } else { @@ -922,6 +918,8 @@ ide_hwif_t *hwif = HWIF(drive); ide_dma_action_t dma_func = ide_dma_off_quietly; + (void) config_chipset_for_pio(drive, 5); + if (id && (id->capability & 1) && hwif->autodma) { /* Consult the list of known "bad" drives */ if (ide_dmaproc(ide_dma_bad_drive, drive)) { @@ -991,6 +989,7 @@ switch (dev->device) { case PCI_DEVICE_ID_PROMISE_20276: case PCI_DEVICE_ID_PROMISE_20275: + case PCI_DEVICE_ID_PROMISE_20271: case PCI_DEVICE_ID_PROMISE_20269: case PCI_DEVICE_ID_PROMISE_20268R: case PCI_DEVICE_ID_PROMISE_20268: @@ -1067,6 +1066,8 @@ mdelay(1000); printk("PDC202XX: %s channel reset.\n", HWIF(drive)->channel ? "Secondary" : "Primary"); + /* the reset clears the configuration, reinit to pio */ + config_chipset_for_pio(drive, 5); } void pdc202xx_reset (ide_drive_t *drive) @@ -1124,6 +1125,7 @@ switch (dev->device) { case PCI_DEVICE_ID_PROMISE_20276: case PCI_DEVICE_ID_PROMISE_20275: + case PCI_DEVICE_ID_PROMISE_20271: case PCI_DEVICE_ID_PROMISE_20269: case PCI_DEVICE_ID_PROMISE_20268R: case PCI_DEVICE_ID_PROMISE_20268: @@ -1219,6 +1221,7 @@ switch(hwif->pci_dev->device) { case PCI_DEVICE_ID_PROMISE_20276: case PCI_DEVICE_ID_PROMISE_20275: + case PCI_DEVICE_ID_PROMISE_20271: case PCI_DEVICE_ID_PROMISE_20269: case PCI_DEVICE_ID_PROMISE_20268: case PCI_DEVICE_ID_PROMISE_20268R: @@ -1238,6 +1241,7 @@ switch(hwif->pci_dev->device) { case PCI_DEVICE_ID_PROMISE_20276: case PCI_DEVICE_ID_PROMISE_20275: + case PCI_DEVICE_ID_PROMISE_20271: case PCI_DEVICE_ID_PROMISE_20269: case PCI_DEVICE_ID_PROMISE_20268: case PCI_DEVICE_ID_PROMISE_20268R: diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/pdc4030.c linux.19pre5-ac1/drivers/ide/pdc4030.c --- linux.19p5/drivers/ide/pdc4030.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/ide/pdc4030.c Thu Mar 21 01:04:19 2002 @@ -187,7 +187,7 @@ "%s: Failed Promise read config!\n",hwif->name); return 0; } - ide_input_data(drive,&ident,SECTOR_WORDS); + ata_input_data(drive, &ident, SECTOR_WORDS); if (ident.id[1] != 'P' || ident.id[0] != 'T') { return 0; } @@ -313,6 +313,10 @@ int total_remaining; unsigned int sectors_left, sectors_avail, nsect; struct request *rq; +#ifdef __TASKFILE__IO + unsigned long flags; + char *to; +#endif /* __TASKFILE__IO */ if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) { return ide_error(drive, "promise_read_intr", stat); @@ -334,20 +338,34 @@ if (nsect > sectors_avail) nsect = sectors_avail; sectors_avail -= nsect; - ide_input_data(drive, rq->buffer, nsect * SECTOR_WORDS); +#ifdef __TASKFILE__IO + to = ide_map_buffer(rq, &flags); + ata_input_data(drive, to, nsect * SECTOR_WORDS); +#else /* !__TASKFILE__IO */ + ata_input_data(drive, rq->buffer, nsect * SECTOR_WORDS); +#endif /* __TASKFILE__IO */ #ifdef DEBUG_READ printk(KERN_DEBUG "%s: promise_read: sectors(%ld-%ld), " "buf=0x%08lx, rem=%ld\n", drive->name, rq->sector, - rq->sector+nsect-1, (unsigned long) rq->buffer, + rq->sector+nsect-1, +#ifdef __TASKFILE__IO + (unsigned long) to, +#else /* !__TASKFILE__IO */ + (unsigned long) rq->buffer, +#endif /* __TASKFILE__IO */ rq->nr_sectors-nsect); #endif - rq->sector += nsect; +#ifdef __TASKFILE__IO + ide_unmap_buffer(to, &flags); +#else /* !__TASKFILE__IO */ rq->buffer += nsect<<9; +#endif /* __TASKFILE__IO */ + rq->sector += nsect; rq->errors = 0; rq->nr_sectors -= nsect; total_remaining = rq->nr_sectors; if ((rq->current_nr_sectors -= nsect) <= 0) { - ide_end_request(1, HWGROUP(drive)); + ide_end_request(drive, 1); } /* * Now the data has been read in, do the following: @@ -412,12 +430,80 @@ #endif for (i = rq->nr_sectors; i > 0; ) { i -= rq->current_nr_sectors; - ide_end_request(1, hwgroup); + ide_end_request(drive, 1); } return ide_stopped; } /* + * promise_multwrite() transfers a block of up to mcount sectors of data + * to a drive as part of a disk multiple-sector write operation. + * + * Returns 0 on success. + * + * Note that we may be called from two contexts - the do_rw_disk context + * and IRQ context. The IRQ can happen any time after we've output the + * full "mcount" number of sectors, so we must make sure we update the + * state _before_ we output the final part of the data! + */ +int promise_multwrite (ide_drive_t *drive, unsigned int mcount) +{ + ide_hwgroup_t *hwgroup = HWGROUP(drive); + struct request *rq = &hwgroup->wrq; + + do { + char *buffer; + int nsect = rq->current_nr_sectors; +#ifdef __TASKFILE__IO + unsigned long flags; +#endif /* __TASKFILE__IO */ + + if (nsect > mcount) + nsect = mcount; + mcount -= nsect; +#ifdef __TASKFILE__IO + buffer = ide_map_buffer(rq, &flags); + rq->sector += nsect; +#else /* !__TASKFILE__IO */ + buffer = rq->buffer; + + rq->sector += nsect; + rq->buffer += nsect << 9; +#endif /* __TASKFILE__IO */ + rq->nr_sectors -= nsect; + rq->current_nr_sectors -= nsect; + + /* Do we move to the next bh after this? */ + if (!rq->current_nr_sectors) { + struct buffer_head *bh = rq->bh->b_reqnext; + + /* end early early we ran out of requests */ + if (!bh) { + mcount = 0; + } else { + rq->bh = bh; + rq->current_nr_sectors = bh->b_size >> 9; +#ifdef __TASKFILE__IO + rq->hard_cur_sectors = rq->current_nr_sectors; +#endif /* __TASKFILE__IO */ + rq->buffer = bh->b_data; + } + } + + /* + * Ok, we're all setup for the interrupt + * re-entering us on the last transfer. + */ + taskfile_output_data(drive, buffer, nsect<<7); +#ifdef __TASKFILE__IO + ide_unmap_buffer(buffer, &flags); +#endif /* __TASKFILE__IO */ + } while (mcount); + + return 0; +} + +/* * promise_write_pollfunc() is the handler for disk write completion polling. */ static ide_startstop_t promise_write_pollfunc (ide_drive_t *drive) @@ -437,7 +523,7 @@ /* * Now write out last 4 sectors and poll for not BUSY */ - ide_multwrite(drive, 4); + promise_multwrite(drive, 4); hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL); #ifdef DEBUG_WRITE @@ -470,7 +556,7 @@ * the polling strategy as defined above. */ if (rq->nr_sectors > 4) { - if (ide_multwrite(drive, rq->nr_sectors - 4)) + if (promise_multwrite(drive, rq->nr_sectors - 4)) return ide_stopped; hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; ide_set_handler (drive, &promise_write_pollfunc, HZ/100, NULL); @@ -480,7 +566,7 @@ * There are 4 or fewer sectors to transfer, do them all in one go * and wait for NOT BUSY. */ - if (ide_multwrite(drive, rq->nr_sectors)) + if (promise_multwrite(drive, rq->nr_sectors)) return ide_stopped; hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL); @@ -497,16 +583,39 @@ * already set up. It issues a READ or WRITE command to the Promise * controller, assuming LBA has been used to set up the block number. */ +#ifndef __TASKFILE__IO ide_startstop_t do_pdc4030_io (ide_drive_t *drive, struct request *rq) { +#else +ide_startstop_t do_pdc4030_io (ide_drive_t *drive, ide_task_t *task) +{ + struct request *rq = HWGROUP(drive)->rq; + task_struct_t *taskfile = (task_struct_t *) task->tfRegister; +#endif ide_startstop_t startstop; unsigned long timeout; byte stat; +#ifdef __TASKFILE__IO + if (IDE_CONTROL_REG) + OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */ + SELECT_MASK(HWIF(drive), drive, 0); + + OUT_BYTE(taskfile->feature, IDE_FEATURE_REG); + OUT_BYTE(taskfile->sector_count, IDE_NSECTOR_REG); + /* refers to number of sectors to transfer */ + OUT_BYTE(taskfile->sector_number, IDE_SECTOR_REG); + /* refers to sector offset or start sector */ + OUT_BYTE(taskfile->low_cylinder, IDE_LCYL_REG); + OUT_BYTE(taskfile->high_cylinder, IDE_HCYL_REG); + OUT_BYTE(taskfile->device_head, IDE_SELECT_REG); + OUT_BYTE(taskfile->command, IDE_COMMAND_REG); +#endif + switch(rq->cmd) { - case READ: + case READ: #ifndef __TASKFILE__IO - OUT_BYTE(PROMISE_READ, IDE_COMMAND_REG); + OUT_BYTE(PROMISE_READ, IDE_COMMAND_REG); #endif /* * The card's behaviour is odd at this point. If the data is @@ -518,41 +627,41 @@ * If neither of these is the case, we wait for up to 50ms (badly I'm * afraid!) until one of them is. */ - timeout = jiffies + HZ/20; /* 50ms wait */ - do { - stat=GET_STAT(); - if (stat & DRQ_STAT) { - udelay(1); - return promise_read_intr(drive); - } - if (IN_BYTE(IDE_SELECT_REG) & 0x01) { + timeout = jiffies + HZ/20; /* 50ms wait */ + do { + stat=GET_STAT(); + if (stat & DRQ_STAT) { + udelay(1); + return promise_read_intr(drive); + } + if (IN_BYTE(IDE_SELECT_REG) & 0x01) { #ifdef DEBUG_READ printk(KERN_DEBUG "%s: read: waiting for interrupt\n", drive->name); #endif - ide_set_handler(drive, &promise_read_intr, WAIT_CMD, NULL); - return ide_started; - } - udelay(1); - } while (time_before(jiffies, timeout)); + ide_set_handler(drive, &promise_read_intr, WAIT_CMD, NULL); + return ide_started; + } + udelay(1); + } while (time_before(jiffies, timeout)); - printk(KERN_ERR "%s: reading: No DRQ and not waiting - Odd!\n", drive->name); - return ide_stopped; - case WRITE: + printk(KERN_ERR "%s: reading: No DRQ and not waiting - Odd!\n", drive->name); + return ide_stopped; + case WRITE: #ifndef __TASKFILE__IO - OUT_BYTE(PROMISE_WRITE, IDE_COMMAND_REG); + OUT_BYTE(PROMISE_WRITE, IDE_COMMAND_REG); #endif - if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) { - printk(KERN_ERR "%s: no DRQ after issuing PROMISE_WRITE\n", drive->name); - return startstop; - } - if (!drive->unmask) - __cli(); /* local CPU only */ - HWGROUP(drive)->wrq = *rq; /* scratchpad */ - return promise_write(drive); - default: - printk("KERN_WARNING %s: bad command: %d\n", drive->name, rq->cmd); - ide_end_request(0, HWGROUP(drive)); - return ide_stopped; + if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) { + printk(KERN_ERR "%s: no DRQ after issuing PROMISE_WRITE\n", drive->name); + return startstop; + } + if (!drive->unmask) + __cli(); /* local CPU only */ + HWGROUP(drive)->wrq = *rq; /* scratchpad */ + return promise_write(drive); + default: + printk("KERN_WARNING %s: bad command: %d\n", drive->name, rq->cmd); + ide_end_request(drive, 0); + return ide_stopped; } } @@ -560,7 +669,8 @@ ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) { - struct hd_drive_task_hdr taskfile; + struct hd_drive_task_hdr taskfile; + ide_task_t args; memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr)); @@ -571,8 +681,17 @@ taskfile.device_head = ((block>>8)&0x0f)|drive->select.all; taskfile.command = (rq->cmd==READ)?PROMISE_READ:PROMISE_WRITE; - do_taskfile(drive, &taskfile, NULL, NULL); - return do_pdc4030_io(drive, rq); + memcpy(args.tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr)); + memcpy(args.hobRegister, NULL, sizeof(struct hd_drive_hob_hdr)); + args.command_type = ide_cmd_type_parser(&args); + args.prehandler = NULL; + args.handler = NULL; + args.posthandler = NULL; + args.rq = (struct request *) rq; + rq->special = NULL; + rq->special = (ide_task_t *)&args; + + return do_pdc4030_io(drive, &args); } #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/piix.c linux.19pre5-ac1/drivers/ide/piix.c --- linux.19p5/drivers/ide/piix.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/ide/piix.c Thu Mar 21 00:32:25 2002 @@ -417,6 +417,8 @@ struct hd_driveid *id = drive->id; ide_dma_action_t dma_func = ide_dma_on; + config_chipset_for_pio(drive); + if (id && (id->capability & 1) && HWIF(drive)->autodma) { /* Consult the list of known "bad" drives */ if (ide_dmaproc(ide_dma_bad_drive, drive)) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/serverworks.c linux.19pre5-ac1/drivers/ide/serverworks.c --- linux.19p5/drivers/ide/serverworks.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/ide/serverworks.c Thu Mar 21 00:32:25 2002 @@ -456,6 +456,8 @@ struct hd_driveid *id = drive->id; ide_dma_action_t dma_func = ide_dma_on; + config_chipset_for_pio(drive); + if (id && (id->capability & 1) && HWIF(drive)->autodma) { /* Consult the list of known "bad" drives */ if (ide_dmaproc(ide_dma_bad_drive, drive)) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/sis5513.c linux.19pre5-ac1/drivers/ide/sis5513.c --- linux.19p5/drivers/ide/sis5513.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/ide/sis5513.c Thu Mar 21 00:32:25 2002 @@ -1,12 +1,19 @@ /* - * linux/drivers/ide/sis5513.c Version 0.13 February 14, 2002 + * linux/drivers/ide/sis5513.c Version 0.13 March 6, 2002 * * Copyright (C) 1999-2000 Andre Hedrick * Copyright (C) 2002 Lionel Bouton , Maintainer * May be copied or modified under the terms of the GNU General Public License * - * Thanks to SIS Taiwan for direct support and hardware. - * Thanks to Daniela Engert for ATA100 support advice. + * + * Thanks : + * + * SiS Taiwan : for direct support and hardware. + * Daniela Engert : for initial ATA100 advices and numerous others. + * John Fremlin, Manfred Spraul : + * for checking code correctness, providing patches. + * + * * Original tests and design on the SiS620/5513 chipset. * ATA100 tests and design on the SiS735/5513 chipset. * ATA16/33 design from specs @@ -14,11 +21,11 @@ /* * TODO: - * - Are there pre-ATA_16 SiS chips ? -> tune init code for them - * or remove ATA_00 defines * - Get ridden of SisHostChipInfo[] completness dependancy. * - Get ATA-133 datasheets, implement ATA-133 init code. - * - Check latency timer init correctness. + * - Study drivers/ide/ide-timing.h. + * - Are there pre-ATA_16 SiS5513 chips ? -> tune init code for them + * or remove ATA_00 define * - More checks in the config registers (force values instead of * relying on the BIOS setting them correctly). * - Further optimisations ? @@ -45,62 +52,45 @@ #include "ide_modes.h" -#define DEBUG -/* if BROKEN_LEVEL is defined it limits the DMA mode +/* When DEBUG is defined it outputs initial PCI config register + values and changes made to them by the driver */ +// #define DEBUG +/* When BROKEN_LEVEL is defined it limits the DMA mode at boot time to its value */ // #define BROKEN_LEVEL XFER_SW_DMA_0 #define DISPLAY_SIS_TIMINGS /* Miscellaneaous flags */ #define SIS5513_LATENCY 0x01 -/* ATA transfer mode capabilities */ + +/* registers layout and init values are chipset family dependant */ +/* 1/ define families */ #define ATA_00 0x00 #define ATA_16 0x01 #define ATA_33 0x02 #define ATA_66 0x03 -#define ATA_100 0x04 -#define ATA_133 0x05 - -static unsigned char dma_capability = 0x00; +#define ATA_100a 0x04 // SiS730 is ATA100 with ATA66 layout +#define ATA_100 0x05 +#define ATA_133 0x06 +/* 2/ variable holding the controller chipset family value */ +static unsigned char chipset_family; /* * Debug code: following IDE config registers' changes */ #ifdef DEBUG -/* Copy of IDE Config registers 0x00 -> 0x58 +/* Copy of IDE Config registers 0x00 -> 0x57 Fewer might be used depending on the actual chipset */ -static unsigned char ide_regs_copy[] = { - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0 -}; +static unsigned char ide_regs_copy[0x58]; static byte sis5513_max_config_register(void) { - switch(dma_capability) { + switch(chipset_family) { case ATA_00: case ATA_16: return 0x4f; case ATA_33: return 0x52; case ATA_66: + case ATA_100a: case ATA_100: case ATA_133: default: return 0x57; @@ -145,7 +135,7 @@ printk(" %0#x:%0#x", reg, ide_regs_copy[reg]); } -/* Print valuable registers (for ATA100) */ +/* Print valuable registers */ static void sis5513_print_registers(struct pci_dev* dev, char* marker) { int i; byte max = sis5513_max_config_register(); @@ -176,14 +166,14 @@ static const struct { const char *name; unsigned short host_id; - unsigned char dma_capability; + unsigned char chipset_family; unsigned char flags; } SiSHostChipInfo[] = { { "SiS750", PCI_DEVICE_ID_SI_750, ATA_100, SIS5513_LATENCY }, { "SiS745", PCI_DEVICE_ID_SI_745, ATA_100, SIS5513_LATENCY }, { "SiS740", PCI_DEVICE_ID_SI_740, ATA_100, SIS5513_LATENCY }, { "SiS735", PCI_DEVICE_ID_SI_735, ATA_100, SIS5513_LATENCY }, - { "SiS730", PCI_DEVICE_ID_SI_730, ATA_100, SIS5513_LATENCY }, + { "SiS730", PCI_DEVICE_ID_SI_730, ATA_100a, SIS5513_LATENCY }, { "SiS650", PCI_DEVICE_ID_SI_650, ATA_100, SIS5513_LATENCY }, { "SiS645", PCI_DEVICE_ID_SI_645, ATA_100, SIS5513_LATENCY }, { "SiS635", PCI_DEVICE_ID_SI_635, ATA_100, SIS5513_LATENCY }, @@ -202,14 +192,15 @@ /* Cycle time bits and values vary accross chip dma capabilities These three arrays hold the register layout and the values to set. - Indexed by dma_capability and (dma_mode - XFER_UDMA_0) */ -static byte cycle_time_offset[] = {0,0,5,4,0,0}; -static byte cycle_time_range[] = {0,0,2,3,4,4}; + Indexed by chipset_family and (dma_mode - XFER_UDMA_0) */ +static byte cycle_time_offset[] = {0,0,5,4,4,0,0}; +static byte cycle_time_range[] = {0,0,2,3,3,4,4}; static byte cycle_time_value[][XFER_UDMA_5 - XFER_UDMA_0 + 1] = { {0,0,0,0,0,0}, /* no udma */ {0,0,0,0,0,0}, /* no udma */ {3,2,1,0,0,0}, {7,5,3,2,1,0}, + {7,5,3,2,1,0}, {11,7,5,4,2,1}, {0,0,0,0,0,0} /* not yet known, ask SiS */ }; @@ -283,23 +274,25 @@ pci_read_config_byte(bmide_dev, 0x45+2*pos, ®11); /* UDMA */ - if (dma_capability >= ATA_33) { + if (chipset_family >= ATA_33) { p += sprintf(p, " UDMA %s \t \t \t UDMA %s\n", (reg01 & 0x80) ? "Enabled" : "Disabled", (reg11 & 0x80) ? "Enabled" : "Disabled"); p += sprintf(p, " UDMA Cycle Time "); - switch(dma_capability) { + switch(chipset_family) { case ATA_33: p += sprintf(p, cycle_time[(reg01 & 0x60) >> 5]); break; - case ATA_66: p += sprintf(p, cycle_time[(reg01 & 0x70) >> 4]); break; + case ATA_66: + case ATA_100a: p += sprintf(p, cycle_time[(reg01 & 0x70) >> 4]); break; case ATA_100: p += sprintf(p, cycle_time[reg01 & 0x0F]); break; case ATA_133: default: p += sprintf(p, "133+ ?"); break; } p += sprintf(p, " \t UDMA Cycle Time "); - switch(dma_capability) { + switch(chipset_family) { case ATA_33: p += sprintf(p, cycle_time[(reg11 & 0x60) >> 5]); break; - case ATA_66: p += sprintf(p, cycle_time[(reg11 & 0x70) >> 4]); break; + case ATA_66: + case ATA_100a: p += sprintf(p, cycle_time[(reg11 & 0x70) >> 4]); break; case ATA_100: p += sprintf(p, cycle_time[reg11 & 0x0F]); break; case ATA_133: default: p += sprintf(p, "133+ ?"); break; @@ -309,21 +302,23 @@ /* Data Active */ p += sprintf(p, " Data Active Time "); - switch(dma_capability) { + switch(chipset_family) { case ATA_00: case ATA_16: /* confirmed */ case ATA_33: - case ATA_66: p += sprintf(p, active_time[reg01 & 0x07]); break; + case ATA_66: + case ATA_100a: p += sprintf(p, active_time[reg01 & 0x07]); break; case ATA_100: p += sprintf(p, active_time[(reg00 & 0x70) >> 4]); break; case ATA_133: default: p += sprintf(p, "133+ ?"); break; } p += sprintf(p, " \t Data Active Time "); - switch(dma_capability) { + switch(chipset_family) { case ATA_00: case ATA_16: case ATA_33: - case ATA_66: p += sprintf(p, active_time[reg11 & 0x07]); break; + case ATA_66: + case ATA_100a: p += sprintf(p, active_time[reg11 & 0x07]); break; case ATA_100: p += sprintf(p, active_time[(reg10 & 0x70) >> 4]); break; case ATA_133: default: p += sprintf(p, "133+ ?"); break; @@ -356,11 +351,12 @@ u16 reg2, reg3; p += sprintf(p, "\nSiS 5513 "); - switch(dma_capability) { + switch(chipset_family) { case ATA_00: p += sprintf(p, "Unknown???"); break; case ATA_16: p += sprintf(p, "DMA 16"); break; case ATA_33: p += sprintf(p, "Ultra 33"); break; case ATA_66: p += sprintf(p, "Ultra 66"); break; + case ATA_100a: case ATA_100: p += sprintf(p, "Ultra 100"); break; case ATA_133: default: p+= sprintf(p, "Ultra 133+"); break; @@ -371,7 +367,7 @@ /* Status */ pci_read_config_byte(bmide_dev, 0x4a, ®); p += sprintf(p, "Channel Status: "); - if (dma_capability < ATA_66) { + if (chipset_family < ATA_66) { p += sprintf(p, "%s \t \t \t \t %s\n", (reg & 0x04) ? "On" : "Off", (reg & 0x02) ? "On" : "Off"); @@ -388,7 +384,7 @@ (reg & 0x04) ? "Native" : "Compatible"); /* 80-pin cable ? */ - if (dma_capability > ATA_33) { + if (chipset_family > ATA_33) { pci_read_config_byte(bmide_dev, 0x48, ®); p += sprintf(p, "Cable Type: %s \t \t \t %s\n", (reg & 0x10) ? cable_type[1] : cable_type[0], @@ -489,8 +485,8 @@ default: return; } - /* register layout changed with ATA100 chips */ - if (dma_capability < ATA_100) { + /* register layout changed with newer ATA100 chips */ + if (chipset_family < ATA_100) { pci_read_config_byte(dev, drive_pci, &test1); pci_read_config_byte(dev, drive_pci+1, &test2); @@ -570,7 +566,7 @@ pci_read_config_byte(dev, drive_pci+1, ®); /* Disable UDMA bit for non UDMA modes on UDMA chips */ - if ((speed < XFER_UDMA_0) && (dma_capability > ATA_16)) { + if ((speed < XFER_UDMA_0) && (chipset_family > ATA_16)) { reg &= 0x7F; pci_write_config_byte(dev, drive_pci+1, reg); } @@ -584,12 +580,14 @@ case XFER_UDMA_2: case XFER_UDMA_1: case XFER_UDMA_0: + /* Force the UDMA bit on if we want to use UDMA */ + reg |= 0x80; /* clean reg cycle time bits */ - reg &= ~((0xFF >> (8 - cycle_time_range[dma_capability])) - << cycle_time_offset[dma_capability]); + reg &= ~((0xFF >> (8 - cycle_time_range[chipset_family])) + << cycle_time_offset[chipset_family]); /* set reg cycle time bits */ - reg |= cycle_time_value[dma_capability-ATA_00][speed-XFER_UDMA_0] - << cycle_time_offset[dma_capability]; + reg |= cycle_time_value[chipset_family-ATA_00][speed-XFER_UDMA_0] + << cycle_time_offset[chipset_family]; pci_write_config_byte(dev, drive_pci+1, reg); break; case XFER_MW_DMA_2: @@ -638,17 +636,17 @@ drive->dn, ultra); #endif - if ((id->dma_ultra & 0x0020) && ultra && udma_66 && (dma_capability >= ATA_100)) + if ((id->dma_ultra & 0x0020) && ultra && udma_66 && (chipset_family >= ATA_100a)) speed = XFER_UDMA_5; - else if ((id->dma_ultra & 0x0010) && ultra && udma_66 && (dma_capability >= ATA_66)) + else if ((id->dma_ultra & 0x0010) && ultra && udma_66 && (chipset_family >= ATA_66)) speed = XFER_UDMA_4; - else if ((id->dma_ultra & 0x0008) && ultra && udma_66 && (dma_capability >= ATA_66)) + else if ((id->dma_ultra & 0x0008) && ultra && udma_66 && (chipset_family >= ATA_66)) speed = XFER_UDMA_3; - else if ((id->dma_ultra & 0x0004) && ultra && (dma_capability >= ATA_33)) + else if ((id->dma_ultra & 0x0004) && ultra && (chipset_family >= ATA_33)) speed = XFER_UDMA_2; - else if ((id->dma_ultra & 0x0002) && ultra && (dma_capability >= ATA_33)) + else if ((id->dma_ultra & 0x0002) && ultra && (chipset_family >= ATA_33)) speed = XFER_UDMA_1; - else if ((id->dma_ultra & 0x0001) && ultra && (dma_capability >= ATA_33)) + else if ((id->dma_ultra & 0x0001) && ultra && (chipset_family >= ATA_33)) speed = XFER_UDMA_0; else if (id->dma_mword & 0x0004) speed = XFER_MW_DMA_2; @@ -681,6 +679,8 @@ struct hd_driveid *id = drive->id; ide_dma_action_t dma_func = ide_dma_off_quietly; + (void) config_chipset_for_pio(drive, 5); + if (id && (id->capability & 1) && HWIF(drive)->autodma) { /* Consult the list of known "bad" drives */ if (ide_dmaproc(ide_dma_bad_drive, drive)) { @@ -745,10 +745,6 @@ struct pci_dev *host; int i = 0; -#ifdef DEBUG - sis5513_print_registers(dev, "pci_init_sis5513 start"); -#endif - /* Find the chip */ for (i = 0; i < ARRAY_SIZE(SiSHostChipInfo) && !host_dev; i++) { host = pci_find_device (PCI_VENDOR_ID_SI, @@ -758,12 +754,16 @@ continue; host_dev = host; - dma_capability = SiSHostChipInfo[i].dma_capability; + chipset_family = SiSHostChipInfo[i].chipset_family; printk(SiSHostChipInfo[i].name); printk("\n"); +#ifdef DEBUG + sis5513_print_registers(dev, "pci_init_sis5513 start"); +#endif + if (SiSHostChipInfo[i].flags & SIS5513_LATENCY) { - byte latency = (dma_capability == ATA_100)? 0x80 : 0x10; /* Lacking specs */ + byte latency = (chipset_family == ATA_100)? 0x80 : 0x10; /* Lacking specs */ pci_write_config_byte(dev, PCI_LATENCY_TIMER, latency); } } @@ -773,7 +773,7 @@ 2/ tell old chips to allow per drive IDE timings */ if (host_dev) { byte reg; - switch(dma_capability) { + switch(chipset_family) { case ATA_133: case ATA_100: /* Set compatibility bit */ @@ -782,6 +782,7 @@ pci_write_config_byte(dev, 0x49, reg|0x01); } break; + case ATA_100a: case ATA_66: /* On ATA_66 chips the bit was elsewhere */ pci_read_config_byte(dev, 0x52, ®); @@ -827,7 +828,7 @@ byte mask = hwif->channel ? 0x20 : 0x10; pci_read_config_byte(hwif->pci_dev, 0x48, ®48h); - if (dma_capability >= ATA_66) { + if (chipset_family >= ATA_66) { ata66 = (reg48h & mask) ? 0 : 1; } return ata66; @@ -846,7 +847,7 @@ if (host_dev) { #ifdef CONFIG_BLK_DEV_IDEDMA - if (dma_capability > ATA_16) { + if (chipset_family > ATA_16) { hwif->autodma = noautodma ? 0 : 1; hwif->dmaproc = &sis5513_dmaproc; } else { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/slc90e66.c linux.19pre5-ac1/drivers/ide/slc90e66.c --- linux.19p5/drivers/ide/slc90e66.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/ide/slc90e66.c Thu Mar 14 22:09:41 2002 @@ -86,13 +86,8 @@ * at that point bibma+0x2 et bibma+0xa are byte registers * to investigate: */ -#ifdef __mips__ /* only for mips? */ c0 = inb_p(bibma + 0x02); c1 = inb_p(bibma + 0x0a); -#else - c0 = inb_p((unsigned short)bibma + 0x02); - c1 = inb_p((unsigned short)bibma + 0x0a); -#endif p += sprintf(p, " SLC90E66 Chipset.\n"); p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/trm290.c linux.19pre5-ac1/drivers/ide/trm290.c --- linux.19p5/drivers/ide/trm290.c Thu Apr 4 13:19:32 2002 +++ linux.19pre5-ac1/drivers/ide/trm290.c Thu Mar 21 00:32:25 2002 @@ -195,8 +195,26 @@ if (drive->media != ide_disk) return 0; ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); - OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); - return 0; +/* + * FIX ME to use only ACB ide_task_t args Struct + */ +#if 0 + { + ide_task_t *args = HWGROUP(drive)->rq->special; + OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG); + } +#else + if ((HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE) && + (drive->addressing == 1)) { + ide_task_t *args = HWGROUP(drive)->rq->special; + OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG); + } else if (drive->addressing) { + OUT_BYTE(reading ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG); + } else { + OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); + } +#endif + return HWIF(drive)->dmaproc(ide_dma_begin, drive); case ide_dma_begin: return 0; case ide_dma_end: diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/md/md.c linux.19pre5-ac1/drivers/md/md.c --- linux.19p5/drivers/md/md.c Thu Apr 4 13:19:50 2002 +++ linux.19pre5-ac1/drivers/md/md.c Wed Feb 27 18:32:03 2002 @@ -2936,8 +2936,6 @@ * bdflush, otherwise bdflush will deadlock if there are too * many dirty RAID5 blocks. */ - current->policy = SCHED_OTHER; - current->nice = -20; md_unlock_kernel(); complete(thread->event); @@ -3387,11 +3385,6 @@ "(but not more than %d KB/sec) for reconstruction.\n", sysctl_speed_limit_max); - /* - * Resync has low priority. - */ - current->nice = 19; - is_mddev_idle(mddev); /* this also initializes IO event counters */ for (m = 0; m < SYNC_MARKS; m++) { mark[m] = jiffies; @@ -3469,16 +3462,13 @@ currspeed = (j-mddev->resync_mark_cnt)/2/((jiffies-mddev->resync_mark)/HZ +1) +1; if (currspeed > sysctl_speed_limit_min) { - current->nice = 19; - if ((currspeed > sysctl_speed_limit_max) || !is_mddev_idle(mddev)) { current->state = TASK_INTERRUPTIBLE; md_schedule_timeout(HZ/4); goto repeat; } - } else - current->nice = -20; + } } printk(KERN_INFO "md: md%d: sync done.\n",mdidx(mddev)); err = 0; @@ -3708,7 +3698,7 @@ * Searches all registered partitions for autorun RAID arrays * at boot time. */ -static int detected_devices[128]; +static kdev_t detected_devices[128]; static int dev_cnt; void md_autodetect_dev(kdev_t dev) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/Config.in linux.19pre5-ac1/drivers/media/video/Config.in --- linux.19p5/drivers/media/video/Config.in Thu Apr 4 13:19:44 2002 +++ linux.19pre5-ac1/drivers/media/video/Config.in Thu Feb 21 23:41:27 2002 @@ -11,6 +11,8 @@ if [ "$CONFIG_I2C_ALGOBIT" = "y" -o "$CONFIG_I2C_ALGOBIT" = "m" ]; then dep_tristate ' BT848 Video For Linux' CONFIG_VIDEO_BT848 $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_I2C_ALGOBIT fi +dep_tristate ' Luxsonor LS220 (EXPERIMENTAL)' CONFIG_VIDEO_LS220 $CONFIG_VIDEO_DEV +dep_tristate ' Margi DVD-to-Go (EXPERIMENTAL)' CONFIG_VIDEO_MARGI $CONFIG_PCMCIA $CONFIG_VIDEO_DEV dep_tristate ' Mediavision Pro Movie Studio Video For Linux' CONFIG_VIDEO_PMS $CONFIG_VIDEO_DEV if [ "$CONFIG_ALL_PPC" = "y" ]; then dep_tristate ' PlanB Video-In on PowerMac' CONFIG_VIDEO_PLANB $CONFIG_VIDEO_DEV diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/Makefile linux.19pre5-ac1/drivers/media/video/Makefile --- linux.19p5/drivers/media/video/Makefile Thu Apr 4 13:19:44 2002 +++ linux.19pre5-ac1/drivers/media/video/Makefile Fri Feb 22 00:29:13 2002 @@ -1,5 +1,5 @@ # -# Makefile for the kernel character device drivers. +# Makefile for the video capture/playback device drivers. # # Note! Dependencies are done automagically by 'make dep', which also # removes any old dependencies. DON'T put your own dependencies here @@ -16,10 +16,6 @@ obj-n := obj- := -SUB_DIRS := -MOD_SUB_DIRS := $(SUB_DIRS) -ALL_SUB_DIRS := $(SUB_DIRS) - O_TARGET := video.o # All of the (potential) objects that export symbols. @@ -31,8 +27,16 @@ bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o +mod-subdirs := margi + obj-$(CONFIG_VIDEO_DEV) += videodev.o +ifeq ($(CONFIG_VIDEO_MARGI),y) + obj-y += margi/margi_cs.o +endif + +subdir-$(CONFIG_VIDEO_MARGI) += margi + obj-$(CONFIG_BUS_I2C) += i2c-old.o obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \ tda7432.o tda9875.o tuner.o @@ -58,6 +62,7 @@ obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o obj-$(CONFIG_VIDEO_MEYE) += meye.o obj-$(CONFIG_TUNER_3036) += tuner-3036.o +obj-$(CONFIG_VIDEO_LS220) += luxsonor.o # Extract lists of the multi-part drivers. # The 'int-*' lists are the intermediate files used to build the multi's. @@ -78,8 +83,6 @@ include $(TOPDIR)/Rules.make -fastdep: - zoran.o: zr36120.o zr36120_i2c.o zr36120_mem.o $(LD) $(LD_RFLAG) -r -o $@ zr36120.o zr36120_i2c.o zr36120_mem.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/ac3.h linux.19pre5-ac1/drivers/media/video/ls220/ac3.h --- linux.19p5/drivers/media/video/ls220/ac3.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/ls220/ac3.h Thu Feb 21 20:41:21 2002 @@ -0,0 +1,2850 @@ +static u32 AC3Ucode1f1800[] = { + 0xb500000f, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xb5001223, 0x00000000, 0x00000000, 0x00000000, + 0x820f001f, 0x802f001f, 0x80070800, 0x001f6193, + 0x800500d4, 0x8053ffff, 0x9842c7ff, 0x8039ff7c, + 0x1400b802, 0x003f6000, 0x94210007, 0xb0010001, + 0xb4200001, 0x98002800, 0xb0010000, 0xb4200001, + 0x98000800, 0x805300ff, 0x1800b802, 0x800600d4, + 0x8013001f, 0x9020c000, 0x003fb006, 0x803effe0, + 0x803effe8, 0x803effec, 0x9020e000, 0x9021ffe4, + 0x9020fa00, 0x803effd0, 0x803effdc, 0x803effd8, + 0x9020fe00, 0x803effd4, 0x90400000, 0x804600a2, + 0x90421800, 0x804600a3, 0x80134099, 0x98000040, + 0x800600a6, 0x80130000, 0x98003ca1, 0x800600a1, + 0x80050080, 0x98000002, 0x80060080, 0x80070001, + 0x001f2013, 0x001f2324, 0x80070000, 0x001fb0ba, + 0x001f23f9, 0x801eb3f0, 0x80070800, 0x001f600f, + 0x80070000, 0x001f2012, 0x001fb0cb, 0x001fb010, + 0x801efff0, 0x98004000, 0x98008000, 0x001f600e, + 0x83e40137, 0x80070000, 0x801eb3f8, 0x801eff70, + 0x800500a0, 0xb0000001, 0xb4000009, 0x80070001, + 0x800600a0, 0x80050080, 0x98000020, 0x80060080, + 0x9400ffdf, 0x80060080, 0x80070000, 0x800600a0, + 0x81df0004, 0x00000000, 0x00000000, 0x801bfff0, + 0x00000000, 0x940000ff, 0xb0000000, 0xb420004e, + 0x003f400e, 0x94010010, 0xb0000000, 0xb400fff4, + 0x838413d5, 0x003f0013, 0xb0010001, 0xb420003b, + 0x803bffe8, 0x801bffec, 0x00000000, 0x3001b800, + 0xb4600001, 0x90212000, 0x0421b800, 0x005f4193, + 0x5841b802, 0x3001b802, 0xb460000d, 0x80050086, + 0x005f9016, 0xb0020000, 0xb4200002, 0x001fb016, + 0xb500ffdf, 0x0420b802, 0xb0010b50, 0xb4a0ffdc, + 0x80070000, 0x001fb016, 0x83e40101, 0xb500ffd8, + 0x80070000, 0x001fb016, 0x001f400e, 0x9400000f, + 0xb0000000, 0xb4000014, 0xb0000001, 0xb4000010, + 0x003f400e, 0x9421fff0, 0x003f600e, 0x003f9006, + 0x9421ffff, 0x90210004, 0xb001e000, 0xb4800002, + 0x8421e000, 0x9021c000, 0x8013001f, 0x1021b800, + 0x003fb006, 0x003f90cb, 0x90210004, 0x003fb0cb, + 0x83e400f7, 0x83e413b4, 0x8007001f, 0x94000003, + 0x5810b800, 0x83e71aa8, 0x1bffb800, 0x003f9008, + 0x1821b800, 0x00ffb801, 0x83e41407, 0x80270000, + 0x003f2013, 0x8007001f, 0x94000003, 0x5810b800, + 0x83671ad4, 0x1b7bb800, 0x003f9009, 0x1821b800, + 0x00ffb801, 0xb500ffaa, 0x803bffc0, 0x805bffc4, + 0x807bffc8, 0x809bffcc, 0x5828b801, 0x5cb8b802, + 0x1821b805, 0x5848b802, 0x5cb8b803, 0x1842b805, + 0x5868b803, 0x5cb8b804, 0x1863b805, 0x5888b804, + 0x1884b800, 0x803effc0, 0x805effc4, 0x807effc8, + 0x809effcc, 0x003f400e, 0xb0000086, 0xb4400040, + 0xb0000084, 0xb400002a, 0xb0000085, 0xb4000030, + 0xb0000086, 0xb4000032, 0x001f4000, 0x94000080, + 0xb0000080, 0xb400006a, 0x80130000, 0x98003ca1, + 0x005f4000, 0x94420008, 0xb0020008, 0xb4000001, + 0xa0000080, 0x800600a1, 0x8013001f, 0x9040c000, + 0x005fb006, 0x805effe0, 0x805effe8, 0x805effec, + 0x9040e000, 0x805effe4, 0x9040fa00, 0x805effd0, + 0x805effdc, 0x805effd8, 0x9040fe00, 0x805effd4, + 0x80070001, 0x001f2013, 0x80070000, 0x001fb0cb, + 0x001fb010, 0x001f2058, 0x80071fc0, 0x001fb008, + 0x80075fb0, 0x001fb009, 0x98214000, 0xb5000010, + 0x94011000, 0xb0001000, 0xb4200001, 0x9421efff, + 0x98210010, 0xb500000a, 0x80070000, 0x001fb0cb, + 0x83e40097, 0x003f400e, 0x9421ffef, 0xb5000004, + 0x83e40093, 0x003f400e, 0x98211000, 0x9421ffef, + 0x003f600e, 0x80070100, 0x801efff0, 0xb500ff54, + 0xb000008b, 0xb400001c, 0xb000008e, 0xb4000022, + 0xb000008d, 0xb400001c, 0xb000008c, 0xb4000021, + 0xb0000087, 0xb400ffe8, 0xb0000088, 0xb4000014, + 0xb000008a, 0xb4000015, 0xb0000089, 0xb400001d, + 0xb00000a0, 0xb400001f, 0xb00000a1, 0xb4000041, + 0xb00000a2, 0xb400004e, 0xb00000a3, 0xb4000046, + 0xb00000a4, 0xb4000050, 0xb00000a5, 0xb4000054, + 0xb00000a6, 0xb4000058, 0x803efff8, 0xb500ffdd, + 0x9421ffdf, 0xb500ffda, 0xb500ffda, 0x80270100, + 0x803efff8, 0xb500ffd7, 0x80070000, 0x001fb017, + 0xb500ffd4, 0x801bffb0, 0x00000000, 0x001fb003, + 0xb500ffd0, 0x803bff80, 0x00000000, 0x003f6001, + 0xb500ffcc, 0x003f90ba, 0x803efff8, 0xb500ffc9, + 0x80130001, 0x98003da1, 0x800600a1, 0x80070200, + 0x801ebf34, 0x83e40042, 0x8013001f, 0x9840c000, + 0x805effe0, 0x005fb006, 0x805effe8, 0x805effec, + 0x90422000, 0x805effe4, 0x9040fa00, 0x805effd0, + 0x805effdc, 0x805effd8, 0x9040fe00, 0x805effd4, + 0x80070001, 0x001f2013, 0x80070000, 0x001f2324, + 0x001fb0cb, 0x001fb010, 0x001f2058, 0x80077560, + 0x001fb008, 0x80077810, 0x001fb009, 0x98214000, + 0xb500ffa7, 0x80270000, 0x8047fef0, 0x003eb802, + 0x90420004, 0x003eb802, 0x90420004, 0x003eb802, + 0x90420004, 0x003eb802, 0x81df0000, 0x00000000, + 0x00000000, 0x83641491, 0x81df0004, 0xb500ff99, + 0x81df0000, 0x00000000, 0x00000000, 0x8364143b, + 0x81df0004, 0xb500ff93, 0x81df0000, 0x00000000, + 0x00000000, 0x836413f6, 0x81df0004, 0xb500ff8d, + 0x81df0000, 0x00000000, 0x00000000, 0x83441359, + 0x81df0004, 0xb500ff87, 0x81df0000, 0x00000000, + 0x00000000, 0x8344133e, 0x81df0004, 0xb500ff81, + 0x80070000, 0x80470000, 0x81df0000, 0x00000000, + 0x00000000, 0xb6002003, 0xb6003002, 0x001eb802, + 0x90420004, 0x80171000, 0x8057ffff, 0xb6002002, + 0xb6001801, 0x001fa020, 0x81df0004, 0x00ffb81f, + 0x001f4000, 0x94000080, 0xb0000080, 0xb4200001, + 0xb500ffeb, 0xb500000a, 0x80270000, 0x003f2013, + 0x8007001f, 0x94000003, 0x5810b800, 0x83671ea0, + 0x1b7bb800, 0x003f9009, 0x1821b800, 0x00ffb801, + 0x003f0013, 0xb0010001, 0xb420fff3, 0x83a70000, + 0x803bff70, 0x00000000, 0xb0010000, 0xb4000015, + 0x80170300, 0x80070000, 0x81df0000, 0x00000000, + 0x00000000, 0xb6000601, 0x001fa020, 0x83640ce3, + 0x00ff0325, 0x82870000, 0xb6270002, 0x83640228, + 0x92940001, 0x81df0004, 0x001f033b, 0xb0000000, + 0xb4000002, 0x80270000, 0xb5000001, 0x80270001, + 0x003f233b, 0x80270000, 0x003f2013, 0x8007001f, + 0x94000003, 0x5810b800, 0x83671f3c, 0x1b7bb800, + 0x003f9009, 0x1821b800, 0x00ffb801, 0x003f0013, + 0xb0010001, 0xb420fff3, 0x93bd0001, 0xb01d0004, + 0xb480ffd7, 0x803bff70, 0x00000000, 0xb0010000, + 0xb4000005, 0x81df0000, 0x00000000, 0x00000000, + 0x83640c8b, 0x81df0004, 0x00000000, 0x00000000, + 0x00ffb81f, 0x007f90cb, 0x90630400, 0x007fb0cb, + 0x003f9006, 0x9421ffff, 0x90210400, 0xb001e000, + 0xb4800002, 0x8421e000, 0x9021c000, 0x8013001f, + 0x1021b800, 0x003fb006, 0x803effec, 0x00ffb81f, + 0x015f400e, 0x944a4000, 0xb0024000, 0xb4200090, + 0x954abfff, 0x015f600e, 0x820f001f, 0x802f001f, + 0x81470000, 0x015f23f9, 0x829702ec, 0x82d7ffff, + 0x82f70000, 0x81df0000, 0x00000000, 0x00000000, + 0xb6000501, 0x029fa02a, 0x82970400, 0xb6000702, + 0xb6000001, 0x029fa02a, 0x81df0004, 0x8053ff00, + 0x98420000, 0x805ebf14, 0x805ebf18, 0x805ebf1c, + 0x805ebf20, 0x805ebf24, 0x805ebf28, 0x80270000, + 0x003f2328, 0x80275480, 0x005fb801, 0x8033001f, + 0x9821c000, 0x803effe0, 0x90212000, 0x803effe4, + 0x80dbff8c, 0x80fbff90, 0x80debf14, 0x80febf18, + 0x80dbff94, 0x80fbff98, 0x80debf1c, 0x80febf20, + 0x80dbff9c, 0x80fbffa0, 0x80debf24, 0x80febf28, + 0x80dbff84, 0x80e70001, 0x00dfb001, 0x80dbff88, + 0x00ff6191, 0x00dfb002, 0x80dbffb0, 0x80470000, + 0x00dfb003, 0x80d9ff80, 0x005fb0cf, 0x005fb0c6, + 0x00df6001, 0x80470001, 0x005f618f, 0x804700ff, + 0x005f231c, 0x005f231d, 0x80470000, 0x005f204e, + 0x8047e138, 0x5c42b802, 0x814f6300, 0x80cf00a9, + 0x005fb0bc, 0x5842b802, 0x01cfb802, 0x005f90bc, + 0xb520ffff, 0x8067e16c, 0x5c62b803, 0x80270040, + 0x81df0000, 0x00000000, 0x00000000, 0xb6000209, + 0x814fffc0, 0x00cfb801, 0x007fb0bc, 0x5862b803, + 0x01cfb803, 0x007f90bc, 0xb520ffff, 0x90210020, + 0x90630020, 0x81df0004, 0x8047e398, 0x5c42b802, + 0x814fce40, 0x80cf0080, 0x005fb0bc, 0x5842b802, + 0x01cfb802, 0x005f90bc, 0xb520ffff, 0x8047e400, + 0x5c42b802, 0x814f7380, 0x80cf009a, 0x005fb0bc, + 0x5842b802, 0x01cfb802, 0x005f90bc, 0xb520ffff, + 0x8047e43c, 0x5c42b802, 0x814f18c0, 0x80cf00b6, + 0x005fb0bc, 0x5842b802, 0x01cfb802, 0x005f90bc, + 0xb520ffff, 0x80e70000, 0x00ffb0ba, 0x808f0000, + 0x806f001f, 0x80af001f, 0x8027b9fc, 0x5c22b801, + 0x80670700, 0x81df0000, 0x00000000, 0x00000000, + 0xb600080a, 0x00cfb803, 0x003fb0bc, 0x5822b801, + 0x01cfb801, 0x003f90bc, 0x0047b86f, 0xb0020001, + 0xb4c0fffd, 0x90210020, 0x90630020, 0x81df0004, + 0x834400d7, 0xb0180000, 0xb4200025, 0x834406dc, + 0x80c70000, 0x00df2324, 0x83640026, 0x83440228, + 0x00df0324, 0x90c60001, 0x00df2324, 0xb0060006, + 0xb4000003, 0x81472228, 0x015fb008, 0x00ffb81f, + 0x00ff90ba, 0x90e70001, 0x00ffb0ba, 0x019f9006, + 0x958cffff, 0x00df4193, 0x58c1b806, 0x118cb806, + 0xb00ce000, 0xb4800002, 0x858ce000, 0x918cc000, + 0x8153001f, 0x118cb80a, 0x819effec, 0x019fb006, + 0x015f4193, 0x5941b80a, 0x019f90cb, 0x118cb80a, + 0x019fb0cb, 0x81472210, 0x015fb008, 0x00ffb81f, + 0x015f400e, 0x194ab818, 0x015f600e, 0x802500a5, + 0x00ffb81f, 0x803bff8c, 0x805bff90, 0x803ebf14, + 0x805ebf18, 0x803bff94, 0x805bff98, 0x803ebf1c, + 0x805ebf20, 0x803bff9c, 0x805bffa0, 0x803ebf24, + 0x805ebf28, 0x80470003, 0x805ebefc, 0x003f0384, + 0x5822b801, 0x9021eb50, 0x005bb801, 0x00000000, + 0xb0020001, 0xb4200002, 0x80470001, 0x805ebefc, + 0x8073ff80, 0x98630000, 0x8027bf14, 0x8047befc, + 0x81df0000, 0x00000000, 0x00000000, 0xb6000609, + 0x009bb801, 0x00000000, 0x00a7b804, 0x6081b804, + 0x3004b803, 0xb4000001, 0x00beb802, 0x90210004, + 0x90420004, 0x81df0004, 0x00ffb81b, 0x00000000, + 0x81150010, 0x00000000, 0x00000000, 0x81350010, + 0x00000000, 0x00000000, 0x81550002, 0x00000000, + 0x015f2380, 0x81550006, 0x00000000, 0x015f2381, + 0x81550005, 0x00000000, 0x015f2382, 0x81550003, + 0x00000000, 0x015f2383, 0x81550003, 0x015f2384, + 0xb00a0001, 0xb4000005, 0x956a0001, 0xb00b0000, + 0xb4000002, 0x81750002, 0x017f2385, 0x956a0004, + 0xb00b0000, 0xb4000002, 0x81750002, 0x017f2386, + 0xb00a0002, 0xb4200003, 0x81750002, 0x00000000, + 0x017f2387, 0x81750001, 0x00000000, 0x017f2388, + 0x81750005, 0x00000000, 0x017f2389, 0x81750001, + 0x017f239f, 0xb00b0001, 0xb4200003, 0x81750008, + 0x5968b80b, 0x017f61c5, 0x81750001, 0x017f238c, + 0xb00b0001, 0xb4200003, 0x81750008, 0x00000000, + 0x017f238d, 0x81750001, 0x017f238e, 0xb00b0001, + 0xb4200005, 0x81750005, 0x00000000, 0x017f238f, + 0x81750002, 0x017f2390, 0xb00a0000, 0xb420001b, + 0x81750005, 0x00000000, 0x017f2391, 0x81750001, + 0x017f23a0, 0xb00b0001, 0xb4200003, 0x81750008, + 0x5968b80b, 0x017f61c9, 0x81750001, 0x017f2394, + 0xb00b0001, 0xb4200003, 0x81750008, 0x00000000, + 0x017f2395, 0x81750001, 0x017f2396, 0xb00b0001, + 0xb4200006, 0x81750005, 0x00000000, 0x017f2397, + 0x81750002, 0x00000000, 0x017f2398, 0x81750001, + 0x00000000, 0x017f2399, 0x81750001, 0x00000000, + 0x017f239a, 0x81750001, 0x017f239b, 0xb00b0001, + 0xb4200003, 0x8175000e, 0x00000000, 0x017f61be, + 0x81750001, 0x017f239c, 0xb00b0001, 0xb4200003, + 0x8175000e, 0x00000000, 0x017f237e, 0x81750001, + 0x017f239d, 0xb00b0001, 0xb4200006, 0x81750006, + 0x017f239e, 0x916b0001, 0x81550008, 0x856b0001, + 0xb4e0fffd, 0x00ffb81c, 0x00000000, 0x00000000, + 0x81470000, 0x015f2385, 0x015f2386, 0x015f2387, + 0x015f238d, 0x015f238f, 0x015f2390, 0x015f2391, + 0x015f2395, 0x015f2396, 0x015f2397, 0x015f2398, + 0x015f61be, 0x015f61bf, 0x82070028, 0x023f9006, + 0x83a40034, 0x83270000, 0x003fb819, 0x003f9006, + 0x5823b801, 0x83338000, 0x1b39b801, 0x003fb819, + 0x00000000, 0x00000000, 0x81550000, 0x8384ff64, + 0x017f0380, 0xad4b0026, 0x013f0381, 0x114ab809, + 0x5941b80a, 0x914ae00c, 0x0199b80a, 0x00000000, + 0x019f6193, 0xb0080b77, 0xb4200010, 0x015f0380, + 0xb00a0003, 0xb4600011, 0xb0090026, 0xb4600013, + 0x017f90ba, 0xb00b0000, 0xb4200002, 0x017f0383, + 0x017f2057, 0x015f0383, 0x017f0057, 0x300ab80b, + 0xb420000e, 0x83070000, 0x00ffb81a, 0x83070800, + 0x031f6193, 0x83070001, 0x00ffb81a, 0x83070800, + 0x031f6193, 0x83070002, 0x00ffb81a, 0x83070800, + 0x031f6193, 0x83070003, 0x00ffb81a, 0x83070003, + 0x00ffb81a, 0x5e02b810, 0x5a02b810, 0x00bf9011, + 0x00df004f, 0xa5260020, 0x81e70000, 0x82471000, + 0x95d1ffff, 0xa5cee000, 0x300eb810, 0xb4600002, + 0x05f0b80e, 0x0207b80e, 0x8267001f, 0x82c70020, + 0x82971000, 0xb0100080, 0xb4800023, 0x5a8bb813, + 0x5aa6b813, 0x1a94b815, 0x01efb812, 0x014fb814, + 0x01cfb811, 0xb520ffff, 0x81df0000, 0x00000000, + 0x00000000, 0xb636000f, 0x81470000, 0x039f8014, + 0xb6000404, 0x5948b80a, 0x957c00ff, 0x194ab80b, + 0x5f88b81c, 0xb0060020, 0xb4200001, 0x80a70000, + 0x64a6b805, 0x68e9b80a, 0x18a5b807, 0x029fa025, + 0x00a7b80a, 0x81df0004, 0x01efb812, 0x014fb814, + 0x01afb811, 0xb520ffff, 0x5ae2b816, 0x1231b817, + 0x0610b817, 0xb500ffda, 0xb0100000, 0xb4000003, + 0x5ec2b810, 0x86760001, 0xb500ffd8, 0xb00f0000, + 0xb4000005, 0x0207b80f, 0x81f3001f, 0x9a2fc000, + 0x81e70000, 0xb500ffcc, 0x015fb011, 0x00ffb81d, + 0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x81d7ffff, + 0x8257ffff, 0x82d7ffff, 0x8357ffff, 0x83d7ffff, + 0x80770000, 0x80f70000, 0x81770000, 0x81f70000, + 0x82770000, 0x82f70000, 0x83770000, 0x83f70000, + 0xaeb40080, 0x808f0000, 0x806f001f, 0x80af001f, + 0xb0140000, 0xb4400014, 0x806f001f, 0x80af001f, + 0x8027b9fc, 0x5c22b801, 0x80670700, 0xb6000208, + 0x00cfb803, 0x003fb0bc, 0x5822b801, 0x01cfb801, + 0x003f90bc, 0xb520ffff, 0x90630020, 0x90210020, + 0x80270000, 0x80171000, 0xb6000303, 0xb6000001, + 0x001fa021, 0x00000000, 0x82670000, 0xb6000268, + 0x80170a00, 0x80970afc, 0x81170b00, 0x81970bfc, + 0x80271c00, 0x1021b813, 0x1021b813, 0x0217b801, + 0x80271ffc, 0x0421b813, 0x0421b813, 0x0297b801, + 0x80270c00, 0x1021b813, 0x1021b813, 0x0317b801, + 0x80270ffc, 0x0421b813, 0x0421b813, 0x0397b801, + 0x80478500, 0x1042b813, 0x5c42b802, 0x1022b815, + 0x80670280, 0x00cfb803, 0x003fb0bc, 0x5822b801, + 0x01cfb801, 0x003f90bc, 0xb520ffff, 0x009f033b, + 0x80478480, 0x0442b813, 0x5c42b802, 0x1022b815, + 0x806702a0, 0x00cfb803, 0x003fb0bc, 0x5822b801, + 0x01cfb801, 0x003f90bc, 0xb520ffff, 0xb0040000, + 0xb4000002, 0x80479000, 0xb5000001, 0x80479c00, + 0x1042b813, 0x5c42b802, 0x1022b815, 0x806702c0, + 0x00cfb803, 0x003fb0bc, 0x5822b801, 0x01cfb801, + 0x003f90bc, 0xb520ffff, 0xb0040000, 0xb4000002, + 0x80479180, 0xb5000001, 0x80479d80, 0x0442b813, + 0x5c42b802, 0x1022b815, 0x806702e0, 0x00cfb803, + 0x003fb0bc, 0x5822b801, 0x01cfb801, 0x003f90bc, + 0xb520ffff, 0x81270000, 0x80370000, 0x80b70000, + 0x81370000, 0x81b70000, 0x82370004, 0x82b7fffc, + 0xb6002016, 0x41498008, 0x51498814, 0x51498814, + 0x51418810, 0x51418810, 0x41818814, 0x0308a02a, + 0x49958820, 0x51898810, 0x51918828, 0x414d8814, + 0x0388a7ec, 0x494d8814, 0x49458810, 0x49458810, + 0x418d8810, 0x0308a02a, 0x49918fec, 0x51858814, + 0x51958fe4, 0x00000000, 0x0388a7ec, 0x92730080, + 0x009f033b, 0x5802b814, 0x90400300, 0x001f9802, + 0x00000000, 0xb0000000, 0xb4200016, 0x80170a00, + 0x80070000, 0xb6002001, 0x001fa020, 0xb0040000, + 0xb4200002, 0x80279000, 0xb5000001, 0x80279c00, + 0xac740080, 0x5c22b801, 0x11e1b803, 0x806f001f, + 0x80af001f, 0xb6000407, 0x80cf0280, 0x01ffb0bc, + 0x59e2b80f, 0x01afb80f, 0x01ff90bc, 0xb520ffff, + 0x91ef0020, 0x007f0320, 0x011f90cd, 0xaca30006, + 0x80c7b004, 0x10a5b814, 0x58a1b805, 0x10a5b806, + 0x0099b805, 0x8027b3dc, 0x5841b804, 0x1021b802, + 0x0159b801, 0x8027b3d0, 0x5841b804, 0x1021b802, + 0x0139b801, 0x80170c00, 0x0097b80a, 0xb0090000, + 0xb4200004, 0xb6000002, 0x015f8020, 0x009fe0ca, + 0xb5000004, 0x015fc024, 0xb6000002, 0x015f8020, + 0x009fe0ca, 0x00ffb81b, 0x00000000, 0x00000000, + 0x009f0011, 0x015f0012, 0xb0060000, 0xb4200007, + 0x968a0001, 0xb0140000, 0xb400000d, 0x80870001, + 0x009f2011, 0x954a0002, 0x015f2012, 0xb0060002, + 0xb4200007, 0x968a0002, 0xb0140000, 0xb4000004, + 0x80870001, 0x009f2011, 0x81470000, 0x015f2012, + 0x83640037, 0x00bf2010, 0xb0060000, 0xb4200003, + 0xb0050000, 0xb4200001, 0x836400a1, 0xb0050000, + 0xb4200001, 0x836400ca, 0x00bf0010, 0xb0050000, + 0xb420000a, 0x81df0000, 0x00000000, 0x00000000, + 0x836409e4, 0x836402f6, 0x00000000, 0x8364098c, + 0x81df0004, 0x00000000, 0xb5000009, 0x00bf0010, + 0xb0050001, 0xb4000006, 0x00000000, 0x81df0000, + 0x00000000, 0x00000000, 0x83640981, 0x81df0004, + 0x00ff0325, 0x82870000, 0x81df0000, 0x00000000, + 0x00000000, 0xb6270002, 0x8364fef5, 0x92940001, + 0x81df0004, 0x80070001, 0x801eff70, 0x001f0010, + 0xb0000001, 0xb4000007, 0x001f033b, 0xb0000000, + 0xb4000002, 0x80270000, 0xb5000001, 0x80270001, + 0x003f233b, 0x00ffb81a, 0x00000000, 0x00000000, + 0x027f4001, 0x5e2ab813, 0x96310003, 0x81c70000, + 0x820700ff, 0xb0110000, 0xb4000005, 0x5a21b811, + 0x81c70200, 0x8207000e, 0x69d1b80e, 0x1210b811, + 0x01dfb0cd, 0x5e2cb813, 0x96310003, 0x023f2323, + 0x5e28b813, 0x96310003, 0x023f2322, 0x5e27b813, + 0x96310001, 0x023f2328, 0x5e23b813, 0x96310001, + 0x023f2321, 0x95f30007, 0x01ff2320, 0x920fe004, + 0x0258b810, 0x00000000, 0x1252b811, 0x025f2325, + 0x8167befc, 0x017f6195, 0x021f031c, 0x01df031d, + 0x3010b80f, 0xb4200003, 0x3011b80e, 0xb4200001, + 0xb5000025, 0x80270000, 0x80471000, 0x0017b802, + 0x8057ffff, 0x81df0000, 0x00000000, 0x00000000, + 0xb6002001, 0x001fa021, 0x80270400, 0x80679000, + 0x5c62b803, 0xb6001809, 0x00cfb801, 0x007fb0bc, + 0x5862b803, 0x01afb803, 0x007f90bc, 0x0047b86f, + 0xb0020001, 0xb4c0fffd, 0x90630020, 0x80679c00, + 0x5c62b803, 0xb6001809, 0x00cfb801, 0x007fb0bc, + 0x5862b803, 0x01afb803, 0x007f90bc, 0x0047b86f, + 0xb0020001, 0xb4c0fffd, 0x90630020, 0x81df0004, + 0x01ff231c, 0x023f231d, 0x83970300, 0x82070000, + 0x81df0000, 0x00000000, 0x00000000, 0xb6320001, + 0x039fa030, 0x81df0004, 0x00bf0010, 0x021f0324, + 0xb0100000, 0xb4200001, 0x80a70000, 0xb0050000, + 0xb4200008, 0xb0040000, 0xb4a00002, 0x80a70001, + 0xb5000004, 0x82070000, 0x021f204e, 0xb4000001, + 0x80a70002, 0xb0050001, 0xb4200007, 0x021f004e, + 0xb0100002, 0xb4a00002, 0x80a70002, 0x00ffb81b, + 0x92100001, 0x021f204e, 0x00000000, 0x00ffb81b, + 0x81530000, 0x003fb80a, 0x00000000, 0x00000000, + 0x003fb819, 0x00000000, 0x00000000, 0x81550000, + 0x8384fd63, 0x81470000, 0x015f61ee, 0x015f61ef, + 0x015f23a4, 0x8297050c, 0x82d7ffff, 0x81df0000, + 0x00000000, 0x00000000, 0xb6000501, 0x029fa02a, + 0x81df0004, 0x8167e004, 0x116b0384, 0x0158b80b, + 0x019f0382, 0x015f237b, 0x017f0388, 0x116bb80a, + 0xb00c0008, 0xb4a00003, 0x80a70003, 0x00bf2010, + 0x00ffb81b, 0xb00a0005, 0xb4400003, 0xb00b0006, + 0xb4400001, 0x00ffb81b, 0x80a70004, 0x00bf2010, + 0x00ffb81b, 0x00000000, 0x00000000, 0x00000000, + 0x027f0388, 0x02bf037b, 0x02df0384, 0x02ff03a1, + 0x82970400, 0x8257ffff, 0x82d7ffff, 0x81df0000, + 0x00000000, 0x00000000, 0xb6350003, 0x81550001, + 0x8357ffff, 0x029fa02a, 0x82970414, 0xb6350003, + 0x81550001, 0x83d7ffff, 0x029fa02a, 0x81df0004, + 0x81550001, 0xb00a0001, 0xb4200004, 0x814d0008, + 0x6149b80a, 0x954affff, 0x015f61ee, 0xb0160000, + 0xb4200007, 0x81550001, 0xb00a0001, 0xb4200004, + 0x814d0008, 0x6149b80a, 0x954affff, 0x015f61ef, + 0x81550001, 0xb00a0001, 0xb4200042, 0x82f50001, + 0x02ff23a1, 0xb0170001, 0xb4200034, 0x82970428, + 0x81df0000, 0x00000000, 0x00000000, 0xb6350003, + 0x81550001, 0x00000000, 0x029fa02a, 0x81df0004, + 0x82970428, 0x81470000, 0x017f8034, 0xb00b0001, + 0xb4000004, 0x914a0001, 0x300ab815, 0xb480fffa, + 0xb5000001, 0x015f23a5, 0x81670000, 0xb0160002, + 0xb4200002, 0x81750001, 0x00000000, 0x017f233a, + 0x81550004, 0xadaa000c, 0x015f23a2, 0x81750004, + 0x916b0003, 0x017f23a3, 0x91ad0025, 0x01bf23a6, + 0xadab000c, 0x81e70000, 0x91ad0025, 0x01bf23a7, + 0x920a0001, 0x05abb810, 0xb00d0000, 0xb4000015, + 0x81df0000, 0x00000000, 0x00000000, 0xb62d0004, + 0x81b50001, 0x65b0b80d, 0x19efb80d, 0x92100001, + 0x81df0004, 0x01ffb0be, 0xb500000a, 0x81a70000, + 0x82970428, 0x81df0000, 0x00000000, 0x00000000, + 0xb6350001, 0x029fa02d, 0x81df0004, 0x01bf233a, + 0x01bf23a5, 0x82070000, 0x82270000, 0x82170428, + 0x81df0000, 0x00000000, 0x00000000, 0xb635003a, + 0x01bf8030, 0xb00d0001, 0xb4200036, 0x81d50001, + 0x65b1b80e, 0x1a10b80d, 0xb00e0001, 0xb4200031, + 0x81b50002, 0xadad0003, 0xae510048, 0x91cd000f, + 0x91320868, 0x015f03a2, 0xad4a0004, 0x92920700, + 0x1189b80a, 0x0297b80c, 0x1194b80a, 0x0317b80c, + 0x01ff90be, 0x015f03a2, 0x017f03a3, 0x064bb80a, + 0x0107b80a, 0xb0120000, 0xb400001e, 0xb632001d, + 0x6928b80f, 0x95290001, 0xb0090000, 0xb420000e, + 0x81350004, 0x1129b80d, 0x029fa029, 0x824d0004, + 0x5a48b812, 0x5e48b812, 0x3009b80e, 0xb4200002, + 0x5e41b812, 0xb500000d, 0x5e42b812, 0x81330040, + 0x1a52b809, 0xb5000009, 0x0127b854, 0x85290004, + 0x0397b809, 0x0287b858, 0x86940004, 0x013f803c, + 0x0397b814, 0x029fa029, 0x025f803c, 0x031fa032, + 0x91080001, 0x92310001, 0x81df0004, 0x015f03a2, + 0x017f03a3, 0x013f033a, 0xb0090001, 0xb4200023, + 0x95300002, 0x95900001, 0x1929b80c, 0xb0090000, + 0xb400001e, 0x064bb80a, 0x0107b80a, 0x81df0000, + 0x00000000, 0x00000000, 0xb6320017, 0x6928b80f, + 0x95290001, 0xb0090000, 0xb4200002, 0x81350001, + 0x013f23f8, 0x81a70700, 0x91ad0048, 0x5982b808, + 0x11adb80c, 0x0397b80d, 0x013f03f8, 0xb0090001, + 0xb4200005, 0x019f801c, 0x0196b80c, 0x81b3ff80, + 0x418cb80d, 0xb5000002, 0x019f801c, 0x0196b80c, + 0x039fa00c, 0x91080001, 0x81df0004, 0xb0160002, + 0xb420001e, 0xb0170001, 0xb4200008, 0xb00a0000, + 0xb4200002, 0x81270002, 0xb5000005, 0xb00a0002, + 0xb4400002, 0x81270003, 0xb5000001, 0x81270004, + 0x013f23a9, 0x81950001, 0xb00c0001, 0xb4200011, + 0x81a70000, 0x8397043c, 0x81df0000, 0x00000000, + 0x00000000, 0xb6290006, 0x81150001, 0x039fa028, + 0xb0080001, 0xb4200001, 0x81a70001, 0x00000000, + 0x81df0004, 0x01bf23a8, 0xb5000002, 0x81a70000, + 0x01bf23a8, 0xb0170001, 0xb4200001, 0x81b50002, + 0x82970c20, 0x81df0000, 0x00000000, 0x00000000, + 0xb6350003, 0x81550002, 0x00000000, 0x029fa02a, + 0x81df0004, 0xb0130001, 0xb4200001, 0x81150001, + 0x81c70000, 0x81df0000, 0x00000000, 0x00000000, + 0xb6350014, 0x922e0c20, 0x015ff011, 0xb00a0000, + 0xb400000f, 0x922e0428, 0x015ff011, 0xb00a0001, + 0xb4200005, 0x922e044c, 0x0297b811, 0x015f03a6, + 0x029fa00a, 0xb5000006, 0x81550006, 0xad4a0003, + 0x922e044c, 0x0297b811, 0x914a0049, 0x029fa00a, + 0x91ce0004, 0x81df0004, 0xb0170001, 0xb4200022, + 0xb00d0000, 0xb4000020, 0x852d0001, 0x81470001, + 0x6549b80a, 0xad6a0003, 0x019f03a7, 0x058c03a6, + 0x81270000, 0xb00b0000, 0xb4000005, 0x300cb80b, + 0xb4800003, 0x058cb80b, 0x91290001, 0xb500fffb, + 0x81750004, 0x5961b80b, 0x839704ec, 0x0187b860, + 0x039fa02c, 0x039fa02a, 0x039fa029, 0x039fa02b, + 0xb0090000, 0xb4000007, 0x81df0000, 0x00000000, + 0x00000000, 0xb6290003, 0x81550007, 0x00000000, + 0x00000000, 0x81df0004, 0x81c70000, 0x81df0000, + 0x00000000, 0x00000000, 0xb635002e, 0x922e0c20, + 0x01fff011, 0xb00f0000, 0xb4000029, 0x852f0001, + 0x81470001, 0x6549b80a, 0xad6a0003, 0x922e044c, + 0x025fd811, 0x86520001, 0x0227b812, 0x81270000, + 0xb00b0000, 0xb4000005, 0x3012b80b, 0xb4800003, + 0x0652b80b, 0x91290001, 0xb500fffb, 0x2e09b80b, + 0x00000000, 0x3010b811, 0xb4600001, 0x91290001, + 0xae4e0004, 0x82150004, 0x9232049c, 0x0297b811, + 0x0187b860, 0x029fa02c, 0x029fa02a, 0x029fa029, + 0x029fa030, 0xb0090000, 0xb4000004, 0xb6290003, + 0x81550007, 0x00000000, 0x00000000, 0x82270460, + 0x1231b80e, 0x0217b811, 0x81550002, 0x021fa00a, + 0x91ce0004, 0x81df0004, 0xb0130001, 0xb420000c, + 0xb0080000, 0xb400000a, 0x81550004, 0x839704fc, + 0x0167b860, 0x039fa02b, 0x81670001, 0x039fa02b, + 0x8175000e, 0x81670002, 0x039fa02b, 0x039fa02a, + 0x81150001, 0xb0080001, 0xb420000a, 0x8135000b, + 0x5d2923aa, 0x95490180, 0x5d4723ab, 0x95490060, + 0x5d4523ac, 0x95490018, 0x5d4323ad, 0x95490007, + 0x015f23ae, 0x81350001, 0xb0090001, 0xb420001b, + 0x81350006, 0x013f23af, 0xb0170001, 0xb4200005, + 0x81550004, 0x00000000, 0x015f23b0, 0x81550003, + 0x015f23b1, 0x82970474, 0x83170488, 0x81df0000, + 0x00000000, 0x00000000, 0xb6350004, 0x81550007, + 0x5e83a02a, 0x954a0007, 0x031fa02a, 0x81df0004, + 0xb0130001, 0xb4200005, 0x81750004, 0x00000000, + 0x017f23b2, 0x81750003, 0x017f23b3, 0xb0170001, + 0xb420000b, 0x81b50001, 0xb00d0001, 0xb4200008, + 0x81d50003, 0x59c8b80e, 0x91ce0300, 0x01df61da, + 0x81d50003, 0x59c8b80e, 0x91ce0300, 0x01df61db, + 0x81550001, 0xb00a0001, 0xb4200057, 0xb0170001, + 0xb4200001, 0x81550002, 0x82470000, 0x82270000, + 0x81df0000, 0x00000000, 0x00000000, 0xb6350004, + 0x81750002, 0x6571b80b, 0x92310002, 0x1a52b80b, + 0x81df0004, 0xb0170001, 0xb420001b, 0xb00a0001, + 0xb4200015, 0x81150003, 0x91080001, 0x011f23a4, + 0x829709d0, 0x831709f0, 0x83970060, 0x81df0000, + 0x00000000, 0x00000000, 0xb6280009, 0x81750005, + 0x00000000, 0x029fa02b, 0x81750004, 0x00000000, + 0x031fa02b, 0x81750003, 0x00000000, 0x039fa02b, + 0x81df0004, 0xb5000004, 0xb00a0002, 0xb4800002, + 0x81070000, 0x011f23a4, 0x82270000, 0x81270000, + 0x81df0000, 0x00000000, 0x00000000, 0xb6350025, + 0x6a11b812, 0x92310002, 0x96100003, 0xb0100001, + 0xb4200018, 0xada90020, 0x81750003, 0x920d0520, + 0x0217b810, 0x920d05c0, 0x0297b810, 0x920d0660, + 0x0317b810, 0x5942b809, 0x920a050c, 0x0397b810, + 0x916b0001, 0x039fa02b, 0xb62b0009, 0x81750005, + 0x00000000, 0x021fa02b, 0x81750004, 0x00000000, + 0x029fa02b, 0x81750003, 0x00000000, 0x031fa02b, + 0xb5000007, 0xb0100002, 0xb4800005, 0x59a2b809, + 0x91ad050c, 0x0397b80d, 0x82070000, 0x039fa010, + 0x91290001, 0x81df0004, 0x81550001, 0xb00a0001, + 0xb420000a, 0x81550009, 0xb00a0000, 0xb4000007, + 0x81df0000, 0x00000000, 0x00000000, 0xb62a0003, + 0x82150008, 0x00000000, 0x00000000, 0x81df0004, + 0xb00a0100, 0xb4a0000b, 0x954aff00, 0x81df0000, + 0x00000000, 0x00000000, 0xb6008003, 0x82150010, + 0x00000000, 0x00000000, 0x81df0004, 0x854a0100, + 0xb4e0fff6, 0x00ffb81b, 0x00000000, 0x00000000, + 0x81070000, 0x011f61dc, 0x011f61de, 0x011f61e0, + 0x011f03aa, 0x9108e0f4, 0x0138b808, 0x011f03ab, + 0x013f61ac, 0x9108e0f0, 0x0138b808, 0x011f03ac, + 0x013f61ad, 0x5901b808, 0x9108e0f8, 0x0139b808, + 0x011f03ad, 0x013f61ae, 0x5901b808, 0x9108e100, + 0x0139b808, 0x011f03ae, 0x013f61b0, 0x5901b808, + 0x9108e108, 0x0179b808, 0x013f03af, 0x017f61b1, + 0x02bf037b, 0x82970474, 0xb6350002, 0x015f8034, + 0x1929b80a, 0x011f03a1, 0xb0080001, 0xb4200002, + 0x015f03b0, 0x1929b80a, 0x019f0388, 0xb00c0001, + 0xb4200002, 0x015f03b2, 0x1929b80a, 0x013f61b3, + 0x015f03a8, 0xb00a0001, 0xb420003a, 0x81a70000, + 0x01bf237a, 0x83840056, 0x806f001f, 0x80af001f, + 0x80270300, 0x8067a800, 0x5c62b803, 0xb600080a, + 0x00cfb801, 0x007fb0bc, 0x5862b803, 0x01afb803, + 0x007f90bc, 0x0047b86f, 0xb0020001, 0xb4c0fffd, + 0x90210020, 0x90630020, 0x81a70001, 0x01bf237a, + 0x83840043, 0x838403ce, 0x81a70000, 0x01bf237a, + 0x82470400, 0x01bff012, 0x01bf23fa, 0x83840420, + 0x83840497, 0x83840546, 0x8384059d, 0x806f001f, + 0x80af001f, 0x80270300, 0x8067ac00, 0x5c62b803, + 0xb600080a, 0x00cfb801, 0x007fb0bc, 0x5862b803, + 0x01cfb803, 0x007f90bc, 0x0047b86f, 0xb0020001, + 0xb4c0fffd, 0x90210020, 0x90630020, 0x81a70001, + 0x01bf237a, 0x82470404, 0x015ff012, 0x015f23fa, + 0x83840407, 0x8384047e, 0x8384052d, 0x83840584, + 0xb5000011, 0x81a70000, 0x01bf237a, 0xb635000e, + 0x8384001b, 0x01bf037a, 0xad4d0004, 0x00000000, + 0x914a0400, 0x01bff00a, 0x01bf23fa, 0x838403f8, + 0x8384046f, 0x8384051e, 0x83840575, 0x01df037a, + 0x91ce0001, 0x01df237a, 0x019f0388, 0xb00c0001, + 0xb4200009, 0x02bf037b, 0x02bf237a, 0x838400e8, + 0x82470000, 0x025f23fa, 0x838403e9, 0x83840460, + 0x8384050f, 0x83840566, 0x00ffb81b, 0x00000000, + 0x80770000, 0x80f70000, 0x81770000, 0x81f70000, + 0x82770000, 0x82f70000, 0x83770000, 0x83f70000, + 0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x81d7ffff, + 0x8257ffff, 0x82d7ffff, 0x8357ffff, 0x83d7ffff, + 0x017f037a, 0x5a42b80b, 0x01bf03a8, 0xb00d0001, + 0xb4200004, 0x011f9118, 0x013f9119, 0x7929b808, + 0xb5000002, 0x91b20460, 0x013ff00d, 0x91b20340, + 0x0297b80d, 0x00000000, 0x029fa009, 0x01df0384, + 0xb00e0000, 0xb4200005, 0xb00b0001, 0xb4200003, + 0x009f90c6, 0x00bf0391, 0xb5000002, 0x009f90cf, + 0x00bf0389, 0x83a40142, 0x81870000, 0x019f61b5, + 0x019f61b4, 0x5a02b80b, 0x9190044c, 0x01dfd80c, + 0x01df61b6, 0x91900488, 0x01dff00c, 0x59c1b80e, + 0x918ee118, 0x01d9b80c, 0x019f03af, 0x01df61af, + 0x858c000f, 0x5986b80c, 0x91d00474, 0x01bff00e, + 0x59c2b80d, 0x11cc61b2, 0x81870000, 0x019f61b8, + 0x91900414, 0x01dfd80c, 0x01df61b7, 0xadab0010, + 0x00000000, 0x908d049c, 0x83a40191, 0xadcb0020, + 0x5982b80b, 0x908e0520, 0x90ae05c0, 0x90ce0660, + 0x928c050c, 0x00ff9814, 0x83a40169, 0x83a401b8, + 0x017f037a, 0x59c2b80b, 0x918e0428, 0x01fff00c, + 0xb00f0001, 0xb4200081, 0x023f03a5, 0x3011b80b, + 0xb420000f, 0x01c7b860, 0x01dfb0fa, 0x01df41dc, + 0x01df61e8, 0x01df41de, 0x01df61ea, 0x01df41e0, + 0x01df61ec, 0x01df41dd, 0x01df61e9, 0x01df41df, + 0x01df61eb, 0x01df41e1, 0x01df61ed, 0xb5000024, + 0x01c7b860, 0x01dfb0f9, 0x01df41dc, 0x01df61e2, + 0x01df41de, 0x01df61e4, 0x01df41e0, 0x01df61e6, + 0x01df41dd, 0x01df61e3, 0x01df41df, 0x01df61e5, + 0x01df41e1, 0x01df61e7, 0x803f0000, 0x00000000, + 0x00000000, 0x01df90fa, 0x003fb80e, 0x00000000, + 0x00000000, 0x81d50000, 0x00000000, 0x00000000, + 0x01df41e8, 0x01df61dc, 0x01df41ea, 0x01df61de, + 0x01df41ec, 0x01df61e0, 0x01df41e9, 0x01df61dd, + 0x01df41eb, 0x01df61df, 0x01df41ed, 0x01df61e1, + 0x029f03a6, 0x029f236a, 0x029f03a7, 0x029f236c, + 0x027f03a2, 0x92b3e128, 0x0298b815, 0x019f03b0, + 0x029f2368, 0x5982b80c, 0x01df03af, 0x85ce000f, + 0x59c6b80e, 0x11cc61b2, 0x82a70001, 0x02bf61b8, + 0x82a70000, 0x02bf61b9, 0x029f41da, 0x029f61ba, + 0x029f41db, 0x029f61bb, 0x019f03b1, 0x5981b80c, + 0x918ce118, 0x0299b80c, 0xad8b0048, 0x029f61af, + 0x59a2b813, 0x118cb80d, 0x928c0868, 0x029fb0fb, + 0x928c0700, 0x029fb0fc, 0x019f41bc, 0x918c0003, + 0x019f61bc, 0x5a02b80b, 0x91900414, 0x029fd80c, + 0x029f236e, 0x808704ec, 0x83a40121, 0x808709d0, + 0x80a709f0, 0x80c70060, 0x00ff03a4, 0x83a400fc, + 0x83a4014b, 0x021f037a, 0x019f03a5, 0x300cb810, + 0xb4000016, 0x803f0000, 0x00000000, 0x00000000, + 0x01df90f9, 0x003fb80e, 0x00000000, 0x00000000, + 0x81d50000, 0x00000000, 0x00000000, 0x01df41e2, + 0x01df61dc, 0x01df41e4, 0x01df61de, 0x01df41e6, + 0x01df61e0, 0x01df41e3, 0x01df61dd, 0x01df41e5, + 0x01df61df, 0x01df41e7, 0x01df61e1, 0x029f41b6, + 0xa6d40100, 0xaeb40004, 0x81870000, 0x92b50c00, + 0x0397b815, 0xb6360001, 0x039fa02c, 0x00ffb81c, + 0x009f90cf, 0x00bf0389, 0x019f037a, 0x5982b80c, + 0x918c0340, 0x0397b80c, 0x81870000, 0x039fa00c, + 0x83a40083, 0x81870000, 0x019f61b5, 0x019f61b4, + 0x81870007, 0x019f61b6, 0x019f03b3, 0x5981b80c, + 0x918ce118, 0x01b9b80c, 0x019f03af, 0x01bf61af, + 0x858c000f, 0x5986b80c, 0x01bf03b2, 0x59a2b80d, + 0x118cb80d, 0x019f61b2, 0x81870000, 0x019f61b7, + 0x019f61b8, 0x808704fc, 0x83a400d9, 0x80870000, + 0x80a70000, 0x80c70000, 0x80e70000, 0x83a400b4, + 0x83a40103, 0x81470000, 0x81e70c1c, 0x0397b80f, + 0xb600f901, 0x039fa02a, 0x00ffb81c, 0x00000000, + 0x82270000, 0x023f2011, 0x0227b860, 0x023fb0ff, + 0x02bf9006, 0x92350028, 0x8213001f, 0x9210e000, + 0x3011b810, 0xb4800001, 0x86312000, 0x021f4193, + 0x5a01b810, 0x86100028, 0x83a4fa2e, 0x82270000, + 0x003fb811, 0x02bf9006, 0x5aa3b815, 0x82338000, + 0x1a31b815, 0x003fb811, 0x8067e950, 0x5c62b803, + 0x81f50000, 0x80270400, 0x81df0000, 0x00000000, + 0x00000000, 0xb6000409, 0x814fffc0, 0x00cfb801, + 0x007fb0bc, 0x5862b803, 0x01cfb803, 0x007f90bc, + 0xb520ffff, 0x90210020, 0x90630020, 0x81df0004, + 0x82870000, 0x81f50010, 0x019f4193, 0x5d61b80c, + 0x5d43b80c, 0x114ab80b, 0x0187b80a, 0x960cff00, + 0x92100100, 0x858c0001, 0x81df0000, 0x00000000, + 0x00000000, 0xb62c000c, 0x81f50010, 0x5e28b80f, + 0xb6000209, 0x5a48b814, 0x9652ff00, 0x5e68b814, + 0x5981b813, 0x918c1000, 0x01dfd80c, 0x2252b811, + 0x2292b80e, 0x962f00ff, 0x81df0004, 0x81870000, + 0x86100100, 0xb4e0ffec, 0xb00a0000, 0xb4000009, + 0x81670000, 0xb0140000, 0xb4000001, 0x81670001, + 0x017f2012, 0x258a4193, 0x918c0001, 0x81470000, + 0xb500ffde, 0x81670000, 0xb0140000, 0xb4000001, + 0x81670002, 0x116b0012, 0x803f0000, 0x00000000, + 0x00000000, 0x003fb811, 0x00000000, 0x00000000, + 0x81f50000, 0x017f2012, 0x00ffb81a, 0x00000000, + 0x61f4b804, 0x91ef0001, 0x8233003f, 0x9a31ffff, + 0x5a02b804, 0x1610b811, 0x92510001, 0x1a10b812, + 0x029f03fb, 0xb0140001, 0xb4200012, 0x5a21b805, + 0x92b1e910, 0x0299b815, 0x5a22b805, 0x5a90b814, + 0x6290b814, 0x92b1e890, 0x11efb814, 0x029bb815, + 0x8233ff80, 0x3011b814, 0xb4000006, 0x4294b811, + 0x00000000, 0x0288b814, 0x4210b814, 0x00000000, + 0x0208b810, 0x029f9003, 0x82f3007f, 0x9af7ffff, + 0x3017b814, 0xb4000003, 0x4210b814, 0x00000000, + 0x0208b810, 0x82270000, 0x02c7b810, 0xb0160000, + 0xb400000a, 0x1676b812, 0x3013b812, 0xb4000003, + 0x5ac1b816, 0x92310001, 0xb500fffa, 0x81d3ff80, + 0x3010b80e, 0xb4200001, 0x1ad6b80e, 0x05efb811, + 0x027f037a, 0x5a62b813, 0x92730340, 0x0397b813, + 0x023fd813, 0x02dfb0fd, 0x5a30b811, 0x6230b811, + 0x0631b80f, 0x3010b812, 0xb4200001, 0x92310001, + 0x82470000, 0xb0110000, 0xb4800004, 0x82470003, + 0xb0110003, 0xb4400001, 0x0247b811, 0x039fa012, + 0x124f61bc, 0x00ffb81d, 0x00000000, 0x00000000, + 0x83970a10, 0x82070000, 0xb6003201, 0x039fa030, + 0xb0070000, 0xb4000019, 0x029f41b4, 0x0297b804, + 0x0317b805, 0x0397b806, 0xb6270014, 0x12948034, + 0x01df8038, 0xb00e0000, 0xb4a0000e, 0x02bf803c, + 0x5a02b814, 0x91b00a10, 0x0217b80d, 0xb62e0008, + 0x96150003, 0x91f00001, 0xadef0080, 0xb0150004, + 0xb4600001, 0x85ef0280, 0x021fa02f, 0x92940001, + 0xb5000001, 0x021f803c, 0x00000000, 0x00ffb81d, + 0x0397b804, 0x021f036a, 0x027f803c, 0x029f803c, + 0x02bf803c, 0x02df803c, 0x5a22b810, 0x92311000, + 0x0397b811, 0xb0100000, 0xb4200001, 0x039fa036, + 0xb0150000, 0xb4000021, 0x0227b860, 0x023fb0ff, + 0xb520ffff, 0x803f0000, 0x82138000, 0x1a10b813, + 0x003fb810, 0x00000000, 0x00000000, 0x82150000, + 0x00000000, 0xb635000d, 0x82550007, 0x5a42b812, + 0x9212e4b8, 0x025bb810, 0x8227000c, 0xb6000307, + 0x68d1b812, 0x94c6000f, 0x84c60002, 0x12d6b806, + 0xb6340001, 0x039fa036, 0x86310004, 0x803f0000, + 0x82138000, 0x023f90ff, 0x1a31b810, 0x003fb811, + 0x00000000, 0x00000000, 0x82150000, 0x00ffb81d, + 0x00ff41b5, 0x011f41b4, 0x019f41af, 0x01bf41ae, + 0x01df41ba, 0x01ff41bb, 0x82070000, 0x023f0380, + 0x82470000, 0xae310032, 0x029f41b3, 0x5862b807, + 0x90431000, 0x81970ad8, 0x0217b802, 0x90430c00, + 0x0297b802, 0x0317b802, 0x912802a4, 0x007ff009, + 0x58478030, 0x792341b6, 0x0529b807, 0x019fa029, + 0xb0080014, 0xb4800011, 0xa5420c00, 0x031fa02a, + 0x84690001, 0xb4a00011, 0xb623000b, 0x58678030, + 0xa4030c00, 0x031fa020, 0x044ab800, 0x0056b802, + 0x5c41b802, 0xf84200ff, 0x90620100, 0x005ff003, + 0x7d40b80a, 0x114ab802, 0xb5000004, 0xa5420c00, + 0x58478010, 0xa5620c00, 0x031fa02a, 0xb0080016, + 0xb4400043, 0xb0080013, 0xb440002c, 0xb0080006, + 0xb4400024, 0xb0080005, 0xb4400014, 0xb0080002, + 0xb4400006, 0x80440030, 0x015f619c, 0x05cab80c, + 0x05eab80d, 0x066eb810, 0xb500003c, 0x8044002a, + 0x300a419c, 0xb4800001, 0x82470001, 0x015f619c, + 0xb0120001, 0xb4200001, 0xb500001a, 0x05cab80c, + 0x05eab80d, 0x066eb810, 0xb5000030, 0x001f41b6, + 0xb0000007, 0xb4000001, 0x8044001b, 0x300a419c, + 0xb4800001, 0x82470001, 0xb0120001, 0xb4200001, + 0xb500000c, 0x05cab80c, 0x05eab80d, 0x066eb810, + 0xb5000022, 0x80440010, 0x840b0100, 0x300ab800, + 0xb4200001, 0x86100040, 0xb5000002, 0x86100080, + 0xfe100000, 0x046e41ad, 0x042ab80c, 0x7dc1b803, + 0x044f41ac, 0x042ab80d, 0x7de1b802, 0x046eb810, + 0x7e6fb803, 0xb5000011, 0x840b0100, 0x3000b80a, + 0xb4200002, 0x82070180, 0x00ffb802, 0x300ab80b, + 0xb4a00002, 0x86100040, 0xfe100000, 0x00ffb802, + 0x046e41ad, 0x042ab80c, 0x7dc1b803, 0x044f41ac, + 0x042ab80d, 0x7de1b802, 0x7e6eb80f, 0x380a41b0, + 0xb4600003, 0x242a41b0, 0x5c22b801, 0x1273b801, + 0xb0140000, 0xb4200002, 0x80071fe0, 0xb5000016, + 0x1011b808, 0x5801b800, 0x9020e26c, 0x0079b801, + 0x5842b808, 0x90420a10, 0x7c03b813, 0x003f9802, + 0x1000b801, 0x003f41b2, 0x5830b801, 0x6030b801, + 0x0400b801, 0x003f41b1, 0x5830b801, 0x6030b801, + 0x0400b801, 0xfc000000, 0xf8001fe0, 0x94001fe0, + 0x100041b1, 0x9400ffff, 0x8067003f, 0xb6290008, + 0x005f8014, 0x0442b800, 0x9442ffff, 0x5850b802, + 0x6050b802, 0xfc420000, 0x5c45b802, 0x7a82a023, + 0x10e7b809, 0x91080001, 0x300741b6, 0xb420ff6a, + 0x019f61af, 0x01bf61ae, 0x01df61ba, 0x01ff61bb, + 0x00ff41b5, 0x011f41b4, 0x019f41b8, 0x01bf41b7, + 0x01df41dd, 0x01ff41df, 0x021f41e1, 0x027f90fd, + 0x029f41bc, 0x02ff41dc, 0x031f41de, 0x033f41e0, + 0x5822b807, 0x91210c00, 0x0117b809, 0x81970ad8, + 0x91211000, 0x0217b809, 0x91210c00, 0x0317b809, + 0x80170ba0, 0x013f802c, 0xb629005f, 0x003f8038, + 0xb001000e, 0xb440001e, 0xb001000c, 0xb4400054, + 0xb001000a, 0xb4400043, 0xb0010007, 0xb440003c, + 0xb0010005, 0xb440002b, 0xb0010000, 0xb440001a, + 0xb00d0001, 0xb4200010, 0x005f418f, 0xac42bb75, + 0x8073005a, 0x9442ffff, 0x005f618f, 0x95628000, + 0x5848b802, 0xb00b8000, 0xb4200002, 0x8173ff00, + 0x1842b80b, 0x9863827a, 0x4043b802, 0x00000000, + 0x0048b802, 0xb500003f, 0x80470000, 0xb500003d, + 0x8401000f, 0x5c22b800, 0x902102d8, 0x001ff001, + 0x004db800, 0xb5000037, 0x86f70001, 0xb4600005, + 0x80750005, 0x5862b803, 0x9043e44c, 0x01d9b802, + 0x82e70002, 0x5c4cb80e, 0x9462000f, 0x5862b803, + 0x90630200, 0x005f9803, 0x59c4b80e, 0x95ceffff, + 0xb5000028, 0x87180001, 0xb4600005, 0x80750007, + 0x5862b803, 0x9043e4b8, 0x01f9b802, 0x83070002, + 0x5c4cb80f, 0x9462000f, 0x5862b803, 0x9063020c, + 0x005f9803, 0x59e4b80f, 0x95efffff, 0xb5000019, + 0x80750003, 0x5862b803, 0x90630220, 0x005f9803, + 0xb5000014, 0x87390001, 0xb4600005, 0x80750007, + 0x5862b803, 0x9043e6ac, 0x0219b802, 0x83270001, + 0x5c4cb810, 0x9462000f, 0x5862b803, 0x9063023c, + 0x005f9803, 0x5a04b810, 0x9610ffff, 0xb5000005, + 0x80750004, 0x5862b803, 0x90630268, 0x005f9803, + 0x00000000, 0x001fa022, 0x80170ba0, 0xb00c0001, + 0xb4200035, 0x023f90fb, 0x007f9811, 0x025f90fc, + 0x06d4b803, 0x007f9812, 0x4083b813, 0x00000000, + 0x0088b804, 0xb629002b, 0x24368030, 0x9421ffff, + 0x5830b801, 0x6030b801, 0x40448020, 0xb0010020, + 0xb4800003, 0x80470000, 0x80670000, 0xb500000e, + 0xb0010000, 0xb4a00004, 0x82b30080, 0x6aa1b815, + 0x4042b815, 0xb5000008, 0x6c41b802, 0x82a70017, + 0x12b5b801, 0x6875b803, 0x1842b803, 0x00000000, + 0x00000000, 0x00000000, 0x0108a022, 0x007f41b9, + 0x90630001, 0x007f61b9, 0xb003000c, 0xb420000c, + 0x92310004, 0x023fb0fb, 0x007f9811, 0x92520004, + 0x06d4b803, 0x025fb0fc, 0x007f9812, 0x80470000, + 0x4083b813, 0x00000000, 0x0088b804, 0x005f61b9, + 0x00000000, 0xb500001a, 0xb6290019, 0x24348030, + 0x9421ffff, 0x5830b801, 0x6030b801, 0x40538020, + 0xb0010020, 0xb4800003, 0x80470000, 0x80670000, + 0xb500000e, 0xb0010000, 0xb4a00004, 0x82b30080, + 0x6aa1b815, 0x4042b815, 0xb5000008, 0x6c41b802, + 0x82a70017, 0x12b5b801, 0x6875b803, 0x1842b803, + 0x00000000, 0x00000000, 0x00000000, 0x0108a022, + 0x10e7b809, 0x91080001, 0x300741b6, 0xb420ff48, + 0x00ff61b5, 0x011f61b4, 0x01df61dd, 0x01ff61df, + 0x021f61e1, 0x02ff61dc, 0x031f61de, 0x033f61e0, + 0x00ffb81d, 0x00000000, 0x00000000, 0x00000000, + 0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x81d7ffff, + 0x8257ffff, 0x808f0000, 0x003f9113, 0x005f9114, + 0x7141b802, 0x80cf0700, 0x8027b064, 0x5c22b801, + 0x003fb0bc, 0x5822b801, 0x01cfb801, 0x003f90bc, + 0xb520ffff, 0x80cf0704, 0x8027b06c, 0x5c22b801, + 0x003fb0bc, 0x5822b801, 0x01cfb801, 0x003f90bc, + 0xb520ffff, 0x81e7043c, 0x82071c00, 0x82271c10, + 0x019f03a9, 0x806f001f, 0x80af001f, 0x80270400, + 0x8067a800, 0x5c62b803, 0xb6000808, 0x00cfb801, + 0x007fb0bc, 0x5862b803, 0x01cfb803, 0x007f90bc, + 0xb520ffff, 0x90210020, 0x90630020, 0x81971000, + 0x82170c00, 0xb6000004, 0x003f800c, 0x005f8010, + 0x021fa021, 0x019fa022, 0x00bfd810, 0x003fd811, + 0x70c1b80a, 0x001f980f, 0x91ef0004, 0x92100002, + 0x92310002, 0x5822b805, 0x90411000, 0x0197b802, + 0x90410c00, 0x0217b802, 0x0466b805, 0xb0000000, + 0xb4000005, 0xb6230004, 0x003f8010, 0x005f800c, + 0x1201a022, 0x0581a022, 0x858c0001, 0xb4e0ffea, + 0x80270400, 0x8067ac00, 0x5c62b803, 0xb6000808, + 0x00cfb801, 0x007fb0bc, 0x5862b803, 0x01afb803, + 0x007f90bc, 0xb520ffff, 0x90210020, 0x90630020, + 0x00ffb81c, 0x00000000, 0x00000000, 0x00000000, + 0x808f0000, 0x806f001f, 0x80af001f, 0x003f037a, + 0xb0010000, 0xb4400030, 0x81a7b7fc, 0x5da2b80d, + 0x80670500, 0xb6000208, 0x00cfb803, 0x01bfb0bc, + 0x59a2b80d, 0x01cfb80d, 0x01bf90bc, 0xb520ffff, + 0x90630020, 0x91ad0020, 0x81c7b8fc, 0x5dc2b80e, + 0x80670540, 0xb6000208, 0x00cfb803, 0x01dfb0bc, + 0x59c2b80e, 0x01cfb80e, 0x01df90bc, 0xb520ffff, + 0x90630020, 0x91ce0020, 0x81a7b3fc, 0x5da2b80d, + 0x80670600, 0xb6000408, 0x00cfb803, 0x01bfb0bc, + 0x59a2b80d, 0x01cfb80d, 0x01bf90bc, 0xb520ffff, + 0x90630020, 0x91ad0020, 0x81c7b5fc, 0x5dc2b80e, + 0x80670680, 0xb6000408, 0x00cfb803, 0x01dfb0bc, + 0x59c2b80e, 0x01cfb80e, 0x01df90bc, 0xb520ffff, + 0x90630020, 0x91ce0020, 0x005f03fa, 0xb0020000, + 0xb4000024, 0x8057ffff, 0x80d7ffff, 0x8157ffff, + 0x81d7ffff, 0x8257ffff, 0x82d7ffff, 0x8357ffff, + 0x83d7ffff, 0x83971300, 0x83171200, 0x82971100, + 0x82171000, 0x81170c00, 0x81970ff8, 0x80171400, + 0x80971500, 0x005f802c, 0x001f8028, 0xb6004010, + 0x41028000, 0x51008004, 0x007f876c, 0x0208a028, + 0x41008000, 0x49028004, 0x003f8068, 0x0388a028, + 0x41038000, 0x51018004, 0x005f802c, 0x0288a028, + 0x41018020, 0x49038024, 0x001f8028, 0x0308a028, + 0x00ffb81c, 0x83d7ffff, 0x8357ffff, 0x82d7ffff, + 0x8257ffff, 0x8157ffff, 0x81d7ffff, 0x8057ffff, + 0x80d7ffff, 0x82971200, 0x82171000, 0x81170c00, + 0x81970ffc, 0x83171800, 0x83971a00, 0x83370000, + 0x83b70000, 0x81370008, 0x81b7fff8, 0x4119880c, + 0xb6008006, 0x511d8808, 0x41498838, 0x0208a028, + 0x494d883c, 0x4119880c, 0x0288a02a, 0x00ffb81c, + 0x82670000, 0x82a70000, 0x003f037a, 0xb0010000, + 0xb4400018, 0x81a7bdfc, 0x5da2b80d, 0x80670580, + 0xb6000208, 0x00cfb803, 0x01bfb0bc, 0x59a2b80d, + 0x01cfb80d, 0x01bf90bc, 0xb520ffff, 0x90630020, + 0x91ad0020, 0x81a7eb70, 0x5da2b80d, 0x806705c0, + 0xb6000208, 0x00cfb803, 0x01bfb0bc, 0x59a2b80d, + 0x01cfb80d, 0x01bf90bc, 0xb520ffff, 0x90630020, + 0x91ad0020, 0x02bf03fa, 0x808f0000, 0xb0150000, + 0xb4000006, 0x81470040, 0x81670003, 0x81870002, + 0x81a71000, 0x81c71300, 0xb5000005, 0x81470080, + 0x81670004, 0x81870001, 0x81a71000, 0x81c71200, + 0x0017b80d, 0x0097b80e, 0x108db80a, 0x0117b804, + 0x108eb80a, 0x0197b804, 0x5841b80a, 0x108db802, + 0x0217b804, 0x108eb802, 0x0297b804, 0x106ab802, + 0x108db803, 0x0317b804, 0x108eb803, 0x0397b804, + 0x5ea2b80a, 0xb6350020, 0x001f8000, 0x003f8008, + 0x005f8004, 0x007f800c, 0x10c08010, 0x10a18018, + 0x10828014, 0x10e3801c, 0x1246b805, 0x0686b805, + 0x10c4b807, 0x0484b807, 0x80e70000, 0x80a70000, + 0x0008a032, 0x0108a034, 0x0088a026, 0x0188a024, + 0x04c08010, 0x04a18018, 0x04828014, 0x04e3801c, + 0x0646b807, 0x1286b807, 0x10c4b805, 0x0484b805, + 0x80e70000, 0x80a70000, 0x0208a032, 0x0308a034, + 0x0288a026, 0x0388a024, 0x5de1b80a, 0x82070004, + 0xb62b002a, 0x0017b80d, 0x0097b80e, 0x102db80f, + 0x0117b801, 0x104eb80f, 0x0197b802, 0x82171600, + 0x82971700, 0x0037b80f, 0x00b7b80f, 0x0137b80f, + 0x01b7b80f, 0xb630001b, 0x003f8030, 0x005f8034, + 0x5ee2b80f, 0x8013007f, 0x9800ffff, 0xb6370011, + 0x41008000, 0x51018008, 0x4902800c, 0x40c08000, + 0x0008a028, 0x48c18008, 0x50c2800c, 0x42808004, + 0x00c8b806, 0x52828008, 0x5281800c, 0x41008004, + 0x0088a034, 0x49028008, 0x4901800c, 0x011fa026, + 0x0188a028, 0x001f8001, 0x001f8005, 0x001f8009, + 0x001f800d, 0x5de1b80f, 0x5a01b810, 0x0017b80d, + 0x0097b80e, 0x902d0004, 0x0117b801, 0x904e0004, + 0x0197b802, 0x82171600, 0x82971700, 0x5ea1b80a, + 0x8013007f, 0x9800ffff, 0xb6350013, 0x003f8030, + 0x005f8034, 0x42408000, 0x52418008, 0x4a42800c, + 0x41008000, 0x0008a052, 0x49018008, 0x5102800c, + 0x42808004, 0x0108b808, 0x52828008, 0x5281800c, + 0x40c08004, 0x0088a054, 0x48c28008, 0x48c1800c, + 0x011fa048, 0x0188a046, 0x81a71100, 0x81c71200, + 0x858c0001, 0xb4e0ff7e, 0x00ffb81c, 0x00000000, + 0x005f03fa, 0x00000000, 0xb0020000, 0xb4000034, + 0x81b70080, 0x81d7ffff, 0x81f70001, 0x82370080, + 0x8257ffff, 0x82770001, 0x82b70080, 0x82d7ffff, + 0x82f70001, 0x83370080, 0x8357ffff, 0x83770001, + 0x81971000, 0x82171100, 0x82971200, 0x83171300, + 0x815703fc, 0x81370200, 0x81170c00, 0x83d703fc, + 0x83b70200, 0x83970f00, 0x8057ffff, 0x80d7ffff, + 0x80171400, 0x80971500, 0x001f800d, 0x003f8019, + 0xb6004012, 0x41008000, 0x51018004, 0x007f8011, + 0x0128a008, 0x41018000, 0x49008004, 0x009f8015, + 0x03a8a008, 0x41038000, 0x51048004, 0x001f800d, + 0x03a8a008, 0x41048020, 0x49038024, 0x003f8019, + 0x0128a008, 0x005f8028, 0x005f803c, 0x81f70000, + 0x82770000, 0x82f70000, 0x83770000, 0x00ffb81c, + 0x82370040, 0x8257ffff, 0x82770001, 0x82b70040, + 0x82d7ffff, 0x82f70001, 0x82171000, 0x82971200, + 0x8157ffff, 0x81170c00, 0x81d7ffff, 0x81970e00, + 0x8057ffff, 0x80d7ffff, 0x80171800, 0x80971a00, + 0xb600800a, 0x001f8011, 0x003f8015, 0x41008000, + 0x51018004, 0x00000000, 0x0108a028, 0x41018020, + 0x49008024, 0x00000000, 0x0188a028, 0x82770000, + 0x82f70000, 0x00ffb81c, 0x00000000, 0x00000000, + 0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x808f0000, + 0x015f0384, 0x017f037a, 0xac4a0006, 0x8027b004, + 0x1042b80b, 0x5841b802, 0x1021b802, 0x0159b801, + 0x013f0325, 0x01bf0320, 0x5822b80b, 0x90210340, + 0x00ff9801, 0x8027b2e8, 0x5842b807, 0x1021b802, + 0x025bb801, 0x80070000, 0xac4d0006, 0x8027b004, + 0x1042b800, 0x5841b802, 0x1021b802, 0x0199b801, + 0x00000000, 0xac4c0006, 0x8027b078, 0x1042b80a, + 0x5842b802, 0x1021b802, 0x011bb801, 0x00000000, + 0x40d2b808, 0x00000000, 0xb0060000, 0xb4000080, + 0x005f033b, 0x80278400, 0xac600080, 0x5c22b801, + 0x10a1b803, 0xb0020000, 0xb4200002, 0x80279000, + 0xb5000001, 0x80279c00, 0x5c22b801, 0x11e1b803, + 0x80470300, 0x5822b800, 0x1042b801, 0x003f9802, + 0x806f001f, 0x80af001f, 0xb0010000, 0xb4200024, + 0x80170c00, 0x80971000, 0x003f8020, 0xb6000003, + 0x4201b806, 0x003f8020, 0x0088a030, 0x80270400, + 0xb6000208, 0x00cfb801, 0x00bfb0bc, 0x58a2b805, + 0x01afb805, 0x00bf90bc, 0xb520ffff, 0x90210020, + 0x90a50020, 0xb6000408, 0x00cfb801, 0x01ffb0bc, + 0x59e2b80f, 0x01afb80f, 0x01ff90bc, 0xb520ffff, + 0x90210020, 0x91ef0020, 0xb6000208, 0x00cfb801, + 0x00bfb0bc, 0x58a2b805, 0x01afb805, 0x00bf90bc, + 0xb520ffff, 0x90210020, 0x90a50020, 0xb5000043, + 0x80270400, 0x0087b805, 0x01c7b80f, 0xb6000208, + 0x00cfb801, 0x009fb0bc, 0x5882b804, 0x01cfb804, + 0x009f90bc, 0xb520ffff, 0x90210020, 0x90840020, + 0xb6000408, 0x00cfb801, 0x01dfb0bc, 0x59c2b80e, + 0x01cfb80e, 0x01df90bc, 0xb520ffff, 0x90210020, + 0x91ce0020, 0xb6000208, 0x00cfb801, 0x009fb0bc, + 0x5882b804, 0x01cfb804, 0x009f90bc, 0xb520ffff, + 0x90210020, 0x90840020, 0x80170c00, 0x80971000, + 0x8053007f, 0x9842ffff, 0xb6000004, 0x42028004, + 0x4a068020, 0x00000000, 0x0088a030, 0x80270400, + 0xb6000208, 0x00cfb801, 0x00bfb0bc, 0x58a2b805, + 0x01afb805, 0x00bf90bc, 0xb520ffff, 0x90210020, + 0x90a50020, 0xb6000408, 0x00cfb801, 0x01ffb0bc, + 0x59e2b80f, 0x01afb80f, 0x01ff90bc, 0xb520ffff, + 0x90210020, 0x91ef0020, 0xb6000208, 0x00cfb801, + 0x00bfb0bc, 0x58a2b805, 0x01afb805, 0x00bf90bc, + 0xb520ffff, 0x90210020, 0x90a50020, 0x5822b800, + 0x90210300, 0x0117b801, 0x80470001, 0x011fa002, + 0x90000001, 0x3000b809, 0xb480ff6b, 0x00ffb81c, + 0x8057ffff, 0x013f0325, 0x015f033b, 0x80171000, + 0x80070000, 0xb6002001, 0x001fa020, 0xb00a0001, + 0xb4c00002, 0x81679000, 0xb5000001, 0x81679c00, + 0x5d62b80b, 0x81878400, 0x5d82b80c, 0x80070000, + 0x5822b800, 0x90410300, 0x003f9802, 0x00000000, + 0xb0010000, 0xb4200019, 0xac400080, 0x00000000, + 0x10ccb802, 0x10abb802, 0x806f001f, 0x80af001f, + 0x80cf0400, 0xb6000408, 0xb520ffff, 0x00dfb0bc, + 0x58c2b806, 0x01afb806, 0x00df90bc, 0xb520ffff, + 0x80cf0400, 0x90c60020, 0x80cf0400, 0xb6000407, + 0x00bfb0bc, 0x58a2b805, 0x01afb805, 0x00bf90bc, + 0xb520ffff, 0x80cf0400, 0x90a50020, 0x90000001, + 0x3000b809, 0xb480ffde, 0x00ffb81b, 0x8057ffff, + 0x013f0325, 0x80171000, 0x80070000, 0xb6002001, + 0x001fa020, 0x81878400, 0x5d82b80c, 0x80070000, + 0x5822b800, 0x90410300, 0x003f9802, 0x00000000, + 0xb0010000, 0xb420000f, 0xac400080, 0x00000000, + 0x10ccb802, 0x806f001f, 0x80af001f, 0x80cf0400, + 0xb6000408, 0xb520ffff, 0x00dfb0bc, 0x58c2b806, + 0x01afb806, 0x00df90bc, 0xb520ffff, 0x80cf0400, + 0x90c60020, 0x90000001, 0x3000b809, 0xb480ffe8, + 0x00ffb81b, 0x8057ffff, 0x80d7ffff, 0x8157ffff, + 0x8139b000, 0x00000000, 0xb0090000, 0xb4000012, + 0x806f001f, 0x80af001f, 0x80cf0400, 0x013fb0bc, + 0x5922b809, 0x01cfb809, 0x013f90bc, 0xb520ffff, + 0x806f0003, 0x80af0003, 0x80cf0420, 0x91290020, + 0x013fb0bc, 0x5922b809, 0x01cfb809, 0x013f90bc, + 0xb520ffff, 0xb5000233, 0x80270000, 0x80171000, + 0xb6002401, 0x001fa021, 0x007f0384, 0x009f0320, + 0x00bf0385, 0x00df0386, 0x80e7b36c, 0x5821b803, + 0x1021b807, 0x0159b801, 0x5821b804, 0x1021b807, + 0x0179b801, 0x80e7b37c, 0x5821b803, 0x1021b807, + 0x0199b801, 0x5821b804, 0x1021b807, 0x01b9b801, + 0x80e7b38c, 0x5821b803, 0x1021b807, 0x01d9b801, + 0x5821b804, 0x1021b807, 0x01f9b801, 0x005f0385, + 0x8027b39c, 0x5842b802, 0x1021b802, 0x021bb801, + 0x005f0386, 0x8027b3ac, 0x5842b802, 0x1021b802, + 0x023bb801, 0x027f0383, 0x003f0328, 0x005f4195, + 0xb0130007, 0xb42000df, 0xb0010000, 0xb42000dd, + 0xb0020000, 0xb40000db, 0xb0030002, 0xb48000d9, + 0x029bb802, 0x82a7b108, 0xb00b0001, 0xb4200001, + 0xb5000005, 0xb00b0002, 0xb4200002, 0x92b500a0, + 0xb5000001, 0x92b50140, 0xb0030004, 0xb4600002, + 0x82870000, 0xb5000006, 0xb0030006, 0xb4600004, + 0xb0140001, 0xb4a00002, 0x82870001, 0xb5000000, + 0xac54000a, 0x806f0009, 0x80af0009, 0x5c22b815, + 0x80cf0440, 0x1021b802, 0x003fb0bc, 0x5822b801, + 0x01cfb801, 0x003f90bc, 0xb520ffff, 0xb0030003, + 0xb400000f, 0xb0030004, 0xb400001d, 0xb0030005, + 0xb400002b, 0xb0030006, 0xb4000042, 0xb0030007, + 0xb4000059, 0x80171000, 0x005f9440, 0x001fa002, + 0x80171038, 0x005f9440, 0x001fa002, 0xb5000073, + 0x80171000, 0x005f9440, 0x001fa002, 0x80171004, + 0x005f9443, 0x001fa002, 0x8017101c, 0x005f9446, + 0x001fa002, 0x80171034, 0x005f9449, 0x001fa002, + 0x80171038, 0x005f9440, 0x001fa002, 0xb5000063, + 0x80171000, 0x005f9440, 0x001fa002, 0x80171008, + 0x005f9441, 0x001fa002, 0x80171020, 0x005f9444, + 0x001fa002, 0x80171034, 0x005f9440, 0x001fa002, + 0x80171038, 0x005f9447, 0x001fa002, 0xb5000053, + 0x80171000, 0x005f9440, 0x001fa002, 0x80171004, + 0x005f9443, 0x001fa002, 0x8017100c, 0x005f9441, + 0x001fa002, 0x8017101c, 0x005f9446, 0x001fa002, + 0x80171024, 0x005f9444, 0x001fa002, 0x80171034, + 0x005f9449, 0x001fa002, 0x80171038, 0x005f9440, + 0x001fa002, 0x8017103c, 0x005f9447, 0x001fa002, + 0xb500003a, 0x80171000, 0x005f9440, 0x001fa002, + 0x80171008, 0x005f9441, 0x001fa002, 0x8017100c, + 0x005f9442, 0x001fa002, 0x80171020, 0x005f9444, + 0x001fa002, 0x80171024, 0x005f9445, 0x001fa002, + 0x80171034, 0x005f9440, 0x001fa002, 0x80171038, + 0x005f9447, 0x001fa002, 0x8017103c, 0x005f9448, + 0x001fa002, 0xb5000021, 0x80171000, 0x005f9440, + 0x001fa002, 0x80171004, 0x005f9443, 0x001fa002, + 0x8017100c, 0x005f9441, 0x001fa002, 0x80171010, + 0x005f9442, 0x001fa002, 0x8017101c, 0x005f9446, + 0x001fa002, 0x80171024, 0x005f9444, 0x001fa002, + 0x80171028, 0x005f9445, 0x001fa002, 0x80171034, + 0x005f9449, 0x001fa002, 0x80171038, 0x005f9440, + 0x001fa002, 0x8017103c, 0x005f9447, 0x001fa002, + 0x80171040, 0x005f9448, 0x001fa002, 0x80270001, + 0x803eff90, 0x80171000, 0x82b30020, 0x9ab50000, + 0x40158020, 0xb6000501, 0x48158020, 0x82b30020, + 0x9ab50000, 0x80470000, 0x3015b800, 0xb4600006, + 0x80171000, 0x83840226, 0xb6000603, 0x40028000, + 0x00000000, 0x0008a020, 0x80171018, 0x82b30020, + 0x9ab50000, 0x40158020, 0xb6000501, 0x48158020, + 0x82b30020, 0x9ab50000, 0x80470000, 0x3015b800, + 0xb4600006, 0x80171018, 0x83840215, 0xb6000603, + 0x40028000, 0x00000000, 0x0008a020, 0x80171030, + 0x82b30020, 0x9ab50000, 0x40158020, 0xb6000501, + 0x48158020, 0x82b30020, 0x9ab50000, 0x80470000, + 0x3015b800, 0xb4600006, 0x80171030, 0x83840204, + 0xb6000603, 0x40028000, 0x00000000, 0x0008a020, + 0xb500011e, 0x80270000, 0x803eff90, 0xb0030000, + 0xb4200067, 0x025f0322, 0xb00b0001, 0xb4200016, + 0xb0120001, 0xb4200005, 0x80171018, 0x8033007f, + 0x9821ffff, 0x001fa001, 0xb5000110, 0xb0120002, + 0xb4200005, 0x80171020, 0x8033007f, 0x9821ffff, + 0x001fa001, 0xb5000109, 0x80171018, 0x80330040, + 0x98210000, 0x001fa001, 0x80171020, 0x00000000, + 0x001fa001, 0xb5000101, 0xb00b0002, 0xb420002c, + 0xb0120000, 0xb4200008, 0x80171000, 0x8033007f, + 0x9821ffff, 0x001fa001, 0x80171038, 0x00000000, + 0x001fa001, 0xb50000f5, 0xb0120001, 0xb4200008, + 0x80171000, 0x8033005a, 0x98218279, 0x001fa001, + 0x80171030, 0x00000000, 0x001fa001, 0xb50000eb, + 0xb0120002, 0xb4200008, 0x80171008, 0x8033005a, + 0x98218279, 0x001fa001, 0x80171038, 0x00000000, + 0x001fa001, 0xb50000e1, 0x80171000, 0x80330040, + 0x98210000, 0x001fa001, 0x80171008, 0x00000000, + 0x001fa001, 0x8017100c, 0x00000000, 0x001fa001, + 0x80171038, 0x00000000, 0x001fa001, 0xb50000d3, + 0xb0120000, 0xb4200008, 0x80171000, 0x8033007f, + 0x9821ffff, 0x001fa001, 0x80171038, 0x00000000, + 0x001fa001, 0xb50000c9, 0xb0120001, 0xb4200005, + 0x80171018, 0x8033007f, 0x9821ffff, 0x001fa001, + 0xb50000c2, 0xb0120002, 0xb4200005, 0x80171020, + 0x8033007f, 0x9821ffff, 0x001fa001, 0xb50000bb, + 0x80171018, 0x80330040, 0x98210000, 0x001fa001, + 0x80171020, 0x00000000, 0x001fa001, 0xb50000b3, + 0x80070000, 0x8033007f, 0x9821ffff, 0xb600050e, + 0x144eb80f, 0xb0028000, 0xb4c00008, 0xac400006, + 0x00000000, 0x1042b800, 0x5842b802, 0x90421000, + 0x0017b802, 0x00000000, 0x001fa001, 0x90000001, + 0x59c1b80e, 0x59e1b80f, 0xb0040000, 0xb4200023, + 0xb00a0002, 0xb4000007, 0x80171004, 0x8033005a, + 0x98218279, 0x001fa001, 0x80171034, 0x00000000, + 0x001fa001, 0xb00c0002, 0xb4000009, 0x8017100c, + 0x8033ffa5, 0x98217d87, 0x001fa001, 0x8017103c, + 0x8033005a, 0x98218279, 0x001fa001, 0xb500008b, + 0x8017100c, 0x8033ffa5, 0x98217d87, 0x001fa001, + 0x80171010, 0x00000000, 0x001fa001, 0x8017103c, + 0x8033005a, 0x98218279, 0x001fa001, 0x80171040, + 0x00000000, 0x001fa001, 0xb500007c, 0xb0040001, + 0xb420002a, 0xb00a0001, 0xb4000007, 0x80171018, + 0x8033005a, 0x98218279, 0x001fa001, 0x80171020, + 0x00000000, 0x001fa001, 0xb00a0003, 0xb420000a, + 0x8053005a, 0x98428279, 0x4030b802, 0x8017101c, + 0x5821b801, 0x00000000, 0x00000000, 0x00000000, + 0x0028b801, 0x001fa001, 0xb00c0001, 0xb4200007, + 0x8053005a, 0x98428279, 0x4031b802, 0x80171024, + 0x0028b801, 0x001fa001, 0xb500005c, 0xb00c0002, + 0xb420005a, 0x8053005a, 0x98428279, 0x4031b802, + 0x80171024, 0x0028b801, 0x001fa001, 0x80171028, + 0x00000000, 0x001fa001, 0xb5000050, 0xb00b0002, + 0xb4200012, 0xb00a0001, 0xb4200008, 0x80171004, + 0x8033005a, 0x98218279, 0x001fa001, 0x80171034, + 0x00000000, 0x001fa001, 0xb5000008, 0xb00a0003, + 0xb4200006, 0x80171004, 0x00000000, 0x001fa010, + 0x80171034, 0x00000000, 0x001fa010, 0xb00c0001, + 0xb4200025, 0x027f0383, 0x003f0328, 0xb0130007, + 0xb420000b, 0xb00b0003, 0xb4200009, 0xb0010000, + 0xb4200007, 0x80171024, 0x00000000, 0x001fa011, + 0x80171054, 0x80270000, 0x001fa001, 0xb500002b, + 0xb00d0000, 0xb420000a, 0x8033005a, 0x98218279, + 0x4041b811, 0x8017100c, 0x0048b802, 0x001fa002, + 0x8017103c, 0x00000000, 0x001fa002, 0xb500001f, + 0xb00d0002, 0xb420001d, 0x80171054, 0x8033005a, + 0x98218279, 0x001fa001, 0x8017106c, 0x00000000, + 0x001fa001, 0xb5000015, 0xb00c0002, 0xb4200013, + 0xb00d0000, 0xb4200007, 0x8017100c, 0x00000000, + 0x001fa011, 0x80171040, 0x00000000, 0x001fa011, + 0xb500000a, 0xb00d0001, 0xb4200008, 0x80171054, + 0x8033005a, 0x98218279, 0x001fa001, 0x80171058, + 0x00000000, 0x001fa001, 0xb5000000, 0x029f0388, + 0x02bf0321, 0xb0140000, 0xb4000006, 0xb0150000, + 0xb4000004, 0x8017108c, 0x8033007f, 0x9821ffff, + 0x001fa001, 0x8027b078, 0x5c22b801, 0x806f001f, + 0x80af001f, 0x80cf0400, 0x003fb0bc, 0x5822b801, + 0x01afb801, 0x003f90bc, 0xb520ffff, 0x90210020, + 0x806f0003, 0x80af0003, 0x80cf0420, 0x003fb0bc, + 0x5822b801, 0x01afb801, 0x003f90bc, 0xb520ffff, + 0x81270000, 0x8033007f, 0x9821ffff, 0x80171000, + 0xb600060a, 0x80470000, 0xb6000603, 0x015f8020, + 0x0156b80a, 0x1042b80a, 0x3002b801, 0xb4a00001, + 0x81270001, 0x00000000, 0x00000000, 0x015f0323, + 0x00000000, 0xb00a0000, 0xb4200002, 0x81670000, + 0xb5000001, 0x81670001, 0x017f23fb, 0x01ff41ee, + 0x59f0b80f, 0x61f0b80f, 0x021f41ef, 0x5a10b810, + 0x6210b810, 0xb00a0003, 0xb420003b, 0x017f039f, + 0x019f41c5, 0x5990b80c, 0x6190b80c, 0xb00b0000, + 0xb400000c, 0xb00c0000, 0xb4000005, 0xac4c0100, + 0x8033001d, 0x98215500, 0x12c1b802, 0xb500000f, + 0xac4f0100, 0x8033001d, 0x98215500, 0x12c1b802, + 0xb500000a, 0xb0090000, 0xb4000005, 0xac4f0100, + 0x8033ffe2, 0x9821ab00, 0x12c1b802, 0xb5000003, + 0xac4f0100, 0x00000000, 0x02c7b802, 0xb0030000, + 0xb420007e, 0x01bf03a0, 0x01df41c9, 0x59d0b80e, + 0x61d0b80e, 0xb00d0000, 0xb400000c, 0xb00e0000, + 0xb4000005, 0xac4e0100, 0x8033001d, 0x98215500, + 0x12e1b802, 0xb5000071, 0xac500100, 0x8033001d, + 0x98215500, 0x12e1b802, 0xb500006c, 0xb0090000, + 0xb4000005, 0xac500100, 0x8033ffe2, 0x9821ab00, + 0x12e1b802, 0xb5000065, 0xac500100, 0x00000000, + 0x02e7b802, 0xb5000061, 0xb00a0002, 0xb420002f, + 0x023f9002, 0x025f9001, 0xb00f0000, 0xb4a00007, + 0xac4f0100, 0x00000000, 0x4022b811, 0x00000000, + 0x0028b801, 0x02c7b801, 0xb500000c, 0xb0090000, + 0xb4000004, 0xac4f0100, 0x00000000, 0x02c7b802, + 0xb5000006, 0xac4f0100, 0x00000000, 0x4022b812, + 0x00000000, 0x0028b801, 0x02c7b801, 0xb0030000, + 0xb4200046, 0xb0100000, 0xb4a00007, 0xac500100, + 0x00000000, 0x4022b811, 0x00000000, 0x0028b801, + 0x02e7b801, 0xb500003d, 0xb0090000, 0xb4000004, + 0xac500100, 0x00000000, 0x02e7b802, 0xb5000037, + 0xac500100, 0x00000000, 0x4022b812, 0x00000000, + 0x0028b801, 0x02e7b801, 0xb5000030, 0x023f9002, + 0x025f9001, 0xb00f0000, 0xb4a00007, 0xac4f0100, + 0x00000000, 0x4022b811, 0x00000000, 0x0028b801, + 0x02c7b801, 0xb5000006, 0xac4f0100, 0x00000000, + 0x4022b812, 0x00000000, 0x0028b801, 0x02c7b801, + 0xb0090000, 0xb4000005, 0x0047b816, 0x8033ffe2, + 0x9821ab00, 0x1042b801, 0x02c7b802, 0xb0030000, + 0xb4200016, 0xb0100000, 0xb4a00007, 0xac500100, + 0x00000000, 0x4022b811, 0x00000000, 0x0028b801, + 0x02e7b801, 0xb5000006, 0xac500100, 0x00000000, + 0x4022b812, 0x00000000, 0x0028b801, 0x02e7b801, + 0xb0090000, 0xb4000005, 0x0047b817, 0x8033ffe2, + 0x9821ab00, 0x1042b801, 0x02e7b802, 0x00000000, + 0x00000000, 0x02c8b816, 0x02dfb0cf, 0xb0030000, + 0xb4200002, 0x02e8b817, 0x02ffb0c6, 0x00ffb81b, + 0xb6001807, 0x5841b802, 0x3015b800, 0xb4800002, + 0x06b5b800, 0x98420001, 0x5aa1b815, 0x00000000, + 0x00ffb81c, 0x00000000, 0x00000000, 0x00000000, + 0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000, + 0xb4000011, 0x815bb3f0, 0x81070000, 0x81270bf4, + 0xb00a0000, 0xb4000002, 0x81070c00, 0x812717f4, + 0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc, + 0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809, + 0xb4a0002d, 0xb5000008, 0xb0040000, 0xb4200003, + 0x802717ff, 0x81470000, 0xb5000003, 0x80270001, + 0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200001, + 0x8384020c, 0x80af001f, 0x808f0000, 0x806f0000, + 0x80670400, 0x5d22b80a, 0x81df0000, 0x00000000, + 0x00000000, 0xb600180a, 0x00cfb803, 0x013fb0bc, + 0x5922b809, 0x01afb809, 0x013f90bc, 0x0047b86f, + 0xb0020001, 0xb4c0fffd, 0x90630020, 0x91290020, + 0x81df0004, 0x801bb3f8, 0x80270001, 0xb0000001, + 0xb4000002, 0x802600a0, 0x803eb3f8, 0x81270c00, + 0xb00a0000, 0xb4000001, 0x81270000, 0x813eb3f0, + 0x80270001, 0x003f2013, 0x00ffb81b, 0x00000000, + 0x029fb00a, 0x02bfb00b, 0x02dfb00c, 0x02ffb00d, + 0x031fb00e, 0x033fb00f, 0x033f400f, 0x0287b86f, + 0x029fb005, 0x8285009c, 0x96b48000, 0xb0158000, + 0xb4000195, 0x96b40100, 0xb0150100, 0xb40001ab, + 0x96b40400, 0xb0150400, 0xb40001ac, 0x96b40001, + 0xb0150001, 0xb400000c, 0x96b40008, 0xb0150008, + 0xb400019e, 0x96b44000, 0xb0154000, 0xb40001ab, + 0x96b40002, 0xb0150002, 0xb4000162, 0x00000000, + 0x00000000, 0xb50001bd, 0x02bf9017, 0x92b50001, + 0x02bfb017, 0x82850082, 0x5efdb814, 0x96f70001, + 0xb0170001, 0xb420000b, 0x83050069, 0x9718003f, + 0x82e50064, 0x12f7b818, 0x86f70109, 0x82feff74, + 0x02e7b86f, 0x9af74000, 0x01ffb817, 0x96f7bfff, + 0x01ffb817, 0x83050081, 0x82a5009a, 0x96b50001, + 0xb0150001, 0xb4200014, 0x82a70000, 0x02bfb017, + 0x96b41840, 0xb0150800, 0xb420000c, 0x96b40008, + 0x5aa9b815, 0x96d46000, 0x5ec3b816, 0x82f3000f, + 0x9af7c00f, 0x1718b817, 0x1ab5b818, 0x1ab5b816, + 0x9ab50340, 0x82a60081, 0xb5000132, 0x9b180180, + 0x83060081, 0xb500012f, 0x82a5009a, 0x96b50002, + 0xb0150002, 0xb420001b, 0x82a70000, 0x02bfb017, + 0x96b41800, 0xb0151800, 0xb4000013, 0x96b40040, + 0xb0150040, 0xb4200004, 0xa3180c00, 0x9b180340, + 0x83060081, 0xb500011f, 0x96b40008, 0x5aa9b815, + 0x96d46000, 0x5ec3b816, 0x82f3000f, 0x9af7c00f, + 0x1718b817, 0x1ab5b818, 0x1ab5b816, 0x9ab50340, + 0x82a60081, 0xb5000113, 0x9b180180, 0x83060081, + 0xb5000110, 0x82a500c1, 0x96b5000f, 0xb015000b, + 0xb420000e, 0x96b40020, 0xb0150020, 0xb400000b, + 0x96b40200, 0xb0150200, 0xb4000008, 0x82c50086, + 0x82e50094, 0x3016b817, 0xb4400004, 0x06f7b816, + 0xb017ff00, 0xb4400001, 0xb50000fe, 0x96b46000, + 0xb0156000, 0xb4000011, 0x96b41820, 0xb0150820, + 0xb4200004, 0x9b391000, 0x82a5009a, 0x96b5feff, + 0x82a6009a, 0x96b40040, 0xb0150040, 0xb4200001, + 0x9739efff, 0x96b91000, 0xb0151000, 0xb4200003, + 0x82a5009a, 0x9ab50100, 0x82a6009a, 0x96b40040, + 0xb0150040, 0xb4200019, 0x96b41800, 0xb0151800, + 0xb4200006, 0x96b98000, 0xb0158000, 0xb4200003, + 0x9b180180, 0x83060081, 0xb50000de, 0x96d80c00, + 0x82b300ff, 0x9ab5f3ff, 0x1718b815, 0xb0160c00, + 0xb4000007, 0x82e50098, 0x96f70400, 0xb0170400, + 0xb4200002, 0x82c70c00, 0xb5000001, 0xa2d60c00, + 0x1b18b816, 0x9b180340, 0xb50000c4, 0x96b40220, + 0xb0150000, 0xb4e00028, 0x82a5009d, 0x82f3ffff, + 0x16b5b817, 0x82f3000e, 0x3015b817, 0xb4200022, + 0x96f98000, 0xb0178000, 0xb400001f, 0x82a70000, + 0x02bfb017, 0x82c50081, 0x9ab60020, 0x82a60081, + 0x82a50086, 0x92b50bb8, 0x82a60094, 0x82c60081, + 0x82c5009d, 0x96d6ffff, 0x82b30032, 0x9ab58001, + 0x82e500c1, 0x96f7000f, 0xb017000b, 0xb4000002, + 0x82b30022, 0x9ab58001, 0x1ab5b816, 0x82c5009a, + 0x96d60020, 0xb0160020, 0xb4200002, 0x82b30032, + 0x9ab58001, 0x82a6009d, 0x02ff9017, 0x00000000, + 0xb0170040, 0xb4800000, 0x5eb5b814, 0x96b500f0, + 0x96f46000, 0x5eedb817, 0x1ab5b817, 0xb0170003, + 0xb4000004, 0x96b500ef, 0x96f70001, 0x5ae4b817, + 0x1ab5b817, 0x96d41800, 0xb0161800, 0xb400000a, + 0x96f900ff, 0x96b500ff, 0x9739ff00, 0x1b39b815, + 0x02a7b817, 0x96b500f3, 0x96d40008, 0x5ec1b816, + 0x1ab5b816, 0xb500000c, 0x96f98000, 0xb0178000, + 0xb4200007, 0x5efeb814, 0x96f70001, 0xb0170001, + 0xb4000003, 0x9b180180, 0x83060081, 0xb5000081, + 0x96b500f3, 0x9ab50008, 0x9739fff3, 0x96d40020, + 0xb0160020, 0xb4200017, 0x9b398000, 0x82c70000, + 0x02dfb017, 0x96d40010, 0x5ac8b816, 0x82f300ff, + 0x9af7cfff, 0x1718b817, 0x1b18b816, 0x9b180340, + 0x82c5009d, 0x96d6ffff, 0x82f3000e, 0x9af78001, + 0x1af7b816, 0x82c5009a, 0x96d60020, 0xb0160020, + 0xb4200002, 0x82f30032, 0x9af78001, 0x82e6009d, + 0xb500005a, 0x97397fff, 0x96b500ff, 0x5aaab815, + 0x82f300fc, 0x9af703ff, 0x1718b817, 0x1b18b815, + 0x9b180340, 0x82c5009a, 0x96d60010, 0xb0160010, + 0xb4200024, 0x82c70000, 0x02dfb017, 0x82c50086, + 0x92d60bb8, 0x82c60086, 0x82c50094, 0x5eefb818, + 0x96f70003, 0xb0170003, 0xb4200002, 0x82e70bb8, + 0xb5000001, 0x82e70bb8, 0x12d6b817, 0x82e50081, + 0x9af70020, 0x82e60081, 0x82c60094, 0xa2f70020, + 0x82e60081, 0x82f30001, 0x16f7b818, 0x5ef0b817, + 0xb0170001, 0xb4000004, 0x96f84000, 0x5ee4b817, + 0x9718f3ff, 0x1b18b817, 0x82f3000a, 0x9af78000, + 0x82e6009d, 0x83060081, 0x83070001, 0x8306009f, + 0xb5000096, 0x82c5009d, 0x82f3000e, 0x9af78001, + 0x3016b817, 0xb420000f, 0x82b30032, 0x9ab58001, + 0x82e500c1, 0x96f7000f, 0xb017000b, 0xb4000002, + 0x82b30022, 0x9ab58001, 0x82c5009a, 0x96d60020, + 0xb0160020, 0xb4200002, 0x82b30032, 0x9ab58001, + 0x82a6009d, 0x82c5009a, 0x96d60080, 0xb0160080, + 0xb4000011, 0x02df9017, 0x00000000, 0xb0160010, + 0xb480000d, 0x82c500c1, 0x96d6000f, 0xb016000b, + 0xb4000009, 0x82c50087, 0x96d60080, 0x5ac7b816, + 0x96f84000, 0x3017b816, 0xb4200003, 0x033f400f, + 0x9b394000, 0xb500000b, 0x9739bfff, 0x82e50061, + 0x96f70008, 0xb0170008, 0xb4000005, 0x5eefb818, + 0x96f70003, 0xb0170003, 0xb4000001, 0x9718ffff, + 0x83060081, 0x83070001, 0x8306009f, 0x00000000, + 0xb500005e, 0x82850083, 0x96b400ff, 0xb015003c, + 0xb4200019, 0x96b92000, 0xb0152000, 0xb4000002, + 0x9b392000, 0xb5000014, 0x9739d3ff, 0x82870000, + 0x82860087, 0x82870008, 0x82860083, 0x829bff78, + 0x82a7001f, 0xb0140400, 0xb4000001, 0x82a70010, + 0x82a600c9, 0x829bff78, 0x00000000, 0x828600cb, + 0x8285009d, 0x82b3ffff, 0x9ab5fffd, 0x1694b815, + 0x8286009d, 0xb5000000, 0x83070002, 0x8306009f, + 0x00000000, 0xb500003d, 0x96b90800, 0xb0150800, + 0xb4200009, 0x9739f7ff, 0x82a703fd, 0x82a600cb, + 0x82a7003c, 0x82a60083, 0x8285009d, 0x9a940002, + 0x8286009d, 0xb5000004, 0x82850087, 0x5a82b814, + 0xa2940200, 0x82860087, 0xb5000000, 0x83078000, + 0x8306009f, 0x00000000, 0xb5000028, 0x83070008, + 0x8306009f, 0x00000000, 0xb5000024, 0x83070100, + 0x8306009f, 0x00000000, 0xb5000020, 0x83070000, + 0x83050081, 0x9b180180, 0x83060081, 0x83070400, + 0x8306009f, 0x00000000, 0xb5000018, 0x82870000, + 0x82850082, 0x5eb7b814, 0x96b500fc, 0x96d40006, + 0x5ec1b816, 0x1ab5b816, 0x5aacb815, 0x83050081, + 0x82d3001c, 0x9ad600ff, 0x1718b816, 0x1b18b815, + 0x9b180e00, 0x83060081, 0x83074000, 0x8306009f, + 0x8305009d, 0x82d300ff, 0x9ad6bfff, 0x1718b816, + 0x8306009d, 0x00000000, 0xb5000000, 0x029f9005, + 0x01ffb814, 0x033f600f, 0x029f900a, 0x02bf900b, + 0x02df900c, 0x02ff900d, 0x031f900e, 0x033f900f, + 0x00ffb81e, 0x02ff9010, 0x92f70b43, 0x02ffb010, + 0x02ff90cb, 0x82bbffdc, 0x829bffd8, 0x93150004, + 0x3014b815, 0xb400000f, 0x02dbb818, 0x029bb815, + 0x3017b816, 0xb480000b, 0x5a81b814, 0x029fb010, + 0x82860095, 0x8293001f, 0x9294fe00, 0x92b50008, + 0x3015b814, 0xb4800002, 0x82b3001f, 0x92b5fa00, + 0x82beffdc, 0x029f9010, 0x83250094, 0x06d4b819, + 0x02d6b816, 0xb016ffff, 0xb4a0000a, 0x8293000e, + 0x9a948001, 0x82c5009d, 0x96d6ffff, 0x1a94b816, + 0x82c5009a, 0x96d60010, 0xb0160010, 0xb4000001, + 0x8286009d, 0x00ffb81c, 0x82870001, 0x829ef500, + 0x82850086, 0x83250094, 0x06d4b819, 0x02d6b816, + 0xb016ffff, 0xb4a0000b, 0x82870001, 0x829ef504, + 0x82c50081, 0x9ab60020, 0x82a60081, 0x82a50086, + 0x92b50bbb, 0x82a60094, 0x82c60081, 0x86b505df, + 0x82a6009b, 0x00ffb81c, 0x82070028, 0x023f9006, + 0x83a4ef48, 0x80070000, 0x001fb011, 0x001f204f, + 0x003fb800, 0x001f9006, 0x5803b800, 0x80338000, + 0x1800b801, 0x003fb800, 0x005f4193, 0x5c41b802, + 0x80350000, 0x00000000, 0x0027b860, 0x80150010, + 0x5810b800, 0x80750010, 0x1863b800, 0x8087ffff, + 0x80a7770b, 0x80c70000, 0x1403b804, 0x3000b805, + 0xb4000008, 0x5888b804, 0x58a8b805, 0x90c60001, + 0xb0060003, 0xb4a0fff8, 0x84420001, 0xb4e0ffee, + 0xb5000027, 0xb0060003, 0xb4200007, 0x80150010, + 0x5810b800, 0x81150010, 0x950800ff, 0xb0080077, + 0xb4000001, 0xb500fff4, 0x001f400e, 0x98000010, + 0x98004000, 0x9400fffe, 0x001f600e, 0x80e71fc0, + 0x001f4000, 0x94000080, 0xb0000080, 0xb4200001, + 0x80e77560, 0x00ffb008, 0x80e70020, 0xb0060000, + 0xb400000e, 0x58e3b806, 0x90210020, 0x81070000, + 0x5938b803, 0x1908b809, 0x9523ff00, 0x5928b809, + 0x1908b809, 0x5d28b803, 0x9529ff00, 0x1908b809, + 0x5d38b803, 0x1908b809, 0x011fb011, 0x00ff204f, + 0x80137fff, 0x9800ffe7, 0x1421b800, 0x5c23b801, + 0x001f9006, 0x0441b800, 0x3001b800, 0xb4600002, + 0x0440b801, 0xa4422000, 0x007f90cb, 0x1063b802, + 0x007fb0cb, 0x003fb006, 0x803effec, 0x80470001, + 0x005f2013, 0xb500ebae, 0x001f400e, 0x9400000f, + 0xb0000000, 0xb4200001, 0x00ffb81f, 0xb0000001, + 0xb4000005, 0xb0000003, 0xb4000003, 0xb0000002, + 0xb4000001, 0x00ffb81f, 0x80070001, 0x001f2013, + 0xb500eb9f, 0x00000000, 0x00000000, 0x00000000, + 0x001f9012, 0x001fb100, 0x001f004c, 0x001f2404, + 0x801bfef0, 0x8058fef4, 0x803bff68, 0x8078ff6c, + 0x2000b801, 0x2042b803, 0x001fb104, 0x005f2414, + 0x82e70001, 0x83640048, 0x029fb014, 0x829efef0, + 0x8286000f, 0x02bf2054, 0x82bcfef4, 0x82a6000e, + 0x00ffb81a, 0x80e70001, 0x801336e3, 0x9800eb76, + 0x001fb100, 0x800700ab, 0x001f2404, 0x801bc3e8, + 0x8058c3ec, 0x83640024, 0x82e70000, 0x83640036, + 0x029fb300, 0x029fb100, 0x02bf2c04, 0x02bf2404, + 0x801bc000, 0x8058c004, 0x8364001b, 0x82e70000, + 0x8364002d, 0x001f9300, 0x3000b814, 0xb420000a, + 0x001f0c04, 0x3000b815, 0xb4200007, 0x829efef0, + 0x82bcfef4, 0x029fb012, 0x02bf204c, 0x82870001, + 0x829cfef5, 0x00ffb81a, 0xb0070000, 0xb4000007, + 0x80e70000, 0x801399fa, 0x9800c92e, 0x001fb100, + 0x800700af, 0x001f2404, 0xb500ffdc, 0x82870000, + 0x829cfef5, 0x00ffb81a, 0x80c700ff, 0x803bff68, + 0x8078ff6c, 0x14a0b806, 0x2063b805, 0x007f2414, + 0x2021b802, 0x58c8b806, 0x14a0b806, 0x58b0b805, + 0x2021b805, 0x58c8b806, 0x14a0b806, 0x2021b805, + 0x58c8b806, 0x14a0b806, 0x5cb0b805, 0x2021b805, + 0x003fb104, 0x00ffb81b, 0x82c70000, 0x83070400, + 0x83270005, 0x8197040c, 0x81d7ffff, 0x83840126, + 0x83840001, 0x00ffb81b, 0x808f0000, 0x806f001f, + 0x80af001f, 0x80270140, 0x81e7ef98, 0x5de2b80f, + 0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, + 0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020, + 0x90210020, 0x80270180, 0x81e7ee90, 0x5de2b80f, + 0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, + 0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020, + 0x90210020, 0x8057ffff, 0x80170430, 0x80070410, + 0x80270408, 0xb6000509, 0x005ff000, 0x90420500, + 0x007ff001, 0x90630600, 0x009ff002, 0x00bff003, + 0x2004a025, 0x90000001, 0x90210001, 0x80070414, + 0x80d7ffff, 0x8097045c, 0x8017043c, 0xb6000404, + 0x005ff000, 0x007f87e0, 0x84000001, 0x2082a7e3, + 0x80970460, 0x80170440, 0x2082b803, 0x007f8000, + 0x2083a004, 0x80170430, 0x80970450, 0x80270408, + 0xb6000508, 0x005f8024, 0x90420500, 0x007ff001, + 0x90630600, 0x009ff002, 0x00bff003, 0x2004a025, + 0x90210001, 0x80170440, 0x00000000, 0x02bf87e0, + 0x80970460, 0x82870000, 0xb6000404, 0x005f87e4, + 0x5a88b814, 0x204287e0, 0x1a94b802, 0x00ffb81c, + 0x001f0a49, 0x001f2709, 0x001f0a41, 0x001f2708, + 0x001f0a46, 0x001f2707, 0x001f0a48, 0x001f2706, + 0x001f0a42, 0x001f2705, 0x001f0a47, 0x001f2704, + 0x001f0a45, 0x001f2703, 0x001f0a43, 0x001f2702, + 0x001f0a40, 0x001f2701, 0x001f0a44, 0x001f2700, + 0x001f0c25, 0xa020000c, 0x94400001, 0x94600002, + 0x94810004, 0x94a10008, 0x94c00010, 0x5943b802, + 0x5861b803, 0x5882b804, 0x5ca2b805, 0x5cc4b806, + 0x194ab803, 0x194ab804, 0x194ab805, 0x194ab806, + 0x015f2738, 0x801bef90, 0x003f91c1, 0x5c28b801, + 0x005f91c2, 0x5858b802, 0x1821b802, 0x2000b801, + 0x001fb1c4, 0x8018ef94, 0x003f0709, 0x2000b801, + 0x001f2714, 0x82c70001, 0x82e70001, 0x83070710, + 0x8327001e, 0x81970735, 0x8384009f, 0x02df0738, + 0x82170a30, 0x838400f1, 0x819efef0, 0x817cfef4, + 0x819eff68, 0x817cff6c, 0x00ffb81b, 0x820f001f, + 0x8018fef8, 0x8057ffff, 0x001f2709, 0x8018fef6, + 0x80d7ffff, 0x001f2708, 0x8018fefa, 0x8157ffff, + 0x001f2707, 0x8018fefd, 0x81d7ffff, 0x001f2706, + 0x8018fefb, 0x802f001f, 0x001f2705, 0x8018fefe, + 0x00000000, 0x001f2704, 0x8018fef9, 0x00000000, + 0x001f2703, 0x8018feff, 0x00000000, 0x001f2702, + 0x8018fef7, 0x00000000, 0x001f2701, 0x8018fefc, + 0x00000000, 0x001f2700, 0x001f0c25, 0xa0200011, + 0x94410001, 0x94600002, 0x94800004, 0x94a00008, + 0x94c10010, 0x5941b802, 0x5861b803, 0x5c82b804, + 0x58a1b805, 0x5cc1b806, 0x194ab803, 0x194ab804, + 0x194ab805, 0x194ab806, 0x015f2738, 0x801bef90, + 0x003f91c1, 0x5c28b801, 0x005f91c2, 0x5858b802, + 0x1821b802, 0x2000b801, 0x001fb1c4, 0x8018ef94, + 0x003f0709, 0x2000b801, 0x001f2714, 0x82c70001, + 0x82e70001, 0x83070710, 0x8327001e, 0x81970735, + 0x83840055, 0x02df0738, 0x82170a20, 0x838400a7, + 0x819efef0, 0x817cfef4, 0x5ac8b80c, 0x02ff0a44, + 0x1ad6b817, 0x02dfb291, 0x5ed8b80c, 0x5968b80b, + 0x1ad6b80b, 0x02df6524, 0x00ffb81b, 0x820f001f, + 0x8018fefe, 0x8057ffff, 0x001f2709, 0x8018fefa, + 0x80d7ffff, 0x001f2708, 0x8018fefc, 0x8157ffff, + 0x001f2707, 0x8018feff, 0x81d7ffff, 0x001f2706, + 0x8018fef8, 0x802f001f, 0x001f2705, 0x8018fefb, + 0x00000000, 0x001f2704, 0x8018fefd, 0x00000000, + 0x001f2703, 0x8018fef6, 0x00000000, 0x001f2702, + 0x8018fef9, 0x00000000, 0x001f2701, 0x8018fef7, + 0x00000000, 0x001f2700, 0x801bef90, 0x003f91c1, + 0x5c28b801, 0x005f91c2, 0x5858b802, 0x1821b802, + 0x2000b801, 0x001fb1c4, 0x8018ef94, 0x003f0709, + 0x2000b801, 0x001f2714, 0x82c70001, 0x82e70001, + 0x83070710, 0x8327001e, 0x81970735, 0x83840016, + 0x83270000, 0x831bfef0, 0x82f8fef4, 0x02c7b819, + 0x82170a28, 0x83840065, 0x300cb818, 0xb4200002, + 0x300bb817, 0xb4000006, 0x93390001, 0xb0190020, + 0xb480fff6, 0x83270000, 0x833cfef5, 0x00ffb81b, + 0x019fb290, 0x017f2a44, 0x033f2c25, 0x83270001, + 0x833cfef5, 0x00ffb81b, 0x0007b818, 0x90000003, + 0x00000000, 0x015ff000, 0x90000001, 0x5949b80a, + 0x013ff000, 0x194ab809, 0x84000002, 0x994a0100, + 0x017ff000, 0x958b00f8, 0x5981b80c, 0x956b0007, + 0x198cb80b, 0x84000002, 0x998c0008, 0x017ff000, + 0x90000001, 0x5971b80b, 0x198cb80b, 0x017ff000, + 0x5969b80b, 0x198cb80b, 0x81a70000, 0x94d90003, + 0x82a70000, 0xb6260019, 0xb6000818, 0x5df0b80a, + 0x5e02b80a, 0x21efb810, 0x95ef0001, 0x5941b80a, + 0x194ab80f, 0x21efb816, 0x5e18b80c, 0x5e35b80c, + 0x5e54b80c, 0x5e6cb80c, 0x2210b811, 0x2252b813, + 0x2210b812, 0x96100001, 0x5981b80c, 0x198cb810, + 0x2210b817, 0x10afb810, 0x10a5b80d, 0x5da1b805, + 0x94a50001, 0x5aa1b815, 0x1ab5b805, 0x019fa7f5, + 0x5cc2b819, 0xb626001c, 0x82870000, 0xb6000419, + 0xb6000818, 0x5df0b80a, 0x5e02b80a, 0x21efb810, + 0x95ef0001, 0x5941b80a, 0x194ab80f, 0x21efb816, + 0x5e18b80c, 0x5e35b80c, 0x5e54b80c, 0x5e6cb80c, + 0x2210b811, 0x2252b813, 0x2210b812, 0x96100001, + 0x5981b80c, 0x198cb810, 0x2210b817, 0x10afb810, + 0x10a5b80d, 0x5da1b805, 0x94a50001, 0x5a81b814, + 0x1a94b805, 0x019fa7f4, 0x00ffb81c, 0x8257ffff, + 0x808f0000, 0x806f001f, 0x80af001f, 0x80270200, + 0x81e7ec70, 0x5de2b80f, 0xb6000208, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0xb520ffff, 0x91ef0020, 0x90210020, 0x80270240, + 0x81e7ed70, 0x5de2b80f, 0xb6000208, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0xb520ffff, 0x91ef0020, 0x90210020, 0x80270180, + 0x81e7ee90, 0x5de2b80f, 0xb6000208, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0xb520ffff, 0x91ef0020, 0x90210020, 0x806f0007, + 0x80af0007, 0x80270280, 0x81e7ee70, 0x5de2b80f, + 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, + 0x01ff90bc, 0xb520ffff, 0x91ef0020, 0x90210020, + 0x80170760, 0x001f0700, 0x001fa020, 0x001f0701, + 0x001fa020, 0x001f0702, 0x001fa020, 0x001f0703, + 0x001fa020, 0x001f0704, 0x001fa000, 0x80970750, + 0x81170770, 0x82a70735, 0x83a40060, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a4005c, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750, + 0x81170750, 0x81970740, 0x82a70730, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a40050, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a4004c, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970750, 0x80170770, + 0x81170770, 0x81970760, 0x82a7072b, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a40040, 0x83a4004e, + 0xb6000407, 0x86b50001, 0x83a4003c, 0x001f8004, + 0x003f87e8, 0x2080a001, 0x83a40047, 0x00000000, + 0x80970770, 0x80170750, 0x81170750, 0x81970740, + 0x82a70726, 0x001f800c, 0x003f8008, 0x2100a001, + 0x83a4002e, 0x83a4003c, 0xb6000407, 0x86b50001, + 0x83a4002a, 0x001f8004, 0x003f87e8, 0x2080a001, + 0x83a40035, 0x00000000, 0x80970750, 0x80170770, + 0x81170770, 0x81970760, 0x82a70721, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a4001c, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a40018, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750, + 0x81170750, 0x81970740, 0x82a7071c, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a4000c, 0x017f87e4, + 0x81870000, 0xb6000406, 0x86b50001, 0x83a40007, + 0x001f87e4, 0x200087e8, 0x5988b80c, 0x198cb800, + 0x021fa02c, 0x021fa00b, 0x00ffb81c, 0x005ff015, + 0x90420600, 0x003f87e0, 0x001ff002, 0x2060b801, + 0x90630800, 0x90960a00, 0x001ff003, 0x003ff004, + 0x20a0b801, 0x90a50900, 0x00000000, 0x001ff005, + 0x009fa000, 0x00ffb81d, 0x001f8004, 0x5c21b800, + 0x5847b800, 0x1821b802, 0x942100ff, 0x2080a7e1, + 0x00ffb81d, 0x00000000, 0x00000000, 0x00000000, + 0x015f400e, 0x944a4000, 0xb0024000, 0xb420001e, + 0x954abfff, 0x015f600e, 0x820f001f, 0x802f001f, + 0x81470000, 0x015f23f9, 0x015fb0ba, 0x8057ffff, + 0x80770000, 0x82970400, 0x82d7ffff, 0x82f70000, + 0x81df0000, 0x00000000, 0x00000000, 0xb6000702, + 0xb6000001, 0x029fa02a, 0x81df0004, 0x80275480, + 0x005fb801, 0x8033001f, 0x9821c000, 0x803effe0, + 0x90212000, 0x803effe4, 0x80d9ff80, 0x00df6001, + 0x814775e8, 0x015fb008, 0x003f0324, 0xb0010000, + 0xb420007e, 0x8344ebde, 0xb0180000, 0xb4000004, + 0x011f400e, 0x1908b818, 0x011f600e, 0x00ffb81f, + 0x8344f1df, 0xb00b0000, 0xb4000006, 0x023f400e, + 0x9a310002, 0x023f600e, 0x82270000, 0x023f2012, + 0x00ffb81f, 0x8364ed72, 0x82270000, 0x023f2011, + 0x80070000, 0x80170800, 0x81df0000, 0x00000000, + 0x00000000, 0xb6002002, 0xb6003001, 0x001fa020, + 0x81df0004, 0x82270000, 0x003fb811, 0x02bf9006, + 0x5aa3b815, 0x82338000, 0x1a31b815, 0x003fb811, + 0x8067e950, 0x5c62b803, 0x81f50000, 0x019f4193, + 0x0267b80c, 0xadcc0010, 0x80170800, 0x80130000, + 0x9800f872, 0x001fa020, 0x80134e1f, 0x98000001, + 0x001fa020, 0x59d0b80e, 0x81150010, 0x1908b80e, + 0x001fa028, 0x858c0001, 0x5e01b80c, 0x5e25b810, + 0x81df0000, 0x00000000, 0x00000000, 0xb6310006, + 0xb6002005, 0x81150010, 0x5910b808, 0x00000000, + 0x81350010, 0x1808a029, 0x9630001f, 0xb0110000, + 0xb4000006, 0xb6310005, 0x81150010, 0x5910b808, + 0x00000000, 0x81350010, 0x1808a029, 0x81df0004, + 0x962c0001, 0xb0110000, 0xb4000003, 0x81150010, + 0x5910b808, 0x001fa028, 0x019f9006, 0x958cffff, + 0x00df4193, 0x58c1b806, 0x118cb806, 0xb00ce000, + 0xb4800002, 0x858ce000, 0x918cc000, 0x8153001f, + 0x118cb80a, 0x819effec, 0x019fb006, 0x015f4193, + 0x5941b80a, 0x019f90cb, 0x118cb80a, 0x019fb0cb, + 0x019f90ba, 0x918c0001, 0x019fb0ba, 0xb00c0002, + 0xb4200016, 0x019f400e, 0x940c8000, 0xb0008000, + 0xb4200012, 0x958c7fff, 0x019f600e, 0x80070000, + 0x800600a0, 0x80073da1, 0x800600a1, 0x801bff60, + 0x00000000, 0x801eff60, 0x00000000, 0x801bff60, + 0x00000000, 0x801eff60, 0x80130001, 0x98003da1, + 0x800600a1, 0x80070001, 0x800600a0, 0x003f0324, + 0x90210001, 0xb0010005, 0xb4a00001, 0x80270000, + 0x003f2324, 0x00ffb81f, 0x00000000, 0x00000000, + 0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000, + 0xb4000011, 0x815bb3f0, 0x81070000, 0x81270bf4, + 0xb00a0000, 0xb4000002, 0x81070c00, 0x81271800, + 0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc, + 0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809, + 0xb4a00032, 0xb5000008, 0xb0040000, 0xb4200003, + 0x802717ff, 0x81470000, 0xb5000003, 0x80270001, + 0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200001, + 0x8384fbf4, 0x80af001f, 0x808f0002, 0x806f0000, + 0x807bbf34, 0x5d22b80a, 0x81df0000, 0x00000000, + 0x00000000, 0xb600080a, 0x00cfb803, 0x013fb0bc, + 0x5922b809, 0x01afb809, 0x013f90bc, 0x0047b86f, + 0xb0020001, 0xb4c0fffd, 0x90630020, 0x91290060, + 0x81df0004, 0x808f0000, 0x813bb3f8, 0x80270001, + 0xb0090001, 0xb4000002, 0x802600a0, 0x803eb3f8, + 0x81270c00, 0xb00a0000, 0xb4000001, 0x81270000, + 0x813eb3f0, 0xb0030800, 0xb4800001, 0x80670200, + 0x807ebf34, 0x80270001, 0x003f2013, 0x00ffb81b, + +}; + +static u32 AC3Ucode1f8000[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00020000, 0xffff0005, 0xffffffff, + 0x00050001, 0xffffffff, 0xffffffff, 0x00020000, + 0xffff0005, 0xffffffff, 0x00010000, 0x00050002, + 0xffffffff, 0x00020000, 0x00050003, 0xffffffff, + 0x00010000, 0x00030002, 0xffff0005, 0x00020000, + 0x00040003, 0xffff0005, 0x00010000, 0x00030002, + 0x00050004, 0x0019000d, 0x003d0025, 0x00250019, + 0x00fd003d, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x007fffff, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x007fffff, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x007fffff, 0x00000000, + 0x00000000, 0x00599999, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00599999, + 0x007fffff, 0x00599999, 0x00000000, 0x00599999, + 0x00000000, 0x00000000, 0x00000000, 0x00599999, + 0x00000000, 0x00599999, 0x007fffff, 0x00000000, + 0x00599999, 0x00599999, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00599999, 0x00599999, + 0x007fffff, 0x007fffff, 0x00000000, 0x00599999, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00599999, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x007fffff, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x007fffff, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x007fffff, 0x00000000, + 0x007fffff, 0x00000000, 0x007fffff, 0x00400000, + 0x00200000, 0x00100000, 0x00080000, 0x00040000, + 0x00020000, 0x00010000, 0x00008000, 0x00004000, + 0x00002000, 0x00001000, 0x00000800, 0x00000400, + 0x00000200, 0x00000100, 0x00000080, 0x00000040, + 0x00000020, 0x00000010, 0x00000008, 0x00000004, + 0x00000002, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00010002, + 0x00030002, 0x00030002, 0x00030002, 0x00000000, + 0x00000000, 0x00010001, 0x00020002, 0x4000a000, + 0xe000a000, 0xf000b000, 0xf800b800, 0x005a8279, + 0x004c1bf8, 0x00400000, 0x004c1bf8, 0x005a8279, + 0x00400000, 0x00000000, 0x00400000, 0x03020100, + 0x00000000, 0x00000080, 0x00000020, 0x00000008, + 0x00000000, 0x00000001, 0x00010001, 0x10081000, + 0x10041000, 0x10081004, 0x10081008, 0x10081008, + 0x00000000, 0x00000000, 0x00000000, 0xff80000a, + 0xff80031f, 0xff800b24, 0xff801818, 0xff8029fa, + 0xff8040c9, 0xff805c86, 0xff807d2e, 0xff80a2c1, + 0xff80cd3c, 0xff80fc9f, 0xff8130e8, 0xff816a14, + 0xff81a821, 0xff81eb0e, 0xff8232d6, 0xff827f79, + 0xff82d0f2, 0xff83273e, 0xff83825b, 0xff83e244, + 0xff8446f7, 0xff84b06e, 0xff851ea6, 0xff85919b, + 0xff860949, 0xff8685aa, 0xff8706ba, 0xff878c74, + 0xff8816d3, 0xff88a5d1, 0xff89396a, 0xff89d196, + 0xff8a6e51, 0xff8b0f94, 0xff8bb55a, 0xff8c5f9b, + 0xff8d0e51, 0xff8dc176, 0xff8e7902, 0xff8f34ef, + 0xff8ff535, 0xff90b9cc, 0xff9182ae, 0xff924fd3, + 0xff932132, 0xff93f6c3, 0xff94d07f, 0xff95ae5d, + 0xff969054, 0xff97765b, 0xff98606a, 0xff994e78, + 0xff9a407c, 0xff9b366b, 0xff9c303e, 0xff9d2de9, + 0xff9e2f64, 0xff9f34a4, 0xffa03da0, 0xffa14a4c, + 0xffa25aa0, 0xffa36e8f, 0xffa48610, 0xffa5a118, + 0xffa6bf9c, 0xffa7e191, 0xffa906ec, 0xffaa2fa0, + 0xffab5ba4, 0xffac8aeb, 0xffadbd6a, 0xffaef315, + 0xffb02bdf, 0xffb167be, 0xffb2a6a4, 0xffb3e886, + 0xffb52d56, 0xffb67509, 0xffb7bf92, 0xffb90ce4, + 0xffba5cf2, 0xffbbafb0, 0xffbd050f, 0xffbe5d04, + 0xffbfb780, 0xffc11477, 0xffc273db, 0xffc3d59f, + 0xffc539b4, 0xffc6a00d, 0xffc8089d, 0xffc97355, + 0xffcae027, 0xffcc4f05, 0xffcdbfe2, 0xffcf32af, + 0xffd0a75d, 0xffd21ddf, 0xffd39625, 0xffd51022, + 0xffd68bc7, 0xffd80904, 0xffd987cd, 0xffdb0810, + 0xffdc89c1, 0xffde0cd0, 0xffdf912d, 0xffe116cb, + 0xffe29d9a, 0xffe4258b, 0xffe5ae8f, 0xffe73896, + 0xffe8c392, 0xffea4f74, 0xffebdc2b, 0xffed69aa, + 0xffeef7df, 0xfff086bd, 0xfff21634, 0xfff3a634, + 0xfff536ad, 0xfff6c792, 0xfff858d1, 0xfff9ea5b, + 0xfffb7c22, 0xfffd0e16, 0xfffea026, 0xffffcdbc, + 0xfffe3ba0, 0xfffca995, 0xfffb17ac, 0xfff985f3, + 0xfff7f479, 0xfff6634f, 0xfff4d284, 0xfff34228, + 0xfff1b249, 0xfff022f7, 0xffee9442, 0xffed0638, + 0xffeb78ea, 0xffe9ec67, 0xffe860bd, 0xffe6d5fd, + 0xffe54c35, 0xffe3c374, 0xffe23bcb, 0xffe0b547, + 0xffdf2ff7, 0xffddabec, 0xffdc2933, 0xffdaa7dd, + 0xffd927f6, 0xffd7a98f, 0xffd62cb7, 0xffd4b17b, + 0xffd337ea, 0xffd1c013, 0xffd04a05, 0xffced5ce, + 0xffcd637c, 0xffcbf31d, 0xffca84c1, 0xffc91874, + 0xffc7ae45, 0xffc64641, 0xffc4e078, 0xffc37cf6, + 0xffc21bc9, 0xffc0bcff, 0xffbf60a5, 0xffbe06c9, + 0xffbcaf79, 0xffbb5ac0, 0xffba08ae, 0xffb8b94d, + 0xffb76cac, 0xffb622d8, 0xffb4dbdc, 0xffb397c6, + 0xffb256a2, 0xffb1187d, 0xffafdd62, 0xffaea55f, + 0xffad707e, 0xffac3ecc, 0xffab1054, 0xffa9e523, + 0xffa8bd44, 0xffa798c2, 0xffa677a8, 0xffa55a02, + 0xffa43fdb, 0xffa3293d, 0xffa21634, 0xffa106c9, + 0xff9ffb08, 0xff9ef2fa, 0xff9deeab, 0xff9cee23, + 0xff9bf16c, 0xff9af892, 0xff9a039c, 0xff991295, + 0xff982586, 0xff973c78, 0xff965774, 0xff957683, + 0xff9499ad, 0xff93c0fb, 0xff92ec75, 0xff921c24, + 0xff91500f, 0xff90883f, 0xff8fc4bb, 0xff8f058b, + 0xff8e4ab6, 0xff8d9443, 0xff8ce239, 0xff8c349f, + 0xff8b8b7d, 0xff8ae6d7, 0xff8a46b5, 0xff89ab1e, + 0xff891416, 0xff8881a3, 0xff87f3cc, 0xff876a96, + 0xff86e606, 0xff866621, 0xff85eaed, 0xff85746d, + 0xff8502a6, 0xff84959e, 0xff842d57, 0xff83c9d7, + 0xff836b20, 0xff831138, 0xff82bc20, 0xff826bdc, + 0xff822070, 0xff81d9de, 0xff819829, 0xff815b54, + 0xff812360, 0xff80f051, 0xff80c228, 0xff8098e6, + 0xff80748e, 0xff805521, 0xff803a9f, 0xff80250b, + 0xff801464, 0xff8008ad, 0xff8001e4, 0xff800027, + 0xff800c7e, 0xff802c8f, 0xff806056, 0xff80a7cb, + 0xff8102e4, 0xff817191, 0xff81f3c3, 0xff828964, + 0xff83325f, 0xff83ee98, 0xff84bdf3, 0xff85a04f, + 0xff86958b, 0xff879d7f, 0xff88b804, 0xff89e4ee, + 0xff8b240e, 0xff8c7533, 0xff8dd82a, 0xff8f4cbb, + 0xff90d2ad, 0xff9269c4, 0xff9411c1, 0xff95ca62, + 0xff979365, 0xff996c81, 0xff9b5570, 0xff9d4de4, + 0xff9f5590, 0xffa16c24, 0xffa3914e, 0xffa5c4b8, + 0xffa8060d, 0xffaa54f3, 0xffacb10e, 0xffaf1a03, + 0xffb18f70, 0xffb410f7, 0xffb69e33, 0xffb936c0, + 0xffbbda37, 0xffbe8830, 0xffc14042, 0xffc40201, + 0xffc6cd00, 0xffc9a0d2, 0xffcc7d05, 0xffcf612b, + 0xffd24ccf, 0xffd53f80, 0xffd838c8, 0xffdb3833, + 0xffde3d49, 0xffe14795, 0xffe4569d, 0xffe769e9, + 0xffea80ff, 0xffed9b67, 0xfff0b8a4, 0xfff3d83c, + 0xfff6f9b5, 0xfffa1c91, 0xfffd4056, 0xffff9b78, + 0xfffc7756, 0xfff953c0, 0xfff63130, 0xfff31025, + 0xffeff117, 0xffecd484, 0xffe9bae5, 0xffe6a4b6, + 0xffe39270, 0xffe0848b, 0xffdd7b82, 0xffda77cb, + 0xffd779de, 0xffd48231, 0xffd19138, 0xffcea769, + 0xffcbc535, 0xffc8eb10, 0xffc61969, 0xffc350af, + 0xffc09151, 0xffbddbbb, 0xffbb3059, 0xffb88f92, + 0xffb5f9d0, 0xffb36f78, 0xffb0f0ef, 0xffae7e96, + 0xffac18cf, 0xffa9bff9, 0xffa7746f, 0xffa5368c, + 0xffa306aa, 0xffa0e51e, 0xff9ed23c, 0xff9cce56, + 0xff9ad9bc, 0xff98f4bc, 0xff971f9f, 0xff955aae, + 0xff93a62f, 0xff920266, 0xff906f92, 0xff8eedf3, + 0xff8d7dc4, 0xff8c1f3c, 0xff8ad294, 0xff8997fd, + 0xff886fa8, 0xff8759c3, 0xff865679, 0xff8565f2, + 0xff848852, 0xff83bdbd, 0xff830651, 0xff82622b, + 0xff81d163, 0xff815411, 0xff80ea47, 0xff809416, + 0xff80518b, 0xff8022b1, 0xff80078e, 0x00000475, + 0x000007fe, 0x00000c02, 0x000010a3, 0x000015f5, + 0x00001c08, 0x000022ed, 0x00002ab5, 0x00003371, + 0x00003d32, 0x0000480a, 0x0000540d, 0x0000614b, + 0x00006fda, 0x00007fcd, 0x00009138, 0x0000a431, + 0x0000b8cc, 0x0000cf1f, 0x0000e741, 0x00010148, + 0x00011d4b, 0x00013b61, 0x00015ba2, 0x00017e25, + 0x0001a302, 0x0001ca51, 0x0001f42c, 0x000220a9, + 0x00024fe2, 0x000281f0, 0x0002b6ea, 0x0002eee9, + 0x00032a07, 0x0003685a, 0x0003a9fc, 0x0003ef04, + 0x0004378a, 0x000483a5, 0x0004d36d, 0x000526f7, + 0x00057e5b, 0x0005d9ae, 0x00063904, 0x00069c74, + 0x00070410, 0x00076feb, 0x0007e01a, 0x000854ac, + 0x0008cdb3, 0x00094b40, 0x0009cd61, 0x000a5425, + 0x000adf98, 0x000b6fc8, 0x000c04bf, 0x000c9e87, + 0x000d3d2a, 0x000de0ae, 0x000e891a, 0x000f3674, + 0x000fe8c0, 0x00109fff, 0x00115c34, 0x00121d5d, + 0x0012e37b, 0x0013ae89, 0x00147e84, 0x00155366, + 0x00162d27, 0x00170bbf, 0x0017ef23, 0x0018d748, + 0x0019c421, 0x001ab59f, 0x001babb2, 0x001ca648, + 0x001da54f, 0x001ea8b0, 0x001fb058, 0x0020bc2d, + 0x0021cc18, 0x0022dffd, 0x0023f7c2, 0x00251348, + 0x00263272, 0x00275520, 0x00287b31, 0x0029a482, + 0x002ad0f1, 0x002c0059, 0x002d3294, 0x002e677c, + 0x002f9ee8, 0x0030d8b1, 0x003214ac, 0x003352b0, + 0x00349290, 0x0035d422, 0x00371738, 0x00385ba5, + 0x0039a13b, 0x003ae7cc, 0x003c2f2a, 0x003d7725, + 0x003ebf8d, 0x00400834, 0x004150e9, 0x0042997d, + 0x0043e1c0, 0x00452981, 0x00467092, 0x0047b6c3, + 0x0048fbe3, 0x004a3fc6, 0x004b823b, 0x004cc316, + 0x004e0228, 0x004f3f45, 0x00507a40, 0x0051b2ef, + 0x0052e925, 0x00541cba, 0x00554d85, 0x00567b5e, + 0x0057a61d, 0x0058cd9e, 0x0059f1bb, 0x005b1252, + 0x005c2f3f, 0x005d4863, 0x005e5d9d, 0x005f6ed0, + 0x00607bde, 0x006184ad, 0x00628923, 0x00638927, + 0x006484a3, 0x00657b81, 0x00666daf, 0x00675b19, + 0x006843b1, 0x00692767, 0x006a062d, 0x006adff9, + 0x006bb4c2, 0x006c847d, 0x006d4f27, 0x006e14b8, + 0x006ed52f, 0x006f9089, 0x007046c6, 0x0070f7e9, + 0x0071a3f3, 0x00724aea, 0x0072ecd3, 0x007389b6, + 0x0074219d, 0x0074b490, 0x0075429b, 0x0075cbcc, + 0x00765031, 0x0076cfd8, 0x00774ad3, 0x0077c132, + 0x00783308, 0x0078a068, 0x00790968, 0x00796e1c, + 0x0079ce9a, 0x007a2af9, 0x007a8350, 0x007ad7b8, + 0x007b2849, 0x007b751d, 0x007bbe4c, 0x007c03f1, + 0x007c4625, 0x007c8504, 0x007cc0a8, 0x007cf92c, + 0x007d2eaa, 0x007d613e, 0x007d9101, 0x007dbe10, + 0x007de883, 0x007e1076, 0x007e3603, 0x007e5943, + 0x007e7a4f, 0x007e9942, 0x007eb633, 0x007ed13a, + 0x007eea6f, 0x007f01ea, 0x007f17c0, 0x007f2c08, + 0x007f3ed7, 0x007f5043, 0x007f605e, 0x007f6f3c, + 0x007f7cf1, 0x007f898e, 0x007f9525, 0x007f9fc6, + 0x007fa982, 0x007fb268, 0x007fba86, 0x007fc1eb, + 0x007fc8a4, 0x007fcebe, 0x007fd443, 0x007fd941, + 0x007fddc2, 0x007fe1cf, 0x007fe572, 0x007fe8b4, + 0x007feb9e, 0x007fee36, 0x007ff086, 0x007ff293, + 0x007ff463, 0x007ff5fd, 0x007ff765, 0x007ff8a1, + 0x007ff9b6, 0x007ffaa7, 0x007ffb79, 0x007ffc2f, + 0x007ffccb, 0x007ffd52, 0x007ffdc6, 0x007ffe28, + 0x007ffe7b, 0x007ffec2, 0x007ffefd, 0x007fff2f, + 0x007fff58, 0x007fff7b, 0x007fff97, 0x007fffae, + 0x007fffc0, 0x007fffcf, 0x007fffdb, 0x007fffe4, + 0x007fffec, 0x007ffff1, 0x007ffff6, 0x007ffff9, + 0x007ffffb, 0x007ffffd, 0x007ffffe, 0x007fffff, + 0x007fffff, 0x007fffff, 0x007fffff, 0xff800000, + 0x00000000, 0xffa57d86, 0x005a827a, 0xff89be51, + 0x0030fbc5, 0xffcf043b, 0x007641af, 0xff8275a1, + 0x0018f8b8, 0xffb8e313, 0x006a6d99, 0xff959267, + 0x00471ced, 0xffe70748, 0x007d8a5f, 0xff809dc9, + 0x000c8bd3, 0xffaecc33, 0x0062f202, 0xff8f1d34, + 0x003c56ba, 0xffdad7f4, 0x007a7d05, 0xff8582fb, + 0x0025280c, 0xffc3a946, 0x0070e2cc, 0xff9d0dfe, + 0x005133cd, 0xfff3742d, 0x007f6237, 0xff802778, + 0x000647d9, 0xffaa0a5b, 0x005ed77d, 0xff8c4a14, + 0x0036ba20, 0xffd4e0cb, 0x00788484, 0xff83d604, + 0x001f19f9, 0xffbe31e2, 0x006dca0d, 0xff99307f, + 0x004c3fe0, 0xffed37f0, 0x007e9d56, 0xff8162aa, + 0x0012c810, 0xffb3c020, 0x0066cf81, 0xff9235f3, + 0x0041ce1e, 0xffe0e607, 0x007c29fc, 0xff877b7c, + 0x002b1f35, 0xffc945e0, 0x0073b5ec, 0xffa12883, + 0x0055f5a5, 0xfff9b827, 0x007fd888, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + +}; + +static u32 AC3Ucode1fe000[] = { + 0x00000000, 0x03020102, 0x05040403, 0x00400040, + 0x00500050, 0x00600060, 0x00700070, 0x00800080, + 0x00a000a0, 0x00c000c0, 0x00e000e0, 0x01000100, + 0x01400140, 0x01800180, 0x01c001c0, 0x02000200, + 0x02800280, 0x03000300, 0x03800380, 0x04000400, + 0x04800480, 0x05000500, 0x00460045, 0x00580057, + 0x00690068, 0x007a0079, 0x008c008b, 0x00af00ae, + 0x00d100d0, 0x00f400f3, 0x01170116, 0x015d015c, + 0x01a201a1, 0x01e801e7, 0x022e022d, 0x02b902b8, + 0x03440343, 0x03d003cf, 0x045b045a, 0x04e604e5, + 0x05720571, 0x00600060, 0x00780078, 0x00900090, + 0x00a800a8, 0x00c000c0, 0x00f000f0, 0x01200120, + 0x01500150, 0x01800180, 0x01e001e0, 0x02400240, + 0x02a002a0, 0x03000300, 0x03c003c0, 0x04800480, + 0x05400540, 0x06000600, 0x06c006c0, 0x07800780, + 0x7b67533f, 0x1513110f, 0x04d80540, 0x04100478, + 0x07000000, 0x0b000900, 0x02b002f0, 0x02300270, + 0x017001f0, 0xf80000f0, 0x01000080, 0x02000180, + 0x03000280, 0x04000380, 0x2725231f, 0x2c2b2a29, + 0x2e2e2d2d, 0x30302f2f, 0x04030201, 0x08070605, + 0x0c0b0a09, 0x100f0e0d, 0x14131211, 0x18171615, + 0x1c1b1a19, 0x2825221f, 0x37312e2b, 0x4f49433d, + 0x796d6155, 0xcdb59d85, 0x0000fde5, 0x3d3e3f40, + 0x393a3b3c, 0x35363738, 0x32333434, 0x2f2f3031, + 0x2c2c2d2e, 0x29292a2b, 0x26262728, 0x23242425, + 0x21212223, 0x1e1f2020, 0x1c1d1d1e, 0x1a1b1b1c, + 0x1819191a, 0x16171718, 0x15151516, 0x13131414, + 0x12121213, 0x10111111, 0x0f0f1010, 0x0e0e0e0f, + 0x0d0d0d0d, 0x0c0c0c0c, 0x0b0b0b0b, 0x0a0a0a0a, + 0x0909090a, 0x08080909, 0x08080808, 0x07070707, + 0x06060707, 0x06060606, 0x05050606, 0x05050505, + 0x04040505, 0x04040404, 0x04040404, 0x03030304, + 0x03030303, 0x03030303, 0x02030303, 0x02020202, + 0x02020202, 0x02020202, 0x02020202, 0x01010202, + 0x01010101, 0x01010101, 0x01010101, 0x01010101, + 0x01010101, 0x01010101, 0x01010101, 0x00000101, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x04d004d0, + 0x04000440, 0x03c003e0, 0x03b003b0, 0x03a003a0, + 0x03a003a0, 0x039003a0, 0x03900390, 0x03800380, + 0x03700370, 0x03600360, 0x03500350, 0x03400340, + 0x03200330, 0x03000310, 0x02f002f0, 0x02f002f0, + 0x03100300, 0x03900340, 0x042003e0, 0x04900460, + 0x046004a0, 0x04400440, 0x08000520, 0x08400840, + 0x04f004f0, 0x04100460, 0x03d003e0, 0x03b003c0, + 0x03a003b0, 0x03a003a0, 0x03a003a0, 0x03900390, + 0x03800390, 0x03800380, 0x03700370, 0x03600360, + 0x03500350, 0x03400340, 0x03100320, 0x02f00300, + 0x02f002f0, 0x030002f0, 0x03500320, 0x03e00390, + 0x04500420, 0x049004a0, 0x04400460, 0x06300480, + 0x08400840, 0x05800580, 0x045004b0, 0x03f00420, + 0x03d003e0, 0x03b003c0, 0x03b003b0, 0x03a003a0, + 0x03a003a0, 0x03a003a0, 0x03a003a0, 0x03900390, + 0x03900390, 0x03800380, 0x03700380, 0x03500360, + 0x03300340, 0x03100320, 0x02f00300, 0x02f002f0, + 0x03100300, 0x03500330, 0x041003c0, 0x04a00470, + 0x04400460, 0x04e00450, 0xffaaaaab, 0x00000000, + 0x00555555, 0xff99999a, 0xffcccccd, 0x00000000, + 0x00333333, 0x00666666, 0xff924925, 0xffb6db6e, + 0xffdb6db7, 0x00000000, 0x00249249, 0x00492492, + 0x006db6db, 0xff8ba2e9, 0xffa2e8ba, 0xffba2e8c, + 0xffd1745d, 0xffe8ba2f, 0x00000000, 0x001745d1, + 0x002e8ba3, 0x0045d174, 0x005d1746, 0x00745d17, + 0xff888889, 0xff99999a, 0xffaaaaab, 0xffbbbbbc, + 0xffcccccd, 0xffddddde, 0xffeeeeef, 0x00000000, + 0x00111111, 0x00222222, 0x00333333, 0x00444444, + 0x00555555, 0x00666666, 0x00777777, 0x08070605, + 0x0c0b0a09, 0x10100e0e, 0x00000010, 0x00000000, + 0x00000010, 0x00000020, 0x00000100, 0x00000110, + 0x00000120, 0x00000200, 0x00000210, 0x00000220, + 0x00001000, 0x00001010, 0x00001020, 0x00001100, + 0x00001110, 0x00001120, 0x00001200, 0x00001210, + 0x00001220, 0x00002000, 0x00002010, 0x00002020, + 0x00002100, 0x00002110, 0x00002120, 0x00002200, + 0x00002210, 0x00002220, 0x00000000, 0x00000010, + 0x00000020, 0x00000030, 0x00000040, 0x00000100, + 0x00000110, 0x00000120, 0x00000130, 0x00000140, + 0x00000200, 0x00000210, 0x00000220, 0x00000230, + 0x00000240, 0x00000300, 0x00000310, 0x00000320, + 0x00000330, 0x00000340, 0x00000400, 0x00000410, + 0x00000420, 0x00000430, 0x00000440, 0x00001000, + 0x00001010, 0x00001020, 0x00001030, 0x00001040, + 0x00001100, 0x00001110, 0x00001120, 0x00001130, + 0x00001140, 0x00001200, 0x00001210, 0x00001220, + 0x00001230, 0x00001240, 0x00001300, 0x00001310, + 0x00001320, 0x00001330, 0x00001340, 0x00001400, + 0x00001410, 0x00001420, 0x00001430, 0x00001440, + 0x00002000, 0x00002010, 0x00002020, 0x00002030, + 0x00002040, 0x00002100, 0x00002110, 0x00002120, + 0x00002130, 0x00002140, 0x00002200, 0x00002210, + 0x00002220, 0x00002230, 0x00002240, 0x00002300, + 0x00002310, 0x00002320, 0x00002330, 0x00002340, + 0x00002400, 0x00002410, 0x00002420, 0x00002430, + 0x00002440, 0x00003000, 0x00003010, 0x00003020, + 0x00003030, 0x00003040, 0x00003100, 0x00003110, + 0x00003120, 0x00003130, 0x00003140, 0x00003200, + 0x00003210, 0x00003220, 0x00003230, 0x00003240, + 0x00003300, 0x00003310, 0x00003320, 0x00003330, + 0x00003340, 0x00003400, 0x00003410, 0x00003420, + 0x00003430, 0x00003440, 0x00004000, 0x00004010, + 0x00004020, 0x00004030, 0x00004040, 0x00004100, + 0x00004110, 0x00004120, 0x00004130, 0x00004140, + 0x00004200, 0x00004210, 0x00004220, 0x00004230, + 0x00004240, 0x00004300, 0x00004310, 0x00004320, + 0x00004330, 0x00004340, 0x00004400, 0x00004410, + 0x00004420, 0x00004430, 0x00004440, 0x00000000, + 0x00000100, 0x00000200, 0x00000300, 0x00000400, + 0x00000500, 0x00000600, 0x00000700, 0x00000800, + 0x00000900, 0x00000a00, 0x00001000, 0x00001100, + 0x00001200, 0x00001300, 0x00001400, 0x00001500, + 0x00001600, 0x00001700, 0x00001800, 0x00001900, + 0x00001a00, 0x00002000, 0x00002100, 0x00002200, + 0x00002300, 0x00002400, 0x00002500, 0x00002600, + 0x00002700, 0x00002800, 0x00002900, 0x00002a00, + 0x00003000, 0x00003100, 0x00003200, 0x00003300, + 0x00003400, 0x00003500, 0x00003600, 0x00003700, + 0x00003800, 0x00003900, 0x00003a00, 0x00004000, + 0x00004100, 0x00004200, 0x00004300, 0x00004400, + 0x00004500, 0x00004600, 0x00004700, 0x00004800, + 0x00004900, 0x00004a00, 0x00005000, 0x00005100, + 0x00005200, 0x00005300, 0x00005400, 0x00005500, + 0x00005600, 0x00005700, 0x00005800, 0x00005900, + 0x00005a00, 0x00006000, 0x00006100, 0x00006200, + 0x00006300, 0x00006400, 0x00006500, 0x00006600, + 0x00006700, 0x00006800, 0x00006900, 0x00006a00, + 0x00007000, 0x00007100, 0x00007200, 0x00007300, + 0x00007400, 0x00007500, 0x00007600, 0x00007700, + 0x00007800, 0x00007900, 0x00007a00, 0x00008000, + 0x00008100, 0x00008200, 0x00008300, 0x00008400, + 0x00008500, 0x00008600, 0x00008700, 0x00008800, + 0x00008900, 0x00008a00, 0x00009000, 0x00009100, + 0x00009200, 0x00009300, 0x00009400, 0x00009500, + 0x00009600, 0x00009700, 0x00009800, 0x00009900, + 0x00009a00, 0x0000a000, 0x0000a100, 0x0000a200, + 0x0000a300, 0x0000a400, 0x0000a500, 0x0000a600, + 0x0000a700, 0x0000a800, 0x0000a900, 0x0000aa00, + 0xff800000, 0xff800000, 0xffb82995, 0xffaf5d75, + 0xffa57d87, 0xff9a6806, 0xff8df708, 0xff800000, + 0xffb82995, 0xffaf5d75, 0xffa57d87, 0xff9a6806, + 0xff8df708, 0xff800000, 0xffb82995, 0xffaf5d75, + 0xffa57d87, 0xff9a6806, 0xff8df708, 0xff800000, + 0xffb82995, 0xffaf5d75, 0xffa57d87, 0xff9a6806, + 0xff8df708, 0xff800000, 0xffb82995, 0xffaf5d75, + 0xffa57d87, 0xff9a6806, 0xff8df708, 0xff800000, + 0xfffb0000, 0xfffcfffc, 0xfffcfffc, 0xfffcfffc, + 0xfffdfffd, 0xfffdfffd, 0xfffdfffd, 0xfffefffe, + 0xfffefffe, 0xfffefffe, 0xffffffff, 0xffffffff, + 0xffffffff, 0x00000000, 0x00000000, 0x00000000, + 0x80050000, 0x000a800f, 0x001e801b, 0x80110014, + 0x00368033, 0x8039003c, 0x802d0028, 0x00228027, + 0x00668063, 0x8069006c, 0x807d0078, 0x00728077, + 0x80550050, 0x005a805f, 0x004e804b, 0x80410044, + 0x00c680c3, 0x80c900cc, 0x80dd00d8, 0x00d280d7, + 0x80f500f0, 0x00fa80ff, 0x00ee80eb, 0x80e100e4, + 0x80a500a0, 0x00aa80af, 0x00be80bb, 0x80b100b4, + 0x00968093, 0x8099009c, 0x808d0088, 0x00828087, + 0x01868183, 0x8189018c, 0x819d0198, 0x01928197, + 0x81b501b0, 0x01ba81bf, 0x01ae81ab, 0x81a101a4, + 0x81e501e0, 0x01ea81ef, 0x01fe81fb, 0x81f101f4, + 0x01d681d3, 0x81d901dc, 0x81cd01c8, 0x01c281c7, + 0x81450140, 0x014a814f, 0x015e815b, 0x81510154, + 0x01768173, 0x8179017c, 0x816d0168, 0x01628167, + 0x01268123, 0x8129012c, 0x813d0138, 0x01328137, + 0x81150110, 0x011a811f, 0x010e810b, 0x81010104, + 0x03068303, 0x8309030c, 0x831d0318, 0x03128317, + 0x83350330, 0x033a833f, 0x032e832b, 0x83210324, + 0x83650360, 0x036a836f, 0x037e837b, 0x83710374, + 0x03568353, 0x8359035c, 0x834d0348, 0x03428347, + 0x83c503c0, 0x03ca83cf, 0x03de83db, 0x83d103d4, + 0x03f683f3, 0x83f903fc, 0x83ed03e8, 0x03e283e7, + 0x03a683a3, 0x83a903ac, 0x83bd03b8, 0x03b283b7, + 0x83950390, 0x039a839f, 0x038e838b, 0x83810384, + 0x82850280, 0x028a828f, 0x029e829b, 0x82910294, + 0x02b682b3, 0x82b902bc, 0x82ad02a8, 0x02a282a7, + 0x02e682e3, 0x82e902ec, 0x82fd02f8, 0x02f282f7, + 0x82d502d0, 0x02da82df, 0x02ce82cb, 0x82c102c4, + 0x02468243, 0x8249024c, 0x825d0258, 0x02528257, + 0x82750270, 0x027a827f, 0x026e826b, 0x82610264, + 0x82250220, 0x022a822f, 0x023e823b, 0x82310234, + 0x02168213, 0x8219021c, 0x820d0208, 0x02028207, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x00000002, 0x00000002, + 0x00000000, 0xff800000, 0xffa57d86, 0xffa57d86, + 0xffcf043b, 0xff89be51, 0xff89be51, 0xffcf043b, + 0xffe70748, 0xff8275a1, 0xff959267, 0xffb8e313, + 0xffb8e313, 0xff959267, 0xff8275a1, 0xffe70748, + 0xfff3742d, 0xff809dc9, 0xff9d0dfe, 0xffaecc33, + 0xffc3a946, 0xff8f1d34, 0xff8582fb, 0xffdad7f4, + 0xffdad7f4, 0xff8582fb, 0xff8f1d34, 0xffc3a946, + 0xffaecc33, 0xff9d0dfe, 0xff809dc9, 0xfff3742d, + 0xfff9b827, 0xff802778, 0xffa12883, 0xffaa0a5b, + 0xffc945e0, 0xff8c4a14, 0xff877b7c, 0xffd4e0cb, + 0xffe0e607, 0xff83d604, 0xff9235f3, 0xffbe31e2, + 0xffb3c020, 0xff99307f, 0xff8162aa, 0xffed37f0, + 0xffed37f0, 0xff8162aa, 0xff99307f, 0xffb3c020, + 0xffbe31e2, 0xff9235f3, 0xff83d604, 0xffe0e607, + 0xffd4e0cb, 0xff877b7c, 0xff8c4a14, 0xffc945e0, + 0xffaa0a5b, 0xffa12883, 0xff802778, 0xfff9b827, + 0xcbcecdc4, 0xcfcac9c8, 0xc3c6c5cc, 0xc7c2c1c0, + 0x1b1e1d14, 0x1f1a1918, 0x1316151c, 0x17121110, + 0x2b2e2d24, 0x2f2a2928, 0x2326252c, 0x27222120, + 0x3b3e3d34, 0x3f3a3938, 0x3336353c, 0x37323130, + 0x0b0e0d04, 0x0f0a0908, 0x0306050c, 0x07020100, + 0xdbdeddd4, 0xdfdad9d8, 0xd3d6d5dc, 0xd7d2d1d0, + 0xebeeede4, 0xefeae9e8, 0xe3e6e5ec, 0xe7e2e1e0, + 0xfbfefdf4, 0xfffaf9f8, 0xf3f6f5fc, 0xf7f2f1f0, + 0x4b4e4d44, 0x4f4a4948, 0x4346454c, 0x47424140, + 0x9b9e9d94, 0x9f9a9998, 0x9396959c, 0x97929190, + 0xabaeada4, 0xafaaa9a8, 0xa3a6a5ac, 0xa7a2a1a0, + 0xbbbebdb4, 0xbfbab9b8, 0xb3b6b5bc, 0xb7b2b1b0, + 0x8b8e8d84, 0x8f8a8988, 0x8386858c, 0x87828180, + 0x5b5e5d54, 0x5f5a5958, 0x5356555c, 0x57525150, + 0x6b6e6d64, 0x6f6a6968, 0x6366656c, 0x67626160, + 0x7b7e7d74, 0x7f7a7978, 0x7376757c, 0x77727170, + 0x341424c4, 0x3e1e2ece, 0x3d1d2dcd, 0x3b1b2bcb, + 0xb494a444, 0xbe9eae4e, 0xbd9dad4d, 0xbb9bab4b, + 0xf4d4e404, 0xfedeee0e, 0xfddded0d, 0xfbdbeb0b, + 0x74546484, 0x7e5e6e8e, 0x7d5d6d8d, 0x7b5b6b8b, + 0x3c1c2ccc, 0x361626c6, 0x351525c5, 0x331323c3, + 0xbc9cac4c, 0xb696a646, 0xb595a545, 0xb393a343, + 0xfcdcec0c, 0xf6d6e606, 0xf5d5e505, 0xf3d3e303, + 0x7c5c6c8c, 0x76566686, 0x75556585, 0x73536383, + 0x381828c8, 0x3a1a2aca, 0x391929c9, 0x3f1f2fcf, + 0xb898a848, 0xba9aaa4a, 0xb999a949, 0xbf9faf4f, + 0xf8d8e808, 0xfadaea0a, 0xf9d9e909, 0xffdfef0f, + 0x78586888, 0x7a5a6a8a, 0x79596989, 0x7f5f6f8f, + 0x301020c0, 0x321222c2, 0x311121c1, 0x371727c7, + 0xb090a040, 0xb292a242, 0xb191a141, 0xb797a747, + 0xf0d0e000, 0xf2d2e202, 0xf1d1e101, 0xf7d7e707, + 0x70506080, 0x72526282, 0x71516181, 0x77576787, + 0x05040100, 0x15141110, 0x25242120, 0x35343130, + 0x85848180, 0x95949190, 0xa5a4a1a0, 0xb5b4b1b0, + 0xc0408000, 0xe060a020, 0xd0509010, 0xf070b030, + 0xc8488808, 0xe868a828, 0xd8589818, 0xf878b838, + 0xc4448404, 0xe464a424, 0xd4549414, 0xf474b434, + 0xcc4c8c0c, 0xec6cac2c, 0xdc5c9c1c, 0xfc7cbc3c, + 0xc2428202, 0xe262a222, 0xd2529212, 0xf272b232, + 0xca4a8a0a, 0xea6aaa2a, 0xda5a9a1a, 0xfa7aba3a, + 0xc6468606, 0xe666a626, 0xd6569616, 0xf676b636, + 0xce4e8e0e, 0xee6eae2e, 0xde5e9e1e, 0xfe7ebe3e, + 0xc1418101, 0xe161a121, 0xd1519111, 0xf171b131, + 0xc9498909, 0xe969a929, 0xd9599919, 0xf979b939, + 0xc5458505, 0xe565a525, 0xd5559515, 0xf575b535, + 0xcd4d8d0d, 0xed6dad2d, 0xdd5d9d1d, 0xfd7dbd3d, + 0xc3438303, 0xe363a323, 0xd3539313, 0xf373b333, + 0xcb4b8b0b, 0xeb6bab2b, 0xdb5b9b1b, 0xfb7bbb3b, + 0xc7478707, 0xe767a727, 0xd7579717, 0xf777b737, + 0xcf4f8f0f, 0xef6faf2f, 0xdf5f9f1f, 0xff7fbf3f, + 0x1045a3e2, 0x000000f4, 0x263b7333, 0x766b2363, + 0x2b367e3e, 0x7b662e6e, 0x06db93d3, 0x964b0343, + 0x0bd69ede, 0x9b460e4e, 0x825f1757, 0x12cf87c7, + 0x8f521a5a, 0x1fc28aca, 0x00d199d9, 0x90410949, + 0x01d098d8, 0x91400848, 0x24357d3d, 0x74652d6d, + 0x25347c3c, 0x75642c6c, 0x04d59ddd, 0x94450d4d, + 0x05d49cdc, 0x95440c4c, 0x80511959, 0x10c189c9, + 0x81501858, 0x11c088c8, 0x02df97d7, 0x924f0747, + 0x0fd29ada, 0x9f420a4a, 0x865b1353, 0x16cb83c3, + 0x8b561e5e, 0x1bc68ece, 0xa6bbf3b3, 0xf6eba3e3, + 0xabb6febe, 0xfbe6aeee, 0x223f7737, 0x726f2767, + 0x2f327a3a, 0x7f622a6a, 0xa0b1f9b9, 0xf0e1a9e9, + 0xa1b0f8b8, 0xf1e0a8e8, 0x84551d5d, 0x14c58dcd, + 0x85541c5c, 0x15c48ccc, 0xa4b5fdbd, 0xf4e5aded, + 0xa5b4fcbc, 0xf5e4acec, 0x20317939, 0x70612969, + 0x21307838, 0x71602868, 0xa2bff7b7, 0xf2efa7e7, + 0xafb2faba, 0xffe2aaea, 0x00000000, 0x00000000, +}; + +static u32 AC3Ucode1fff80[] = { + 0x0000240f, 0x007fffff, 0x007fffff, 0x00000003, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, +}; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/ac3_240.h linux.19pre5-ac1/drivers/media/video/ls220/ac3_240.h --- linux.19p5/drivers/media/video/ls220/ac3_240.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/ls220/ac3_240.h Thu Feb 21 20:41:21 2002 @@ -0,0 +1,2835 @@ +static u32 AC3240Ucode1f1800[] = { + 0xb500000f, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xb500118f, 0x00000000, 0x00000000, 0x00000000, + 0x820f001f, 0x802f001f, 0x80070800, 0x001f6193, + 0x800500d4, 0x8053ffff, 0x9842c7ff, 0x8039ff7c, + 0x1400b802, 0x003f6000, 0x94210007, 0xb0010001, + 0xb4200001, 0x98002800, 0xb0010000, 0xb4200001, + 0x98000800, 0x805300ff, 0x1800b802, 0x800600d4, + 0x8013001f, 0x9020c000, 0x003fb006, 0x803effe0, + 0x803effe8, 0x803effec, 0x9020e000, 0x9021ffe4, + 0x9020fa00, 0x803effd0, 0x803effdc, 0x803effd8, + 0x9020fe00, 0x803effd4, 0x90400000, 0x804600a2, + 0x90421800, 0x804600a3, 0x80134099, 0x98000040, + 0x800600a6, 0x80130000, 0x98003ca1, 0x800600a1, + 0x80050080, 0x98000002, 0x80060080, 0x80070001, + 0x001f2013, 0x001f2324, 0x80070000, 0x001fb0ba, + 0x001f23f9, 0x801eb3f0, 0x80070800, 0x001f600f, + 0x80070000, 0x001f2012, 0x001fb0cb, 0x001fb010, + 0x801efff0, 0x98004000, 0x98008000, 0x001f600e, + 0x83e40123, 0x80070000, 0x801eb3f8, 0x801eff70, + 0x800500a0, 0xb0000001, 0xb4000009, 0x80070001, + 0x800600a0, 0x80050080, 0x98000020, 0x80060080, + 0x9400ffdf, 0x80060080, 0x80070000, 0x800600a0, + 0x81df0004, 0x00000000, 0x00000000, 0x801bfff0, + 0x00000000, 0x940000ff, 0xb0000000, 0xb420004e, + 0x003f400e, 0x94010010, 0xb0000000, 0xb400fff4, + 0x838413a4, 0x003f0013, 0xb0010001, 0xb420003b, + 0x803bffe8, 0x801bffec, 0x00000000, 0x3001b800, + 0xb4600001, 0x90212000, 0x0421b800, 0x005f4193, + 0x5841b802, 0x3001b802, 0xb460000d, 0x80050086, + 0x005f9016, 0xb0020000, 0xb4200002, 0x001fb016, + 0xb500ffdf, 0x0420b802, 0xb0010b50, 0xb4a0ffdc, + 0x80070000, 0x001fb016, 0x83e400ed, 0xb500ffd8, + 0x80070000, 0x001fb016, 0x001f400e, 0x9400000f, + 0xb0000000, 0xb4000014, 0xb0000001, 0xb4000010, + 0x003f400e, 0x9421fff0, 0x003f600e, 0x003f9006, + 0x9421ffff, 0x90210004, 0xb001e000, 0xb4800002, + 0x8421e000, 0x9021c000, 0x8013001f, 0x1021b800, + 0x003fb006, 0x003f90cb, 0x90210004, 0x003fb0cb, + 0x83e400df, 0x83e41383, 0x8007001f, 0x94000003, + 0x5810b800, 0x83e71aa8, 0x1bffb800, 0x003f9008, + 0x1821b800, 0x00ffb801, 0x83e413d6, 0x80270000, + 0x003f2013, 0x8007001f, 0x94000003, 0x5810b800, + 0x83671ad4, 0x1b7bb800, 0x003f9009, 0x1821b800, + 0x00ffb801, 0xb500ffaa, 0x803bffc0, 0x805bffc4, + 0x807bffc8, 0x809bffcc, 0x5828b801, 0x5cb8b802, + 0x1821b805, 0x5848b802, 0x5cb8b803, 0x1842b805, + 0x5868b803, 0x5cb8b804, 0x1863b805, 0x5888b804, + 0x1884b800, 0x803effc0, 0x805effc4, 0x807effc8, + 0x809effcc, 0x003f400e, 0xb0000086, 0xb4400040, + 0xb0000084, 0xb400002a, 0xb0000085, 0xb4000030, + 0xb0000086, 0xb4000032, 0x001f4000, 0x94000080, + 0xb0000080, 0xb400006a, 0x80130000, 0x98003ca1, + 0x005f4000, 0x94420008, 0xb0020008, 0xb4000001, + 0xa0000080, 0x800600a1, 0x8013001f, 0x9040c000, + 0x005fb006, 0x805effe0, 0x805effe8, 0x805effec, + 0x9040e000, 0x805effe4, 0x9040fa00, 0x805effd0, + 0x805effdc, 0x805effd8, 0x9040fe00, 0x805effd4, + 0x80070001, 0x001f2013, 0x80070000, 0x001fb0cb, + 0x001fb010, 0x001f2058, 0x80071f40, 0x001fb008, + 0x80075d70, 0x001fb009, 0x98214000, 0xb5000010, + 0x94011000, 0xb0001000, 0xb4200001, 0x9421efff, + 0x98210010, 0xb500000a, 0x80070000, 0x001fb0cb, + 0x83e4007f, 0x003f400e, 0x9421ffef, 0xb5000004, + 0x83e4007b, 0x003f400e, 0x98211000, 0x9421ffef, + 0x003f600e, 0x80070100, 0x801efff0, 0xb500ff54, + 0xb000008b, 0xb400001c, 0xb000008e, 0xb4000022, + 0xb000008d, 0xb400001c, 0xb000008c, 0xb4000021, + 0xb0000087, 0xb400ffe8, 0xb0000088, 0xb4000014, + 0xb000008a, 0xb4000015, 0xb0000089, 0xb400001d, + 0xb00000a0, 0xb400001f, 0xb00000a1, 0xb4000041, + 0xb00000a2, 0xb400004a, 0xb00000a3, 0xb4000046, + 0xb00000a4, 0xb4000048, 0xb00000a5, 0xb4000048, + 0xb00000a6, 0xb4000048, 0x803efff8, 0xb500ffdd, + 0x9421ffdf, 0xb500ffda, 0xb500ffda, 0x80270100, + 0x803efff8, 0xb500ffd7, 0x80070000, 0x001fb017, + 0xb500ffd4, 0x801bffb0, 0x00000000, 0x001fb003, + 0xb500ffd0, 0x803bff80, 0x00000000, 0x003f6001, + 0xb500ffcc, 0x003f90ba, 0x803efff8, 0xb500ffc9, + 0x80130001, 0x98003da1, 0x800600a1, 0x80070200, + 0x801ebf34, 0x83e4002e, 0x8013001f, 0x9840c000, + 0x805effe0, 0x005fb006, 0x805effe8, 0x805effec, + 0x90422000, 0x805effe4, 0x9040fa00, 0x805effd0, + 0x805effdc, 0x805effd8, 0x9040fe00, 0x805effd4, + 0x80070001, 0x001f2013, 0x80070000, 0x001f2324, + 0x001fb0cb, 0x001fb010, 0x001f2058, 0x80077490, + 0x001fb008, 0x80077710, 0x001fb009, 0x98214000, + 0xb500ffa7, 0x80270000, 0x8047fef0, 0x003eb802, + 0x90420004, 0x003eb802, 0x90420004, 0x003eb802, + 0x90420004, 0x003eb802, 0x83641460, 0xb500ff9d, + 0x8364140e, 0xb500ff9b, 0x836413cd, 0xb500ff99, + 0x83441334, 0xb500ff97, 0x8344131d, 0xb500ff95, + 0x80070000, 0x80470000, 0xb6002003, 0xb6003002, + 0x001eb802, 0x90420004, 0x80171000, 0x8057ffff, + 0xb6002002, 0xb6001801, 0x001fa020, 0x00ffb81f, + 0x001f4000, 0x94000080, 0xb0000080, 0xb4200001, + 0xb500ffef, 0xb500000a, 0x80270000, 0x003f2013, + 0x8007001f, 0x94000003, 0x5810b800, 0x83671e40, + 0x1b7bb800, 0x003f9009, 0x1821b800, 0x00ffb801, + 0x003f0013, 0xb0010001, 0xb420fff3, 0x83a70000, + 0x803bff70, 0x00000000, 0xb0010000, 0xb4000011, + 0x80170300, 0x80070000, 0xb6000601, 0x001fa020, + 0x83640c6e, 0x00ff0325, 0x82870000, 0xb6270002, + 0x83640217, 0x92940001, 0x001f033b, 0xb0000000, + 0xb4000002, 0x80270000, 0xb5000001, 0x80270001, + 0x003f233b, 0x80270000, 0x003f2013, 0x8007001f, + 0x94000003, 0x5810b800, 0x83671ecc, 0x1b7bb800, + 0x003f9009, 0x1821b800, 0x00ffb801, 0x003f0013, + 0xb0010001, 0xb420fff3, 0x93bd0001, 0xb01d0004, + 0xb480ffdb, 0x803bff70, 0x00000000, 0xb0010000, + 0xb4000001, 0x83640c1a, 0x00000000, 0x00000000, + 0x00ffb81f, 0x007f90cb, 0x90630400, 0x007fb0cb, + 0x003f9006, 0x9421ffff, 0x90210400, 0xb001e000, + 0xb4800002, 0x8421e000, 0x9021c000, 0x8013001f, + 0x1021b800, 0x003fb006, 0x803effec, 0x00ffb81f, + 0x015f400e, 0x944a4000, 0xb0024000, 0xb4200084, + 0x954abfff, 0x015f600e, 0x820f001f, 0x802f001f, + 0x81470000, 0x015f23f9, 0x829702ec, 0x82d7ffff, + 0x82f70000, 0xb6000501, 0x029fa02a, 0x82970400, + 0xb6000702, 0xb6000001, 0x029fa02a, 0x8053ff00, + 0x98420000, 0x805ebf14, 0x805ebf18, 0x805ebf1c, + 0x805ebf20, 0x805ebf24, 0x805ebf28, 0x80270000, + 0x003f2328, 0x80275480, 0x005fb801, 0x8033001f, + 0x9821c000, 0x803effe0, 0x90212000, 0x803effe4, + 0x80dbff8c, 0x80fbff90, 0x80debf14, 0x80febf18, + 0x80dbff94, 0x80fbff98, 0x80debf1c, 0x80febf20, + 0x80dbff9c, 0x80fbffa0, 0x80debf24, 0x80febf28, + 0x80dbff84, 0x80e70001, 0x00dfb001, 0x80dbff88, + 0x00ff6191, 0x00dfb002, 0x80dbffb0, 0x80470000, + 0x00dfb003, 0x80d9ff80, 0x005fb0cf, 0x005fb0c6, + 0x00df6001, 0x80470001, 0x005f618f, 0x804700ff, + 0x005f231c, 0x005f231d, 0x80470000, 0x005f204e, + 0x8047e138, 0x5c42b802, 0x814f6300, 0x80cf00a9, + 0x005fb0bc, 0x5842b802, 0x01cfb802, 0x005f90bc, + 0xb520ffff, 0x8067e16c, 0x5c62b803, 0x80270040, + 0xb6000209, 0x814fffc0, 0x00cfb801, 0x007fb0bc, + 0x5862b803, 0x01cfb803, 0x007f90bc, 0xb520ffff, + 0x90210020, 0x90630020, 0x8047e398, 0x5c42b802, + 0x814fce40, 0x80cf0080, 0x005fb0bc, 0x5842b802, + 0x01cfb802, 0x005f90bc, 0xb520ffff, 0x8047e400, + 0x5c42b802, 0x814f7380, 0x80cf009a, 0x005fb0bc, + 0x5842b802, 0x01cfb802, 0x005f90bc, 0xb520ffff, + 0x8047e43c, 0x5c42b802, 0x814f18c0, 0x80cf00b6, + 0x005fb0bc, 0x5842b802, 0x01cfb802, 0x005f90bc, + 0xb520ffff, 0x80e70000, 0x00ffb0ba, 0x808f0000, + 0x806f001f, 0x80af001f, 0x8027b9fc, 0x5c22b801, + 0x80670700, 0xb600080a, 0x00cfb803, 0x003fb0bc, + 0x5822b801, 0x01cfb801, 0x003f90bc, 0x0047b86f, + 0xb0020001, 0xb4c0fffd, 0x90210020, 0x90630020, + 0x834400d3, 0xb0180000, 0xb4200025, 0x83440680, + 0x80c70000, 0x00df2324, 0x83640026, 0x83440228, + 0x00df0324, 0x90c60001, 0x00df2324, 0xb0060006, + 0xb4000003, 0x81472178, 0x015fb008, 0x00ffb81f, + 0x00ff90ba, 0x90e70001, 0x00ffb0ba, 0x019f9006, + 0x958cffff, 0x00df4193, 0x58c1b806, 0x118cb806, + 0xb00ce000, 0xb4800002, 0x858ce000, 0x918cc000, + 0x8153001f, 0x118cb80a, 0x819effec, 0x019fb006, + 0x015f4193, 0x5941b80a, 0x019f90cb, 0x118cb80a, + 0x019fb0cb, 0x81472160, 0x015fb008, 0x00ffb81f, + 0x015f400e, 0x194ab818, 0x015f600e, 0x802500a5, + 0x00ffb81f, 0x803bff8c, 0x805bff90, 0x803ebf14, + 0x805ebf18, 0x803bff94, 0x805bff98, 0x803ebf1c, + 0x805ebf20, 0x803bff9c, 0x805bffa0, 0x803ebf24, + 0x805ebf28, 0x80470003, 0x805ebefc, 0x003f0384, + 0x5822b801, 0x9021eb50, 0x005bb801, 0x00000000, + 0xb0020001, 0xb4200002, 0x80470001, 0x805ebefc, + 0x8073ff80, 0x98630000, 0x8027bf14, 0x8047befc, + 0xb6000609, 0x009bb801, 0x00000000, 0x00a7b804, + 0x6081b804, 0x3004b803, 0xb4000001, 0x00beb802, + 0x90210004, 0x90420004, 0x00ffb81b, 0x00000000, + 0x81150010, 0x00000000, 0x00000000, 0x81350010, + 0x00000000, 0x00000000, 0x81550002, 0x00000000, + 0x015f2380, 0x81550006, 0x00000000, 0x015f2381, + 0x81550005, 0x00000000, 0x015f2382, 0x81550003, + 0x00000000, 0x015f2383, 0x81550003, 0x015f2384, + 0xb00a0001, 0xb4000005, 0x956a0001, 0xb00b0000, + 0xb4000002, 0x81750002, 0x017f2385, 0x956a0004, + 0xb00b0000, 0xb4000002, 0x81750002, 0x017f2386, + 0xb00a0002, 0xb4200003, 0x81750002, 0x00000000, + 0x017f2387, 0x81750001, 0x00000000, 0x017f2388, + 0x81750005, 0x00000000, 0x017f2389, 0x81750001, + 0x017f239f, 0xb00b0001, 0xb4200003, 0x81750008, + 0x5968b80b, 0x017f61c5, 0x81750001, 0x017f238c, + 0xb00b0001, 0xb4200003, 0x81750008, 0x00000000, + 0x017f238d, 0x81750001, 0x017f238e, 0xb00b0001, + 0xb4200005, 0x81750005, 0x00000000, 0x017f238f, + 0x81750002, 0x017f2390, 0xb00a0000, 0xb420001b, + 0x81750005, 0x00000000, 0x017f2391, 0x81750001, + 0x017f23a0, 0xb00b0001, 0xb4200003, 0x81750008, + 0x5968b80b, 0x017f61c9, 0x81750001, 0x017f2394, + 0xb00b0001, 0xb4200003, 0x81750008, 0x00000000, + 0x017f2395, 0x81750001, 0x017f2396, 0xb00b0001, + 0xb4200006, 0x81750005, 0x00000000, 0x017f2397, + 0x81750002, 0x00000000, 0x017f2398, 0x81750001, + 0x00000000, 0x017f2399, 0x81750001, 0x00000000, + 0x017f239a, 0x81750001, 0x017f239b, 0xb00b0001, + 0xb4200003, 0x8175000e, 0x00000000, 0x017f61be, + 0x81750001, 0x017f239c, 0xb00b0001, 0xb4200003, + 0x8175000e, 0x00000000, 0x017f237e, 0x81750001, + 0x017f239d, 0xb00b0001, 0xb4200006, 0x81750006, + 0x017f239e, 0x916b0001, 0x81550008, 0x856b0001, + 0xb4e0fffd, 0x00ffb81c, 0x00000000, 0x00000000, + 0x81470000, 0x015f2385, 0x015f2386, 0x015f2387, + 0x015f238d, 0x015f238f, 0x015f2390, 0x015f2391, + 0x015f2395, 0x015f2396, 0x015f2397, 0x015f2398, + 0x015f61be, 0x015f61bf, 0x82070028, 0x023f9006, + 0x83a4003a, 0x83270000, 0x003fb819, 0x003f9006, + 0x5823b801, 0x83338000, 0x1b39b801, 0x003fb819, + 0x00000000, 0x00000000, 0x81550000, 0x8384ff64, + 0x017f0380, 0xad4b0026, 0x013f0381, 0x114ab809, + 0x5941b80a, 0x914ae00c, 0x0199b80a, 0x00000000, + 0x019f6193, 0xb0080b77, 0xb4200016, 0x015f0380, + 0xb00a0003, 0xb4600017, 0xb0090026, 0xb4600019, + 0x017f90ba, 0xb00b0000, 0xb4200004, 0x017f0384, + 0x017f204d, 0x017f0383, 0x017f2057, 0x015f0383, + 0x017f0057, 0x300ab80b, 0xb4200012, 0x015f0384, + 0x017f004d, 0x300ab80b, 0xb420000e, 0x83070000, + 0x00ffb81a, 0x83070800, 0x031f6193, 0x83070001, + 0x00ffb81a, 0x83070800, 0x031f6193, 0x83070002, + 0x00ffb81a, 0x83070800, 0x031f6193, 0x83070003, + 0x00ffb81a, 0x83070003, 0x00ffb81a, 0x5e02b810, + 0x5a02b810, 0x00bf9011, 0x00df004f, 0xa5260020, + 0x81e70000, 0x82471000, 0x95d1ffff, 0xa5cee000, + 0x300eb810, 0xb4600002, 0x05f0b80e, 0x0207b80e, + 0x8267001f, 0x82c70020, 0x82971000, 0xb0100080, + 0xb480001f, 0x5a8bb813, 0x5aa6b813, 0x1a94b815, + 0x01efb812, 0x014fb814, 0x01cfb811, 0xb520ffff, + 0xb636000f, 0x81470000, 0x039f8014, 0xb6000404, + 0x5948b80a, 0x957c00ff, 0x194ab80b, 0x5f88b81c, + 0xb0060020, 0xb4200001, 0x80a70000, 0x64a6b805, + 0x68e9b80a, 0x18a5b807, 0x029fa025, 0x00a7b80a, + 0x01efb812, 0x014fb814, 0x01afb811, 0xb520ffff, + 0x5ae2b816, 0x1231b817, 0x0610b817, 0xb500ffde, + 0xb0100000, 0xb4000003, 0x5ec2b810, 0x86760001, + 0xb500ffdc, 0xb00f0000, 0xb4000005, 0x0207b80f, + 0x81f3001f, 0x9a2fc000, 0x81e70000, 0xb500ffd0, + 0x015fb011, 0x00ffb81d, 0x00000000, 0x00000000, + 0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x81d7ffff, + 0x8257ffff, 0x82d7ffff, 0x8357ffff, 0x83d7ffff, + 0x80770000, 0x80f70000, 0x81770000, 0x81f70000, + 0x82770000, 0x82f70000, 0x83770000, 0x83f70000, + 0xaeb40080, 0x808f0000, 0x806f001f, 0x80af001f, + 0xb0140000, 0xb4400014, 0x806f001f, 0x80af001f, + 0x8027b9fc, 0x5c22b801, 0x80670700, 0xb6000208, + 0x00cfb803, 0x003fb0bc, 0x5822b801, 0x01cfb801, + 0x003f90bc, 0xb520ffff, 0x90630020, 0x90210020, + 0x80270000, 0x80171000, 0xb6000303, 0xb6000001, + 0x001fa021, 0x00000000, 0x82670000, 0xb6000268, + 0x80170a00, 0x80970afc, 0x81170b00, 0x81970bfc, + 0x80271c00, 0x1021b813, 0x1021b813, 0x0217b801, + 0x80271ffc, 0x0421b813, 0x0421b813, 0x0297b801, + 0x80270c00, 0x1021b813, 0x1021b813, 0x0317b801, + 0x80270ffc, 0x0421b813, 0x0421b813, 0x0397b801, + 0x80478500, 0x1042b813, 0x5c42b802, 0x1022b815, + 0x80670280, 0x00cfb803, 0x003fb0bc, 0x5822b801, + 0x01cfb801, 0x003f90bc, 0xb520ffff, 0x009f033b, + 0x80478480, 0x0442b813, 0x5c42b802, 0x1022b815, + 0x806702a0, 0x00cfb803, 0x003fb0bc, 0x5822b801, + 0x01cfb801, 0x003f90bc, 0xb520ffff, 0xb0040000, + 0xb4000002, 0x80479000, 0xb5000001, 0x80479c00, + 0x1042b813, 0x5c42b802, 0x1022b815, 0x806702c0, + 0x00cfb803, 0x003fb0bc, 0x5822b801, 0x01cfb801, + 0x003f90bc, 0xb520ffff, 0xb0040000, 0xb4000002, + 0x80479180, 0xb5000001, 0x80479d80, 0x0442b813, + 0x5c42b802, 0x1022b815, 0x806702e0, 0x00cfb803, + 0x003fb0bc, 0x5822b801, 0x01cfb801, 0x003f90bc, + 0xb520ffff, 0x81270000, 0x80370000, 0x80b70000, + 0x81370000, 0x81b70000, 0x82370004, 0x82b7fffc, + 0xb6002016, 0x41498008, 0x51498814, 0x51498814, + 0x51418810, 0x51418810, 0x41818814, 0x0308a02a, + 0x49958820, 0x51898810, 0x51918828, 0x414d8814, + 0x0388a7ec, 0x494d8814, 0x49458810, 0x49458810, + 0x418d8810, 0x0308a02a, 0x49918fec, 0x51858814, + 0x51958fe4, 0x00000000, 0x0388a7ec, 0x92730080, + 0x009f033b, 0x5802b814, 0x90400300, 0x001f9802, + 0x00000000, 0xb0000000, 0xb4200016, 0x80170a00, + 0x80070000, 0xb6002001, 0x001fa020, 0xb0040000, + 0xb4200002, 0x80279000, 0xb5000001, 0x80279c00, + 0xac740080, 0x5c22b801, 0x11e1b803, 0x806f001f, + 0x80af001f, 0xb6000407, 0x80cf0280, 0x01ffb0bc, + 0x59e2b80f, 0x01afb80f, 0x01ff90bc, 0xb520ffff, + 0x91ef0020, 0x007f0320, 0x011f90cd, 0xaca30006, + 0x80c7b004, 0x10a5b814, 0x58a1b805, 0x10a5b806, + 0x0099b805, 0x8027b3dc, 0x5841b804, 0x1021b802, + 0x0159b801, 0x8027b3d0, 0x5841b804, 0x1021b802, + 0x0139b801, 0x80170c00, 0x0097b80a, 0xb0090000, + 0xb4200004, 0xb6000002, 0x015f8020, 0x009fe0ca, + 0xb5000004, 0x015fc024, 0xb6000002, 0x015f8020, + 0x009fe0ca, 0x00ffb81b, 0x00000000, 0x00000000, + 0x009f0011, 0x015f0012, 0xb0060000, 0xb4200007, + 0x968a0001, 0xb0140000, 0xb400000d, 0x80870001, + 0x009f2011, 0x954a0002, 0x015f2012, 0xb0060002, + 0xb4200007, 0x968a0002, 0xb0140000, 0xb4000004, + 0x80870001, 0x009f2011, 0x81470000, 0x015f2012, + 0x8364002b, 0x00bf2010, 0xb0060000, 0xb4200003, + 0xb0050000, 0xb4200001, 0x8364008d, 0xb0050000, + 0xb4200001, 0x836400b2, 0x00bf0010, 0xb0050000, + 0xb4200006, 0x83640983, 0x8364029d, 0x00000000, + 0x8364092b, 0x00000000, 0xb5000005, 0x00bf0010, + 0xb0050001, 0xb4000002, 0x00000000, 0x83640924, + 0x00ff0325, 0x82870000, 0xb6270002, 0x8364ff00, + 0x92940001, 0x80070001, 0x801eff70, 0x001f0010, + 0xb0000001, 0xb4000007, 0x001f033b, 0xb0000000, + 0xb4000002, 0x80270000, 0xb5000001, 0x80270001, + 0x003f233b, 0x00ffb81a, 0x00000000, 0x00000000, + 0x027f4001, 0x5e2ab813, 0x96310003, 0x81c70000, + 0x820700ff, 0xb0110000, 0xb4000005, 0x5a21b811, + 0x81c70200, 0x8207000e, 0x69d1b80e, 0x1210b811, + 0x01dfb0cd, 0x5e2cb813, 0x96310003, 0x023f2323, + 0x5e28b813, 0x96310003, 0x023f2322, 0x5e27b813, + 0x96310001, 0x023f2328, 0x5e23b813, 0x96310001, + 0x023f2321, 0x95f30007, 0x01ff2320, 0x920fe004, + 0x0258b810, 0x00000000, 0x1252b811, 0x025f2325, + 0x8167befc, 0x017f6195, 0x021f031c, 0x01df031d, + 0x3010b80f, 0xb4200003, 0x3011b80e, 0xb4200001, + 0xb5000021, 0x80270000, 0x80471000, 0x0017b802, + 0x8057ffff, 0xb6002001, 0x001fa021, 0x80270400, + 0x80679000, 0x5c62b803, 0xb6001809, 0x00cfb801, + 0x007fb0bc, 0x5862b803, 0x01afb803, 0x007f90bc, + 0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x90630020, + 0x80679c00, 0x5c62b803, 0xb6001809, 0x00cfb801, + 0x007fb0bc, 0x5862b803, 0x01afb803, 0x007f90bc, + 0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x90630020, + 0x01ff231c, 0x023f231d, 0x83970300, 0x82070000, + 0xb6320001, 0x039fa030, 0x00bf0010, 0x021f0324, + 0xb0100000, 0xb4200001, 0x80a70000, 0xb0050000, + 0xb4200008, 0xb0040000, 0xb4a00002, 0x80a70001, + 0xb5000004, 0x82070000, 0x021f204e, 0xb4000001, + 0x80a70002, 0xb0050001, 0xb4200007, 0x021f004e, + 0xb0100002, 0xb4a00002, 0x80a70002, 0x00ffb81b, + 0x92100001, 0x021f204e, 0x00000000, 0x00ffb81b, + 0x81530000, 0x003fb80a, 0x00000000, 0x00000000, + 0x003fb819, 0x00000000, 0x00000000, 0x81550000, + 0x8384fd73, 0x81470000, 0x015f61ee, 0x015f61ef, + 0x015f23a4, 0x8297050c, 0x82d7ffff, 0xb6000501, + 0x029fa02a, 0x8167e004, 0x116b0384, 0x0158b80b, + 0x019f0382, 0x015f237b, 0x017f0388, 0x116bb80a, + 0xb00c0008, 0xb4a00003, 0x80a70003, 0x00bf2010, + 0x00ffb81b, 0xb00a0005, 0xb4400003, 0xb00b0006, + 0xb4400001, 0x00ffb81b, 0x80a70004, 0x00bf2010, + 0x00ffb81b, 0x00000000, 0x00000000, 0x00000000, + 0x027f0388, 0x02bf037b, 0x02df0384, 0x02ff03a1, + 0x82970400, 0x8257ffff, 0x82d7ffff, 0xb6350003, + 0x81550001, 0x8357ffff, 0x029fa02a, 0x82970414, + 0xb6350003, 0x81550001, 0x83d7ffff, 0x029fa02a, + 0x81550001, 0xb00a0001, 0xb4200004, 0x814d0008, + 0x6149b80a, 0x954affff, 0x015f61ee, 0xb0160000, + 0xb4200007, 0x81550001, 0xb00a0001, 0xb4200004, + 0x814d0008, 0x6149b80a, 0x954affff, 0x015f61ef, + 0x81550001, 0xb00a0001, 0xb4200036, 0x82f50001, + 0x02ff23a1, 0xb0170001, 0xb420002c, 0x82970428, + 0xb6350003, 0x81550001, 0x00000000, 0x029fa02a, + 0x82970428, 0x81470000, 0x017f8034, 0xb00b0001, + 0xb4000004, 0x914a0001, 0x300ab815, 0xb480fffa, + 0xb5000001, 0x015f23a5, 0x81670000, 0xb0160002, + 0xb4200002, 0x81750001, 0x00000000, 0x017f233a, + 0x81550004, 0xadaa000c, 0x015f23a2, 0x81750004, + 0x916b0003, 0x017f23a3, 0x91ad0025, 0x01bf23a6, + 0xadab000c, 0x81e70000, 0x91ad0025, 0x01bf23a7, + 0x920a0001, 0x05abb810, 0xb00d0000, 0xb400000d, + 0xb62d0004, 0x81b50001, 0x65b0b80d, 0x19efb80d, + 0x92100001, 0x01ffb0be, 0xb5000006, 0x81a70000, + 0x82970428, 0xb6350001, 0x029fa02d, 0x01bf233a, + 0x01bf23a5, 0x82070000, 0x82270000, 0x82170428, + 0xb635003a, 0x01bf8030, 0xb00d0001, 0xb4200036, + 0x81d50001, 0x65b1b80e, 0x1a10b80d, 0xb00e0001, + 0xb4200031, 0x81b50002, 0xadad0003, 0xae510048, + 0x91cd000f, 0x91320868, 0x015f03a2, 0xad4a0004, + 0x92920700, 0x1189b80a, 0x0297b80c, 0x1194b80a, + 0x0317b80c, 0x01ff90be, 0x015f03a2, 0x017f03a3, + 0x064bb80a, 0x0107b80a, 0xb0120000, 0xb400001e, + 0xb632001d, 0x6928b80f, 0x95290001, 0xb0090000, + 0xb420000e, 0x81350004, 0x1129b80d, 0x029fa029, + 0x824d0004, 0x5a48b812, 0x5e48b812, 0x3009b80e, + 0xb4200002, 0x5e41b812, 0xb500000d, 0x5e42b812, + 0x81330040, 0x1a52b809, 0xb5000009, 0x0127b854, + 0x85290004, 0x0397b809, 0x0287b858, 0x86940004, + 0x013f803c, 0x0397b814, 0x029fa029, 0x025f803c, + 0x031fa032, 0x91080001, 0x92310001, 0x015f03a2, + 0x017f03a3, 0x013f033a, 0xb0090001, 0xb420001f, + 0x95300002, 0x95900001, 0x1929b80c, 0xb0090000, + 0xb400001a, 0x064bb80a, 0x0107b80a, 0xb6320017, + 0x6928b80f, 0x95290001, 0xb0090000, 0xb4200002, + 0x81350001, 0x013f23f8, 0x81a70700, 0x91ad0048, + 0x5982b808, 0x11adb80c, 0x0397b80d, 0x013f03f8, + 0xb0090001, 0xb4200005, 0x019f801c, 0x0196b80c, + 0x81b3ff80, 0x418cb80d, 0xb5000002, 0x019f801c, + 0x0196b80c, 0x039fa00c, 0x91080001, 0xb0160002, + 0xb420001a, 0xb0170001, 0xb4200008, 0xb00a0000, + 0xb4200002, 0x81270002, 0xb5000005, 0xb00a0002, + 0xb4400002, 0x81270003, 0xb5000001, 0x81270004, + 0x013f23a9, 0x81950001, 0xb00c0001, 0xb420000d, + 0x81a70000, 0x8397043c, 0xb6290006, 0x81150001, + 0x039fa028, 0xb0080001, 0xb4200001, 0x81a70001, + 0x00000000, 0x01bf23a8, 0xb5000002, 0x81a70000, + 0x01bf23a8, 0xb0170001, 0xb4200001, 0x81b50002, + 0x82970c20, 0xb6350003, 0x81550002, 0x00000000, + 0x029fa02a, 0xb0130001, 0xb4200001, 0x81150001, + 0x81c70000, 0xb6350014, 0x922e0c20, 0x015ff011, + 0xb00a0000, 0xb400000f, 0x922e0428, 0x015ff011, + 0xb00a0001, 0xb4200005, 0x922e044c, 0x0297b811, + 0x015f03a6, 0x029fa00a, 0xb5000006, 0x81550006, + 0xad4a0003, 0x922e044c, 0x0297b811, 0x914a0049, + 0x029fa00a, 0x91ce0004, 0xb0170001, 0xb420001e, + 0xb00d0000, 0xb400001c, 0x852d0001, 0x81470001, + 0x6549b80a, 0xad6a0003, 0x019f03a7, 0x058c03a6, + 0x81270000, 0xb00b0000, 0xb4000005, 0x300cb80b, + 0xb4800003, 0x058cb80b, 0x91290001, 0xb500fffb, + 0x81750004, 0x5961b80b, 0x839704ec, 0x0187b860, + 0x039fa02c, 0x039fa02a, 0x039fa029, 0x039fa02b, + 0xb0090000, 0xb4000004, 0xb6290003, 0x81550007, + 0x00000000, 0x00000000, 0x81c70000, 0xb635002e, + 0x922e0c20, 0x01fff011, 0xb00f0000, 0xb4000029, + 0x852f0001, 0x81470001, 0x6549b80a, 0xad6a0003, + 0x922e044c, 0x025fd811, 0x86520001, 0x0227b812, + 0x81270000, 0xb00b0000, 0xb4000005, 0x3012b80b, + 0xb4800003, 0x0652b80b, 0x91290001, 0xb500fffb, + 0x2e09b80b, 0x00000000, 0x3010b811, 0xb4600001, + 0x91290001, 0xae4e0004, 0x82150004, 0x9232049c, + 0x0297b811, 0x0187b860, 0x029fa02c, 0x029fa02a, + 0x029fa029, 0x029fa030, 0xb0090000, 0xb4000004, + 0xb6290003, 0x81550007, 0x00000000, 0x00000000, + 0x82270460, 0x1231b80e, 0x0217b811, 0x81550002, + 0x021fa00a, 0x91ce0004, 0xb0130001, 0xb420000c, + 0xb0080000, 0xb400000a, 0x81550004, 0x839704fc, + 0x0167b860, 0x039fa02b, 0x81670001, 0x039fa02b, + 0x8175000e, 0x81670002, 0x039fa02b, 0x039fa02a, + 0x81150001, 0xb0080001, 0xb420000a, 0x8135000b, + 0x5d2923aa, 0x95490180, 0x5d4723ab, 0x95490060, + 0x5d4523ac, 0x95490018, 0x5d4323ad, 0x95490007, + 0x015f23ae, 0x81350001, 0xb0090001, 0xb4200017, + 0x81350006, 0x013f23af, 0xb0170001, 0xb4200005, + 0x81550004, 0x00000000, 0x015f23b0, 0x81550003, + 0x015f23b1, 0x82970474, 0x83170488, 0xb6350004, + 0x81550007, 0x5e83a02a, 0x954a0007, 0x031fa02a, + 0xb0130001, 0xb4200005, 0x81750004, 0x00000000, + 0x017f23b2, 0x81750003, 0x017f23b3, 0xb0170001, + 0xb420000b, 0x81b50001, 0xb00d0001, 0xb4200008, + 0x81d50003, 0x59c8b80e, 0x91ce0300, 0x01df61da, + 0x81d50003, 0x59c8b80e, 0x91ce0300, 0x01df61db, + 0x81550001, 0xb00a0001, 0xb420004b, 0xb0170001, + 0xb4200001, 0x81550002, 0x82470000, 0x82270000, + 0xb6350004, 0x81750002, 0x6571b80b, 0x92310002, + 0x1a52b80b, 0xb0170001, 0xb4200017, 0xb00a0001, + 0xb4200011, 0x81150003, 0x91080001, 0x011f23a4, + 0x829709d0, 0x831709f0, 0x83970060, 0xb6280009, + 0x81750005, 0x00000000, 0x029fa02b, 0x81750004, + 0x00000000, 0x031fa02b, 0x81750003, 0x00000000, + 0x039fa02b, 0xb5000004, 0xb00a0002, 0xb4800002, + 0x81070000, 0x011f23a4, 0x82270000, 0x81270000, + 0xb6350025, 0x6a11b812, 0x92310002, 0x96100003, + 0xb0100001, 0xb4200018, 0xada90020, 0x81750003, + 0x920d0520, 0x0217b810, 0x920d05c0, 0x0297b810, + 0x920d0660, 0x0317b810, 0x5942b809, 0x920a050c, + 0x0397b810, 0x916b0001, 0x039fa02b, 0xb62b0009, + 0x81750005, 0x00000000, 0x021fa02b, 0x81750004, + 0x00000000, 0x029fa02b, 0x81750003, 0x00000000, + 0x031fa02b, 0xb5000007, 0xb0100002, 0xb4800005, + 0x59a2b809, 0x91ad050c, 0x0397b80d, 0x82070000, + 0x039fa010, 0x91290001, 0x81550001, 0xb00a0001, + 0xb4200007, 0x81550009, 0xb00a0000, 0xb4000004, + 0xb62a0003, 0x82150008, 0x00000000, 0x00000000, + 0xb00a0100, 0xb4a00007, 0x954aff00, 0xb6008003, + 0x82150010, 0x00000000, 0x00000000, 0x854a0100, + 0xb4e0fffa, 0x00ffb81b, 0x00000000, 0x00000000, + 0x81070000, 0x011f61dc, 0x011f61de, 0x011f61e0, + 0x011f03aa, 0x9108e0f4, 0x0138b808, 0x011f03ab, + 0x013f61ac, 0x9108e0f0, 0x0138b808, 0x011f03ac, + 0x013f61ad, 0x5901b808, 0x9108e0f8, 0x0139b808, + 0x011f03ad, 0x013f61ae, 0x5901b808, 0x9108e100, + 0x0139b808, 0x011f03ae, 0x013f61b0, 0x5901b808, + 0x9108e108, 0x0179b808, 0x013f03af, 0x017f61b1, + 0x02bf037b, 0x82970474, 0xb6350002, 0x015f8034, + 0x1929b80a, 0x011f03a1, 0xb0080001, 0xb4200002, + 0x015f03b0, 0x1929b80a, 0x019f0388, 0xb00c0001, + 0xb4200002, 0x015f03b2, 0x1929b80a, 0x013f61b3, + 0x015f03a8, 0xb00a0001, 0xb420003a, 0x81a70000, + 0x01bf237a, 0x83840056, 0x806f001f, 0x80af001f, + 0x80270300, 0x8067a800, 0x5c62b803, 0xb600080a, + 0x00cfb801, 0x007fb0bc, 0x5862b803, 0x01afb803, + 0x007f90bc, 0x0047b86f, 0xb0020001, 0xb4c0fffd, + 0x90210020, 0x90630020, 0x81a70001, 0x01bf237a, + 0x83840043, 0x838403c6, 0x81a70000, 0x01bf237a, + 0x82470400, 0x01bff012, 0x01bf23fa, 0x83840418, + 0x8384048f, 0x8384053e, 0x83840595, 0x806f001f, + 0x80af001f, 0x80270300, 0x8067ac00, 0x5c62b803, + 0xb600080a, 0x00cfb801, 0x007fb0bc, 0x5862b803, + 0x01cfb803, 0x007f90bc, 0x0047b86f, 0xb0020001, + 0xb4c0fffd, 0x90210020, 0x90630020, 0x81a70001, + 0x01bf237a, 0x82470404, 0x015ff012, 0x015f23fa, + 0x838403ff, 0x83840476, 0x83840525, 0x8384057c, + 0xb5000011, 0x81a70000, 0x01bf237a, 0xb635000e, + 0x8384001b, 0x01bf037a, 0xad4d0004, 0x00000000, + 0x914a0400, 0x01bff00a, 0x01bf23fa, 0x838403f0, + 0x83840467, 0x83840516, 0x8384056d, 0x01df037a, + 0x91ce0001, 0x01df237a, 0x019f0388, 0xb00c0001, + 0xb4200009, 0x02bf037b, 0x02bf237a, 0x838400e8, + 0x82470000, 0x025f23fa, 0x838403e1, 0x83840458, + 0x83840507, 0x8384055e, 0x00ffb81b, 0x00000000, + 0x80770000, 0x80f70000, 0x81770000, 0x81f70000, + 0x82770000, 0x82f70000, 0x83770000, 0x83f70000, + 0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x81d7ffff, + 0x8257ffff, 0x82d7ffff, 0x8357ffff, 0x83d7ffff, + 0x017f037a, 0x5a42b80b, 0x01bf03a8, 0xb00d0001, + 0xb4200004, 0x011f9118, 0x013f9119, 0x7929b808, + 0xb5000002, 0x91b20460, 0x013ff00d, 0x91b20340, + 0x0297b80d, 0x00000000, 0x029fa009, 0x01df0384, + 0xb00e0000, 0xb4200005, 0xb00b0001, 0xb4200003, + 0x009f90c6, 0x00bf0391, 0xb5000002, 0x009f90cf, + 0x00bf0389, 0x83a4013a, 0x81870000, 0x019f61b5, + 0x019f61b4, 0x5a02b80b, 0x9190044c, 0x01dfd80c, + 0x01df61b6, 0x91900488, 0x01dff00c, 0x59c1b80e, + 0x918ee118, 0x01d9b80c, 0x019f03af, 0x01df61af, + 0x858c000f, 0x5986b80c, 0x91d00474, 0x01bff00e, + 0x59c2b80d, 0x11cc61b2, 0x81870000, 0x019f61b8, + 0x91900414, 0x01dfd80c, 0x01df61b7, 0xadab0010, + 0x00000000, 0x908d049c, 0x83a40189, 0xadcb0020, + 0x5982b80b, 0x908e0520, 0x90ae05c0, 0x90ce0660, + 0x928c050c, 0x00ff9814, 0x83a40161, 0x83a401b0, + 0x017f037a, 0x59c2b80b, 0x918e0428, 0x01fff00c, + 0xb00f0001, 0xb4200081, 0x023f03a5, 0x3011b80b, + 0xb420000f, 0x01c7b860, 0x01dfb0fa, 0x01df41dc, + 0x01df61e8, 0x01df41de, 0x01df61ea, 0x01df41e0, + 0x01df61ec, 0x01df41dd, 0x01df61e9, 0x01df41df, + 0x01df61eb, 0x01df41e1, 0x01df61ed, 0xb5000024, + 0x01c7b860, 0x01dfb0f9, 0x01df41dc, 0x01df61e2, + 0x01df41de, 0x01df61e4, 0x01df41e0, 0x01df61e6, + 0x01df41dd, 0x01df61e3, 0x01df41df, 0x01df61e5, + 0x01df41e1, 0x01df61e7, 0x803f0000, 0x00000000, + 0x00000000, 0x01df90fa, 0x003fb80e, 0x00000000, + 0x00000000, 0x81d50000, 0x00000000, 0x00000000, + 0x01df41e8, 0x01df61dc, 0x01df41ea, 0x01df61de, + 0x01df41ec, 0x01df61e0, 0x01df41e9, 0x01df61dd, + 0x01df41eb, 0x01df61df, 0x01df41ed, 0x01df61e1, + 0x029f03a6, 0x029f236a, 0x029f03a7, 0x029f236c, + 0x027f03a2, 0x92b3e128, 0x0298b815, 0x019f03b0, + 0x029f2368, 0x5982b80c, 0x01df03af, 0x85ce000f, + 0x59c6b80e, 0x11cc61b2, 0x82a70001, 0x02bf61b8, + 0x82a70000, 0x02bf61b9, 0x029f41da, 0x029f61ba, + 0x029f41db, 0x029f61bb, 0x019f03b1, 0x5981b80c, + 0x918ce118, 0x0299b80c, 0xad8b0048, 0x029f61af, + 0x59a2b813, 0x118cb80d, 0x928c0868, 0x029fb0fb, + 0x928c0700, 0x029fb0fc, 0x019f41bc, 0x918c0003, + 0x019f61bc, 0x5a02b80b, 0x91900414, 0x029fd80c, + 0x029f236e, 0x808704ec, 0x83a40119, 0x808709d0, + 0x80a709f0, 0x80c70060, 0x00ff03a4, 0x83a400f4, + 0x83a40143, 0x021f037a, 0x019f03a5, 0x300cb810, + 0xb4000016, 0x803f0000, 0x00000000, 0x00000000, + 0x01df90f9, 0x003fb80e, 0x00000000, 0x00000000, + 0x81d50000, 0x00000000, 0x00000000, 0x01df41e2, + 0x01df61dc, 0x01df41e4, 0x01df61de, 0x01df41e6, + 0x01df61e0, 0x01df41e3, 0x01df61dd, 0x01df41e5, + 0x01df61df, 0x01df41e7, 0x01df61e1, 0x029f41b6, + 0xa6d40100, 0xaeb40004, 0x81870000, 0x92b50c00, + 0x0397b815, 0xb6360001, 0x039fa02c, 0x00ffb81c, + 0x009f90cf, 0x00bf0389, 0x019f037a, 0x5982b80c, + 0x918c0340, 0x0397b80c, 0x81870000, 0x039fa00c, + 0x83a4007b, 0x81870000, 0x019f61b5, 0x019f61b4, + 0x81870007, 0x019f61b6, 0x019f03b3, 0x5981b80c, + 0x918ce118, 0x01b9b80c, 0x019f03af, 0x01bf61af, + 0x858c000f, 0x5986b80c, 0x01bf03b2, 0x59a2b80d, + 0x118cb80d, 0x019f61b2, 0x81870000, 0x019f61b7, + 0x019f61b8, 0x808704fc, 0x83a400d1, 0x80870000, + 0x80a70000, 0x80c70000, 0x80e70000, 0x83a400ac, + 0x83a400fb, 0x81470000, 0x81e70c1c, 0x0397b80f, + 0xb600f901, 0x039fa02a, 0x00ffb81c, 0x00000000, + 0x82270000, 0x023f2011, 0x0227b860, 0x023fb0ff, + 0x02bf9006, 0x92350028, 0x8213001f, 0x9210e000, + 0x3011b810, 0xb4800001, 0x86312000, 0x021f4193, + 0x5a01b810, 0x86100028, 0x83a4fa8c, 0x82270000, + 0x003fb811, 0x02bf9006, 0x5aa3b815, 0x82338000, + 0x1a31b815, 0x003fb811, 0x8067e950, 0x5c62b803, + 0x81f50000, 0x80270400, 0xb6000409, 0x814fffc0, + 0x00cfb801, 0x007fb0bc, 0x5862b803, 0x01cfb803, + 0x007f90bc, 0xb520ffff, 0x90210020, 0x90630020, + 0x82870000, 0x81f50010, 0x019f4193, 0x5d61b80c, + 0x5d43b80c, 0x114ab80b, 0x0187b80a, 0x960cff00, + 0x92100100, 0x858c0001, 0xb62c000c, 0x81f50010, + 0x5e28b80f, 0xb6000209, 0x5a48b814, 0x9652ff00, + 0x5e68b814, 0x5981b813, 0x918c1000, 0x01dfd80c, + 0x2252b811, 0x2292b80e, 0x962f00ff, 0x81870000, + 0x86100100, 0xb4e0fff0, 0xb00a0000, 0xb4000009, + 0x81670000, 0xb0140000, 0xb4000001, 0x81670001, + 0x017f2012, 0x258a4193, 0x918c0001, 0x81470000, + 0xb500ffe2, 0x81670000, 0xb0140000, 0xb4000001, + 0x81670002, 0x116b0012, 0x803f0000, 0x00000000, + 0x00000000, 0x003fb811, 0x00000000, 0x00000000, + 0x81f50000, 0x017f2012, 0x00ffb81a, 0x00000000, + 0x61f4b804, 0x91ef0001, 0x8233003f, 0x9a31ffff, + 0x5a02b804, 0x1610b811, 0x92510001, 0x1a10b812, + 0x029f03fb, 0xb0140001, 0xb4200012, 0x5a21b805, + 0x92b1e910, 0x0299b815, 0x5a22b805, 0x5a90b814, + 0x6290b814, 0x92b1e890, 0x11efb814, 0x029bb815, + 0x8233ff80, 0x3011b814, 0xb4000006, 0x4294b811, + 0x00000000, 0x0288b814, 0x4210b814, 0x00000000, + 0x0208b810, 0x029f9003, 0x82f3007f, 0x9af7ffff, + 0x3017b814, 0xb4000003, 0x4210b814, 0x00000000, + 0x0208b810, 0x82270000, 0x02c7b810, 0xb0160000, + 0xb400000a, 0x1676b812, 0x3013b812, 0xb4000003, + 0x5ac1b816, 0x92310001, 0xb500fffa, 0x81d3ff80, + 0x3010b80e, 0xb4200001, 0x1ad6b80e, 0x05efb811, + 0x027f037a, 0x5a62b813, 0x92730340, 0x0397b813, + 0x023fd813, 0x02dfb0fd, 0x5a30b811, 0x6230b811, + 0x0631b80f, 0x3010b812, 0xb4200001, 0x92310001, + 0x82470000, 0xb0110000, 0xb4800004, 0x82470003, + 0xb0110003, 0xb4400001, 0x0247b811, 0x039fa012, + 0x124f61bc, 0x00ffb81d, 0x00000000, 0x00000000, + 0x83970a10, 0x82070000, 0xb6003201, 0x039fa030, + 0xb0070000, 0xb4000019, 0x029f41b4, 0x0297b804, + 0x0317b805, 0x0397b806, 0xb6270014, 0x12948034, + 0x01df8038, 0xb00e0000, 0xb4a0000e, 0x02bf803c, + 0x5a02b814, 0x91b00a10, 0x0217b80d, 0xb62e0008, + 0x96150003, 0x91f00001, 0xadef0080, 0xb0150004, + 0xb4600001, 0x85ef0280, 0x021fa02f, 0x92940001, + 0xb5000001, 0x021f803c, 0x00000000, 0x00ffb81d, + 0x0397b804, 0x021f036a, 0x027f803c, 0x029f803c, + 0x02bf803c, 0x02df803c, 0x5a22b810, 0x92311000, + 0x0397b811, 0xb0100000, 0xb4200001, 0x039fa036, + 0xb0150000, 0xb4000021, 0x0227b860, 0x023fb0ff, + 0xb520ffff, 0x803f0000, 0x82138000, 0x1a10b813, + 0x003fb810, 0x00000000, 0x00000000, 0x82150000, + 0x00000000, 0xb635000d, 0x82550007, 0x5a42b812, + 0x9212e4b8, 0x025bb810, 0x8227000c, 0xb6000307, + 0x68d1b812, 0x94c6000f, 0x84c60002, 0x12d6b806, + 0xb6340001, 0x039fa036, 0x86310004, 0x803f0000, + 0x82138000, 0x023f90ff, 0x1a31b810, 0x003fb811, + 0x00000000, 0x00000000, 0x82150000, 0x00ffb81d, + 0x00ff41b5, 0x011f41b4, 0x019f41af, 0x01bf41ae, + 0x01df41ba, 0x01ff41bb, 0x82070000, 0x023f0380, + 0x82470000, 0xae310032, 0x029f41b3, 0x5862b807, + 0x90431000, 0x81970ad8, 0x0217b802, 0x90430c00, + 0x0297b802, 0x0317b802, 0x912802a4, 0x007ff009, + 0x58478030, 0x792341b6, 0x0529b807, 0x019fa029, + 0xb0080014, 0xb4800011, 0xa5420c00, 0x031fa02a, + 0x84690001, 0xb4a00011, 0xb623000b, 0x58678030, + 0xa4030c00, 0x031fa020, 0x044ab800, 0x0056b802, + 0x5c41b802, 0xf84200ff, 0x90620100, 0x005ff003, + 0x7d40b80a, 0x114ab802, 0xb5000004, 0xa5420c00, + 0x58478010, 0xa5620c00, 0x031fa02a, 0xb0080016, + 0xb4400043, 0xb0080013, 0xb440002c, 0xb0080006, + 0xb4400024, 0xb0080005, 0xb4400014, 0xb0080002, + 0xb4400006, 0x80440030, 0x015f619c, 0x05cab80c, + 0x05eab80d, 0x066eb810, 0xb500003c, 0x8044002a, + 0x300a419c, 0xb4800001, 0x82470001, 0x015f619c, + 0xb0120001, 0xb4200001, 0xb500001a, 0x05cab80c, + 0x05eab80d, 0x066eb810, 0xb5000030, 0x001f41b6, + 0xb0000007, 0xb4000001, 0x8044001b, 0x300a419c, + 0xb4800001, 0x82470001, 0xb0120001, 0xb4200001, + 0xb500000c, 0x05cab80c, 0x05eab80d, 0x066eb810, + 0xb5000022, 0x80440010, 0x840b0100, 0x300ab800, + 0xb4200001, 0x86100040, 0xb5000002, 0x86100080, + 0xfe100000, 0x046e41ad, 0x042ab80c, 0x7dc1b803, + 0x044f41ac, 0x042ab80d, 0x7de1b802, 0x046eb810, + 0x7e6fb803, 0xb5000011, 0x840b0100, 0x3000b80a, + 0xb4200002, 0x82070180, 0x00ffb802, 0x300ab80b, + 0xb4a00002, 0x86100040, 0xfe100000, 0x00ffb802, + 0x046e41ad, 0x042ab80c, 0x7dc1b803, 0x044f41ac, + 0x042ab80d, 0x7de1b802, 0x7e6eb80f, 0x380a41b0, + 0xb4600003, 0x242a41b0, 0x5c22b801, 0x1273b801, + 0xb0140000, 0xb4200002, 0x80071fe0, 0xb5000016, + 0x1011b808, 0x5801b800, 0x9020e26c, 0x0079b801, + 0x5842b808, 0x90420a10, 0x7c03b813, 0x003f9802, + 0x1000b801, 0x003f41b2, 0x5830b801, 0x6030b801, + 0x0400b801, 0x003f41b1, 0x5830b801, 0x6030b801, + 0x0400b801, 0xfc000000, 0xf8001fe0, 0x94001fe0, + 0x100041b1, 0x9400ffff, 0x8067003f, 0xb6290008, + 0x005f8014, 0x0442b800, 0x9442ffff, 0x5850b802, + 0x6050b802, 0xfc420000, 0x5c45b802, 0x7a82a023, + 0x10e7b809, 0x91080001, 0x300741b6, 0xb420ff6a, + 0x019f61af, 0x01bf61ae, 0x01df61ba, 0x01ff61bb, + 0x00ff41b5, 0x011f41b4, 0x019f41b8, 0x01bf41b7, + 0x01df41dd, 0x01ff41df, 0x021f41e1, 0x027f90fd, + 0x029f41bc, 0x02ff41dc, 0x031f41de, 0x033f41e0, + 0x5822b807, 0x91210c00, 0x0117b809, 0x81970ad8, + 0x91211000, 0x0217b809, 0x91210c00, 0x0317b809, + 0x80170ba0, 0x013f802c, 0xb629005f, 0x003f8038, + 0xb001000e, 0xb440001e, 0xb001000c, 0xb4400054, + 0xb001000a, 0xb4400043, 0xb0010007, 0xb440003c, + 0xb0010005, 0xb440002b, 0xb0010000, 0xb440001a, + 0xb00d0001, 0xb4200010, 0x005f418f, 0xac42bb75, + 0x8073005a, 0x9442ffff, 0x005f618f, 0x95628000, + 0x5848b802, 0xb00b8000, 0xb4200002, 0x8173ff00, + 0x1842b80b, 0x9863827a, 0x4043b802, 0x00000000, + 0x0048b802, 0xb500003f, 0x80470000, 0xb500003d, + 0x8401000f, 0x5c22b800, 0x902102d8, 0x001ff001, + 0x004db800, 0xb5000037, 0x86f70001, 0xb4600005, + 0x80750005, 0x5862b803, 0x9043e44c, 0x01d9b802, + 0x82e70002, 0x5c4cb80e, 0x9462000f, 0x5862b803, + 0x90630200, 0x005f9803, 0x59c4b80e, 0x95ceffff, + 0xb5000028, 0x87180001, 0xb4600005, 0x80750007, + 0x5862b803, 0x9043e4b8, 0x01f9b802, 0x83070002, + 0x5c4cb80f, 0x9462000f, 0x5862b803, 0x9063020c, + 0x005f9803, 0x59e4b80f, 0x95efffff, 0xb5000019, + 0x80750003, 0x5862b803, 0x90630220, 0x005f9803, + 0xb5000014, 0x87390001, 0xb4600005, 0x80750007, + 0x5862b803, 0x9043e6ac, 0x0219b802, 0x83270001, + 0x5c4cb810, 0x9462000f, 0x5862b803, 0x9063023c, + 0x005f9803, 0x5a04b810, 0x9610ffff, 0xb5000005, + 0x80750004, 0x5862b803, 0x90630268, 0x005f9803, + 0x00000000, 0x001fa022, 0x80170ba0, 0xb00c0001, + 0xb4200035, 0x023f90fb, 0x007f9811, 0x025f90fc, + 0x06d4b803, 0x007f9812, 0x4083b813, 0x00000000, + 0x0088b804, 0xb629002b, 0x24368030, 0x9421ffff, + 0x5830b801, 0x6030b801, 0x40448020, 0xb0010020, + 0xb4800003, 0x80470000, 0x80670000, 0xb500000e, + 0xb0010000, 0xb4a00004, 0x82b30080, 0x6aa1b815, + 0x4042b815, 0xb5000008, 0x6c41b802, 0x82a70017, + 0x12b5b801, 0x6875b803, 0x1842b803, 0x00000000, + 0x00000000, 0x00000000, 0x0108a022, 0x007f41b9, + 0x90630001, 0x007f61b9, 0xb003000c, 0xb420000c, + 0x92310004, 0x023fb0fb, 0x007f9811, 0x92520004, + 0x06d4b803, 0x025fb0fc, 0x007f9812, 0x80470000, + 0x4083b813, 0x00000000, 0x0088b804, 0x005f61b9, + 0x00000000, 0xb500001a, 0xb6290019, 0x24348030, + 0x9421ffff, 0x5830b801, 0x6030b801, 0x40538020, + 0xb0010020, 0xb4800003, 0x80470000, 0x80670000, + 0xb500000e, 0xb0010000, 0xb4a00004, 0x82b30080, + 0x6aa1b815, 0x4042b815, 0xb5000008, 0x6c41b802, + 0x82a70017, 0x12b5b801, 0x6875b803, 0x1842b803, + 0x00000000, 0x00000000, 0x00000000, 0x0108a022, + 0x10e7b809, 0x91080001, 0x300741b6, 0xb420ff48, + 0x00ff61b5, 0x011f61b4, 0x01df61dd, 0x01ff61df, + 0x021f61e1, 0x02ff61dc, 0x031f61de, 0x033f61e0, + 0x00ffb81d, 0x00000000, 0x00000000, 0x00000000, + 0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x81d7ffff, + 0x8257ffff, 0x808f0000, 0x003f9113, 0x005f9114, + 0x7141b802, 0x80cf0700, 0x8027b064, 0x5c22b801, + 0x003fb0bc, 0x5822b801, 0x01cfb801, 0x003f90bc, + 0xb520ffff, 0x80cf0704, 0x8027b06c, 0x5c22b801, + 0x003fb0bc, 0x5822b801, 0x01cfb801, 0x003f90bc, + 0xb520ffff, 0x81e7043c, 0x82071c00, 0x82271c10, + 0x019f03a9, 0x806f001f, 0x80af001f, 0x80270400, + 0x8067a800, 0x5c62b803, 0xb6000808, 0x00cfb801, + 0x007fb0bc, 0x5862b803, 0x01cfb803, 0x007f90bc, + 0xb520ffff, 0x90210020, 0x90630020, 0x81971000, + 0x82170c00, 0xb6000004, 0x003f800c, 0x005f8010, + 0x021fa021, 0x019fa022, 0x00bfd810, 0x003fd811, + 0x70c1b80a, 0x001f980f, 0x91ef0004, 0x92100002, + 0x92310002, 0x5822b805, 0x90411000, 0x0197b802, + 0x90410c00, 0x0217b802, 0x0466b805, 0xb0000000, + 0xb4000005, 0xb6230004, 0x003f8010, 0x005f800c, + 0x1201a022, 0x0581a022, 0x858c0001, 0xb4e0ffea, + 0x80270400, 0x8067ac00, 0x5c62b803, 0xb6000808, + 0x00cfb801, 0x007fb0bc, 0x5862b803, 0x01afb803, + 0x007f90bc, 0xb520ffff, 0x90210020, 0x90630020, + 0x00ffb81c, 0x00000000, 0x00000000, 0x00000000, + 0x808f0000, 0x806f001f, 0x80af001f, 0x003f037a, + 0xb0010000, 0xb4400030, 0x81a7b7fc, 0x5da2b80d, + 0x80670500, 0xb6000208, 0x00cfb803, 0x01bfb0bc, + 0x59a2b80d, 0x01cfb80d, 0x01bf90bc, 0xb520ffff, + 0x90630020, 0x91ad0020, 0x81c7b8fc, 0x5dc2b80e, + 0x80670540, 0xb6000208, 0x00cfb803, 0x01dfb0bc, + 0x59c2b80e, 0x01cfb80e, 0x01df90bc, 0xb520ffff, + 0x90630020, 0x91ce0020, 0x81a7b3fc, 0x5da2b80d, + 0x80670600, 0xb6000408, 0x00cfb803, 0x01bfb0bc, + 0x59a2b80d, 0x01cfb80d, 0x01bf90bc, 0xb520ffff, + 0x90630020, 0x91ad0020, 0x81c7b5fc, 0x5dc2b80e, + 0x80670680, 0xb6000408, 0x00cfb803, 0x01dfb0bc, + 0x59c2b80e, 0x01cfb80e, 0x01df90bc, 0xb520ffff, + 0x90630020, 0x91ce0020, 0x005f03fa, 0xb0020000, + 0xb4000024, 0x8057ffff, 0x80d7ffff, 0x8157ffff, + 0x81d7ffff, 0x8257ffff, 0x82d7ffff, 0x8357ffff, + 0x83d7ffff, 0x83971300, 0x83171200, 0x82971100, + 0x82171000, 0x81170c00, 0x81970ff8, 0x80171400, + 0x80971500, 0x005f802c, 0x001f8028, 0xb6004010, + 0x41028000, 0x51008004, 0x007f876c, 0x0208a028, + 0x41008000, 0x49028004, 0x003f8068, 0x0388a028, + 0x41038000, 0x51018004, 0x005f802c, 0x0288a028, + 0x41018020, 0x49038024, 0x001f8028, 0x0308a028, + 0x00ffb81c, 0x83d7ffff, 0x8357ffff, 0x82d7ffff, + 0x8257ffff, 0x8157ffff, 0x81d7ffff, 0x8057ffff, + 0x80d7ffff, 0x82971200, 0x82171000, 0x81170c00, + 0x81970ffc, 0x83171800, 0x83971a00, 0x83370000, + 0x83b70000, 0x81370008, 0x81b7fff8, 0x4119880c, + 0xb6008006, 0x511d8808, 0x41498838, 0x0208a028, + 0x494d883c, 0x4119880c, 0x0288a02a, 0x00ffb81c, + 0x82670000, 0x82a70000, 0x003f037a, 0xb0010000, + 0xb4400018, 0x81a7bdfc, 0x5da2b80d, 0x80670580, + 0xb6000208, 0x00cfb803, 0x01bfb0bc, 0x59a2b80d, + 0x01cfb80d, 0x01bf90bc, 0xb520ffff, 0x90630020, + 0x91ad0020, 0x81a7eb70, 0x5da2b80d, 0x806705c0, + 0xb6000208, 0x00cfb803, 0x01bfb0bc, 0x59a2b80d, + 0x01cfb80d, 0x01bf90bc, 0xb520ffff, 0x90630020, + 0x91ad0020, 0x02bf03fa, 0x808f0000, 0xb0150000, + 0xb4000006, 0x81470040, 0x81670003, 0x81870002, + 0x81a71000, 0x81c71300, 0xb5000005, 0x81470080, + 0x81670004, 0x81870001, 0x81a71000, 0x81c71200, + 0x0017b80d, 0x0097b80e, 0x108db80a, 0x0117b804, + 0x108eb80a, 0x0197b804, 0x5841b80a, 0x108db802, + 0x0217b804, 0x108eb802, 0x0297b804, 0x106ab802, + 0x108db803, 0x0317b804, 0x108eb803, 0x0397b804, + 0x5ea2b80a, 0xb6350020, 0x001f8000, 0x003f8008, + 0x005f8004, 0x007f800c, 0x10c08010, 0x10a18018, + 0x10828014, 0x10e3801c, 0x1246b805, 0x0686b805, + 0x10c4b807, 0x0484b807, 0x80e70000, 0x80a70000, + 0x0008a032, 0x0108a034, 0x0088a026, 0x0188a024, + 0x04c08010, 0x04a18018, 0x04828014, 0x04e3801c, + 0x0646b807, 0x1286b807, 0x10c4b805, 0x0484b805, + 0x80e70000, 0x80a70000, 0x0208a032, 0x0308a034, + 0x0288a026, 0x0388a024, 0x5de1b80a, 0x82070004, + 0xb62b002a, 0x0017b80d, 0x0097b80e, 0x102db80f, + 0x0117b801, 0x104eb80f, 0x0197b802, 0x82171600, + 0x82971700, 0x0037b80f, 0x00b7b80f, 0x0137b80f, + 0x01b7b80f, 0xb630001b, 0x003f8030, 0x005f8034, + 0x5ee2b80f, 0x8013007f, 0x9800ffff, 0xb6370011, + 0x41008000, 0x51018008, 0x4902800c, 0x40c08000, + 0x0008a028, 0x48c18008, 0x50c2800c, 0x42808004, + 0x00c8b806, 0x52828008, 0x5281800c, 0x41008004, + 0x0088a034, 0x49028008, 0x4901800c, 0x011fa026, + 0x0188a028, 0x001f8001, 0x001f8005, 0x001f8009, + 0x001f800d, 0x5de1b80f, 0x5a01b810, 0x0017b80d, + 0x0097b80e, 0x902d0004, 0x0117b801, 0x904e0004, + 0x0197b802, 0x82171600, 0x82971700, 0x5ea1b80a, + 0x8013007f, 0x9800ffff, 0xb6350013, 0x003f8030, + 0x005f8034, 0x42408000, 0x52418008, 0x4a42800c, + 0x41008000, 0x0008a052, 0x49018008, 0x5102800c, + 0x42808004, 0x0108b808, 0x52828008, 0x5281800c, + 0x40c08004, 0x0088a054, 0x48c28008, 0x48c1800c, + 0x011fa048, 0x0188a046, 0x81a71100, 0x81c71200, + 0x858c0001, 0xb4e0ff7e, 0x00ffb81c, 0x00000000, + 0x005f03fa, 0x00000000, 0xb0020000, 0xb4000034, + 0x81b70080, 0x81d7ffff, 0x81f70001, 0x82370080, + 0x8257ffff, 0x82770001, 0x82b70080, 0x82d7ffff, + 0x82f70001, 0x83370080, 0x8357ffff, 0x83770001, + 0x81971000, 0x82171100, 0x82971200, 0x83171300, + 0x815703fc, 0x81370200, 0x81170c00, 0x83d703fc, + 0x83b70200, 0x83970f00, 0x8057ffff, 0x80d7ffff, + 0x80171400, 0x80971500, 0x001f800d, 0x003f8019, + 0xb6004012, 0x41008000, 0x51018004, 0x007f8011, + 0x0128a008, 0x41018000, 0x49008004, 0x009f8015, + 0x03a8a008, 0x41038000, 0x51048004, 0x001f800d, + 0x03a8a008, 0x41048020, 0x49038024, 0x003f8019, + 0x0128a008, 0x005f8028, 0x005f803c, 0x81f70000, + 0x82770000, 0x82f70000, 0x83770000, 0x00ffb81c, + 0x82370040, 0x8257ffff, 0x82770001, 0x82b70040, + 0x82d7ffff, 0x82f70001, 0x82171000, 0x82971200, + 0x8157ffff, 0x81170c00, 0x81d7ffff, 0x81970e00, + 0x8057ffff, 0x80d7ffff, 0x80171800, 0x80971a00, + 0xb600800a, 0x001f8011, 0x003f8015, 0x41008000, + 0x51018004, 0x00000000, 0x0108a028, 0x41018020, + 0x49008024, 0x00000000, 0x0188a028, 0x82770000, + 0x82f70000, 0x00ffb81c, 0x00000000, 0x00000000, + 0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x808f0000, + 0x015f0384, 0x017f037a, 0xac4a0006, 0x8027b004, + 0x1042b80b, 0x5841b802, 0x1021b802, 0x0159b801, + 0x013f0325, 0x01bf0320, 0x5822b80b, 0x90210340, + 0x00ff9801, 0x8027b2e8, 0x5842b807, 0x1021b802, + 0x025bb801, 0x80070000, 0xac4d0006, 0x8027b004, + 0x1042b800, 0x5841b802, 0x1021b802, 0x0199b801, + 0x00000000, 0xac4c0006, 0x8027b078, 0x1042b80a, + 0x5842b802, 0x1021b802, 0x011bb801, 0x00000000, + 0x40d2b808, 0x00000000, 0xb0060000, 0xb4000080, + 0x005f033b, 0x80278400, 0xac600080, 0x5c22b801, + 0x10a1b803, 0xb0020000, 0xb4200002, 0x80279000, + 0xb5000001, 0x80279c00, 0x5c22b801, 0x11e1b803, + 0x80470300, 0x5822b800, 0x1042b801, 0x003f9802, + 0x806f001f, 0x80af001f, 0xb0010000, 0xb4200024, + 0x80170c00, 0x80971000, 0x003f8020, 0xb6000003, + 0x4201b806, 0x003f8020, 0x0088a030, 0x80270400, + 0xb6000208, 0x00cfb801, 0x00bfb0bc, 0x58a2b805, + 0x01afb805, 0x00bf90bc, 0xb520ffff, 0x90210020, + 0x90a50020, 0xb6000408, 0x00cfb801, 0x01ffb0bc, + 0x59e2b80f, 0x01afb80f, 0x01ff90bc, 0xb520ffff, + 0x90210020, 0x91ef0020, 0xb6000208, 0x00cfb801, + 0x00bfb0bc, 0x58a2b805, 0x01afb805, 0x00bf90bc, + 0xb520ffff, 0x90210020, 0x90a50020, 0xb5000043, + 0x80270400, 0x0087b805, 0x01c7b80f, 0xb6000208, + 0x00cfb801, 0x009fb0bc, 0x5882b804, 0x01cfb804, + 0x009f90bc, 0xb520ffff, 0x90210020, 0x90840020, + 0xb6000408, 0x00cfb801, 0x01dfb0bc, 0x59c2b80e, + 0x01cfb80e, 0x01df90bc, 0xb520ffff, 0x90210020, + 0x91ce0020, 0xb6000208, 0x00cfb801, 0x009fb0bc, + 0x5882b804, 0x01cfb804, 0x009f90bc, 0xb520ffff, + 0x90210020, 0x90840020, 0x80170c00, 0x80971000, + 0x8053007f, 0x9842ffff, 0xb6000004, 0x42028004, + 0x4a068020, 0x00000000, 0x0088a030, 0x80270400, + 0xb6000208, 0x00cfb801, 0x00bfb0bc, 0x58a2b805, + 0x01afb805, 0x00bf90bc, 0xb520ffff, 0x90210020, + 0x90a50020, 0xb6000408, 0x00cfb801, 0x01ffb0bc, + 0x59e2b80f, 0x01afb80f, 0x01ff90bc, 0xb520ffff, + 0x90210020, 0x91ef0020, 0xb6000208, 0x00cfb801, + 0x00bfb0bc, 0x58a2b805, 0x01afb805, 0x00bf90bc, + 0xb520ffff, 0x90210020, 0x90a50020, 0x5822b800, + 0x90210300, 0x0117b801, 0x80470001, 0x011fa002, + 0x90000001, 0x3000b809, 0xb480ff6b, 0x00ffb81c, + 0x8057ffff, 0x013f0325, 0x015f033b, 0x80171000, + 0x80070000, 0xb6002001, 0x001fa020, 0xb00a0001, + 0xb4c00002, 0x81679000, 0xb5000001, 0x81679c00, + 0x5d62b80b, 0x81878400, 0x5d82b80c, 0x80070000, + 0x5822b800, 0x90410300, 0x003f9802, 0x00000000, + 0xb0010000, 0xb4200019, 0xac400080, 0x00000000, + 0x10ccb802, 0x10abb802, 0x806f001f, 0x80af001f, + 0x80cf0400, 0xb6000408, 0xb520ffff, 0x00dfb0bc, + 0x58c2b806, 0x01afb806, 0x00df90bc, 0xb520ffff, + 0x80cf0400, 0x90c60020, 0x80cf0400, 0xb6000407, + 0x00bfb0bc, 0x58a2b805, 0x01afb805, 0x00bf90bc, + 0xb520ffff, 0x80cf0400, 0x90a50020, 0x90000001, + 0x3000b809, 0xb480ffde, 0x00ffb81b, 0x8057ffff, + 0x013f0325, 0x80171000, 0x80070000, 0xb6002001, + 0x001fa020, 0x81878400, 0x5d82b80c, 0x80070000, + 0x5822b800, 0x90410300, 0x003f9802, 0x00000000, + 0xb0010000, 0xb420000f, 0xac400080, 0x00000000, + 0x10ccb802, 0x806f001f, 0x80af001f, 0x80cf0400, + 0xb6000408, 0xb520ffff, 0x00dfb0bc, 0x58c2b806, + 0x01afb806, 0x00df90bc, 0xb520ffff, 0x80cf0400, + 0x90c60020, 0x90000001, 0x3000b809, 0xb480ffe8, + 0x00ffb81b, 0x8057ffff, 0x80d7ffff, 0x8157ffff, + 0x8139b000, 0x00000000, 0xb0090000, 0xb4000012, + 0x806f001f, 0x80af001f, 0x80cf0400, 0x013fb0bc, + 0x5922b809, 0x01cfb809, 0x013f90bc, 0xb520ffff, + 0x806f0003, 0x80af0003, 0x80cf0420, 0x91290020, + 0x013fb0bc, 0x5922b809, 0x01cfb809, 0x013f90bc, + 0xb520ffff, 0xb5000233, 0x80270000, 0x80171000, + 0xb6002401, 0x001fa021, 0x007f0384, 0x009f0320, + 0x00bf0385, 0x00df0386, 0x80e7b36c, 0x5821b803, + 0x1021b807, 0x0159b801, 0x5821b804, 0x1021b807, + 0x0179b801, 0x80e7b37c, 0x5821b803, 0x1021b807, + 0x0199b801, 0x5821b804, 0x1021b807, 0x01b9b801, + 0x80e7b38c, 0x5821b803, 0x1021b807, 0x01d9b801, + 0x5821b804, 0x1021b807, 0x01f9b801, 0x005f0385, + 0x8027b39c, 0x5842b802, 0x1021b802, 0x021bb801, + 0x005f0386, 0x8027b3ac, 0x5842b802, 0x1021b802, + 0x023bb801, 0x027f0383, 0x003f0328, 0x005f4195, + 0xb0130007, 0xb42000df, 0xb0010000, 0xb42000dd, + 0xb0020000, 0xb40000db, 0xb0030002, 0xb48000d9, + 0x029bb802, 0x82a7b108, 0xb00b0001, 0xb4200001, + 0xb5000005, 0xb00b0002, 0xb4200002, 0x92b500a0, + 0xb5000001, 0x92b50140, 0xb0030004, 0xb4600002, + 0x82870000, 0xb5000006, 0xb0030006, 0xb4600004, + 0xb0140001, 0xb4a00002, 0x82870001, 0xb5000000, + 0xac54000a, 0x806f0009, 0x80af0009, 0x5c22b815, + 0x80cf0440, 0x1021b802, 0x003fb0bc, 0x5822b801, + 0x01cfb801, 0x003f90bc, 0xb520ffff, 0xb0030003, + 0xb400000f, 0xb0030004, 0xb400001d, 0xb0030005, + 0xb400002b, 0xb0030006, 0xb4000042, 0xb0030007, + 0xb4000059, 0x80171000, 0x005f9440, 0x001fa002, + 0x80171038, 0x005f9440, 0x001fa002, 0xb5000073, + 0x80171000, 0x005f9440, 0x001fa002, 0x80171004, + 0x005f9443, 0x001fa002, 0x8017101c, 0x005f9446, + 0x001fa002, 0x80171034, 0x005f9449, 0x001fa002, + 0x80171038, 0x005f9440, 0x001fa002, 0xb5000063, + 0x80171000, 0x005f9440, 0x001fa002, 0x80171008, + 0x005f9441, 0x001fa002, 0x80171020, 0x005f9444, + 0x001fa002, 0x80171034, 0x005f9440, 0x001fa002, + 0x80171038, 0x005f9447, 0x001fa002, 0xb5000053, + 0x80171000, 0x005f9440, 0x001fa002, 0x80171004, + 0x005f9443, 0x001fa002, 0x8017100c, 0x005f9441, + 0x001fa002, 0x8017101c, 0x005f9446, 0x001fa002, + 0x80171024, 0x005f9444, 0x001fa002, 0x80171034, + 0x005f9449, 0x001fa002, 0x80171038, 0x005f9440, + 0x001fa002, 0x8017103c, 0x005f9447, 0x001fa002, + 0xb500003a, 0x80171000, 0x005f9440, 0x001fa002, + 0x80171008, 0x005f9441, 0x001fa002, 0x8017100c, + 0x005f9442, 0x001fa002, 0x80171020, 0x005f9444, + 0x001fa002, 0x80171024, 0x005f9445, 0x001fa002, + 0x80171034, 0x005f9440, 0x001fa002, 0x80171038, + 0x005f9447, 0x001fa002, 0x8017103c, 0x005f9448, + 0x001fa002, 0xb5000021, 0x80171000, 0x005f9440, + 0x001fa002, 0x80171004, 0x005f9443, 0x001fa002, + 0x8017100c, 0x005f9441, 0x001fa002, 0x80171010, + 0x005f9442, 0x001fa002, 0x8017101c, 0x005f9446, + 0x001fa002, 0x80171024, 0x005f9444, 0x001fa002, + 0x80171028, 0x005f9445, 0x001fa002, 0x80171034, + 0x005f9449, 0x001fa002, 0x80171038, 0x005f9440, + 0x001fa002, 0x8017103c, 0x005f9447, 0x001fa002, + 0x80171040, 0x005f9448, 0x001fa002, 0x80270001, + 0x803eff90, 0x80171000, 0x82b30020, 0x9ab50000, + 0x40158020, 0xb6000501, 0x48158020, 0x82b30020, + 0x9ab50000, 0x80470000, 0x3015b800, 0xb4600006, + 0x80171000, 0x83840226, 0xb6000603, 0x40028000, + 0x00000000, 0x0008a020, 0x80171018, 0x82b30020, + 0x9ab50000, 0x40158020, 0xb6000501, 0x48158020, + 0x82b30020, 0x9ab50000, 0x80470000, 0x3015b800, + 0xb4600006, 0x80171018, 0x83840215, 0xb6000603, + 0x40028000, 0x00000000, 0x0008a020, 0x80171030, + 0x82b30020, 0x9ab50000, 0x40158020, 0xb6000501, + 0x48158020, 0x82b30020, 0x9ab50000, 0x80470000, + 0x3015b800, 0xb4600006, 0x80171030, 0x83840204, + 0xb6000603, 0x40028000, 0x00000000, 0x0008a020, + 0xb500011e, 0x80270000, 0x803eff90, 0xb0030000, + 0xb4200067, 0x025f0322, 0xb00b0001, 0xb4200016, + 0xb0120001, 0xb4200005, 0x80171018, 0x8033007f, + 0x9821ffff, 0x001fa001, 0xb5000110, 0xb0120002, + 0xb4200005, 0x80171020, 0x8033007f, 0x9821ffff, + 0x001fa001, 0xb5000109, 0x80171018, 0x80330040, + 0x98210000, 0x001fa001, 0x80171020, 0x00000000, + 0x001fa001, 0xb5000101, 0xb00b0002, 0xb420002c, + 0xb0120000, 0xb4200008, 0x80171000, 0x8033007f, + 0x9821ffff, 0x001fa001, 0x80171038, 0x00000000, + 0x001fa001, 0xb50000f5, 0xb0120001, 0xb4200008, + 0x80171000, 0x8033005a, 0x98218279, 0x001fa001, + 0x80171030, 0x00000000, 0x001fa001, 0xb50000eb, + 0xb0120002, 0xb4200008, 0x80171008, 0x8033005a, + 0x98218279, 0x001fa001, 0x80171038, 0x00000000, + 0x001fa001, 0xb50000e1, 0x80171000, 0x80330040, + 0x98210000, 0x001fa001, 0x80171008, 0x00000000, + 0x001fa001, 0x8017100c, 0x00000000, 0x001fa001, + 0x80171038, 0x00000000, 0x001fa001, 0xb50000d3, + 0xb0120000, 0xb4200008, 0x80171000, 0x8033007f, + 0x9821ffff, 0x001fa001, 0x80171038, 0x00000000, + 0x001fa001, 0xb50000c9, 0xb0120001, 0xb4200005, + 0x80171018, 0x8033007f, 0x9821ffff, 0x001fa001, + 0xb50000c2, 0xb0120002, 0xb4200005, 0x80171020, + 0x8033007f, 0x9821ffff, 0x001fa001, 0xb50000bb, + 0x80171018, 0x80330040, 0x98210000, 0x001fa001, + 0x80171020, 0x00000000, 0x001fa001, 0xb50000b3, + 0x80070000, 0x8033007f, 0x9821ffff, 0xb600050e, + 0x144eb80f, 0xb0028000, 0xb4c00008, 0xac400006, + 0x00000000, 0x1042b800, 0x5842b802, 0x90421000, + 0x0017b802, 0x00000000, 0x001fa001, 0x90000001, + 0x59c1b80e, 0x59e1b80f, 0xb0040000, 0xb4200023, + 0xb00a0002, 0xb4000007, 0x80171004, 0x8033005a, + 0x98218279, 0x001fa001, 0x80171034, 0x00000000, + 0x001fa001, 0xb00c0002, 0xb4000009, 0x8017100c, + 0x8033ffa5, 0x98217d87, 0x001fa001, 0x8017103c, + 0x8033005a, 0x98218279, 0x001fa001, 0xb500008b, + 0x8017100c, 0x8033ffa5, 0x98217d87, 0x001fa001, + 0x80171010, 0x00000000, 0x001fa001, 0x8017103c, + 0x8033005a, 0x98218279, 0x001fa001, 0x80171040, + 0x00000000, 0x001fa001, 0xb500007c, 0xb0040001, + 0xb420002a, 0xb00a0001, 0xb4000007, 0x80171018, + 0x8033005a, 0x98218279, 0x001fa001, 0x80171020, + 0x00000000, 0x001fa001, 0xb00a0003, 0xb420000a, + 0x8053005a, 0x98428279, 0x4030b802, 0x8017101c, + 0x5821b801, 0x00000000, 0x00000000, 0x00000000, + 0x0028b801, 0x001fa001, 0xb00c0001, 0xb4200007, + 0x8053005a, 0x98428279, 0x4031b802, 0x80171024, + 0x0028b801, 0x001fa001, 0xb500005c, 0xb00c0002, + 0xb420005a, 0x8053005a, 0x98428279, 0x4031b802, + 0x80171024, 0x0028b801, 0x001fa001, 0x80171028, + 0x00000000, 0x001fa001, 0xb5000050, 0xb00b0002, + 0xb4200012, 0xb00a0001, 0xb4200008, 0x80171004, + 0x8033005a, 0x98218279, 0x001fa001, 0x80171034, + 0x00000000, 0x001fa001, 0xb5000008, 0xb00a0003, + 0xb4200006, 0x80171004, 0x00000000, 0x001fa010, + 0x80171034, 0x00000000, 0x001fa010, 0xb00c0001, + 0xb4200025, 0x027f0383, 0x003f0328, 0xb0130007, + 0xb420000b, 0xb00b0003, 0xb4200009, 0xb0010000, + 0xb4200007, 0x80171024, 0x00000000, 0x001fa011, + 0x80171054, 0x80270000, 0x001fa001, 0xb500002b, + 0xb00d0000, 0xb420000a, 0x8033005a, 0x98218279, + 0x4041b811, 0x8017100c, 0x0048b802, 0x001fa002, + 0x8017103c, 0x00000000, 0x001fa002, 0xb500001f, + 0xb00d0002, 0xb420001d, 0x80171054, 0x8033005a, + 0x98218279, 0x001fa001, 0x8017106c, 0x00000000, + 0x001fa001, 0xb5000015, 0xb00c0002, 0xb4200013, + 0xb00d0000, 0xb4200007, 0x8017100c, 0x00000000, + 0x001fa011, 0x80171040, 0x00000000, 0x001fa011, + 0xb500000a, 0xb00d0001, 0xb4200008, 0x80171054, + 0x8033005a, 0x98218279, 0x001fa001, 0x80171058, + 0x00000000, 0x001fa001, 0xb5000000, 0x029f0388, + 0x02bf0321, 0xb0140000, 0xb4000006, 0xb0150000, + 0xb4000004, 0x8017108c, 0x8033007f, 0x9821ffff, + 0x001fa001, 0x8027b078, 0x5c22b801, 0x806f001f, + 0x80af001f, 0x80cf0400, 0x003fb0bc, 0x5822b801, + 0x01afb801, 0x003f90bc, 0xb520ffff, 0x90210020, + 0x806f0003, 0x80af0003, 0x80cf0420, 0x003fb0bc, + 0x5822b801, 0x01afb801, 0x003f90bc, 0xb520ffff, + 0x81270000, 0x8033007f, 0x9821ffff, 0x80171000, + 0xb600060a, 0x80470000, 0xb6000603, 0x015f8020, + 0x0156b80a, 0x1042b80a, 0x3002b801, 0xb4a00001, + 0x81270001, 0x00000000, 0x00000000, 0x015f0323, + 0x00000000, 0xb00a0000, 0xb4200002, 0x81670000, + 0xb5000001, 0x81670001, 0x017f23fb, 0x01ff41ee, + 0x59f0b80f, 0x61f0b80f, 0x021f41ef, 0x5a10b810, + 0x6210b810, 0xb00a0003, 0xb420003b, 0x017f039f, + 0x019f41c5, 0x5990b80c, 0x6190b80c, 0xb00b0000, + 0xb400000c, 0xb00c0000, 0xb4000005, 0xac4c0100, + 0x8033001d, 0x98215500, 0x12c1b802, 0xb500000f, + 0xac4f0100, 0x8033001d, 0x98215500, 0x12c1b802, + 0xb500000a, 0xb0090000, 0xb4000005, 0xac4f0100, + 0x8033ffe2, 0x9821ab00, 0x12c1b802, 0xb5000003, + 0xac4f0100, 0x00000000, 0x02c7b802, 0xb0030000, + 0xb420007e, 0x01bf03a0, 0x01df41c9, 0x59d0b80e, + 0x61d0b80e, 0xb00d0000, 0xb400000c, 0xb00e0000, + 0xb4000005, 0xac4e0100, 0x8033001d, 0x98215500, + 0x12e1b802, 0xb5000071, 0xac500100, 0x8033001d, + 0x98215500, 0x12e1b802, 0xb500006c, 0xb0090000, + 0xb4000005, 0xac500100, 0x8033ffe2, 0x9821ab00, + 0x12e1b802, 0xb5000065, 0xac500100, 0x00000000, + 0x02e7b802, 0xb5000061, 0xb00a0002, 0xb420002f, + 0x023f9002, 0x025f9001, 0xb00f0000, 0xb4a00007, + 0xac4f0100, 0x00000000, 0x4022b811, 0x00000000, + 0x0028b801, 0x02c7b801, 0xb500000c, 0xb0090000, + 0xb4000004, 0xac4f0100, 0x00000000, 0x02c7b802, + 0xb5000006, 0xac4f0100, 0x00000000, 0x4022b812, + 0x00000000, 0x0028b801, 0x02c7b801, 0xb0030000, + 0xb4200046, 0xb0100000, 0xb4a00007, 0xac500100, + 0x00000000, 0x4022b811, 0x00000000, 0x0028b801, + 0x02e7b801, 0xb500003d, 0xb0090000, 0xb4000004, + 0xac500100, 0x00000000, 0x02e7b802, 0xb5000037, + 0xac500100, 0x00000000, 0x4022b812, 0x00000000, + 0x0028b801, 0x02e7b801, 0xb5000030, 0x023f9002, + 0x025f9001, 0xb00f0000, 0xb4a00007, 0xac4f0100, + 0x00000000, 0x4022b811, 0x00000000, 0x0028b801, + 0x02c7b801, 0xb5000006, 0xac4f0100, 0x00000000, + 0x4022b812, 0x00000000, 0x0028b801, 0x02c7b801, + 0xb0090000, 0xb4000005, 0x0047b816, 0x8033ffe2, + 0x9821ab00, 0x1042b801, 0x02c7b802, 0xb0030000, + 0xb4200016, 0xb0100000, 0xb4a00007, 0xac500100, + 0x00000000, 0x4022b811, 0x00000000, 0x0028b801, + 0x02e7b801, 0xb5000006, 0xac500100, 0x00000000, + 0x4022b812, 0x00000000, 0x0028b801, 0x02e7b801, + 0xb0090000, 0xb4000005, 0x0047b817, 0x8033ffe2, + 0x9821ab00, 0x1042b801, 0x02e7b802, 0x00000000, + 0x00000000, 0x02c8b816, 0x02dfb0cf, 0xb0030000, + 0xb4200002, 0x02e8b817, 0x02ffb0c6, 0x00ffb81b, + 0xb6001807, 0x5841b802, 0x3015b800, 0xb4800002, + 0x06b5b800, 0x98420001, 0x5aa1b815, 0x00000000, + 0x00ffb81c, 0x00000000, 0x00000000, 0x00000000, + 0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000, + 0xb4000011, 0x815bb3f0, 0x81070000, 0x81270bf4, + 0xb00a0000, 0xb4000002, 0x81070c00, 0x812717f4, + 0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc, + 0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809, + 0xb4a00029, 0xb5000008, 0xb0040000, 0xb4200003, + 0x802717ff, 0x81470000, 0xb5000003, 0x80270001, + 0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200001, + 0x8384026c, 0x80af001f, 0x808f0000, 0x806f0000, + 0x80670400, 0x5d22b80a, 0xb600180a, 0x00cfb803, + 0x013fb0bc, 0x5922b809, 0x01afb809, 0x013f90bc, + 0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x90630020, + 0x91290020, 0x801bb3f8, 0x80270001, 0xb0000001, + 0xb4000002, 0x802600a0, 0x803eb3f8, 0x81270c00, + 0xb00a0000, 0xb4000001, 0x81270000, 0x813eb3f0, + 0x80270001, 0x003f2013, 0x00ffb81b, 0x00000000, + 0x029fb00a, 0x02bfb00b, 0x02dfb00c, 0x02ffb00d, + 0x031fb00e, 0x033fb00f, 0x033f400f, 0x0287b86f, + 0x029fb005, 0x8285009d, 0x9a940008, 0x8286009d, + 0x8285009c, 0x96b48000, 0xb0158000, 0xb40001b5, + 0x96b40100, 0xb0150100, 0xb400020c, 0x96b40400, + 0xb0150400, 0xb400020d, 0x96b40001, 0xb0150001, + 0xb400000c, 0x96b40008, 0xb0150008, 0xb40001ad, + 0x96b44000, 0xb0154000, 0xb400020c, 0x96b40002, + 0xb0150002, 0xb4000182, 0x00000000, 0x00000000, + 0xb500021e, 0x02bf9017, 0x92b50001, 0x02bfb017, + 0x82850082, 0x96f40001, 0xb0170000, 0xb4000171, + 0x5efdb814, 0x96f70001, 0xb0170001, 0xb420000b, + 0x83050069, 0x9718003f, 0x82e50064, 0x12f7b818, + 0x86f70109, 0x82feff74, 0x02e7b86f, 0x9af74000, + 0x01ffb817, 0x96f7bfff, 0x01ffb817, 0x83050081, + 0x82a5009a, 0x96b50001, 0xb0150001, 0xb4200014, + 0x82a70000, 0x02bfb017, 0x96b41840, 0xb0150800, + 0xb420000c, 0x96b40008, 0x5aa9b815, 0x96d46000, + 0x5ec3b816, 0x82f3000f, 0x9af7c00f, 0x1718b817, + 0x1ab5b818, 0x1ab5b816, 0x9ab50340, 0x82a60081, + 0xb500014c, 0x9b180180, 0x83060081, 0xb5000149, + 0x82a5009a, 0x96b50002, 0xb0150002, 0xb420001b, + 0x82a70000, 0x02bfb017, 0x96b41800, 0xb0151800, + 0xb4000013, 0x96b40040, 0xb0150040, 0xb4200004, + 0xa3180c00, 0x9b180340, 0x83060081, 0xb5000139, + 0x96b40008, 0x5aa9b815, 0x96d46000, 0x5ec3b816, + 0x82f3000f, 0x9af7c00f, 0x1718b817, 0x1ab5b818, + 0x1ab5b816, 0x9ab50340, 0x82a60081, 0xb500012d, + 0x9b180180, 0x83060081, 0xb500012a, 0x82a500c1, + 0x96b5000f, 0xb015000b, 0xb420000e, 0x96b40020, + 0xb0150020, 0xb400000b, 0x96b40200, 0xb0150200, + 0xb4000008, 0x82c50086, 0x82e50094, 0x3016b817, + 0xb4400004, 0x06f7b816, 0xb017ff00, 0xb4400001, + 0xb5000118, 0x96b46000, 0xb0156000, 0xb4000011, + 0x96b41820, 0xb0150820, 0xb4200004, 0x9b391000, + 0x82a5009a, 0x96b5feff, 0x82a6009a, 0x96b40040, + 0xb0150040, 0xb4200001, 0x9739efff, 0x96b91000, + 0xb0151000, 0xb4200003, 0x82a5009a, 0x9ab50100, + 0x82a6009a, 0x96b40040, 0xb0150040, 0xb4200019, + 0x96b41800, 0xb0151800, 0xb4200006, 0x96b98000, + 0xb0158000, 0xb4200003, 0x9b180180, 0x83060081, + 0xb50000f8, 0x96d80c00, 0x82b300ff, 0x9ab5f3ff, + 0x1718b815, 0xb0160c00, 0xb4000007, 0x82e50098, + 0x96f70400, 0xb0170400, 0xb4200002, 0x82c70c00, + 0xb5000001, 0xa2d60c00, 0x1b18b816, 0x9b180340, + 0xb50000c4, 0x96b40220, 0xb0150000, 0xb4e00021, + 0x82a5009d, 0x82f3ffff, 0x16b5b817, 0x82f33800, + 0x3015b817, 0xb420001b, 0x96f98000, 0xb0178000, + 0xb4000018, 0x82a70000, 0x02bfb017, 0x82c5009d, + 0x96d6ffff, 0x82b3c800, 0x9ab58001, 0x82e500c1, + 0x96f7000f, 0xb017000b, 0xb4000002, 0x82b38800, + 0x9ab58001, 0x1ab5b816, 0x82c5009a, 0x96d60020, + 0xb0160020, 0xb4200002, 0x82b3c800, 0x9ab58001, + 0x82a6009d, 0x02ff9017, 0x00000000, 0xb0170040, + 0xb4800000, 0x5eb5b814, 0x96b500f0, 0x96f46000, + 0x5eedb817, 0x1ab5b817, 0xb0170003, 0xb4000004, + 0x96b500ef, 0x96f70001, 0x5ae4b817, 0x1ab5b817, + 0x96d41800, 0xb0161800, 0xb400000a, 0x96f900ff, + 0x96b500ff, 0x9739ff00, 0x1b39b815, 0x02a7b817, + 0x96b500f3, 0x96d40008, 0x5ec1b816, 0x1ab5b816, + 0xb500000c, 0x96f98000, 0xb0178000, 0xb4200007, + 0x5efeb814, 0x96f70001, 0xb0170001, 0xb4000003, + 0x9b180180, 0x83060081, 0xb50000a2, 0x96b500f3, + 0x9ab50008, 0x9739fff3, 0x96d40020, 0xb0160020, + 0xb4200019, 0x82c7001f, 0x82c600c9, 0x9b398000, + 0x82c70000, 0x02dfb017, 0x96d40010, 0x5ac8b816, + 0x82f300ff, 0x9af7cfff, 0x1718b817, 0x1b18b816, + 0x9b180340, 0x82c5009d, 0x96d6ffff, 0x82f33800, + 0x9af78001, 0x1af7b816, 0x82c5009a, 0x96d60020, + 0xb0160020, 0xb4200002, 0x82f3c800, 0x9af78001, + 0x82e6009d, 0xb500005f, 0x97397fff, 0x96b500ff, + 0x5aaab815, 0x82f300fc, 0x9af703ff, 0x1718b817, + 0x1b18b815, 0x9b180340, 0x82c5009a, 0x96d60010, + 0xb0160010, 0xb4200027, 0x82c70000, 0x02dfb017, + 0x82c50086, 0x92d60bb8, 0x82c60086, 0x82c50094, + 0x5eefb818, 0x96f70003, 0xb0170003, 0xb4200002, + 0x82e70bb8, 0xb5000001, 0x82e70bb8, 0x12d6b817, + 0x82e50081, 0x9af70020, 0x82e60081, 0x82c60094, + 0xa2f70020, 0x82e60081, 0x82f30001, 0x16f7b818, + 0x5ef0b817, 0xb0170001, 0xb4000004, 0x96f84000, + 0x5ee4b817, 0x9718f3ff, 0x1b18b817, 0x82f32800, + 0x9af78000, 0x82e6009d, 0x83060081, 0x83070001, + 0x8306009f, 0x8305009c, 0xb0180001, 0xb4e0fffb, + 0xb50000f6, 0x82c5009d, 0x82f33800, 0x9af78001, + 0x3016b817, 0xb420000f, 0x82b3c800, 0x9ab58001, + 0x82e500c1, 0x96f7000f, 0xb017000b, 0xb4000002, + 0x82b38800, 0x9ab58001, 0x82c5009a, 0x96d60020, + 0xb0160020, 0xb4200002, 0x82b3c800, 0x9ab58001, + 0x82a6009d, 0x82c5009a, 0x96d60080, 0xb0160080, + 0xb4000013, 0x02df9017, 0x00000000, 0xb0160010, + 0xb480000f, 0x82c500c1, 0x96d6000f, 0xb016000b, + 0xb400000b, 0x82c50087, 0x96d60080, 0x5ac7b816, + 0x82c50098, 0x96d60800, 0x5ac3b816, 0x96f84000, + 0x3017b816, 0xb4200002, 0x033f400f, 0x9b394000, + 0x9739bfff, 0x82e50061, 0x96f70008, 0xb0170008, + 0xb4000005, 0x5eefb818, 0x96f70003, 0xb0170003, + 0xb4000001, 0x9718ffff, 0x96b41800, 0xb0151800, + 0xb4000008, 0x5eb9b814, 0x96b5000f, 0x82c50099, + 0x5ed0b816, 0x96f6000f, 0x5ab0b815, 0x82a60099, + 0xb5000002, 0x5ef9b814, 0x96f7000f, 0x5aecb817, + 0x82c5009a, 0x96d60fff, 0x1ad6b817, 0x82c6009a, + 0x96b46000, 0xb0156000, 0xb4200005, 0x5ae2b817, + 0x82d30ffc, 0x9ad63fff, 0x1718b816, 0x1b18b817, + 0x83060081, 0x83070001, 0x8306009f, 0x8305009c, + 0xb0180001, 0xb4e0fffb, 0x00000000, 0xb500009f, + 0x82850083, 0x96b400ff, 0xb015003c, 0xb4200019, + 0x96b92000, 0xb0152000, 0xb4000002, 0x9b392000, + 0xb5000014, 0x9739d3ff, 0x82870000, 0x82860087, + 0x82870008, 0x82860083, 0x829bff78, 0x82a7001f, + 0xb0140400, 0xb4000001, 0x82a70010, 0x82a600c9, + 0x829bff78, 0x00000000, 0x828600cb, 0x8285009d, + 0x82b3ffff, 0x9ab5fffd, 0x1694b815, 0x8286009d, + 0xb5000000, 0x83070002, 0x8306009f, 0x00000000, + 0xb500007e, 0x83078000, 0x8306009f, 0x00000000, + 0xb500007a, 0x82850094, 0x82a50086, 0x06b5b814, + 0x02b6b815, 0xb0151700, 0xb440004c, 0x8285006c, + 0x969400ff, 0xb0140024, 0xb4000019, 0xb0140012, + 0xb4000017, 0x8285009a, 0x5eedb814, 0x96f70003, + 0xb0170003, 0xb4000009, 0x82a50083, 0x5ea8b815, + 0x96b500ff, 0xb0150020, 0xb4400002, 0x82c70bbc, + 0xb5000001, 0x82c70bb8, 0xb5000008, 0x82a50083, + 0x5ea8b815, 0x96b500ff, 0xb0150020, 0xb4400002, + 0x82c71199, 0xb5000001, 0x82c71197, 0xb5000017, + 0xb500002e, 0x8285009a, 0x5eedb814, 0x96f70003, + 0xb0170003, 0xb4000009, 0x82a50083, 0x5ea8b815, + 0x96b500ff, 0xb0150020, 0xb4400002, 0x82c70e12, + 0xb5000001, 0x82c70e0e, 0xb5000008, 0x82a50083, + 0x5ea8b815, 0x96b500ff, 0xb0150020, 0xb4400002, + 0x82c70e12, 0xb5000001, 0x82c70e0e, 0x82e50086, + 0x12f7b816, 0x02bf9017, 0xb0150020, 0xb480000b, + 0x82a5009a, 0x96b56000, 0xb0156000, 0xb4000007, + 0x82a50098, 0x96d50a00, 0xb0160a00, 0xb4000002, + 0xb0160000, 0xb4200001, 0x92f705dc, 0x82850081, + 0x9ab40020, 0x82a60081, 0x82c50094, 0x82e60094, + 0x82860081, 0x86b705dc, 0x82a6009b, 0x83070008, + 0x8306009f, 0x00000000, 0xb5000024, 0x83070100, + 0x8306009f, 0x00000000, 0xb5000020, 0x83070000, + 0x83050081, 0x9b180180, 0x83060081, 0x83070400, + 0x8306009f, 0x00000000, 0xb5000018, 0x82870000, + 0x82850082, 0x5eb7b814, 0x96b500fc, 0x96d40006, + 0x5ec1b816, 0x1ab5b816, 0x5aacb815, 0x83050081, + 0x82d3001c, 0x9ad600ff, 0x1718b816, 0x1b18b815, + 0x9b180e00, 0x83060081, 0x83074000, 0x8306009f, + 0x8305009d, 0x82d3ffff, 0x9ad6bfff, 0x1718b816, + 0x8306009d, 0x00000000, 0xb5000000, 0x029f9005, + 0x01ffb814, 0x033f600f, 0x029f900a, 0x02bf900b, + 0x02df900c, 0x02ff900d, 0x031f900e, 0x033f900f, + 0x00ffb81e, 0x02ff9010, 0x92f70b43, 0x02ffb010, + 0x02ff90cb, 0x82bbffdc, 0x829bffd8, 0x93150004, + 0x3014b815, 0xb400000f, 0x02dbb818, 0x029bb815, + 0x3017b816, 0xb480000b, 0x5a81b814, 0x029fb010, + 0x82860095, 0x8293001f, 0x9294fe00, 0x92b50008, + 0x3015b814, 0xb4800002, 0x82b3001f, 0x92b5fa00, + 0x82beffdc, 0x82850086, 0x83250094, 0x06d4b819, + 0x02d6b816, 0xb016ffff, 0xb4a00009, 0x82c50081, + 0x9ab60020, 0x82a60081, 0x82a50086, 0x92b50bbb, + 0x82a60094, 0x82c60081, 0x86b505df, 0x82a6009b, + 0x00ffb81c, 0x82870001, 0x829ef500, 0x82850086, + 0x83250094, 0x06d4b819, 0x02d6b816, 0xb016ffff, + 0xb4a0000b, 0x82870001, 0x829ef504, 0x82c50081, + 0x9ab60020, 0x82a60081, 0x82a50086, 0x92b50bbb, + 0x82a60094, 0x82c60081, 0x86b505df, 0x82a6009b, + 0x00ffb81c, 0x82070028, 0x023f9006, 0x83a4ef4f, + 0x80070000, 0x001fb011, 0x001f204f, 0x003fb800, + 0x001f9006, 0x5803b800, 0x80338000, 0x1800b801, + 0x003fb800, 0x005f4193, 0x5c41b802, 0x80350000, + 0x00000000, 0x0027b860, 0x80150010, 0x5810b800, + 0x80750010, 0x1863b800, 0x8087ffff, 0x80a7770b, + 0x80c70000, 0x1403b804, 0x3000b805, 0xb4000008, + 0x5888b804, 0x58a8b805, 0x90c60001, 0xb0060003, + 0xb4a0fff8, 0x84420001, 0xb4e0ffee, 0xb5000027, + 0xb0060003, 0xb4200007, 0x80150010, 0x5810b800, + 0x81150010, 0x950800ff, 0xb0080077, 0xb4000001, + 0xb500fff4, 0x001f400e, 0x98000010, 0x98004000, + 0x9400fffe, 0x001f600e, 0x80e71f40, 0x001f4000, + 0x94000080, 0xb0000080, 0xb4200001, 0x80e77490, + 0x00ffb008, 0x80e70020, 0xb0060000, 0xb400000e, + 0x58e3b806, 0x90210020, 0x81070000, 0x5938b803, + 0x1908b809, 0x9523ff00, 0x5928b809, 0x1908b809, + 0x5d28b803, 0x9529ff00, 0x1908b809, 0x5d38b803, + 0x1908b809, 0x011fb011, 0x00ff204f, 0x80137fff, + 0x9800ffe7, 0x1421b800, 0x5c23b801, 0x001f9006, + 0x0441b800, 0x3001b800, 0xb4600002, 0x0440b801, + 0xa4422000, 0x007f90cb, 0x1063b802, 0x007fb0cb, + 0x003fb006, 0x803effec, 0x80470001, 0x005f2013, + 0xb500ebdf, 0x001f400e, 0x9400000f, 0xb0000000, + 0xb4200001, 0x00ffb81f, 0xb0000001, 0xb4000005, + 0xb0000003, 0xb4000003, 0xb0000002, 0xb4000001, + 0x00ffb81f, 0x80070001, 0x001f2013, 0xb500ebd0, + 0x001f9012, 0x001fb100, 0x001f004c, 0x001f2404, + 0x801bfef0, 0x8058fef4, 0x803bff68, 0x8078ff6c, + 0x2000b801, 0x2042b803, 0x001fb104, 0x005f2414, + 0x82e70001, 0x83640048, 0x029fb014, 0x829efef0, + 0x8286000f, 0x02bf2054, 0x82bcfef4, 0x82a6000e, + 0x00ffb81a, 0x80e70001, 0x801336e3, 0x9800eb76, + 0x001fb100, 0x800700ab, 0x001f2404, 0x801bc3e8, + 0x8058c3ec, 0x83640024, 0x82e70000, 0x83640036, + 0x029fb300, 0x029fb100, 0x02bf2c04, 0x02bf2404, + 0x801bc000, 0x8058c004, 0x8364001b, 0x82e70000, + 0x8364002d, 0x001f9300, 0x3000b814, 0xb420000a, + 0x001f0c04, 0x3000b815, 0xb4200007, 0x829efef0, + 0x82bcfef4, 0x029fb012, 0x02bf204c, 0x82870001, + 0x829cfef5, 0x00ffb81a, 0xb0070000, 0xb4000007, + 0x80e70000, 0x801399fa, 0x9800c92e, 0x001fb100, + 0x800700af, 0x001f2404, 0xb500ffdc, 0x82870000, + 0x829cfef5, 0x00ffb81a, 0x80c700ff, 0x803bff68, + 0x8078ff6c, 0x14a0b806, 0x2063b805, 0x007f2414, + 0x2021b802, 0x58c8b806, 0x14a0b806, 0x58b0b805, + 0x2021b805, 0x58c8b806, 0x14a0b806, 0x2021b805, + 0x58c8b806, 0x14a0b806, 0x5cb0b805, 0x2021b805, + 0x003fb104, 0x00ffb81b, 0x82c70000, 0x83070400, + 0x83270005, 0x8197040c, 0x81d7ffff, 0x83840126, + 0x83840001, 0x00ffb81b, 0x808f0000, 0x806f001f, + 0x80af001f, 0x80270140, 0x81e7ef98, 0x5de2b80f, + 0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, + 0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020, + 0x90210020, 0x80270180, 0x81e7ee90, 0x5de2b80f, + 0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, + 0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020, + 0x90210020, 0x8057ffff, 0x80170430, 0x80070410, + 0x80270408, 0xb6000509, 0x005ff000, 0x90420500, + 0x007ff001, 0x90630600, 0x009ff002, 0x00bff003, + 0x2004a025, 0x90000001, 0x90210001, 0x80070414, + 0x80d7ffff, 0x8097045c, 0x8017043c, 0xb6000404, + 0x005ff000, 0x007f87e0, 0x84000001, 0x2082a7e3, + 0x80970460, 0x80170440, 0x2082b803, 0x007f8000, + 0x2083a004, 0x80170430, 0x80970450, 0x80270408, + 0xb6000508, 0x005f8024, 0x90420500, 0x007ff001, + 0x90630600, 0x009ff002, 0x00bff003, 0x2004a025, + 0x90210001, 0x80170440, 0x00000000, 0x02bf87e0, + 0x80970460, 0x82870000, 0xb6000404, 0x005f87e4, + 0x5a88b814, 0x204287e0, 0x1a94b802, 0x00ffb81c, + 0x001f0a49, 0x001f2709, 0x001f0a41, 0x001f2708, + 0x001f0a46, 0x001f2707, 0x001f0a48, 0x001f2706, + 0x001f0a42, 0x001f2705, 0x001f0a47, 0x001f2704, + 0x001f0a45, 0x001f2703, 0x001f0a43, 0x001f2702, + 0x001f0a40, 0x001f2701, 0x001f0a44, 0x001f2700, + 0x001f0c25, 0xa020000c, 0x94400001, 0x94600002, + 0x94810004, 0x94a10008, 0x94c00010, 0x5943b802, + 0x5861b803, 0x5882b804, 0x5ca2b805, 0x5cc4b806, + 0x194ab803, 0x194ab804, 0x194ab805, 0x194ab806, + 0x015f2738, 0x801bef90, 0x003f91c1, 0x5c28b801, + 0x005f91c2, 0x5858b802, 0x1821b802, 0x2000b801, + 0x001fb1c4, 0x8018ef94, 0x003f0709, 0x2000b801, + 0x001f2714, 0x82c70001, 0x82e70001, 0x83070710, + 0x8327001e, 0x81970735, 0x8384009f, 0x02df0738, + 0x82170a30, 0x838400f1, 0x819efef0, 0x817cfef4, + 0x819eff68, 0x817cff6c, 0x00ffb81b, 0x820f001f, + 0x8018fef8, 0x8057ffff, 0x001f2709, 0x8018fef6, + 0x80d7ffff, 0x001f2708, 0x8018fefa, 0x8157ffff, + 0x001f2707, 0x8018fefd, 0x81d7ffff, 0x001f2706, + 0x8018fefb, 0x802f001f, 0x001f2705, 0x8018fefe, + 0x00000000, 0x001f2704, 0x8018fef9, 0x00000000, + 0x001f2703, 0x8018feff, 0x00000000, 0x001f2702, + 0x8018fef7, 0x00000000, 0x001f2701, 0x8018fefc, + 0x00000000, 0x001f2700, 0x001f0c25, 0xa0200011, + 0x94410001, 0x94600002, 0x94800004, 0x94a00008, + 0x94c10010, 0x5941b802, 0x5861b803, 0x5c82b804, + 0x58a1b805, 0x5cc1b806, 0x194ab803, 0x194ab804, + 0x194ab805, 0x194ab806, 0x015f2738, 0x801bef90, + 0x003f91c1, 0x5c28b801, 0x005f91c2, 0x5858b802, + 0x1821b802, 0x2000b801, 0x001fb1c4, 0x8018ef94, + 0x003f0709, 0x2000b801, 0x001f2714, 0x82c70001, + 0x82e70001, 0x83070710, 0x8327001e, 0x81970735, + 0x83840055, 0x02df0738, 0x82170a20, 0x838400a7, + 0x819efef0, 0x817cfef4, 0x5ac8b80c, 0x02ff0a44, + 0x1ad6b817, 0x02dfb291, 0x5ed8b80c, 0x5968b80b, + 0x1ad6b80b, 0x02df6524, 0x00ffb81b, 0x820f001f, + 0x8018fefe, 0x8057ffff, 0x001f2709, 0x8018fefa, + 0x80d7ffff, 0x001f2708, 0x8018fefc, 0x8157ffff, + 0x001f2707, 0x8018feff, 0x81d7ffff, 0x001f2706, + 0x8018fef8, 0x802f001f, 0x001f2705, 0x8018fefb, + 0x00000000, 0x001f2704, 0x8018fefd, 0x00000000, + 0x001f2703, 0x8018fef6, 0x00000000, 0x001f2702, + 0x8018fef9, 0x00000000, 0x001f2701, 0x8018fef7, + 0x00000000, 0x001f2700, 0x801bef90, 0x003f91c1, + 0x5c28b801, 0x005f91c2, 0x5858b802, 0x1821b802, + 0x2000b801, 0x001fb1c4, 0x8018ef94, 0x003f0709, + 0x2000b801, 0x001f2714, 0x82c70001, 0x82e70001, + 0x83070710, 0x8327001e, 0x81970735, 0x83840016, + 0x83270000, 0x831bfef0, 0x82f8fef4, 0x02c7b819, + 0x82170a28, 0x83840065, 0x300cb818, 0xb4200002, + 0x300bb817, 0xb4000006, 0x93390001, 0xb0190020, + 0xb480fff6, 0x83270000, 0x833cfef5, 0x00ffb81b, + 0x019fb290, 0x017f2a44, 0x033f2c25, 0x83270001, + 0x833cfef5, 0x00ffb81b, 0x0007b818, 0x90000003, + 0x00000000, 0x015ff000, 0x90000001, 0x5949b80a, + 0x013ff000, 0x194ab809, 0x84000002, 0x994a0100, + 0x017ff000, 0x958b00f8, 0x5981b80c, 0x956b0007, + 0x198cb80b, 0x84000002, 0x998c0008, 0x017ff000, + 0x90000001, 0x5971b80b, 0x198cb80b, 0x017ff000, + 0x5969b80b, 0x198cb80b, 0x81a70000, 0x94d90003, + 0x82a70000, 0xb6260019, 0xb6000818, 0x5df0b80a, + 0x5e02b80a, 0x21efb810, 0x95ef0001, 0x5941b80a, + 0x194ab80f, 0x21efb816, 0x5e18b80c, 0x5e35b80c, + 0x5e54b80c, 0x5e6cb80c, 0x2210b811, 0x2252b813, + 0x2210b812, 0x96100001, 0x5981b80c, 0x198cb810, + 0x2210b817, 0x10afb810, 0x10a5b80d, 0x5da1b805, + 0x94a50001, 0x5aa1b815, 0x1ab5b805, 0x019fa7f5, + 0x5cc2b819, 0xb626001c, 0x82870000, 0xb6000419, + 0xb6000818, 0x5df0b80a, 0x5e02b80a, 0x21efb810, + 0x95ef0001, 0x5941b80a, 0x194ab80f, 0x21efb816, + 0x5e18b80c, 0x5e35b80c, 0x5e54b80c, 0x5e6cb80c, + 0x2210b811, 0x2252b813, 0x2210b812, 0x96100001, + 0x5981b80c, 0x198cb810, 0x2210b817, 0x10afb810, + 0x10a5b80d, 0x5da1b805, 0x94a50001, 0x5a81b814, + 0x1a94b805, 0x019fa7f4, 0x00ffb81c, 0x8257ffff, + 0x808f0000, 0x806f001f, 0x80af001f, 0x80270200, + 0x81e7ec70, 0x5de2b80f, 0xb6000208, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0xb520ffff, 0x91ef0020, 0x90210020, 0x80270240, + 0x81e7ed70, 0x5de2b80f, 0xb6000208, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0xb520ffff, 0x91ef0020, 0x90210020, 0x80270180, + 0x81e7ee90, 0x5de2b80f, 0xb6000208, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0xb520ffff, 0x91ef0020, 0x90210020, 0x806f0007, + 0x80af0007, 0x80270280, 0x81e7ee70, 0x5de2b80f, + 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, + 0x01ff90bc, 0xb520ffff, 0x91ef0020, 0x90210020, + 0x80170760, 0x001f0700, 0x001fa020, 0x001f0701, + 0x001fa020, 0x001f0702, 0x001fa020, 0x001f0703, + 0x001fa020, 0x001f0704, 0x001fa000, 0x80970750, + 0x81170770, 0x82a70735, 0x83a40060, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a4005c, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750, + 0x81170750, 0x81970740, 0x82a70730, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a40050, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a4004c, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970750, 0x80170770, + 0x81170770, 0x81970760, 0x82a7072b, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a40040, 0x83a4004e, + 0xb6000407, 0x86b50001, 0x83a4003c, 0x001f8004, + 0x003f87e8, 0x2080a001, 0x83a40047, 0x00000000, + 0x80970770, 0x80170750, 0x81170750, 0x81970740, + 0x82a70726, 0x001f800c, 0x003f8008, 0x2100a001, + 0x83a4002e, 0x83a4003c, 0xb6000407, 0x86b50001, + 0x83a4002a, 0x001f8004, 0x003f87e8, 0x2080a001, + 0x83a40035, 0x00000000, 0x80970750, 0x80170770, + 0x81170770, 0x81970760, 0x82a70721, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a4001c, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a40018, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750, + 0x81170750, 0x81970740, 0x82a7071c, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a4000c, 0x017f87e4, + 0x81870000, 0xb6000406, 0x86b50001, 0x83a40007, + 0x001f87e4, 0x200087e8, 0x5988b80c, 0x198cb800, + 0x021fa02c, 0x021fa00b, 0x00ffb81c, 0x005ff015, + 0x90420600, 0x003f87e0, 0x001ff002, 0x2060b801, + 0x90630800, 0x90960a00, 0x001ff003, 0x003ff004, + 0x20a0b801, 0x90a50900, 0x00000000, 0x001ff005, + 0x009fa000, 0x00ffb81d, 0x001f8004, 0x5c21b800, + 0x5847b800, 0x1821b802, 0x942100ff, 0x2080a7e1, + 0x00ffb81d, 0x00000000, 0x00000000, 0x00000000, + 0x015f400e, 0x944a4000, 0xb0024000, 0xb420001a, + 0x954abfff, 0x015f600e, 0x820f001f, 0x802f001f, + 0x81470000, 0x015f23f9, 0x015fb0ba, 0x8057ffff, + 0x80770000, 0x82970400, 0x82d7ffff, 0x82f70000, + 0xb6000702, 0xb6000001, 0x029fa02a, 0x80275480, + 0x005fb801, 0x8033001f, 0x9821c000, 0x803effe0, + 0x90212000, 0x803effe4, 0x80d9ff80, 0x00df6001, + 0x81477508, 0x015fb008, 0x003f0324, 0xb0010000, + 0xb4200076, 0x8344ebe6, 0xb0180000, 0xb4000004, + 0x011f400e, 0x1908b818, 0x011f600e, 0x00ffb81f, + 0x8344f18f, 0xb00b0000, 0xb4000006, 0x023f400e, + 0x9a310002, 0x023f600e, 0x82270000, 0x023f2012, + 0x00ffb81f, 0x8364ed72, 0x82270000, 0x023f2011, + 0x80070000, 0x80170800, 0xb6002002, 0xb6003001, + 0x001fa020, 0x82270000, 0x003fb811, 0x02bf9006, + 0x5aa3b815, 0x82338000, 0x1a31b815, 0x003fb811, + 0x8067e950, 0x5c62b803, 0x81f50000, 0x019f4193, + 0x0267b80c, 0xadcc0010, 0x80170800, 0x80130000, + 0x9800f872, 0x001fa020, 0x80134e1f, 0x98000001, + 0x001fa020, 0x59d0b80e, 0x81150010, 0x1908b80e, + 0x001fa028, 0x858c0001, 0x5e01b80c, 0x5e25b810, + 0xb6310006, 0xb6002005, 0x81150010, 0x5910b808, + 0x00000000, 0x81350010, 0x1808a029, 0x9630001f, + 0xb0110000, 0xb4000006, 0xb6310005, 0x81150010, + 0x5910b808, 0x00000000, 0x81350010, 0x1808a029, + 0x962c0001, 0xb0110000, 0xb4000003, 0x81150010, + 0x5910b808, 0x001fa028, 0x019f9006, 0x958cffff, + 0x00df4193, 0x58c1b806, 0x118cb806, 0xb00ce000, + 0xb4800002, 0x858ce000, 0x918cc000, 0x8153001f, + 0x118cb80a, 0x819effec, 0x019fb006, 0x015f4193, + 0x5941b80a, 0x019f90cb, 0x118cb80a, 0x019fb0cb, + 0x019f90ba, 0x918c0001, 0x019fb0ba, 0xb00c0002, + 0xb4200016, 0x019f400e, 0x940c8000, 0xb0008000, + 0xb4200012, 0x958c7fff, 0x019f600e, 0x80070000, + 0x800600a0, 0x80073da1, 0x800600a1, 0x801bff60, + 0x00000000, 0x801eff60, 0x00000000, 0x801bff60, + 0x00000000, 0x801eff60, 0x80130001, 0x98003da1, + 0x800600a1, 0x80070001, 0x800600a0, 0x003f0324, + 0x90210001, 0xb0010005, 0xb4a00001, 0x80270000, + 0x003f2324, 0x00ffb81f, 0x00000000, 0x00000000, + 0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000, + 0xb4000011, 0x815bb3f0, 0x81070000, 0x81270bf4, + 0xb00a0000, 0xb4000002, 0x81070c00, 0x81271800, + 0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc, + 0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809, + 0xb4a0002e, 0xb5000008, 0xb0040000, 0xb4200003, + 0x802717ff, 0x81470000, 0xb5000003, 0x80270001, + 0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200001, + 0x8384fc04, 0x80af001f, 0x808f0002, 0x806f0000, + 0x807bbf34, 0x5d22b80a, 0xb600080a, 0x00cfb803, + 0x013fb0bc, 0x5922b809, 0x01afb809, 0x013f90bc, + 0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x90630020, + 0x91290060, 0x808f0000, 0x813bb3f8, 0x80270001, + 0xb0090001, 0xb4000002, 0x802600a0, 0x803eb3f8, + 0x81270c00, 0xb00a0000, 0xb4000001, 0x81270000, + 0x813eb3f0, 0xb0030800, 0xb4800001, 0x80670200, + 0x807ebf34, 0x80270001, 0x003f2013, 0x00ffb81b, + +}; + +static u32 AC3240Ucode1f8000[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00020000, 0xffff0005, 0xffffffff, + 0x00050001, 0xffffffff, 0xffffffff, 0x00020000, + 0xffff0005, 0xffffffff, 0x00010000, 0x00050002, + 0xffffffff, 0x00020000, 0x00050003, 0xffffffff, + 0x00010000, 0x00030002, 0xffff0005, 0x00020000, + 0x00040003, 0xffff0005, 0x00010000, 0x00030002, + 0x00050004, 0x0019000d, 0x003d0025, 0x00250019, + 0x00fd003d, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x007fffff, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x007fffff, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x007fffff, 0x00000000, + 0x00000000, 0x00599999, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00599999, + 0x007fffff, 0x00599999, 0x00000000, 0x00599999, + 0x00000000, 0x00000000, 0x00000000, 0x00599999, + 0x00000000, 0x00599999, 0x007fffff, 0x00000000, + 0x00599999, 0x00599999, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00599999, 0x00599999, + 0x007fffff, 0x007fffff, 0x00000000, 0x00599999, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00599999, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x007fffff, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x007fffff, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x007fffff, 0x00000000, + 0x007fffff, 0x00000000, 0x007fffff, 0x00400000, + 0x00200000, 0x00100000, 0x00080000, 0x00040000, + 0x00020000, 0x00010000, 0x00008000, 0x00004000, + 0x00002000, 0x00001000, 0x00000800, 0x00000400, + 0x00000200, 0x00000100, 0x00000080, 0x00000040, + 0x00000020, 0x00000010, 0x00000008, 0x00000004, + 0x00000002, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00010002, + 0x00030002, 0x00030002, 0x00030002, 0x00000000, + 0x00000000, 0x00010001, 0x00020002, 0x4000a000, + 0xe000a000, 0xf000b000, 0xf800b800, 0x005a8279, + 0x004c1bf8, 0x00400000, 0x004c1bf8, 0x005a8279, + 0x00400000, 0x00000000, 0x00400000, 0x03020100, + 0x00000000, 0x00000080, 0x00000020, 0x00000008, + 0x00000000, 0x00000001, 0x00010001, 0x10081000, + 0x10041000, 0x10081004, 0x10081008, 0x10081008, + 0x00000000, 0x00000000, 0x00000000, 0xff80000a, + 0xff80031f, 0xff800b24, 0xff801818, 0xff8029fa, + 0xff8040c9, 0xff805c86, 0xff807d2e, 0xff80a2c1, + 0xff80cd3c, 0xff80fc9f, 0xff8130e8, 0xff816a14, + 0xff81a821, 0xff81eb0e, 0xff8232d6, 0xff827f79, + 0xff82d0f2, 0xff83273e, 0xff83825b, 0xff83e244, + 0xff8446f7, 0xff84b06e, 0xff851ea6, 0xff85919b, + 0xff860949, 0xff8685aa, 0xff8706ba, 0xff878c74, + 0xff8816d3, 0xff88a5d1, 0xff89396a, 0xff89d196, + 0xff8a6e51, 0xff8b0f94, 0xff8bb55a, 0xff8c5f9b, + 0xff8d0e51, 0xff8dc176, 0xff8e7902, 0xff8f34ef, + 0xff8ff535, 0xff90b9cc, 0xff9182ae, 0xff924fd3, + 0xff932132, 0xff93f6c3, 0xff94d07f, 0xff95ae5d, + 0xff969054, 0xff97765b, 0xff98606a, 0xff994e78, + 0xff9a407c, 0xff9b366b, 0xff9c303e, 0xff9d2de9, + 0xff9e2f64, 0xff9f34a4, 0xffa03da0, 0xffa14a4c, + 0xffa25aa0, 0xffa36e8f, 0xffa48610, 0xffa5a118, + 0xffa6bf9c, 0xffa7e191, 0xffa906ec, 0xffaa2fa0, + 0xffab5ba4, 0xffac8aeb, 0xffadbd6a, 0xffaef315, + 0xffb02bdf, 0xffb167be, 0xffb2a6a4, 0xffb3e886, + 0xffb52d56, 0xffb67509, 0xffb7bf92, 0xffb90ce4, + 0xffba5cf2, 0xffbbafb0, 0xffbd050f, 0xffbe5d04, + 0xffbfb780, 0xffc11477, 0xffc273db, 0xffc3d59f, + 0xffc539b4, 0xffc6a00d, 0xffc8089d, 0xffc97355, + 0xffcae027, 0xffcc4f05, 0xffcdbfe2, 0xffcf32af, + 0xffd0a75d, 0xffd21ddf, 0xffd39625, 0xffd51022, + 0xffd68bc7, 0xffd80904, 0xffd987cd, 0xffdb0810, + 0xffdc89c1, 0xffde0cd0, 0xffdf912d, 0xffe116cb, + 0xffe29d9a, 0xffe4258b, 0xffe5ae8f, 0xffe73896, + 0xffe8c392, 0xffea4f74, 0xffebdc2b, 0xffed69aa, + 0xffeef7df, 0xfff086bd, 0xfff21634, 0xfff3a634, + 0xfff536ad, 0xfff6c792, 0xfff858d1, 0xfff9ea5b, + 0xfffb7c22, 0xfffd0e16, 0xfffea026, 0xffffcdbc, + 0xfffe3ba0, 0xfffca995, 0xfffb17ac, 0xfff985f3, + 0xfff7f479, 0xfff6634f, 0xfff4d284, 0xfff34228, + 0xfff1b249, 0xfff022f7, 0xffee9442, 0xffed0638, + 0xffeb78ea, 0xffe9ec67, 0xffe860bd, 0xffe6d5fd, + 0xffe54c35, 0xffe3c374, 0xffe23bcb, 0xffe0b547, + 0xffdf2ff7, 0xffddabec, 0xffdc2933, 0xffdaa7dd, + 0xffd927f6, 0xffd7a98f, 0xffd62cb7, 0xffd4b17b, + 0xffd337ea, 0xffd1c013, 0xffd04a05, 0xffced5ce, + 0xffcd637c, 0xffcbf31d, 0xffca84c1, 0xffc91874, + 0xffc7ae45, 0xffc64641, 0xffc4e078, 0xffc37cf6, + 0xffc21bc9, 0xffc0bcff, 0xffbf60a5, 0xffbe06c9, + 0xffbcaf79, 0xffbb5ac0, 0xffba08ae, 0xffb8b94d, + 0xffb76cac, 0xffb622d8, 0xffb4dbdc, 0xffb397c6, + 0xffb256a2, 0xffb1187d, 0xffafdd62, 0xffaea55f, + 0xffad707e, 0xffac3ecc, 0xffab1054, 0xffa9e523, + 0xffa8bd44, 0xffa798c2, 0xffa677a8, 0xffa55a02, + 0xffa43fdb, 0xffa3293d, 0xffa21634, 0xffa106c9, + 0xff9ffb08, 0xff9ef2fa, 0xff9deeab, 0xff9cee23, + 0xff9bf16c, 0xff9af892, 0xff9a039c, 0xff991295, + 0xff982586, 0xff973c78, 0xff965774, 0xff957683, + 0xff9499ad, 0xff93c0fb, 0xff92ec75, 0xff921c24, + 0xff91500f, 0xff90883f, 0xff8fc4bb, 0xff8f058b, + 0xff8e4ab6, 0xff8d9443, 0xff8ce239, 0xff8c349f, + 0xff8b8b7d, 0xff8ae6d7, 0xff8a46b5, 0xff89ab1e, + 0xff891416, 0xff8881a3, 0xff87f3cc, 0xff876a96, + 0xff86e606, 0xff866621, 0xff85eaed, 0xff85746d, + 0xff8502a6, 0xff84959e, 0xff842d57, 0xff83c9d7, + 0xff836b20, 0xff831138, 0xff82bc20, 0xff826bdc, + 0xff822070, 0xff81d9de, 0xff819829, 0xff815b54, + 0xff812360, 0xff80f051, 0xff80c228, 0xff8098e6, + 0xff80748e, 0xff805521, 0xff803a9f, 0xff80250b, + 0xff801464, 0xff8008ad, 0xff8001e4, 0xff800027, + 0xff800c7e, 0xff802c8f, 0xff806056, 0xff80a7cb, + 0xff8102e4, 0xff817191, 0xff81f3c3, 0xff828964, + 0xff83325f, 0xff83ee98, 0xff84bdf3, 0xff85a04f, + 0xff86958b, 0xff879d7f, 0xff88b804, 0xff89e4ee, + 0xff8b240e, 0xff8c7533, 0xff8dd82a, 0xff8f4cbb, + 0xff90d2ad, 0xff9269c4, 0xff9411c1, 0xff95ca62, + 0xff979365, 0xff996c81, 0xff9b5570, 0xff9d4de4, + 0xff9f5590, 0xffa16c24, 0xffa3914e, 0xffa5c4b8, + 0xffa8060d, 0xffaa54f3, 0xffacb10e, 0xffaf1a03, + 0xffb18f70, 0xffb410f7, 0xffb69e33, 0xffb936c0, + 0xffbbda37, 0xffbe8830, 0xffc14042, 0xffc40201, + 0xffc6cd00, 0xffc9a0d2, 0xffcc7d05, 0xffcf612b, + 0xffd24ccf, 0xffd53f80, 0xffd838c8, 0xffdb3833, + 0xffde3d49, 0xffe14795, 0xffe4569d, 0xffe769e9, + 0xffea80ff, 0xffed9b67, 0xfff0b8a4, 0xfff3d83c, + 0xfff6f9b5, 0xfffa1c91, 0xfffd4056, 0xffff9b78, + 0xfffc7756, 0xfff953c0, 0xfff63130, 0xfff31025, + 0xffeff117, 0xffecd484, 0xffe9bae5, 0xffe6a4b6, + 0xffe39270, 0xffe0848b, 0xffdd7b82, 0xffda77cb, + 0xffd779de, 0xffd48231, 0xffd19138, 0xffcea769, + 0xffcbc535, 0xffc8eb10, 0xffc61969, 0xffc350af, + 0xffc09151, 0xffbddbbb, 0xffbb3059, 0xffb88f92, + 0xffb5f9d0, 0xffb36f78, 0xffb0f0ef, 0xffae7e96, + 0xffac18cf, 0xffa9bff9, 0xffa7746f, 0xffa5368c, + 0xffa306aa, 0xffa0e51e, 0xff9ed23c, 0xff9cce56, + 0xff9ad9bc, 0xff98f4bc, 0xff971f9f, 0xff955aae, + 0xff93a62f, 0xff920266, 0xff906f92, 0xff8eedf3, + 0xff8d7dc4, 0xff8c1f3c, 0xff8ad294, 0xff8997fd, + 0xff886fa8, 0xff8759c3, 0xff865679, 0xff8565f2, + 0xff848852, 0xff83bdbd, 0xff830651, 0xff82622b, + 0xff81d163, 0xff815411, 0xff80ea47, 0xff809416, + 0xff80518b, 0xff8022b1, 0xff80078e, 0x00000475, + 0x000007fe, 0x00000c02, 0x000010a3, 0x000015f5, + 0x00001c08, 0x000022ed, 0x00002ab5, 0x00003371, + 0x00003d32, 0x0000480a, 0x0000540d, 0x0000614b, + 0x00006fda, 0x00007fcd, 0x00009138, 0x0000a431, + 0x0000b8cc, 0x0000cf1f, 0x0000e741, 0x00010148, + 0x00011d4b, 0x00013b61, 0x00015ba2, 0x00017e25, + 0x0001a302, 0x0001ca51, 0x0001f42c, 0x000220a9, + 0x00024fe2, 0x000281f0, 0x0002b6ea, 0x0002eee9, + 0x00032a07, 0x0003685a, 0x0003a9fc, 0x0003ef04, + 0x0004378a, 0x000483a5, 0x0004d36d, 0x000526f7, + 0x00057e5b, 0x0005d9ae, 0x00063904, 0x00069c74, + 0x00070410, 0x00076feb, 0x0007e01a, 0x000854ac, + 0x0008cdb3, 0x00094b40, 0x0009cd61, 0x000a5425, + 0x000adf98, 0x000b6fc8, 0x000c04bf, 0x000c9e87, + 0x000d3d2a, 0x000de0ae, 0x000e891a, 0x000f3674, + 0x000fe8c0, 0x00109fff, 0x00115c34, 0x00121d5d, + 0x0012e37b, 0x0013ae89, 0x00147e84, 0x00155366, + 0x00162d27, 0x00170bbf, 0x0017ef23, 0x0018d748, + 0x0019c421, 0x001ab59f, 0x001babb2, 0x001ca648, + 0x001da54f, 0x001ea8b0, 0x001fb058, 0x0020bc2d, + 0x0021cc18, 0x0022dffd, 0x0023f7c2, 0x00251348, + 0x00263272, 0x00275520, 0x00287b31, 0x0029a482, + 0x002ad0f1, 0x002c0059, 0x002d3294, 0x002e677c, + 0x002f9ee8, 0x0030d8b1, 0x003214ac, 0x003352b0, + 0x00349290, 0x0035d422, 0x00371738, 0x00385ba5, + 0x0039a13b, 0x003ae7cc, 0x003c2f2a, 0x003d7725, + 0x003ebf8d, 0x00400834, 0x004150e9, 0x0042997d, + 0x0043e1c0, 0x00452981, 0x00467092, 0x0047b6c3, + 0x0048fbe3, 0x004a3fc6, 0x004b823b, 0x004cc316, + 0x004e0228, 0x004f3f45, 0x00507a40, 0x0051b2ef, + 0x0052e925, 0x00541cba, 0x00554d85, 0x00567b5e, + 0x0057a61d, 0x0058cd9e, 0x0059f1bb, 0x005b1252, + 0x005c2f3f, 0x005d4863, 0x005e5d9d, 0x005f6ed0, + 0x00607bde, 0x006184ad, 0x00628923, 0x00638927, + 0x006484a3, 0x00657b81, 0x00666daf, 0x00675b19, + 0x006843b1, 0x00692767, 0x006a062d, 0x006adff9, + 0x006bb4c2, 0x006c847d, 0x006d4f27, 0x006e14b8, + 0x006ed52f, 0x006f9089, 0x007046c6, 0x0070f7e9, + 0x0071a3f3, 0x00724aea, 0x0072ecd3, 0x007389b6, + 0x0074219d, 0x0074b490, 0x0075429b, 0x0075cbcc, + 0x00765031, 0x0076cfd8, 0x00774ad3, 0x0077c132, + 0x00783308, 0x0078a068, 0x00790968, 0x00796e1c, + 0x0079ce9a, 0x007a2af9, 0x007a8350, 0x007ad7b8, + 0x007b2849, 0x007b751d, 0x007bbe4c, 0x007c03f1, + 0x007c4625, 0x007c8504, 0x007cc0a8, 0x007cf92c, + 0x007d2eaa, 0x007d613e, 0x007d9101, 0x007dbe10, + 0x007de883, 0x007e1076, 0x007e3603, 0x007e5943, + 0x007e7a4f, 0x007e9942, 0x007eb633, 0x007ed13a, + 0x007eea6f, 0x007f01ea, 0x007f17c0, 0x007f2c08, + 0x007f3ed7, 0x007f5043, 0x007f605e, 0x007f6f3c, + 0x007f7cf1, 0x007f898e, 0x007f9525, 0x007f9fc6, + 0x007fa982, 0x007fb268, 0x007fba86, 0x007fc1eb, + 0x007fc8a4, 0x007fcebe, 0x007fd443, 0x007fd941, + 0x007fddc2, 0x007fe1cf, 0x007fe572, 0x007fe8b4, + 0x007feb9e, 0x007fee36, 0x007ff086, 0x007ff293, + 0x007ff463, 0x007ff5fd, 0x007ff765, 0x007ff8a1, + 0x007ff9b6, 0x007ffaa7, 0x007ffb79, 0x007ffc2f, + 0x007ffccb, 0x007ffd52, 0x007ffdc6, 0x007ffe28, + 0x007ffe7b, 0x007ffec2, 0x007ffefd, 0x007fff2f, + 0x007fff58, 0x007fff7b, 0x007fff97, 0x007fffae, + 0x007fffc0, 0x007fffcf, 0x007fffdb, 0x007fffe4, + 0x007fffec, 0x007ffff1, 0x007ffff6, 0x007ffff9, + 0x007ffffb, 0x007ffffd, 0x007ffffe, 0x007fffff, + 0x007fffff, 0x007fffff, 0x007fffff, 0xff800000, + 0x00000000, 0xffa57d86, 0x005a827a, 0xff89be51, + 0x0030fbc5, 0xffcf043b, 0x007641af, 0xff8275a1, + 0x0018f8b8, 0xffb8e313, 0x006a6d99, 0xff959267, + 0x00471ced, 0xffe70748, 0x007d8a5f, 0xff809dc9, + 0x000c8bd3, 0xffaecc33, 0x0062f202, 0xff8f1d34, + 0x003c56ba, 0xffdad7f4, 0x007a7d05, 0xff8582fb, + 0x0025280c, 0xffc3a946, 0x0070e2cc, 0xff9d0dfe, + 0x005133cd, 0xfff3742d, 0x007f6237, 0xff802778, + 0x000647d9, 0xffaa0a5b, 0x005ed77d, 0xff8c4a14, + 0x0036ba20, 0xffd4e0cb, 0x00788484, 0xff83d604, + 0x001f19f9, 0xffbe31e2, 0x006dca0d, 0xff99307f, + 0x004c3fe0, 0xffed37f0, 0x007e9d56, 0xff8162aa, + 0x0012c810, 0xffb3c020, 0x0066cf81, 0xff9235f3, + 0x0041ce1e, 0xffe0e607, 0x007c29fc, 0xff877b7c, + 0x002b1f35, 0xffc945e0, 0x0073b5ec, 0xffa12883, + 0x0055f5a5, 0xfff9b827, 0x007fd888, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + +}; + +static u32 AC3240Ucode1fe000[] = { + 0x00000000, 0x03020102, 0x05040403, 0x00400040, + 0x00500050, 0x00600060, 0x00700070, 0x00800080, + 0x00a000a0, 0x00c000c0, 0x00e000e0, 0x01000100, + 0x01400140, 0x01800180, 0x01c001c0, 0x02000200, + 0x02800280, 0x03000300, 0x03800380, 0x04000400, + 0x04800480, 0x05000500, 0x00460045, 0x00580057, + 0x00690068, 0x007a0079, 0x008c008b, 0x00af00ae, + 0x00d100d0, 0x00f400f3, 0x01170116, 0x015d015c, + 0x01a201a1, 0x01e801e7, 0x022e022d, 0x02b902b8, + 0x03440343, 0x03d003cf, 0x045b045a, 0x04e604e5, + 0x05720571, 0x00600060, 0x00780078, 0x00900090, + 0x00a800a8, 0x00c000c0, 0x00f000f0, 0x01200120, + 0x01500150, 0x01800180, 0x01e001e0, 0x02400240, + 0x02a002a0, 0x03000300, 0x03c003c0, 0x04800480, + 0x05400540, 0x06000600, 0x06c006c0, 0x07800780, + 0x7b67533f, 0x1513110f, 0x04d80540, 0x04100478, + 0x07000000, 0x0b000900, 0x02b002f0, 0x02300270, + 0x017001f0, 0xf80000f0, 0x01000080, 0x02000180, + 0x03000280, 0x04000380, 0x2725231f, 0x2c2b2a29, + 0x2e2e2d2d, 0x30302f2f, 0x04030201, 0x08070605, + 0x0c0b0a09, 0x100f0e0d, 0x14131211, 0x18171615, + 0x1c1b1a19, 0x2825221f, 0x37312e2b, 0x4f49433d, + 0x796d6155, 0xcdb59d85, 0x0000fde5, 0x3d3e3f40, + 0x393a3b3c, 0x35363738, 0x32333434, 0x2f2f3031, + 0x2c2c2d2e, 0x29292a2b, 0x26262728, 0x23242425, + 0x21212223, 0x1e1f2020, 0x1c1d1d1e, 0x1a1b1b1c, + 0x1819191a, 0x16171718, 0x15151516, 0x13131414, + 0x12121213, 0x10111111, 0x0f0f1010, 0x0e0e0e0f, + 0x0d0d0d0d, 0x0c0c0c0c, 0x0b0b0b0b, 0x0a0a0a0a, + 0x0909090a, 0x08080909, 0x08080808, 0x07070707, + 0x06060707, 0x06060606, 0x05050606, 0x05050505, + 0x04040505, 0x04040404, 0x04040404, 0x03030304, + 0x03030303, 0x03030303, 0x02030303, 0x02020202, + 0x02020202, 0x02020202, 0x02020202, 0x01010202, + 0x01010101, 0x01010101, 0x01010101, 0x01010101, + 0x01010101, 0x01010101, 0x01010101, 0x00000101, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x04d004d0, + 0x04000440, 0x03c003e0, 0x03b003b0, 0x03a003a0, + 0x03a003a0, 0x039003a0, 0x03900390, 0x03800380, + 0x03700370, 0x03600360, 0x03500350, 0x03400340, + 0x03200330, 0x03000310, 0x02f002f0, 0x02f002f0, + 0x03100300, 0x03900340, 0x042003e0, 0x04900460, + 0x046004a0, 0x04400440, 0x08000520, 0x08400840, + 0x04f004f0, 0x04100460, 0x03d003e0, 0x03b003c0, + 0x03a003b0, 0x03a003a0, 0x03a003a0, 0x03900390, + 0x03800390, 0x03800380, 0x03700370, 0x03600360, + 0x03500350, 0x03400340, 0x03100320, 0x02f00300, + 0x02f002f0, 0x030002f0, 0x03500320, 0x03e00390, + 0x04500420, 0x049004a0, 0x04400460, 0x06300480, + 0x08400840, 0x05800580, 0x045004b0, 0x03f00420, + 0x03d003e0, 0x03b003c0, 0x03b003b0, 0x03a003a0, + 0x03a003a0, 0x03a003a0, 0x03a003a0, 0x03900390, + 0x03900390, 0x03800380, 0x03700380, 0x03500360, + 0x03300340, 0x03100320, 0x02f00300, 0x02f002f0, + 0x03100300, 0x03500330, 0x041003c0, 0x04a00470, + 0x04400460, 0x04e00450, 0xffaaaaab, 0x00000000, + 0x00555555, 0xff99999a, 0xffcccccd, 0x00000000, + 0x00333333, 0x00666666, 0xff924925, 0xffb6db6e, + 0xffdb6db7, 0x00000000, 0x00249249, 0x00492492, + 0x006db6db, 0xff8ba2e9, 0xffa2e8ba, 0xffba2e8c, + 0xffd1745d, 0xffe8ba2f, 0x00000000, 0x001745d1, + 0x002e8ba3, 0x0045d174, 0x005d1746, 0x00745d17, + 0xff888889, 0xff99999a, 0xffaaaaab, 0xffbbbbbc, + 0xffcccccd, 0xffddddde, 0xffeeeeef, 0x00000000, + 0x00111111, 0x00222222, 0x00333333, 0x00444444, + 0x00555555, 0x00666666, 0x00777777, 0x08070605, + 0x0c0b0a09, 0x10100e0e, 0x00000010, 0x00000000, + 0x00000010, 0x00000020, 0x00000100, 0x00000110, + 0x00000120, 0x00000200, 0x00000210, 0x00000220, + 0x00001000, 0x00001010, 0x00001020, 0x00001100, + 0x00001110, 0x00001120, 0x00001200, 0x00001210, + 0x00001220, 0x00002000, 0x00002010, 0x00002020, + 0x00002100, 0x00002110, 0x00002120, 0x00002200, + 0x00002210, 0x00002220, 0x00000000, 0x00000010, + 0x00000020, 0x00000030, 0x00000040, 0x00000100, + 0x00000110, 0x00000120, 0x00000130, 0x00000140, + 0x00000200, 0x00000210, 0x00000220, 0x00000230, + 0x00000240, 0x00000300, 0x00000310, 0x00000320, + 0x00000330, 0x00000340, 0x00000400, 0x00000410, + 0x00000420, 0x00000430, 0x00000440, 0x00001000, + 0x00001010, 0x00001020, 0x00001030, 0x00001040, + 0x00001100, 0x00001110, 0x00001120, 0x00001130, + 0x00001140, 0x00001200, 0x00001210, 0x00001220, + 0x00001230, 0x00001240, 0x00001300, 0x00001310, + 0x00001320, 0x00001330, 0x00001340, 0x00001400, + 0x00001410, 0x00001420, 0x00001430, 0x00001440, + 0x00002000, 0x00002010, 0x00002020, 0x00002030, + 0x00002040, 0x00002100, 0x00002110, 0x00002120, + 0x00002130, 0x00002140, 0x00002200, 0x00002210, + 0x00002220, 0x00002230, 0x00002240, 0x00002300, + 0x00002310, 0x00002320, 0x00002330, 0x00002340, + 0x00002400, 0x00002410, 0x00002420, 0x00002430, + 0x00002440, 0x00003000, 0x00003010, 0x00003020, + 0x00003030, 0x00003040, 0x00003100, 0x00003110, + 0x00003120, 0x00003130, 0x00003140, 0x00003200, + 0x00003210, 0x00003220, 0x00003230, 0x00003240, + 0x00003300, 0x00003310, 0x00003320, 0x00003330, + 0x00003340, 0x00003400, 0x00003410, 0x00003420, + 0x00003430, 0x00003440, 0x00004000, 0x00004010, + 0x00004020, 0x00004030, 0x00004040, 0x00004100, + 0x00004110, 0x00004120, 0x00004130, 0x00004140, + 0x00004200, 0x00004210, 0x00004220, 0x00004230, + 0x00004240, 0x00004300, 0x00004310, 0x00004320, + 0x00004330, 0x00004340, 0x00004400, 0x00004410, + 0x00004420, 0x00004430, 0x00004440, 0x00000000, + 0x00000100, 0x00000200, 0x00000300, 0x00000400, + 0x00000500, 0x00000600, 0x00000700, 0x00000800, + 0x00000900, 0x00000a00, 0x00001000, 0x00001100, + 0x00001200, 0x00001300, 0x00001400, 0x00001500, + 0x00001600, 0x00001700, 0x00001800, 0x00001900, + 0x00001a00, 0x00002000, 0x00002100, 0x00002200, + 0x00002300, 0x00002400, 0x00002500, 0x00002600, + 0x00002700, 0x00002800, 0x00002900, 0x00002a00, + 0x00003000, 0x00003100, 0x00003200, 0x00003300, + 0x00003400, 0x00003500, 0x00003600, 0x00003700, + 0x00003800, 0x00003900, 0x00003a00, 0x00004000, + 0x00004100, 0x00004200, 0x00004300, 0x00004400, + 0x00004500, 0x00004600, 0x00004700, 0x00004800, + 0x00004900, 0x00004a00, 0x00005000, 0x00005100, + 0x00005200, 0x00005300, 0x00005400, 0x00005500, + 0x00005600, 0x00005700, 0x00005800, 0x00005900, + 0x00005a00, 0x00006000, 0x00006100, 0x00006200, + 0x00006300, 0x00006400, 0x00006500, 0x00006600, + 0x00006700, 0x00006800, 0x00006900, 0x00006a00, + 0x00007000, 0x00007100, 0x00007200, 0x00007300, + 0x00007400, 0x00007500, 0x00007600, 0x00007700, + 0x00007800, 0x00007900, 0x00007a00, 0x00008000, + 0x00008100, 0x00008200, 0x00008300, 0x00008400, + 0x00008500, 0x00008600, 0x00008700, 0x00008800, + 0x00008900, 0x00008a00, 0x00009000, 0x00009100, + 0x00009200, 0x00009300, 0x00009400, 0x00009500, + 0x00009600, 0x00009700, 0x00009800, 0x00009900, + 0x00009a00, 0x0000a000, 0x0000a100, 0x0000a200, + 0x0000a300, 0x0000a400, 0x0000a500, 0x0000a600, + 0x0000a700, 0x0000a800, 0x0000a900, 0x0000aa00, + 0xff800000, 0xff800000, 0xffb82995, 0xffaf5d75, + 0xffa57d87, 0xff9a6806, 0xff8df708, 0xff800000, + 0xffb82995, 0xffaf5d75, 0xffa57d87, 0xff9a6806, + 0xff8df708, 0xff800000, 0xffb82995, 0xffaf5d75, + 0xffa57d87, 0xff9a6806, 0xff8df708, 0xff800000, + 0xffb82995, 0xffaf5d75, 0xffa57d87, 0xff9a6806, + 0xff8df708, 0xff800000, 0xffb82995, 0xffaf5d75, + 0xffa57d87, 0xff9a6806, 0xff8df708, 0xff800000, + 0xfffb0000, 0xfffcfffc, 0xfffcfffc, 0xfffcfffc, + 0xfffdfffd, 0xfffdfffd, 0xfffdfffd, 0xfffefffe, + 0xfffefffe, 0xfffefffe, 0xffffffff, 0xffffffff, + 0xffffffff, 0x00000000, 0x00000000, 0x00000000, + 0x80050000, 0x000a800f, 0x001e801b, 0x80110014, + 0x00368033, 0x8039003c, 0x802d0028, 0x00228027, + 0x00668063, 0x8069006c, 0x807d0078, 0x00728077, + 0x80550050, 0x005a805f, 0x004e804b, 0x80410044, + 0x00c680c3, 0x80c900cc, 0x80dd00d8, 0x00d280d7, + 0x80f500f0, 0x00fa80ff, 0x00ee80eb, 0x80e100e4, + 0x80a500a0, 0x00aa80af, 0x00be80bb, 0x80b100b4, + 0x00968093, 0x8099009c, 0x808d0088, 0x00828087, + 0x01868183, 0x8189018c, 0x819d0198, 0x01928197, + 0x81b501b0, 0x01ba81bf, 0x01ae81ab, 0x81a101a4, + 0x81e501e0, 0x01ea81ef, 0x01fe81fb, 0x81f101f4, + 0x01d681d3, 0x81d901dc, 0x81cd01c8, 0x01c281c7, + 0x81450140, 0x014a814f, 0x015e815b, 0x81510154, + 0x01768173, 0x8179017c, 0x816d0168, 0x01628167, + 0x01268123, 0x8129012c, 0x813d0138, 0x01328137, + 0x81150110, 0x011a811f, 0x010e810b, 0x81010104, + 0x03068303, 0x8309030c, 0x831d0318, 0x03128317, + 0x83350330, 0x033a833f, 0x032e832b, 0x83210324, + 0x83650360, 0x036a836f, 0x037e837b, 0x83710374, + 0x03568353, 0x8359035c, 0x834d0348, 0x03428347, + 0x83c503c0, 0x03ca83cf, 0x03de83db, 0x83d103d4, + 0x03f683f3, 0x83f903fc, 0x83ed03e8, 0x03e283e7, + 0x03a683a3, 0x83a903ac, 0x83bd03b8, 0x03b283b7, + 0x83950390, 0x039a839f, 0x038e838b, 0x83810384, + 0x82850280, 0x028a828f, 0x029e829b, 0x82910294, + 0x02b682b3, 0x82b902bc, 0x82ad02a8, 0x02a282a7, + 0x02e682e3, 0x82e902ec, 0x82fd02f8, 0x02f282f7, + 0x82d502d0, 0x02da82df, 0x02ce82cb, 0x82c102c4, + 0x02468243, 0x8249024c, 0x825d0258, 0x02528257, + 0x82750270, 0x027a827f, 0x026e826b, 0x82610264, + 0x82250220, 0x022a822f, 0x023e823b, 0x82310234, + 0x02168213, 0x8219021c, 0x820d0208, 0x02028207, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x00000002, 0x00000002, + 0x00000000, 0xff800000, 0xffa57d86, 0xffa57d86, + 0xffcf043b, 0xff89be51, 0xff89be51, 0xffcf043b, + 0xffe70748, 0xff8275a1, 0xff959267, 0xffb8e313, + 0xffb8e313, 0xff959267, 0xff8275a1, 0xffe70748, + 0xfff3742d, 0xff809dc9, 0xff9d0dfe, 0xffaecc33, + 0xffc3a946, 0xff8f1d34, 0xff8582fb, 0xffdad7f4, + 0xffdad7f4, 0xff8582fb, 0xff8f1d34, 0xffc3a946, + 0xffaecc33, 0xff9d0dfe, 0xff809dc9, 0xfff3742d, + 0xfff9b827, 0xff802778, 0xffa12883, 0xffaa0a5b, + 0xffc945e0, 0xff8c4a14, 0xff877b7c, 0xffd4e0cb, + 0xffe0e607, 0xff83d604, 0xff9235f3, 0xffbe31e2, + 0xffb3c020, 0xff99307f, 0xff8162aa, 0xffed37f0, + 0xffed37f0, 0xff8162aa, 0xff99307f, 0xffb3c020, + 0xffbe31e2, 0xff9235f3, 0xff83d604, 0xffe0e607, + 0xffd4e0cb, 0xff877b7c, 0xff8c4a14, 0xffc945e0, + 0xffaa0a5b, 0xffa12883, 0xff802778, 0xfff9b827, + 0xcbcecdc4, 0xcfcac9c8, 0xc3c6c5cc, 0xc7c2c1c0, + 0x1b1e1d14, 0x1f1a1918, 0x1316151c, 0x17121110, + 0x2b2e2d24, 0x2f2a2928, 0x2326252c, 0x27222120, + 0x3b3e3d34, 0x3f3a3938, 0x3336353c, 0x37323130, + 0x0b0e0d04, 0x0f0a0908, 0x0306050c, 0x07020100, + 0xdbdeddd4, 0xdfdad9d8, 0xd3d6d5dc, 0xd7d2d1d0, + 0xebeeede4, 0xefeae9e8, 0xe3e6e5ec, 0xe7e2e1e0, + 0xfbfefdf4, 0xfffaf9f8, 0xf3f6f5fc, 0xf7f2f1f0, + 0x4b4e4d44, 0x4f4a4948, 0x4346454c, 0x47424140, + 0x9b9e9d94, 0x9f9a9998, 0x9396959c, 0x97929190, + 0xabaeada4, 0xafaaa9a8, 0xa3a6a5ac, 0xa7a2a1a0, + 0xbbbebdb4, 0xbfbab9b8, 0xb3b6b5bc, 0xb7b2b1b0, + 0x8b8e8d84, 0x8f8a8988, 0x8386858c, 0x87828180, + 0x5b5e5d54, 0x5f5a5958, 0x5356555c, 0x57525150, + 0x6b6e6d64, 0x6f6a6968, 0x6366656c, 0x67626160, + 0x7b7e7d74, 0x7f7a7978, 0x7376757c, 0x77727170, + 0x341424c4, 0x3e1e2ece, 0x3d1d2dcd, 0x3b1b2bcb, + 0xb494a444, 0xbe9eae4e, 0xbd9dad4d, 0xbb9bab4b, + 0xf4d4e404, 0xfedeee0e, 0xfddded0d, 0xfbdbeb0b, + 0x74546484, 0x7e5e6e8e, 0x7d5d6d8d, 0x7b5b6b8b, + 0x3c1c2ccc, 0x361626c6, 0x351525c5, 0x331323c3, + 0xbc9cac4c, 0xb696a646, 0xb595a545, 0xb393a343, + 0xfcdcec0c, 0xf6d6e606, 0xf5d5e505, 0xf3d3e303, + 0x7c5c6c8c, 0x76566686, 0x75556585, 0x73536383, + 0x381828c8, 0x3a1a2aca, 0x391929c9, 0x3f1f2fcf, + 0xb898a848, 0xba9aaa4a, 0xb999a949, 0xbf9faf4f, + 0xf8d8e808, 0xfadaea0a, 0xf9d9e909, 0xffdfef0f, + 0x78586888, 0x7a5a6a8a, 0x79596989, 0x7f5f6f8f, + 0x301020c0, 0x321222c2, 0x311121c1, 0x371727c7, + 0xb090a040, 0xb292a242, 0xb191a141, 0xb797a747, + 0xf0d0e000, 0xf2d2e202, 0xf1d1e101, 0xf7d7e707, + 0x70506080, 0x72526282, 0x71516181, 0x77576787, + 0x05040100, 0x15141110, 0x25242120, 0x35343130, + 0x85848180, 0x95949190, 0xa5a4a1a0, 0xb5b4b1b0, + 0xc0408000, 0xe060a020, 0xd0509010, 0xf070b030, + 0xc8488808, 0xe868a828, 0xd8589818, 0xf878b838, + 0xc4448404, 0xe464a424, 0xd4549414, 0xf474b434, + 0xcc4c8c0c, 0xec6cac2c, 0xdc5c9c1c, 0xfc7cbc3c, + 0xc2428202, 0xe262a222, 0xd2529212, 0xf272b232, + 0xca4a8a0a, 0xea6aaa2a, 0xda5a9a1a, 0xfa7aba3a, + 0xc6468606, 0xe666a626, 0xd6569616, 0xf676b636, + 0xce4e8e0e, 0xee6eae2e, 0xde5e9e1e, 0xfe7ebe3e, + 0xc1418101, 0xe161a121, 0xd1519111, 0xf171b131, + 0xc9498909, 0xe969a929, 0xd9599919, 0xf979b939, + 0xc5458505, 0xe565a525, 0xd5559515, 0xf575b535, + 0xcd4d8d0d, 0xed6dad2d, 0xdd5d9d1d, 0xfd7dbd3d, + 0xc3438303, 0xe363a323, 0xd3539313, 0xf373b333, + 0xcb4b8b0b, 0xeb6bab2b, 0xdb5b9b1b, 0xfb7bbb3b, + 0xc7478707, 0xe767a727, 0xd7579717, 0xf777b737, + 0xcf4f8f0f, 0xef6faf2f, 0xdf5f9f1f, 0xff7fbf3f, + 0x1045a3e2, 0x000000f4, 0x263b7333, 0x766b2363, + 0x2b367e3e, 0x7b662e6e, 0x06db93d3, 0x964b0343, + 0x0bd69ede, 0x9b460e4e, 0x825f1757, 0x12cf87c7, + 0x8f521a5a, 0x1fc28aca, 0x00d199d9, 0x90410949, + 0x01d098d8, 0x91400848, 0x24357d3d, 0x74652d6d, + 0x25347c3c, 0x75642c6c, 0x04d59ddd, 0x94450d4d, + 0x05d49cdc, 0x95440c4c, 0x80511959, 0x10c189c9, + 0x81501858, 0x11c088c8, 0x02df97d7, 0x924f0747, + 0x0fd29ada, 0x9f420a4a, 0x865b1353, 0x16cb83c3, + 0x8b561e5e, 0x1bc68ece, 0xa6bbf3b3, 0xf6eba3e3, + 0xabb6febe, 0xfbe6aeee, 0x223f7737, 0x726f2767, + 0x2f327a3a, 0x7f622a6a, 0xa0b1f9b9, 0xf0e1a9e9, + 0xa1b0f8b8, 0xf1e0a8e8, 0x84551d5d, 0x14c58dcd, + 0x85541c5c, 0x15c48ccc, 0xa4b5fdbd, 0xf4e5aded, + 0xa5b4fcbc, 0xf5e4acec, 0x20317939, 0x70612969, + 0x21307838, 0x71602868, 0xa2bff7b7, 0xf2efa7e7, + 0xafb2faba, 0xffe2aaea, 0x00000000, 0x00000000, + +}; + +static u32 AC3240Ucode1fff80[] = { + 0x0000240f, 0x007fffff, 0x007fffff, 0x00000003, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + +}; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/ac3i2s.h linux.19pre5-ac1/drivers/media/video/ls220/ac3i2s.h --- linux.19p5/drivers/media/video/ls220/ac3i2s.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/ls220/ac3i2s.h Thu Feb 21 20:41:21 2002 @@ -0,0 +1,2850 @@ +static u32 AC3I2SUcode1f1800[] = { + 0xb500000f, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xb500122b, 0x00000000, 0x00000000, 0x00000000, + 0x820f001f, 0x802f001f, 0x80070800, 0x001f6193, + 0x800500d4, 0x8053ffff, 0x9842c7ff, 0x8039ff7c, + 0x1400b802, 0x003f6000, 0x94210007, 0xb0010001, + 0xb4200001, 0x98002800, 0xb0010000, 0xb4200001, + 0x98000800, 0x805300ff, 0x1800b802, 0x800600d4, + 0x8013001f, 0x9020c000, 0x003fb006, 0x803effe0, + 0x803effe8, 0x803effec, 0x9020e000, 0x9021ffe4, + 0x9020fa00, 0x803effd0, 0x803effdc, 0x803effd8, + 0x9020fe00, 0x803effd4, 0x90400000, 0x804600a2, + 0x90421800, 0x804600a3, 0x80134099, 0x98000040, + 0x800600a6, 0x80130000, 0x98003ca1, 0x800600a1, + 0x80050080, 0x98000002, 0x80060080, 0x80070001, + 0x001f2013, 0x001f2324, 0x80070000, 0x001fb0ba, + 0x001f23f9, 0x801eb3f0, 0x80070800, 0x001f600f, + 0x80070000, 0x001f2012, 0x001fb0cb, 0x001fb010, + 0x801efff0, 0x98004000, 0x98008000, 0x001f600e, + 0x83e4013f, 0x80070000, 0x801eb3f8, 0x801eff70, + 0x800500a0, 0xb0000001, 0xb4000009, 0x80070001, + 0x800600a0, 0x80050080, 0x98000020, 0x80060080, + 0x9400ffdf, 0x80060080, 0x80070000, 0x800600a0, + 0x81df0004, 0x00000000, 0x00000000, 0x801bfff0, + 0x00000000, 0x940000ff, 0xb0000000, 0xb420004e, + 0x003f400e, 0x94010010, 0xb0000000, 0xb400fff4, + 0x838413dd, 0x003f0013, 0xb0010001, 0xb420003b, + 0x803bffe8, 0x801bffec, 0x00000000, 0x3001b800, + 0xb4600001, 0x90212000, 0x0421b800, 0x005f4193, + 0x5841b802, 0x3001b802, 0xb460000d, 0x80050086, + 0x005f9016, 0xb0020000, 0xb4200002, 0x001fb016, + 0xb500ffdf, 0x0420b802, 0xb0010b50, 0xb4a0ffdc, + 0x80070000, 0x001fb016, 0x83e40109, 0xb500ffd8, + 0x80070000, 0x001fb016, 0x001f400e, 0x9400000f, + 0xb0000000, 0xb4000014, 0xb0000001, 0xb4000010, + 0x003f400e, 0x9421fff0, 0x003f600e, 0x003f9006, + 0x9421ffff, 0x90210004, 0xb001e000, 0xb4800002, + 0x8421e000, 0x9021c000, 0x8013001f, 0x1021b800, + 0x003fb006, 0x003f90cb, 0x90210004, 0x003fb0cb, + 0x83e400ff, 0x83e413bc, 0x8007001f, 0x94000003, + 0x5810b800, 0x83e71aa8, 0x1bffb800, 0x003f9008, + 0x1821b800, 0x00ffb801, 0x83e4140f, 0x80270000, + 0x003f2013, 0x8007001f, 0x94000003, 0x5810b800, + 0x83671ad4, 0x1b7bb800, 0x003f9009, 0x1821b800, + 0x00ffb801, 0xb500ffaa, 0x803bffc0, 0x805bffc4, + 0x807bffc8, 0x809bffcc, 0x5828b801, 0x5cb8b802, + 0x1821b805, 0x5848b802, 0x5cb8b803, 0x1842b805, + 0x5868b803, 0x5cb8b804, 0x1863b805, 0x5888b804, + 0x1884b800, 0x803effc0, 0x805effc4, 0x807effc8, + 0x809effcc, 0x003f400e, 0xb0000086, 0xb4400048, + 0xb0000084, 0xb4000032, 0xb0000085, 0xb4000038, + 0xb0000086, 0xb400003a, 0x001f4000, 0x94000080, + 0xb0000080, 0xb4000072, 0x800500d4, 0x8053ffff, + 0x9842c7ff, 0x1400b802, 0x805300ff, 0x98422800, + 0x1800b802, 0x800600d4, 0x80130000, 0x98000c7f, + 0x005f4000, 0x94420008, 0xb0020008, 0xb4200001, + 0xa0000080, 0x800600a1, 0x8013001f, 0x9040c000, + 0x005fb006, 0x805effe0, 0x805effe8, 0x805effec, + 0x9040e000, 0x805effe4, 0x9040fa00, 0x805effd0, + 0x805effdc, 0x805effd8, 0x9040fe00, 0x805effd4, + 0x80070001, 0x001f2013, 0x80070000, 0x001fb0cb, + 0x001fb010, 0x001f2058, 0x80071fe0, 0x001fb008, + 0x80075fb0, 0x001fb009, 0x98214000, 0xb5000010, + 0x94011000, 0xb0001000, 0xb4200001, 0x9421efff, + 0x98210010, 0xb500000a, 0x80070000, 0x001fb0cb, + 0x83e40097, 0x003f400e, 0x9421ffef, 0xb5000004, + 0x83e40093, 0x003f400e, 0x98211000, 0x9421ffef, + 0x003f600e, 0x80070100, 0x801efff0, 0xb500ff4c, + 0xb000008b, 0xb400001c, 0xb000008e, 0xb4000022, + 0xb000008d, 0xb400001c, 0xb000008c, 0xb4000021, + 0xb0000087, 0xb400ffe8, 0xb0000088, 0xb4000014, + 0xb000008a, 0xb4000015, 0xb0000089, 0xb400001d, + 0xb00000a0, 0xb400001f, 0xb00000a1, 0xb4000041, + 0xb00000a2, 0xb400004e, 0xb00000a3, 0xb4000046, + 0xb00000a4, 0xb4000050, 0xb00000a5, 0xb4000054, + 0xb00000a6, 0xb4000058, 0x803efff8, 0xb500ffdd, + 0x9421ffdf, 0xb500ffda, 0xb500ffda, 0x80270100, + 0x803efff8, 0xb500ffd7, 0x80070000, 0x001fb017, + 0xb500ffd4, 0x801bffb0, 0x00000000, 0x001fb003, + 0xb500ffd0, 0x803bff80, 0x00000000, 0x003f6001, + 0xb500ffcc, 0x003f90ba, 0x803efff8, 0xb500ffc9, + 0x80130001, 0x98003da1, 0x800600a1, 0x80070200, + 0x801ebf34, 0x83e40042, 0x8013001f, 0x9840c000, + 0x805effe0, 0x005fb006, 0x805effe8, 0x805effec, + 0x90422000, 0x805effe4, 0x9040fa00, 0x805effd0, + 0x805effdc, 0x805effd8, 0x9040fe00, 0x805effd4, + 0x80070001, 0x001f2013, 0x80070000, 0x001f2324, + 0x001fb0cb, 0x001fb010, 0x001f2058, 0x80077580, + 0x001fb008, 0x80077830, 0x001fb009, 0x98214000, + 0xb500ffa7, 0x80270000, 0x8047fef0, 0x003eb802, + 0x90420004, 0x003eb802, 0x90420004, 0x003eb802, + 0x90420004, 0x003eb802, 0x81df0000, 0x00000000, + 0x00000000, 0x83641491, 0x81df0004, 0xb500ff99, + 0x81df0000, 0x00000000, 0x00000000, 0x8364143b, + 0x81df0004, 0xb500ff93, 0x81df0000, 0x00000000, + 0x00000000, 0x836413f6, 0x81df0004, 0xb500ff8d, + 0x81df0000, 0x00000000, 0x00000000, 0x83441359, + 0x81df0004, 0xb500ff87, 0x81df0000, 0x00000000, + 0x00000000, 0x8344133e, 0x81df0004, 0xb500ff81, + 0x80070000, 0x80470000, 0x81df0000, 0x00000000, + 0x00000000, 0xb6002003, 0xb6003002, 0x001eb802, + 0x90420004, 0x80171000, 0x8057ffff, 0xb6002002, + 0xb6001801, 0x001fa020, 0x81df0004, 0x00ffb81f, + 0x001f4000, 0x94000080, 0xb0000080, 0xb4200001, + 0xb500ffeb, 0xb500000a, 0x80270000, 0x003f2013, + 0x8007001f, 0x94000003, 0x5810b800, 0x83671ec0, + 0x1b7bb800, 0x003f9009, 0x1821b800, 0x00ffb801, + 0x003f0013, 0xb0010001, 0xb420fff3, 0x83a70000, + 0x803bff70, 0x00000000, 0xb0010000, 0xb4000015, + 0x80170300, 0x80070000, 0x81df0000, 0x00000000, + 0x00000000, 0xb6000601, 0x001fa020, 0x83640cdb, + 0x00ff0325, 0x82870000, 0xb6270002, 0x83640228, + 0x92940001, 0x81df0004, 0x001f033b, 0xb0000000, + 0xb4000002, 0x80270000, 0xb5000001, 0x80270001, + 0x003f233b, 0x80270000, 0x003f2013, 0x8007001f, + 0x94000003, 0x5810b800, 0x83671f5c, 0x1b7bb800, + 0x003f9009, 0x1821b800, 0x00ffb801, 0x003f0013, + 0xb0010001, 0xb420fff3, 0x93bd0001, 0xb01d0004, + 0xb480ffd7, 0x803bff70, 0x00000000, 0xb0010000, + 0xb4000005, 0x81df0000, 0x00000000, 0x00000000, + 0x83640c83, 0x81df0004, 0x00000000, 0x00000000, + 0x00ffb81f, 0x007f90cb, 0x90630400, 0x007fb0cb, + 0x003f9006, 0x9421ffff, 0x90210400, 0xb001e000, + 0xb4800002, 0x8421e000, 0x9021c000, 0x8013001f, + 0x1021b800, 0x003fb006, 0x803effec, 0x00ffb81f, + 0x015f400e, 0x944a4000, 0xb0024000, 0xb4200090, + 0x954abfff, 0x015f600e, 0x820f001f, 0x802f001f, + 0x81470000, 0x015f23f9, 0x829702ec, 0x82d7ffff, + 0x82f70000, 0x81df0000, 0x00000000, 0x00000000, + 0xb6000501, 0x029fa02a, 0x82970400, 0xb6000702, + 0xb6000001, 0x029fa02a, 0x81df0004, 0x8053ff00, + 0x98420000, 0x805ebf14, 0x805ebf18, 0x805ebf1c, + 0x805ebf20, 0x805ebf24, 0x805ebf28, 0x80270000, + 0x003f2328, 0x80275480, 0x005fb801, 0x8033001f, + 0x9821c000, 0x803effe0, 0x90212000, 0x803effe4, + 0x80dbff8c, 0x80fbff90, 0x80debf14, 0x80febf18, + 0x80dbff94, 0x80fbff98, 0x80debf1c, 0x80febf20, + 0x80dbff9c, 0x80fbffa0, 0x80debf24, 0x80febf28, + 0x80dbff84, 0x80e70001, 0x00dfb001, 0x80dbff88, + 0x00ff6191, 0x00dfb002, 0x80dbffb0, 0x80470000, + 0x00dfb003, 0x80d9ff80, 0x005fb0cf, 0x005fb0c6, + 0x00df6001, 0x80470001, 0x005f618f, 0x804700ff, + 0x005f231c, 0x005f231d, 0x80470000, 0x005f204e, + 0x8047e138, 0x5c42b802, 0x814f6300, 0x80cf00a9, + 0x005fb0bc, 0x5842b802, 0x01cfb802, 0x005f90bc, + 0xb520ffff, 0x8067e16c, 0x5c62b803, 0x80270040, + 0x81df0000, 0x00000000, 0x00000000, 0xb6000209, + 0x814fffc0, 0x00cfb801, 0x007fb0bc, 0x5862b803, + 0x01cfb803, 0x007f90bc, 0xb520ffff, 0x90210020, + 0x90630020, 0x81df0004, 0x8047e398, 0x5c42b802, + 0x814fce40, 0x80cf0080, 0x005fb0bc, 0x5842b802, + 0x01cfb802, 0x005f90bc, 0xb520ffff, 0x8047e400, + 0x5c42b802, 0x814f7380, 0x80cf009a, 0x005fb0bc, + 0x5842b802, 0x01cfb802, 0x005f90bc, 0xb520ffff, + 0x8047e43c, 0x5c42b802, 0x814f18c0, 0x80cf00b6, + 0x005fb0bc, 0x5842b802, 0x01cfb802, 0x005f90bc, + 0xb520ffff, 0x80e70000, 0x00ffb0ba, 0x808f0000, + 0x806f001f, 0x80af001f, 0x8027b9fc, 0x5c22b801, + 0x80670700, 0x81df0000, 0x00000000, 0x00000000, + 0xb600080a, 0x00cfb803, 0x003fb0bc, 0x5822b801, + 0x01cfb801, 0x003f90bc, 0x0047b86f, 0xb0020001, + 0xb4c0fffd, 0x90210020, 0x90630020, 0x81df0004, + 0x834400d7, 0xb0180000, 0xb4200025, 0x834406d4, + 0x80c70000, 0x00df2324, 0x83640026, 0x83440220, + 0x00df0324, 0x90c60001, 0x00df2324, 0xb0060006, + 0xb4000003, 0x81472248, 0x015fb008, 0x00ffb81f, + 0x00ff90ba, 0x90e70001, 0x00ffb0ba, 0x019f9006, + 0x958cffff, 0x00df4193, 0x58c1b806, 0x118cb806, + 0xb00ce000, 0xb4800002, 0x858ce000, 0x918cc000, + 0x8153001f, 0x118cb80a, 0x819effec, 0x019fb006, + 0x015f4193, 0x5941b80a, 0x019f90cb, 0x118cb80a, + 0x019fb0cb, 0x81472230, 0x015fb008, 0x00ffb81f, + 0x015f400e, 0x194ab818, 0x015f600e, 0x802500a5, + 0x00ffb81f, 0x803bff8c, 0x805bff90, 0x803ebf14, + 0x805ebf18, 0x803bff94, 0x805bff98, 0x803ebf1c, + 0x805ebf20, 0x803bff9c, 0x805bffa0, 0x803ebf24, + 0x805ebf28, 0x80470003, 0x805ebefc, 0x003f0384, + 0x5822b801, 0x9021eb50, 0x005bb801, 0x00000000, + 0xb0020001, 0xb4200002, 0x80470001, 0x805ebefc, + 0x8073ff80, 0x98630000, 0x8027bf14, 0x8047befc, + 0x81df0000, 0x00000000, 0x00000000, 0xb6000609, + 0x009bb801, 0x00000000, 0x00a7b804, 0x6081b804, + 0x3004b803, 0xb4000001, 0x00beb802, 0x90210004, + 0x90420004, 0x81df0004, 0x00ffb81b, 0x00000000, + 0x81150010, 0x00000000, 0x00000000, 0x81350010, + 0x00000000, 0x00000000, 0x81550002, 0x00000000, + 0x015f2380, 0x81550006, 0x00000000, 0x015f2381, + 0x81550005, 0x00000000, 0x015f2382, 0x81550003, + 0x00000000, 0x015f2383, 0x81550003, 0x015f2384, + 0xb00a0001, 0xb4000005, 0x956a0001, 0xb00b0000, + 0xb4000002, 0x81750002, 0x017f2385, 0x956a0004, + 0xb00b0000, 0xb4000002, 0x81750002, 0x017f2386, + 0xb00a0002, 0xb4200003, 0x81750002, 0x00000000, + 0x017f2387, 0x81750001, 0x00000000, 0x017f2388, + 0x81750005, 0x00000000, 0x017f2389, 0x81750001, + 0x017f239f, 0xb00b0001, 0xb4200003, 0x81750008, + 0x5968b80b, 0x017f61c5, 0x81750001, 0x017f238c, + 0xb00b0001, 0xb4200003, 0x81750008, 0x00000000, + 0x017f238d, 0x81750001, 0x017f238e, 0xb00b0001, + 0xb4200005, 0x81750005, 0x00000000, 0x017f238f, + 0x81750002, 0x017f2390, 0xb00a0000, 0xb420001b, + 0x81750005, 0x00000000, 0x017f2391, 0x81750001, + 0x017f23a0, 0xb00b0001, 0xb4200003, 0x81750008, + 0x5968b80b, 0x017f61c9, 0x81750001, 0x017f2394, + 0xb00b0001, 0xb4200003, 0x81750008, 0x00000000, + 0x017f2395, 0x81750001, 0x017f2396, 0xb00b0001, + 0xb4200006, 0x81750005, 0x00000000, 0x017f2397, + 0x81750002, 0x00000000, 0x017f2398, 0x81750001, + 0x00000000, 0x017f2399, 0x81750001, 0x00000000, + 0x017f239a, 0x81750001, 0x017f239b, 0xb00b0001, + 0xb4200003, 0x8175000e, 0x00000000, 0x017f61be, + 0x81750001, 0x017f239c, 0xb00b0001, 0xb4200003, + 0x8175000e, 0x00000000, 0x017f237e, 0x81750001, + 0x017f239d, 0xb00b0001, 0xb4200006, 0x81750006, + 0x017f239e, 0x916b0001, 0x81550008, 0x856b0001, + 0xb4e0fffd, 0x00ffb81c, 0x00000000, 0x00000000, + 0x81470000, 0x015f2385, 0x015f2386, 0x015f2387, + 0x015f238d, 0x015f238f, 0x015f2390, 0x015f2391, + 0x015f2395, 0x015f2396, 0x015f2397, 0x015f2398, + 0x015f61be, 0x015f61bf, 0x82070028, 0x023f9006, + 0x83a40034, 0x83270000, 0x003fb819, 0x003f9006, + 0x5823b801, 0x83338000, 0x1b39b801, 0x003fb819, + 0x00000000, 0x00000000, 0x81550000, 0x8384ff64, + 0x017f0380, 0xad4b0026, 0x013f0381, 0x114ab809, + 0x5941b80a, 0x914ae00c, 0x0199b80a, 0x00000000, + 0x019f6193, 0xb0080b77, 0xb4200010, 0x015f0380, + 0xb00a0003, 0xb4600011, 0xb0090026, 0xb4600013, + 0x017f90ba, 0xb00b0000, 0xb4200002, 0x017f0383, + 0x017f2057, 0x015f0383, 0x017f0057, 0x300ab80b, + 0xb420000e, 0x83070000, 0x00ffb81a, 0x83070800, + 0x031f6193, 0x83070001, 0x00ffb81a, 0x83070800, + 0x031f6193, 0x83070002, 0x00ffb81a, 0x83070800, + 0x031f6193, 0x83070003, 0x00ffb81a, 0x83070003, + 0x00ffb81a, 0x5e02b810, 0x5a02b810, 0x00bf9011, + 0x00df004f, 0xa5260020, 0x81e70000, 0x82471000, + 0x95d1ffff, 0xa5cee000, 0x300eb810, 0xb4600002, + 0x05f0b80e, 0x0207b80e, 0x8267001f, 0x82c70020, + 0x82971000, 0xb0100080, 0xb4800023, 0x5a8bb813, + 0x5aa6b813, 0x1a94b815, 0x01efb812, 0x014fb814, + 0x01cfb811, 0xb520ffff, 0x81df0000, 0x00000000, + 0x00000000, 0xb636000f, 0x81470000, 0x039f8014, + 0xb6000404, 0x5948b80a, 0x957c00ff, 0x194ab80b, + 0x5f88b81c, 0xb0060020, 0xb4200001, 0x80a70000, + 0x64a6b805, 0x68e9b80a, 0x18a5b807, 0x029fa025, + 0x00a7b80a, 0x81df0004, 0x01efb812, 0x014fb814, + 0x01afb811, 0xb520ffff, 0x5ae2b816, 0x1231b817, + 0x0610b817, 0xb500ffda, 0xb0100000, 0xb4000003, + 0x5ec2b810, 0x86760001, 0xb500ffd8, 0xb00f0000, + 0xb4000005, 0x0207b80f, 0x81f3001f, 0x9a2fc000, + 0x81e70000, 0xb500ffcc, 0x015fb011, 0x00ffb81d, + 0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x81d7ffff, + 0x8257ffff, 0x82d7ffff, 0x8357ffff, 0x83d7ffff, + 0x80770000, 0x80f70000, 0x81770000, 0x81f70000, + 0x82770000, 0x82f70000, 0x83770000, 0x83f70000, + 0xaeb40080, 0x808f0000, 0x806f001f, 0x80af001f, + 0xb0140000, 0xb4400014, 0x806f001f, 0x80af001f, + 0x8027b9fc, 0x5c22b801, 0x80670700, 0xb6000208, + 0x00cfb803, 0x003fb0bc, 0x5822b801, 0x01cfb801, + 0x003f90bc, 0xb520ffff, 0x90630020, 0x90210020, + 0x80270000, 0x80171000, 0xb6000303, 0xb6000001, + 0x001fa021, 0x00000000, 0x82670000, 0xb6000268, + 0x80170a00, 0x80970afc, 0x81170b00, 0x81970bfc, + 0x80271c00, 0x1021b813, 0x1021b813, 0x0217b801, + 0x80271ffc, 0x0421b813, 0x0421b813, 0x0297b801, + 0x80270c00, 0x1021b813, 0x1021b813, 0x0317b801, + 0x80270ffc, 0x0421b813, 0x0421b813, 0x0397b801, + 0x80478500, 0x1042b813, 0x5c42b802, 0x1022b815, + 0x80670280, 0x00cfb803, 0x003fb0bc, 0x5822b801, + 0x01cfb801, 0x003f90bc, 0xb520ffff, 0x009f033b, + 0x80478480, 0x0442b813, 0x5c42b802, 0x1022b815, + 0x806702a0, 0x00cfb803, 0x003fb0bc, 0x5822b801, + 0x01cfb801, 0x003f90bc, 0xb520ffff, 0xb0040000, + 0xb4000002, 0x80479000, 0xb5000001, 0x80479c00, + 0x1042b813, 0x5c42b802, 0x1022b815, 0x806702c0, + 0x00cfb803, 0x003fb0bc, 0x5822b801, 0x01cfb801, + 0x003f90bc, 0xb520ffff, 0xb0040000, 0xb4000002, + 0x80479180, 0xb5000001, 0x80479d80, 0x0442b813, + 0x5c42b802, 0x1022b815, 0x806702e0, 0x00cfb803, + 0x003fb0bc, 0x5822b801, 0x01cfb801, 0x003f90bc, + 0xb520ffff, 0x81270000, 0x80370000, 0x80b70000, + 0x81370000, 0x81b70000, 0x82370004, 0x82b7fffc, + 0xb6002016, 0x41498008, 0x51498814, 0x51498814, + 0x51418810, 0x51418810, 0x41818814, 0x0308a02a, + 0x49958820, 0x51898810, 0x51918828, 0x414d8814, + 0x0388a7ec, 0x494d8814, 0x49458810, 0x49458810, + 0x418d8810, 0x0308a02a, 0x49918fec, 0x51858814, + 0x51958fe4, 0x00000000, 0x0388a7ec, 0x92730080, + 0x009f033b, 0x5802b814, 0x90400300, 0x001f9802, + 0x00000000, 0xb0000000, 0xb4200016, 0x80170a00, + 0x80070000, 0xb6002001, 0x001fa020, 0xb0040000, + 0xb4200002, 0x80279000, 0xb5000001, 0x80279c00, + 0xac740080, 0x5c22b801, 0x11e1b803, 0x806f001f, + 0x80af001f, 0xb6000407, 0x80cf0280, 0x01ffb0bc, + 0x59e2b80f, 0x01afb80f, 0x01ff90bc, 0xb520ffff, + 0x91ef0020, 0x007f0320, 0x011f90cd, 0xaca30006, + 0x80c7b004, 0x10a5b814, 0x58a1b805, 0x10a5b806, + 0x0099b805, 0x8027b3dc, 0x5841b804, 0x1021b802, + 0x0159b801, 0x8027b3d0, 0x5841b804, 0x1021b802, + 0x0139b801, 0x80170c00, 0x0097b80a, 0xb6000002, + 0x59478020, 0x009fa04a, 0x00ffb81b, 0x00000000, + 0x009f0011, 0x015f0012, 0xb0060000, 0xb4200007, + 0x968a0001, 0xb0140000, 0xb400000d, 0x80870001, + 0x009f2011, 0x954a0002, 0x015f2012, 0xb0060002, + 0xb4200007, 0x968a0002, 0xb0140000, 0xb4000004, + 0x80870001, 0x009f2011, 0x81470000, 0x015f2012, + 0x83640037, 0x00bf2010, 0xb0060000, 0xb4200003, + 0xb0050000, 0xb4200001, 0x836400a1, 0xb0050000, + 0xb4200001, 0x836400ca, 0x00bf0010, 0xb0050000, + 0xb420000a, 0x81df0000, 0x00000000, 0x00000000, + 0x836409e4, 0x836402f6, 0x00000000, 0x8364098c, + 0x81df0004, 0x00000000, 0xb5000009, 0x00bf0010, + 0xb0050001, 0xb4000006, 0x00000000, 0x81df0000, + 0x00000000, 0x00000000, 0x83640981, 0x81df0004, + 0x00ff0325, 0x82870000, 0x81df0000, 0x00000000, + 0x00000000, 0xb6270002, 0x8364fefd, 0x92940001, + 0x81df0004, 0x80070001, 0x801eff70, 0x001f0010, + 0xb0000001, 0xb4000007, 0x001f033b, 0xb0000000, + 0xb4000002, 0x80270000, 0xb5000001, 0x80270001, + 0x003f233b, 0x00ffb81a, 0x00000000, 0x00000000, + 0x027f4001, 0x5e2ab813, 0x96310003, 0x81c70000, + 0x820700ff, 0xb0110000, 0xb4000005, 0x5a21b811, + 0x81c70200, 0x8207000e, 0x69d1b80e, 0x1210b811, + 0x01dfb0cd, 0x5e2cb813, 0x96310003, 0x023f2323, + 0x5e28b813, 0x96310003, 0x023f2322, 0x5e27b813, + 0x96310001, 0x023f2328, 0x5e23b813, 0x96310001, + 0x023f2321, 0x95f30007, 0x01ff2320, 0x920fe004, + 0x0258b810, 0x00000000, 0x1252b811, 0x025f2325, + 0x8167befc, 0x017f6195, 0x021f031c, 0x01df031d, + 0x3010b80f, 0xb4200003, 0x3011b80e, 0xb4200001, + 0xb5000025, 0x80270000, 0x80471000, 0x0017b802, + 0x8057ffff, 0x81df0000, 0x00000000, 0x00000000, + 0xb6002001, 0x001fa021, 0x80270400, 0x80679000, + 0x5c62b803, 0xb6001809, 0x00cfb801, 0x007fb0bc, + 0x5862b803, 0x01afb803, 0x007f90bc, 0x0047b86f, + 0xb0020001, 0xb4c0fffd, 0x90630020, 0x80679c00, + 0x5c62b803, 0xb6001809, 0x00cfb801, 0x007fb0bc, + 0x5862b803, 0x01afb803, 0x007f90bc, 0x0047b86f, + 0xb0020001, 0xb4c0fffd, 0x90630020, 0x81df0004, + 0x01ff231c, 0x023f231d, 0x83970300, 0x82070000, + 0x81df0000, 0x00000000, 0x00000000, 0xb6320001, + 0x039fa030, 0x81df0004, 0x00bf0010, 0x021f0324, + 0xb0100000, 0xb4200001, 0x80a70000, 0xb0050000, + 0xb4200008, 0xb0040000, 0xb4a00002, 0x80a70001, + 0xb5000004, 0x82070000, 0x021f204e, 0xb4000001, + 0x80a70002, 0xb0050001, 0xb4200007, 0x021f004e, + 0xb0100002, 0xb4a00002, 0x80a70002, 0x00ffb81b, + 0x92100001, 0x021f204e, 0x00000000, 0x00ffb81b, + 0x81530000, 0x003fb80a, 0x00000000, 0x00000000, + 0x003fb819, 0x00000000, 0x00000000, 0x81550000, + 0x8384fd6b, 0x81470000, 0x015f61ee, 0x015f61ef, + 0x015f23a4, 0x8297050c, 0x82d7ffff, 0x81df0000, + 0x00000000, 0x00000000, 0xb6000501, 0x029fa02a, + 0x81df0004, 0x8167e004, 0x116b0384, 0x0158b80b, + 0x019f0382, 0x015f237b, 0x017f0388, 0x116bb80a, + 0xb00c0008, 0xb4a00003, 0x80a70003, 0x00bf2010, + 0x00ffb81b, 0xb00a0005, 0xb4400003, 0xb00b0006, + 0xb4400001, 0x00ffb81b, 0x80a70004, 0x00bf2010, + 0x00ffb81b, 0x00000000, 0x00000000, 0x00000000, + 0x027f0388, 0x02bf037b, 0x02df0384, 0x02ff03a1, + 0x82970400, 0x8257ffff, 0x82d7ffff, 0x81df0000, + 0x00000000, 0x00000000, 0xb6350003, 0x81550001, + 0x8357ffff, 0x029fa02a, 0x82970414, 0xb6350003, + 0x81550001, 0x83d7ffff, 0x029fa02a, 0x81df0004, + 0x81550001, 0xb00a0001, 0xb4200004, 0x814d0008, + 0x6149b80a, 0x954affff, 0x015f61ee, 0xb0160000, + 0xb4200007, 0x81550001, 0xb00a0001, 0xb4200004, + 0x814d0008, 0x6149b80a, 0x954affff, 0x015f61ef, + 0x81550001, 0xb00a0001, 0xb4200042, 0x82f50001, + 0x02ff23a1, 0xb0170001, 0xb4200034, 0x82970428, + 0x81df0000, 0x00000000, 0x00000000, 0xb6350003, + 0x81550001, 0x00000000, 0x029fa02a, 0x81df0004, + 0x82970428, 0x81470000, 0x017f8034, 0xb00b0001, + 0xb4000004, 0x914a0001, 0x300ab815, 0xb480fffa, + 0xb5000001, 0x015f23a5, 0x81670000, 0xb0160002, + 0xb4200002, 0x81750001, 0x00000000, 0x017f233a, + 0x81550004, 0xadaa000c, 0x015f23a2, 0x81750004, + 0x916b0003, 0x017f23a3, 0x91ad0025, 0x01bf23a6, + 0xadab000c, 0x81e70000, 0x91ad0025, 0x01bf23a7, + 0x920a0001, 0x05abb810, 0xb00d0000, 0xb4000015, + 0x81df0000, 0x00000000, 0x00000000, 0xb62d0004, + 0x81b50001, 0x65b0b80d, 0x19efb80d, 0x92100001, + 0x81df0004, 0x01ffb0be, 0xb500000a, 0x81a70000, + 0x82970428, 0x81df0000, 0x00000000, 0x00000000, + 0xb6350001, 0x029fa02d, 0x81df0004, 0x01bf233a, + 0x01bf23a5, 0x82070000, 0x82270000, 0x82170428, + 0x81df0000, 0x00000000, 0x00000000, 0xb635003a, + 0x01bf8030, 0xb00d0001, 0xb4200036, 0x81d50001, + 0x65b1b80e, 0x1a10b80d, 0xb00e0001, 0xb4200031, + 0x81b50002, 0xadad0003, 0xae510048, 0x91cd000f, + 0x91320868, 0x015f03a2, 0xad4a0004, 0x92920700, + 0x1189b80a, 0x0297b80c, 0x1194b80a, 0x0317b80c, + 0x01ff90be, 0x015f03a2, 0x017f03a3, 0x064bb80a, + 0x0107b80a, 0xb0120000, 0xb400001e, 0xb632001d, + 0x6928b80f, 0x95290001, 0xb0090000, 0xb420000e, + 0x81350004, 0x1129b80d, 0x029fa029, 0x824d0004, + 0x5a48b812, 0x5e48b812, 0x3009b80e, 0xb4200002, + 0x5e41b812, 0xb500000d, 0x5e42b812, 0x81330040, + 0x1a52b809, 0xb5000009, 0x0127b854, 0x85290004, + 0x0397b809, 0x0287b858, 0x86940004, 0x013f803c, + 0x0397b814, 0x029fa029, 0x025f803c, 0x031fa032, + 0x91080001, 0x92310001, 0x81df0004, 0x015f03a2, + 0x017f03a3, 0x013f033a, 0xb0090001, 0xb4200023, + 0x95300002, 0x95900001, 0x1929b80c, 0xb0090000, + 0xb400001e, 0x064bb80a, 0x0107b80a, 0x81df0000, + 0x00000000, 0x00000000, 0xb6320017, 0x6928b80f, + 0x95290001, 0xb0090000, 0xb4200002, 0x81350001, + 0x013f23f8, 0x81a70700, 0x91ad0048, 0x5982b808, + 0x11adb80c, 0x0397b80d, 0x013f03f8, 0xb0090001, + 0xb4200005, 0x019f801c, 0x0196b80c, 0x81b3ff80, + 0x418cb80d, 0xb5000002, 0x019f801c, 0x0196b80c, + 0x039fa00c, 0x91080001, 0x81df0004, 0xb0160002, + 0xb420001e, 0xb0170001, 0xb4200008, 0xb00a0000, + 0xb4200002, 0x81270002, 0xb5000005, 0xb00a0002, + 0xb4400002, 0x81270003, 0xb5000001, 0x81270004, + 0x013f23a9, 0x81950001, 0xb00c0001, 0xb4200011, + 0x81a70000, 0x8397043c, 0x81df0000, 0x00000000, + 0x00000000, 0xb6290006, 0x81150001, 0x039fa028, + 0xb0080001, 0xb4200001, 0x81a70001, 0x00000000, + 0x81df0004, 0x01bf23a8, 0xb5000002, 0x81a70000, + 0x01bf23a8, 0xb0170001, 0xb4200001, 0x81b50002, + 0x82970c20, 0x81df0000, 0x00000000, 0x00000000, + 0xb6350003, 0x81550002, 0x00000000, 0x029fa02a, + 0x81df0004, 0xb0130001, 0xb4200001, 0x81150001, + 0x81c70000, 0x81df0000, 0x00000000, 0x00000000, + 0xb6350014, 0x922e0c20, 0x015ff011, 0xb00a0000, + 0xb400000f, 0x922e0428, 0x015ff011, 0xb00a0001, + 0xb4200005, 0x922e044c, 0x0297b811, 0x015f03a6, + 0x029fa00a, 0xb5000006, 0x81550006, 0xad4a0003, + 0x922e044c, 0x0297b811, 0x914a0049, 0x029fa00a, + 0x91ce0004, 0x81df0004, 0xb0170001, 0xb4200022, + 0xb00d0000, 0xb4000020, 0x852d0001, 0x81470001, + 0x6549b80a, 0xad6a0003, 0x019f03a7, 0x058c03a6, + 0x81270000, 0xb00b0000, 0xb4000005, 0x300cb80b, + 0xb4800003, 0x058cb80b, 0x91290001, 0xb500fffb, + 0x81750004, 0x5961b80b, 0x839704ec, 0x0187b860, + 0x039fa02c, 0x039fa02a, 0x039fa029, 0x039fa02b, + 0xb0090000, 0xb4000007, 0x81df0000, 0x00000000, + 0x00000000, 0xb6290003, 0x81550007, 0x00000000, + 0x00000000, 0x81df0004, 0x81c70000, 0x81df0000, + 0x00000000, 0x00000000, 0xb635002e, 0x922e0c20, + 0x01fff011, 0xb00f0000, 0xb4000029, 0x852f0001, + 0x81470001, 0x6549b80a, 0xad6a0003, 0x922e044c, + 0x025fd811, 0x86520001, 0x0227b812, 0x81270000, + 0xb00b0000, 0xb4000005, 0x3012b80b, 0xb4800003, + 0x0652b80b, 0x91290001, 0xb500fffb, 0x2e09b80b, + 0x00000000, 0x3010b811, 0xb4600001, 0x91290001, + 0xae4e0004, 0x82150004, 0x9232049c, 0x0297b811, + 0x0187b860, 0x029fa02c, 0x029fa02a, 0x029fa029, + 0x029fa030, 0xb0090000, 0xb4000004, 0xb6290003, + 0x81550007, 0x00000000, 0x00000000, 0x82270460, + 0x1231b80e, 0x0217b811, 0x81550002, 0x021fa00a, + 0x91ce0004, 0x81df0004, 0xb0130001, 0xb420000c, + 0xb0080000, 0xb400000a, 0x81550004, 0x839704fc, + 0x0167b860, 0x039fa02b, 0x81670001, 0x039fa02b, + 0x8175000e, 0x81670002, 0x039fa02b, 0x039fa02a, + 0x81150001, 0xb0080001, 0xb420000a, 0x8135000b, + 0x5d2923aa, 0x95490180, 0x5d4723ab, 0x95490060, + 0x5d4523ac, 0x95490018, 0x5d4323ad, 0x95490007, + 0x015f23ae, 0x81350001, 0xb0090001, 0xb420001b, + 0x81350006, 0x013f23af, 0xb0170001, 0xb4200005, + 0x81550004, 0x00000000, 0x015f23b0, 0x81550003, + 0x015f23b1, 0x82970474, 0x83170488, 0x81df0000, + 0x00000000, 0x00000000, 0xb6350004, 0x81550007, + 0x5e83a02a, 0x954a0007, 0x031fa02a, 0x81df0004, + 0xb0130001, 0xb4200005, 0x81750004, 0x00000000, + 0x017f23b2, 0x81750003, 0x017f23b3, 0xb0170001, + 0xb420000b, 0x81b50001, 0xb00d0001, 0xb4200008, + 0x81d50003, 0x59c8b80e, 0x91ce0300, 0x01df61da, + 0x81d50003, 0x59c8b80e, 0x91ce0300, 0x01df61db, + 0x81550001, 0xb00a0001, 0xb4200057, 0xb0170001, + 0xb4200001, 0x81550002, 0x82470000, 0x82270000, + 0x81df0000, 0x00000000, 0x00000000, 0xb6350004, + 0x81750002, 0x6571b80b, 0x92310002, 0x1a52b80b, + 0x81df0004, 0xb0170001, 0xb420001b, 0xb00a0001, + 0xb4200015, 0x81150003, 0x91080001, 0x011f23a4, + 0x829709d0, 0x831709f0, 0x83970060, 0x81df0000, + 0x00000000, 0x00000000, 0xb6280009, 0x81750005, + 0x00000000, 0x029fa02b, 0x81750004, 0x00000000, + 0x031fa02b, 0x81750003, 0x00000000, 0x039fa02b, + 0x81df0004, 0xb5000004, 0xb00a0002, 0xb4800002, + 0x81070000, 0x011f23a4, 0x82270000, 0x81270000, + 0x81df0000, 0x00000000, 0x00000000, 0xb6350025, + 0x6a11b812, 0x92310002, 0x96100003, 0xb0100001, + 0xb4200018, 0xada90020, 0x81750003, 0x920d0520, + 0x0217b810, 0x920d05c0, 0x0297b810, 0x920d0660, + 0x0317b810, 0x5942b809, 0x920a050c, 0x0397b810, + 0x916b0001, 0x039fa02b, 0xb62b0009, 0x81750005, + 0x00000000, 0x021fa02b, 0x81750004, 0x00000000, + 0x029fa02b, 0x81750003, 0x00000000, 0x031fa02b, + 0xb5000007, 0xb0100002, 0xb4800005, 0x59a2b809, + 0x91ad050c, 0x0397b80d, 0x82070000, 0x039fa010, + 0x91290001, 0x81df0004, 0x81550001, 0xb00a0001, + 0xb420000a, 0x81550009, 0xb00a0000, 0xb4000007, + 0x81df0000, 0x00000000, 0x00000000, 0xb62a0003, + 0x82150008, 0x00000000, 0x00000000, 0x81df0004, + 0xb00a0100, 0xb4a0000b, 0x954aff00, 0x81df0000, + 0x00000000, 0x00000000, 0xb6008003, 0x82150010, + 0x00000000, 0x00000000, 0x81df0004, 0x854a0100, + 0xb4e0fff6, 0x00ffb81b, 0x00000000, 0x00000000, + 0x81070000, 0x011f61dc, 0x011f61de, 0x011f61e0, + 0x011f03aa, 0x9108e0f4, 0x0138b808, 0x011f03ab, + 0x013f61ac, 0x9108e0f0, 0x0138b808, 0x011f03ac, + 0x013f61ad, 0x5901b808, 0x9108e0f8, 0x0139b808, + 0x011f03ad, 0x013f61ae, 0x5901b808, 0x9108e100, + 0x0139b808, 0x011f03ae, 0x013f61b0, 0x5901b808, + 0x9108e108, 0x0179b808, 0x013f03af, 0x017f61b1, + 0x02bf037b, 0x82970474, 0xb6350002, 0x015f8034, + 0x1929b80a, 0x011f03a1, 0xb0080001, 0xb4200002, + 0x015f03b0, 0x1929b80a, 0x019f0388, 0xb00c0001, + 0xb4200002, 0x015f03b2, 0x1929b80a, 0x013f61b3, + 0x015f03a8, 0xb00a0001, 0xb420003a, 0x81a70000, + 0x01bf237a, 0x83840056, 0x806f001f, 0x80af001f, + 0x80270300, 0x8067a800, 0x5c62b803, 0xb600080a, + 0x00cfb801, 0x007fb0bc, 0x5862b803, 0x01afb803, + 0x007f90bc, 0x0047b86f, 0xb0020001, 0xb4c0fffd, + 0x90210020, 0x90630020, 0x81a70001, 0x01bf237a, + 0x83840043, 0x838403ce, 0x81a70000, 0x01bf237a, + 0x82470400, 0x01bff012, 0x01bf23fa, 0x83840420, + 0x83840497, 0x83840546, 0x8384059d, 0x806f001f, + 0x80af001f, 0x80270300, 0x8067ac00, 0x5c62b803, + 0xb600080a, 0x00cfb801, 0x007fb0bc, 0x5862b803, + 0x01cfb803, 0x007f90bc, 0x0047b86f, 0xb0020001, + 0xb4c0fffd, 0x90210020, 0x90630020, 0x81a70001, + 0x01bf237a, 0x82470404, 0x015ff012, 0x015f23fa, + 0x83840407, 0x8384047e, 0x8384052d, 0x83840584, + 0xb5000011, 0x81a70000, 0x01bf237a, 0xb635000e, + 0x8384001b, 0x01bf037a, 0xad4d0004, 0x00000000, + 0x914a0400, 0x01bff00a, 0x01bf23fa, 0x838403f8, + 0x8384046f, 0x8384051e, 0x83840575, 0x01df037a, + 0x91ce0001, 0x01df237a, 0x019f0388, 0xb00c0001, + 0xb4200009, 0x02bf037b, 0x02bf237a, 0x838400e8, + 0x82470000, 0x025f23fa, 0x838403e9, 0x83840460, + 0x8384050f, 0x83840566, 0x00ffb81b, 0x00000000, + 0x80770000, 0x80f70000, 0x81770000, 0x81f70000, + 0x82770000, 0x82f70000, 0x83770000, 0x83f70000, + 0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x81d7ffff, + 0x8257ffff, 0x82d7ffff, 0x8357ffff, 0x83d7ffff, + 0x017f037a, 0x5a42b80b, 0x01bf03a8, 0xb00d0001, + 0xb4200004, 0x011f9118, 0x013f9119, 0x7929b808, + 0xb5000002, 0x91b20460, 0x013ff00d, 0x91b20340, + 0x0297b80d, 0x00000000, 0x029fa009, 0x01df0384, + 0xb00e0000, 0xb4200005, 0xb00b0001, 0xb4200003, + 0x009f90c6, 0x00bf0391, 0xb5000002, 0x009f90cf, + 0x00bf0389, 0x83a40142, 0x81870000, 0x019f61b5, + 0x019f61b4, 0x5a02b80b, 0x9190044c, 0x01dfd80c, + 0x01df61b6, 0x91900488, 0x01dff00c, 0x59c1b80e, + 0x918ee118, 0x01d9b80c, 0x019f03af, 0x01df61af, + 0x858c000f, 0x5986b80c, 0x91d00474, 0x01bff00e, + 0x59c2b80d, 0x11cc61b2, 0x81870000, 0x019f61b8, + 0x91900414, 0x01dfd80c, 0x01df61b7, 0xadab0010, + 0x00000000, 0x908d049c, 0x83a40191, 0xadcb0020, + 0x5982b80b, 0x908e0520, 0x90ae05c0, 0x90ce0660, + 0x928c050c, 0x00ff9814, 0x83a40169, 0x83a401b8, + 0x017f037a, 0x59c2b80b, 0x918e0428, 0x01fff00c, + 0xb00f0001, 0xb4200081, 0x023f03a5, 0x3011b80b, + 0xb420000f, 0x01c7b860, 0x01dfb0fa, 0x01df41dc, + 0x01df61e8, 0x01df41de, 0x01df61ea, 0x01df41e0, + 0x01df61ec, 0x01df41dd, 0x01df61e9, 0x01df41df, + 0x01df61eb, 0x01df41e1, 0x01df61ed, 0xb5000024, + 0x01c7b860, 0x01dfb0f9, 0x01df41dc, 0x01df61e2, + 0x01df41de, 0x01df61e4, 0x01df41e0, 0x01df61e6, + 0x01df41dd, 0x01df61e3, 0x01df41df, 0x01df61e5, + 0x01df41e1, 0x01df61e7, 0x803f0000, 0x00000000, + 0x00000000, 0x01df90fa, 0x003fb80e, 0x00000000, + 0x00000000, 0x81d50000, 0x00000000, 0x00000000, + 0x01df41e8, 0x01df61dc, 0x01df41ea, 0x01df61de, + 0x01df41ec, 0x01df61e0, 0x01df41e9, 0x01df61dd, + 0x01df41eb, 0x01df61df, 0x01df41ed, 0x01df61e1, + 0x029f03a6, 0x029f236a, 0x029f03a7, 0x029f236c, + 0x027f03a2, 0x92b3e128, 0x0298b815, 0x019f03b0, + 0x029f2368, 0x5982b80c, 0x01df03af, 0x85ce000f, + 0x59c6b80e, 0x11cc61b2, 0x82a70001, 0x02bf61b8, + 0x82a70000, 0x02bf61b9, 0x029f41da, 0x029f61ba, + 0x029f41db, 0x029f61bb, 0x019f03b1, 0x5981b80c, + 0x918ce118, 0x0299b80c, 0xad8b0048, 0x029f61af, + 0x59a2b813, 0x118cb80d, 0x928c0868, 0x029fb0fb, + 0x928c0700, 0x029fb0fc, 0x019f41bc, 0x918c0003, + 0x019f61bc, 0x5a02b80b, 0x91900414, 0x029fd80c, + 0x029f236e, 0x808704ec, 0x83a40121, 0x808709d0, + 0x80a709f0, 0x80c70060, 0x00ff03a4, 0x83a400fc, + 0x83a4014b, 0x021f037a, 0x019f03a5, 0x300cb810, + 0xb4000016, 0x803f0000, 0x00000000, 0x00000000, + 0x01df90f9, 0x003fb80e, 0x00000000, 0x00000000, + 0x81d50000, 0x00000000, 0x00000000, 0x01df41e2, + 0x01df61dc, 0x01df41e4, 0x01df61de, 0x01df41e6, + 0x01df61e0, 0x01df41e3, 0x01df61dd, 0x01df41e5, + 0x01df61df, 0x01df41e7, 0x01df61e1, 0x029f41b6, + 0xa6d40100, 0xaeb40004, 0x81870000, 0x92b50c00, + 0x0397b815, 0xb6360001, 0x039fa02c, 0x00ffb81c, + 0x009f90cf, 0x00bf0389, 0x019f037a, 0x5982b80c, + 0x918c0340, 0x0397b80c, 0x81870000, 0x039fa00c, + 0x83a40083, 0x81870000, 0x019f61b5, 0x019f61b4, + 0x81870007, 0x019f61b6, 0x019f03b3, 0x5981b80c, + 0x918ce118, 0x01b9b80c, 0x019f03af, 0x01bf61af, + 0x858c000f, 0x5986b80c, 0x01bf03b2, 0x59a2b80d, + 0x118cb80d, 0x019f61b2, 0x81870000, 0x019f61b7, + 0x019f61b8, 0x808704fc, 0x83a400d9, 0x80870000, + 0x80a70000, 0x80c70000, 0x80e70000, 0x83a400b4, + 0x83a40103, 0x81470000, 0x81e70c1c, 0x0397b80f, + 0xb600f901, 0x039fa02a, 0x00ffb81c, 0x00000000, + 0x82270000, 0x023f2011, 0x0227b860, 0x023fb0ff, + 0x02bf9006, 0x92350028, 0x8213001f, 0x9210e000, + 0x3011b810, 0xb4800001, 0x86312000, 0x021f4193, + 0x5a01b810, 0x86100028, 0x83a4fa36, 0x82270000, + 0x003fb811, 0x02bf9006, 0x5aa3b815, 0x82338000, + 0x1a31b815, 0x003fb811, 0x8067e950, 0x5c62b803, + 0x81f50000, 0x80270400, 0x81df0000, 0x00000000, + 0x00000000, 0xb6000409, 0x814fffc0, 0x00cfb801, + 0x007fb0bc, 0x5862b803, 0x01cfb803, 0x007f90bc, + 0xb520ffff, 0x90210020, 0x90630020, 0x81df0004, + 0x82870000, 0x81f50010, 0x019f4193, 0x5d61b80c, + 0x5d43b80c, 0x114ab80b, 0x0187b80a, 0x960cff00, + 0x92100100, 0x858c0001, 0x81df0000, 0x00000000, + 0x00000000, 0xb62c000c, 0x81f50010, 0x5e28b80f, + 0xb6000209, 0x5a48b814, 0x9652ff00, 0x5e68b814, + 0x5981b813, 0x918c1000, 0x01dfd80c, 0x2252b811, + 0x2292b80e, 0x962f00ff, 0x81df0004, 0x81870000, + 0x86100100, 0xb4e0ffec, 0xb00a0000, 0xb4000009, + 0x81670000, 0xb0140000, 0xb4000001, 0x81670001, + 0x017f2012, 0x258a4193, 0x918c0001, 0x81470000, + 0xb500ffde, 0x81670000, 0xb0140000, 0xb4000001, + 0x81670002, 0x116b0012, 0x803f0000, 0x00000000, + 0x00000000, 0x003fb811, 0x00000000, 0x00000000, + 0x81f50000, 0x017f2012, 0x00ffb81a, 0x00000000, + 0x61f4b804, 0x91ef0001, 0x8233003f, 0x9a31ffff, + 0x5a02b804, 0x1610b811, 0x92510001, 0x1a10b812, + 0x029f03fb, 0xb0140001, 0xb4200012, 0x5a21b805, + 0x92b1e910, 0x0299b815, 0x5a22b805, 0x5a90b814, + 0x6290b814, 0x92b1e890, 0x11efb814, 0x029bb815, + 0x8233ff80, 0x3011b814, 0xb4000006, 0x4294b811, + 0x00000000, 0x0288b814, 0x4210b814, 0x00000000, + 0x0208b810, 0x029f9003, 0x82f3007f, 0x9af7ffff, + 0x3017b814, 0xb4000003, 0x4210b814, 0x00000000, + 0x0208b810, 0x82270000, 0x02c7b810, 0xb0160000, + 0xb400000a, 0x1676b812, 0x3013b812, 0xb4000003, + 0x5ac1b816, 0x92310001, 0xb500fffa, 0x81d3ff80, + 0x3010b80e, 0xb4200001, 0x1ad6b80e, 0x05efb811, + 0x027f037a, 0x5a62b813, 0x92730340, 0x0397b813, + 0x023fd813, 0x02dfb0fd, 0x5a30b811, 0x6230b811, + 0x0631b80f, 0x3010b812, 0xb4200001, 0x92310001, + 0x82470000, 0xb0110000, 0xb4800004, 0x82470003, + 0xb0110003, 0xb4400001, 0x0247b811, 0x039fa012, + 0x124f61bc, 0x00ffb81d, 0x00000000, 0x00000000, + 0x83970a10, 0x82070000, 0xb6003201, 0x039fa030, + 0xb0070000, 0xb4000019, 0x029f41b4, 0x0297b804, + 0x0317b805, 0x0397b806, 0xb6270014, 0x12948034, + 0x01df8038, 0xb00e0000, 0xb4a0000e, 0x02bf803c, + 0x5a02b814, 0x91b00a10, 0x0217b80d, 0xb62e0008, + 0x96150003, 0x91f00001, 0xadef0080, 0xb0150004, + 0xb4600001, 0x85ef0280, 0x021fa02f, 0x92940001, + 0xb5000001, 0x021f803c, 0x00000000, 0x00ffb81d, + 0x0397b804, 0x021f036a, 0x027f803c, 0x029f803c, + 0x02bf803c, 0x02df803c, 0x5a22b810, 0x92311000, + 0x0397b811, 0xb0100000, 0xb4200001, 0x039fa036, + 0xb0150000, 0xb4000021, 0x0227b860, 0x023fb0ff, + 0xb520ffff, 0x803f0000, 0x82138000, 0x1a10b813, + 0x003fb810, 0x00000000, 0x00000000, 0x82150000, + 0x00000000, 0xb635000d, 0x82550007, 0x5a42b812, + 0x9212e4b8, 0x025bb810, 0x8227000c, 0xb6000307, + 0x68d1b812, 0x94c6000f, 0x84c60002, 0x12d6b806, + 0xb6340001, 0x039fa036, 0x86310004, 0x803f0000, + 0x82138000, 0x023f90ff, 0x1a31b810, 0x003fb811, + 0x00000000, 0x00000000, 0x82150000, 0x00ffb81d, + 0x00ff41b5, 0x011f41b4, 0x019f41af, 0x01bf41ae, + 0x01df41ba, 0x01ff41bb, 0x82070000, 0x023f0380, + 0x82470000, 0xae310032, 0x029f41b3, 0x5862b807, + 0x90431000, 0x81970ad8, 0x0217b802, 0x90430c00, + 0x0297b802, 0x0317b802, 0x912802a4, 0x007ff009, + 0x58478030, 0x792341b6, 0x0529b807, 0x019fa029, + 0xb0080014, 0xb4800011, 0xa5420c00, 0x031fa02a, + 0x84690001, 0xb4a00011, 0xb623000b, 0x58678030, + 0xa4030c00, 0x031fa020, 0x044ab800, 0x0056b802, + 0x5c41b802, 0xf84200ff, 0x90620100, 0x005ff003, + 0x7d40b80a, 0x114ab802, 0xb5000004, 0xa5420c00, + 0x58478010, 0xa5620c00, 0x031fa02a, 0xb0080016, + 0xb4400043, 0xb0080013, 0xb440002c, 0xb0080006, + 0xb4400024, 0xb0080005, 0xb4400014, 0xb0080002, + 0xb4400006, 0x80440030, 0x015f619c, 0x05cab80c, + 0x05eab80d, 0x066eb810, 0xb500003c, 0x8044002a, + 0x300a419c, 0xb4800001, 0x82470001, 0x015f619c, + 0xb0120001, 0xb4200001, 0xb500001a, 0x05cab80c, + 0x05eab80d, 0x066eb810, 0xb5000030, 0x001f41b6, + 0xb0000007, 0xb4000001, 0x8044001b, 0x300a419c, + 0xb4800001, 0x82470001, 0xb0120001, 0xb4200001, + 0xb500000c, 0x05cab80c, 0x05eab80d, 0x066eb810, + 0xb5000022, 0x80440010, 0x840b0100, 0x300ab800, + 0xb4200001, 0x86100040, 0xb5000002, 0x86100080, + 0xfe100000, 0x046e41ad, 0x042ab80c, 0x7dc1b803, + 0x044f41ac, 0x042ab80d, 0x7de1b802, 0x046eb810, + 0x7e6fb803, 0xb5000011, 0x840b0100, 0x3000b80a, + 0xb4200002, 0x82070180, 0x00ffb802, 0x300ab80b, + 0xb4a00002, 0x86100040, 0xfe100000, 0x00ffb802, + 0x046e41ad, 0x042ab80c, 0x7dc1b803, 0x044f41ac, + 0x042ab80d, 0x7de1b802, 0x7e6eb80f, 0x380a41b0, + 0xb4600003, 0x242a41b0, 0x5c22b801, 0x1273b801, + 0xb0140000, 0xb4200002, 0x80071fe0, 0xb5000016, + 0x1011b808, 0x5801b800, 0x9020e26c, 0x0079b801, + 0x5842b808, 0x90420a10, 0x7c03b813, 0x003f9802, + 0x1000b801, 0x003f41b2, 0x5830b801, 0x6030b801, + 0x0400b801, 0x003f41b1, 0x5830b801, 0x6030b801, + 0x0400b801, 0xfc000000, 0xf8001fe0, 0x94001fe0, + 0x100041b1, 0x9400ffff, 0x8067003f, 0xb6290008, + 0x005f8014, 0x0442b800, 0x9442ffff, 0x5850b802, + 0x6050b802, 0xfc420000, 0x5c45b802, 0x7a82a023, + 0x10e7b809, 0x91080001, 0x300741b6, 0xb420ff6a, + 0x019f61af, 0x01bf61ae, 0x01df61ba, 0x01ff61bb, + 0x00ff41b5, 0x011f41b4, 0x019f41b8, 0x01bf41b7, + 0x01df41dd, 0x01ff41df, 0x021f41e1, 0x027f90fd, + 0x029f41bc, 0x02ff41dc, 0x031f41de, 0x033f41e0, + 0x5822b807, 0x91210c00, 0x0117b809, 0x81970ad8, + 0x91211000, 0x0217b809, 0x91210c00, 0x0317b809, + 0x80170ba0, 0x013f802c, 0xb629005f, 0x003f8038, + 0xb001000e, 0xb440001e, 0xb001000c, 0xb4400054, + 0xb001000a, 0xb4400043, 0xb0010007, 0xb440003c, + 0xb0010005, 0xb440002b, 0xb0010000, 0xb440001a, + 0xb00d0001, 0xb4200010, 0x005f418f, 0xac42bb75, + 0x8073005a, 0x9442ffff, 0x005f618f, 0x95628000, + 0x5848b802, 0xb00b8000, 0xb4200002, 0x8173ff00, + 0x1842b80b, 0x9863827a, 0x4043b802, 0x00000000, + 0x0048b802, 0xb500003f, 0x80470000, 0xb500003d, + 0x8401000f, 0x5c22b800, 0x902102d8, 0x001ff001, + 0x004db800, 0xb5000037, 0x86f70001, 0xb4600005, + 0x80750005, 0x5862b803, 0x9043e44c, 0x01d9b802, + 0x82e70002, 0x5c4cb80e, 0x9462000f, 0x5862b803, + 0x90630200, 0x005f9803, 0x59c4b80e, 0x95ceffff, + 0xb5000028, 0x87180001, 0xb4600005, 0x80750007, + 0x5862b803, 0x9043e4b8, 0x01f9b802, 0x83070002, + 0x5c4cb80f, 0x9462000f, 0x5862b803, 0x9063020c, + 0x005f9803, 0x59e4b80f, 0x95efffff, 0xb5000019, + 0x80750003, 0x5862b803, 0x90630220, 0x005f9803, + 0xb5000014, 0x87390001, 0xb4600005, 0x80750007, + 0x5862b803, 0x9043e6ac, 0x0219b802, 0x83270001, + 0x5c4cb810, 0x9462000f, 0x5862b803, 0x9063023c, + 0x005f9803, 0x5a04b810, 0x9610ffff, 0xb5000005, + 0x80750004, 0x5862b803, 0x90630268, 0x005f9803, + 0x00000000, 0x001fa022, 0x80170ba0, 0xb00c0001, + 0xb4200035, 0x023f90fb, 0x007f9811, 0x025f90fc, + 0x06d4b803, 0x007f9812, 0x4083b813, 0x00000000, + 0x0088b804, 0xb629002b, 0x24368030, 0x9421ffff, + 0x5830b801, 0x6030b801, 0x40448020, 0xb0010020, + 0xb4800003, 0x80470000, 0x80670000, 0xb500000e, + 0xb0010000, 0xb4a00004, 0x82b30080, 0x6aa1b815, + 0x4042b815, 0xb5000008, 0x6c41b802, 0x82a70017, + 0x12b5b801, 0x6875b803, 0x1842b803, 0x00000000, + 0x00000000, 0x00000000, 0x0108a022, 0x007f41b9, + 0x90630001, 0x007f61b9, 0xb003000c, 0xb420000c, + 0x92310004, 0x023fb0fb, 0x007f9811, 0x92520004, + 0x06d4b803, 0x025fb0fc, 0x007f9812, 0x80470000, + 0x4083b813, 0x00000000, 0x0088b804, 0x005f61b9, + 0x00000000, 0xb500001a, 0xb6290019, 0x24348030, + 0x9421ffff, 0x5830b801, 0x6030b801, 0x40538020, + 0xb0010020, 0xb4800003, 0x80470000, 0x80670000, + 0xb500000e, 0xb0010000, 0xb4a00004, 0x82b30080, + 0x6aa1b815, 0x4042b815, 0xb5000008, 0x6c41b802, + 0x82a70017, 0x12b5b801, 0x6875b803, 0x1842b803, + 0x00000000, 0x00000000, 0x00000000, 0x0108a022, + 0x10e7b809, 0x91080001, 0x300741b6, 0xb420ff48, + 0x00ff61b5, 0x011f61b4, 0x01df61dd, 0x01ff61df, + 0x021f61e1, 0x02ff61dc, 0x031f61de, 0x033f61e0, + 0x00ffb81d, 0x00000000, 0x00000000, 0x00000000, + 0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x81d7ffff, + 0x8257ffff, 0x808f0000, 0x003f9113, 0x005f9114, + 0x7141b802, 0x80cf0700, 0x8027b064, 0x5c22b801, + 0x003fb0bc, 0x5822b801, 0x01cfb801, 0x003f90bc, + 0xb520ffff, 0x80cf0704, 0x8027b06c, 0x5c22b801, + 0x003fb0bc, 0x5822b801, 0x01cfb801, 0x003f90bc, + 0xb520ffff, 0x81e7043c, 0x82071c00, 0x82271c10, + 0x019f03a9, 0x806f001f, 0x80af001f, 0x80270400, + 0x8067a800, 0x5c62b803, 0xb6000808, 0x00cfb801, + 0x007fb0bc, 0x5862b803, 0x01cfb803, 0x007f90bc, + 0xb520ffff, 0x90210020, 0x90630020, 0x81971000, + 0x82170c00, 0xb6000004, 0x003f800c, 0x005f8010, + 0x021fa021, 0x019fa022, 0x00bfd810, 0x003fd811, + 0x70c1b80a, 0x001f980f, 0x91ef0004, 0x92100002, + 0x92310002, 0x5822b805, 0x90411000, 0x0197b802, + 0x90410c00, 0x0217b802, 0x0466b805, 0xb0000000, + 0xb4000005, 0xb6230004, 0x003f8010, 0x005f800c, + 0x1201a022, 0x0581a022, 0x858c0001, 0xb4e0ffea, + 0x80270400, 0x8067ac00, 0x5c62b803, 0xb6000808, + 0x00cfb801, 0x007fb0bc, 0x5862b803, 0x01afb803, + 0x007f90bc, 0xb520ffff, 0x90210020, 0x90630020, + 0x00ffb81c, 0x00000000, 0x00000000, 0x00000000, + 0x808f0000, 0x806f001f, 0x80af001f, 0x003f037a, + 0xb0010000, 0xb4400030, 0x81a7b7fc, 0x5da2b80d, + 0x80670500, 0xb6000208, 0x00cfb803, 0x01bfb0bc, + 0x59a2b80d, 0x01cfb80d, 0x01bf90bc, 0xb520ffff, + 0x90630020, 0x91ad0020, 0x81c7b8fc, 0x5dc2b80e, + 0x80670540, 0xb6000208, 0x00cfb803, 0x01dfb0bc, + 0x59c2b80e, 0x01cfb80e, 0x01df90bc, 0xb520ffff, + 0x90630020, 0x91ce0020, 0x81a7b3fc, 0x5da2b80d, + 0x80670600, 0xb6000408, 0x00cfb803, 0x01bfb0bc, + 0x59a2b80d, 0x01cfb80d, 0x01bf90bc, 0xb520ffff, + 0x90630020, 0x91ad0020, 0x81c7b5fc, 0x5dc2b80e, + 0x80670680, 0xb6000408, 0x00cfb803, 0x01dfb0bc, + 0x59c2b80e, 0x01cfb80e, 0x01df90bc, 0xb520ffff, + 0x90630020, 0x91ce0020, 0x005f03fa, 0xb0020000, + 0xb4000024, 0x8057ffff, 0x80d7ffff, 0x8157ffff, + 0x81d7ffff, 0x8257ffff, 0x82d7ffff, 0x8357ffff, + 0x83d7ffff, 0x83971300, 0x83171200, 0x82971100, + 0x82171000, 0x81170c00, 0x81970ff8, 0x80171400, + 0x80971500, 0x005f802c, 0x001f8028, 0xb6004010, + 0x41028000, 0x51008004, 0x007f876c, 0x0208a028, + 0x41008000, 0x49028004, 0x003f8068, 0x0388a028, + 0x41038000, 0x51018004, 0x005f802c, 0x0288a028, + 0x41018020, 0x49038024, 0x001f8028, 0x0308a028, + 0x00ffb81c, 0x83d7ffff, 0x8357ffff, 0x82d7ffff, + 0x8257ffff, 0x8157ffff, 0x81d7ffff, 0x8057ffff, + 0x80d7ffff, 0x82971200, 0x82171000, 0x81170c00, + 0x81970ffc, 0x83171800, 0x83971a00, 0x83370000, + 0x83b70000, 0x81370008, 0x81b7fff8, 0x4119880c, + 0xb6008006, 0x511d8808, 0x41498838, 0x0208a028, + 0x494d883c, 0x4119880c, 0x0288a02a, 0x00ffb81c, + 0x82670000, 0x82a70000, 0x003f037a, 0xb0010000, + 0xb4400018, 0x81a7bdfc, 0x5da2b80d, 0x80670580, + 0xb6000208, 0x00cfb803, 0x01bfb0bc, 0x59a2b80d, + 0x01cfb80d, 0x01bf90bc, 0xb520ffff, 0x90630020, + 0x91ad0020, 0x81a7eb70, 0x5da2b80d, 0x806705c0, + 0xb6000208, 0x00cfb803, 0x01bfb0bc, 0x59a2b80d, + 0x01cfb80d, 0x01bf90bc, 0xb520ffff, 0x90630020, + 0x91ad0020, 0x02bf03fa, 0x808f0000, 0xb0150000, + 0xb4000006, 0x81470040, 0x81670003, 0x81870002, + 0x81a71000, 0x81c71300, 0xb5000005, 0x81470080, + 0x81670004, 0x81870001, 0x81a71000, 0x81c71200, + 0x0017b80d, 0x0097b80e, 0x108db80a, 0x0117b804, + 0x108eb80a, 0x0197b804, 0x5841b80a, 0x108db802, + 0x0217b804, 0x108eb802, 0x0297b804, 0x106ab802, + 0x108db803, 0x0317b804, 0x108eb803, 0x0397b804, + 0x5ea2b80a, 0xb6350020, 0x001f8000, 0x003f8008, + 0x005f8004, 0x007f800c, 0x10c08010, 0x10a18018, + 0x10828014, 0x10e3801c, 0x1246b805, 0x0686b805, + 0x10c4b807, 0x0484b807, 0x80e70000, 0x80a70000, + 0x0008a032, 0x0108a034, 0x0088a026, 0x0188a024, + 0x04c08010, 0x04a18018, 0x04828014, 0x04e3801c, + 0x0646b807, 0x1286b807, 0x10c4b805, 0x0484b805, + 0x80e70000, 0x80a70000, 0x0208a032, 0x0308a034, + 0x0288a026, 0x0388a024, 0x5de1b80a, 0x82070004, + 0xb62b002a, 0x0017b80d, 0x0097b80e, 0x102db80f, + 0x0117b801, 0x104eb80f, 0x0197b802, 0x82171600, + 0x82971700, 0x0037b80f, 0x00b7b80f, 0x0137b80f, + 0x01b7b80f, 0xb630001b, 0x003f8030, 0x005f8034, + 0x5ee2b80f, 0x8013007f, 0x9800ffff, 0xb6370011, + 0x41008000, 0x51018008, 0x4902800c, 0x40c08000, + 0x0008a028, 0x48c18008, 0x50c2800c, 0x42808004, + 0x00c8b806, 0x52828008, 0x5281800c, 0x41008004, + 0x0088a034, 0x49028008, 0x4901800c, 0x011fa026, + 0x0188a028, 0x001f8001, 0x001f8005, 0x001f8009, + 0x001f800d, 0x5de1b80f, 0x5a01b810, 0x0017b80d, + 0x0097b80e, 0x902d0004, 0x0117b801, 0x904e0004, + 0x0197b802, 0x82171600, 0x82971700, 0x5ea1b80a, + 0x8013007f, 0x9800ffff, 0xb6350013, 0x003f8030, + 0x005f8034, 0x42408000, 0x52418008, 0x4a42800c, + 0x41008000, 0x0008a052, 0x49018008, 0x5102800c, + 0x42808004, 0x0108b808, 0x52828008, 0x5281800c, + 0x40c08004, 0x0088a054, 0x48c28008, 0x48c1800c, + 0x011fa048, 0x0188a046, 0x81a71100, 0x81c71200, + 0x858c0001, 0xb4e0ff7e, 0x00ffb81c, 0x00000000, + 0x005f03fa, 0x00000000, 0xb0020000, 0xb4000034, + 0x81b70080, 0x81d7ffff, 0x81f70001, 0x82370080, + 0x8257ffff, 0x82770001, 0x82b70080, 0x82d7ffff, + 0x82f70001, 0x83370080, 0x8357ffff, 0x83770001, + 0x81971000, 0x82171100, 0x82971200, 0x83171300, + 0x815703fc, 0x81370200, 0x81170c00, 0x83d703fc, + 0x83b70200, 0x83970f00, 0x8057ffff, 0x80d7ffff, + 0x80171400, 0x80971500, 0x001f800d, 0x003f8019, + 0xb6004012, 0x41008000, 0x51018004, 0x007f8011, + 0x0128a008, 0x41018000, 0x49008004, 0x009f8015, + 0x03a8a008, 0x41038000, 0x51048004, 0x001f800d, + 0x03a8a008, 0x41048020, 0x49038024, 0x003f8019, + 0x0128a008, 0x005f8028, 0x005f803c, 0x81f70000, + 0x82770000, 0x82f70000, 0x83770000, 0x00ffb81c, + 0x82370040, 0x8257ffff, 0x82770001, 0x82b70040, + 0x82d7ffff, 0x82f70001, 0x82171000, 0x82971200, + 0x8157ffff, 0x81170c00, 0x81d7ffff, 0x81970e00, + 0x8057ffff, 0x80d7ffff, 0x80171800, 0x80971a00, + 0xb600800a, 0x001f8011, 0x003f8015, 0x41008000, + 0x51018004, 0x00000000, 0x0108a028, 0x41018020, + 0x49008024, 0x00000000, 0x0188a028, 0x82770000, + 0x82f70000, 0x00ffb81c, 0x00000000, 0x00000000, + 0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x808f0000, + 0x015f0384, 0x017f037a, 0xac4a0006, 0x8027b004, + 0x1042b80b, 0x5841b802, 0x1021b802, 0x0159b801, + 0x013f0325, 0x01bf0320, 0x5822b80b, 0x90210340, + 0x00ff9801, 0x8027b2e8, 0x5842b807, 0x1021b802, + 0x025bb801, 0x80070000, 0xac4d0006, 0x8027b004, + 0x1042b800, 0x5841b802, 0x1021b802, 0x0199b801, + 0x00000000, 0xac4c0006, 0x8027b078, 0x1042b80a, + 0x5842b802, 0x1021b802, 0x011bb801, 0x00000000, + 0x40d2b808, 0x00000000, 0xb0060000, 0xb4000080, + 0x005f033b, 0x80278400, 0xac600080, 0x5c22b801, + 0x10a1b803, 0xb0020000, 0xb4200002, 0x80279000, + 0xb5000001, 0x80279c00, 0x5c22b801, 0x11e1b803, + 0x80470300, 0x5822b800, 0x1042b801, 0x003f9802, + 0x806f001f, 0x80af001f, 0xb0010000, 0xb4200024, + 0x80170c00, 0x80971000, 0x003f8020, 0xb6000003, + 0x4201b806, 0x003f8020, 0x0088a030, 0x80270400, + 0xb6000208, 0x00cfb801, 0x00bfb0bc, 0x58a2b805, + 0x01afb805, 0x00bf90bc, 0xb520ffff, 0x90210020, + 0x90a50020, 0xb6000408, 0x00cfb801, 0x01ffb0bc, + 0x59e2b80f, 0x01afb80f, 0x01ff90bc, 0xb520ffff, + 0x90210020, 0x91ef0020, 0xb6000208, 0x00cfb801, + 0x00bfb0bc, 0x58a2b805, 0x01afb805, 0x00bf90bc, + 0xb520ffff, 0x90210020, 0x90a50020, 0xb5000043, + 0x80270400, 0x0087b805, 0x01c7b80f, 0xb6000208, + 0x00cfb801, 0x009fb0bc, 0x5882b804, 0x01cfb804, + 0x009f90bc, 0xb520ffff, 0x90210020, 0x90840020, + 0xb6000408, 0x00cfb801, 0x01dfb0bc, 0x59c2b80e, + 0x01cfb80e, 0x01df90bc, 0xb520ffff, 0x90210020, + 0x91ce0020, 0xb6000208, 0x00cfb801, 0x009fb0bc, + 0x5882b804, 0x01cfb804, 0x009f90bc, 0xb520ffff, + 0x90210020, 0x90840020, 0x80170c00, 0x80971000, + 0x8053007f, 0x9842ffff, 0xb6000004, 0x42028004, + 0x4a068020, 0x00000000, 0x0088a030, 0x80270400, + 0xb6000208, 0x00cfb801, 0x00bfb0bc, 0x58a2b805, + 0x01afb805, 0x00bf90bc, 0xb520ffff, 0x90210020, + 0x90a50020, 0xb6000408, 0x00cfb801, 0x01ffb0bc, + 0x59e2b80f, 0x01afb80f, 0x01ff90bc, 0xb520ffff, + 0x90210020, 0x91ef0020, 0xb6000208, 0x00cfb801, + 0x00bfb0bc, 0x58a2b805, 0x01afb805, 0x00bf90bc, + 0xb520ffff, 0x90210020, 0x90a50020, 0x5822b800, + 0x90210300, 0x0117b801, 0x80470001, 0x011fa002, + 0x90000001, 0x3000b809, 0xb480ff6b, 0x00ffb81c, + 0x8057ffff, 0x013f0325, 0x015f033b, 0x80171000, + 0x80070000, 0xb6002001, 0x001fa020, 0xb00a0001, + 0xb4c00002, 0x81679000, 0xb5000001, 0x81679c00, + 0x5d62b80b, 0x81878400, 0x5d82b80c, 0x80070000, + 0x5822b800, 0x90410300, 0x003f9802, 0x00000000, + 0xb0010000, 0xb4200019, 0xac400080, 0x00000000, + 0x10ccb802, 0x10abb802, 0x806f001f, 0x80af001f, + 0x80cf0400, 0xb6000408, 0xb520ffff, 0x00dfb0bc, + 0x58c2b806, 0x01afb806, 0x00df90bc, 0xb520ffff, + 0x80cf0400, 0x90c60020, 0x80cf0400, 0xb6000407, + 0x00bfb0bc, 0x58a2b805, 0x01afb805, 0x00bf90bc, + 0xb520ffff, 0x80cf0400, 0x90a50020, 0x90000001, + 0x3000b809, 0xb480ffde, 0x00ffb81b, 0x8057ffff, + 0x013f0325, 0x80171000, 0x80070000, 0xb6002001, + 0x001fa020, 0x81878400, 0x5d82b80c, 0x80070000, + 0x5822b800, 0x90410300, 0x003f9802, 0x00000000, + 0xb0010000, 0xb420000f, 0xac400080, 0x00000000, + 0x10ccb802, 0x806f001f, 0x80af001f, 0x80cf0400, + 0xb6000408, 0xb520ffff, 0x00dfb0bc, 0x58c2b806, + 0x01afb806, 0x00df90bc, 0xb520ffff, 0x80cf0400, + 0x90c60020, 0x90000001, 0x3000b809, 0xb480ffe8, + 0x00ffb81b, 0x8057ffff, 0x80d7ffff, 0x8157ffff, + 0x8139b000, 0x00000000, 0xb0090000, 0xb4000012, + 0x806f001f, 0x80af001f, 0x80cf0400, 0x013fb0bc, + 0x5922b809, 0x01cfb809, 0x013f90bc, 0xb520ffff, + 0x806f0003, 0x80af0003, 0x80cf0420, 0x91290020, + 0x013fb0bc, 0x5922b809, 0x01cfb809, 0x013f90bc, + 0xb520ffff, 0xb5000233, 0x80270000, 0x80171000, + 0xb6002401, 0x001fa021, 0x007f0384, 0x009f0320, + 0x00bf0385, 0x00df0386, 0x80e7b36c, 0x5821b803, + 0x1021b807, 0x0159b801, 0x5821b804, 0x1021b807, + 0x0179b801, 0x80e7b37c, 0x5821b803, 0x1021b807, + 0x0199b801, 0x5821b804, 0x1021b807, 0x01b9b801, + 0x80e7b38c, 0x5821b803, 0x1021b807, 0x01d9b801, + 0x5821b804, 0x1021b807, 0x01f9b801, 0x005f0385, + 0x8027b39c, 0x5842b802, 0x1021b802, 0x021bb801, + 0x005f0386, 0x8027b3ac, 0x5842b802, 0x1021b802, + 0x023bb801, 0x027f0383, 0x003f0328, 0x005f4195, + 0xb0130007, 0xb42000df, 0xb0010000, 0xb42000dd, + 0xb0020000, 0xb40000db, 0xb0030002, 0xb48000d9, + 0x029bb802, 0x82a7b108, 0xb00b0001, 0xb4200001, + 0xb5000005, 0xb00b0002, 0xb4200002, 0x92b500a0, + 0xb5000001, 0x92b50140, 0xb0030004, 0xb4600002, + 0x82870000, 0xb5000006, 0xb0030006, 0xb4600004, + 0xb0140001, 0xb4a00002, 0x82870001, 0xb5000000, + 0xac54000a, 0x806f0009, 0x80af0009, 0x5c22b815, + 0x80cf0440, 0x1021b802, 0x003fb0bc, 0x5822b801, + 0x01cfb801, 0x003f90bc, 0xb520ffff, 0xb0030003, + 0xb400000f, 0xb0030004, 0xb400001d, 0xb0030005, + 0xb400002b, 0xb0030006, 0xb4000042, 0xb0030007, + 0xb4000059, 0x80171000, 0x005f9440, 0x001fa002, + 0x80171038, 0x005f9440, 0x001fa002, 0xb5000073, + 0x80171000, 0x005f9440, 0x001fa002, 0x80171004, + 0x005f9443, 0x001fa002, 0x8017101c, 0x005f9446, + 0x001fa002, 0x80171034, 0x005f9449, 0x001fa002, + 0x80171038, 0x005f9440, 0x001fa002, 0xb5000063, + 0x80171000, 0x005f9440, 0x001fa002, 0x80171008, + 0x005f9441, 0x001fa002, 0x80171020, 0x005f9444, + 0x001fa002, 0x80171034, 0x005f9440, 0x001fa002, + 0x80171038, 0x005f9447, 0x001fa002, 0xb5000053, + 0x80171000, 0x005f9440, 0x001fa002, 0x80171004, + 0x005f9443, 0x001fa002, 0x8017100c, 0x005f9441, + 0x001fa002, 0x8017101c, 0x005f9446, 0x001fa002, + 0x80171024, 0x005f9444, 0x001fa002, 0x80171034, + 0x005f9449, 0x001fa002, 0x80171038, 0x005f9440, + 0x001fa002, 0x8017103c, 0x005f9447, 0x001fa002, + 0xb500003a, 0x80171000, 0x005f9440, 0x001fa002, + 0x80171008, 0x005f9441, 0x001fa002, 0x8017100c, + 0x005f9442, 0x001fa002, 0x80171020, 0x005f9444, + 0x001fa002, 0x80171024, 0x005f9445, 0x001fa002, + 0x80171034, 0x005f9440, 0x001fa002, 0x80171038, + 0x005f9447, 0x001fa002, 0x8017103c, 0x005f9448, + 0x001fa002, 0xb5000021, 0x80171000, 0x005f9440, + 0x001fa002, 0x80171004, 0x005f9443, 0x001fa002, + 0x8017100c, 0x005f9441, 0x001fa002, 0x80171010, + 0x005f9442, 0x001fa002, 0x8017101c, 0x005f9446, + 0x001fa002, 0x80171024, 0x005f9444, 0x001fa002, + 0x80171028, 0x005f9445, 0x001fa002, 0x80171034, + 0x005f9449, 0x001fa002, 0x80171038, 0x005f9440, + 0x001fa002, 0x8017103c, 0x005f9447, 0x001fa002, + 0x80171040, 0x005f9448, 0x001fa002, 0x80270001, + 0x803eff90, 0x80171000, 0x82b30020, 0x9ab50000, + 0x40158020, 0xb6000501, 0x48158020, 0x82b30020, + 0x9ab50000, 0x80470000, 0x3015b800, 0xb4600006, + 0x80171000, 0x83840226, 0xb6000603, 0x40028000, + 0x00000000, 0x0008a020, 0x80171018, 0x82b30020, + 0x9ab50000, 0x40158020, 0xb6000501, 0x48158020, + 0x82b30020, 0x9ab50000, 0x80470000, 0x3015b800, + 0xb4600006, 0x80171018, 0x83840215, 0xb6000603, + 0x40028000, 0x00000000, 0x0008a020, 0x80171030, + 0x82b30020, 0x9ab50000, 0x40158020, 0xb6000501, + 0x48158020, 0x82b30020, 0x9ab50000, 0x80470000, + 0x3015b800, 0xb4600006, 0x80171030, 0x83840204, + 0xb6000603, 0x40028000, 0x00000000, 0x0008a020, + 0xb500011e, 0x80270000, 0x803eff90, 0xb0030000, + 0xb4200067, 0x025f0322, 0xb00b0001, 0xb4200016, + 0xb0120001, 0xb4200005, 0x80171018, 0x8033007f, + 0x9821ffff, 0x001fa001, 0xb5000110, 0xb0120002, + 0xb4200005, 0x80171020, 0x8033007f, 0x9821ffff, + 0x001fa001, 0xb5000109, 0x80171018, 0x80330040, + 0x98210000, 0x001fa001, 0x80171020, 0x00000000, + 0x001fa001, 0xb5000101, 0xb00b0002, 0xb420002c, + 0xb0120000, 0xb4200008, 0x80171000, 0x8033007f, + 0x9821ffff, 0x001fa001, 0x80171038, 0x00000000, + 0x001fa001, 0xb50000f5, 0xb0120001, 0xb4200008, + 0x80171000, 0x8033005a, 0x98218279, 0x001fa001, + 0x80171030, 0x00000000, 0x001fa001, 0xb50000eb, + 0xb0120002, 0xb4200008, 0x80171008, 0x8033005a, + 0x98218279, 0x001fa001, 0x80171038, 0x00000000, + 0x001fa001, 0xb50000e1, 0x80171000, 0x80330040, + 0x98210000, 0x001fa001, 0x80171008, 0x00000000, + 0x001fa001, 0x8017100c, 0x00000000, 0x001fa001, + 0x80171038, 0x00000000, 0x001fa001, 0xb50000d3, + 0xb0120000, 0xb4200008, 0x80171000, 0x8033007f, + 0x9821ffff, 0x001fa001, 0x80171038, 0x00000000, + 0x001fa001, 0xb50000c9, 0xb0120001, 0xb4200005, + 0x80171018, 0x8033007f, 0x9821ffff, 0x001fa001, + 0xb50000c2, 0xb0120002, 0xb4200005, 0x80171020, + 0x8033007f, 0x9821ffff, 0x001fa001, 0xb50000bb, + 0x80171018, 0x80330040, 0x98210000, 0x001fa001, + 0x80171020, 0x00000000, 0x001fa001, 0xb50000b3, + 0x80070000, 0x8033007f, 0x9821ffff, 0xb600050e, + 0x144eb80f, 0xb0028000, 0xb4c00008, 0xac400006, + 0x00000000, 0x1042b800, 0x5842b802, 0x90421000, + 0x0017b802, 0x00000000, 0x001fa001, 0x90000001, + 0x59c1b80e, 0x59e1b80f, 0xb0040000, 0xb4200023, + 0xb00a0002, 0xb4000007, 0x80171004, 0x8033005a, + 0x98218279, 0x001fa001, 0x80171034, 0x00000000, + 0x001fa001, 0xb00c0002, 0xb4000009, 0x8017100c, + 0x8033ffa5, 0x98217d87, 0x001fa001, 0x8017103c, + 0x8033005a, 0x98218279, 0x001fa001, 0xb500008b, + 0x8017100c, 0x8033ffa5, 0x98217d87, 0x001fa001, + 0x80171010, 0x00000000, 0x001fa001, 0x8017103c, + 0x8033005a, 0x98218279, 0x001fa001, 0x80171040, + 0x00000000, 0x001fa001, 0xb500007c, 0xb0040001, + 0xb420002a, 0xb00a0001, 0xb4000007, 0x80171018, + 0x8033005a, 0x98218279, 0x001fa001, 0x80171020, + 0x00000000, 0x001fa001, 0xb00a0003, 0xb420000a, + 0x8053005a, 0x98428279, 0x4030b802, 0x8017101c, + 0x5821b801, 0x00000000, 0x00000000, 0x00000000, + 0x0028b801, 0x001fa001, 0xb00c0001, 0xb4200007, + 0x8053005a, 0x98428279, 0x4031b802, 0x80171024, + 0x0028b801, 0x001fa001, 0xb500005c, 0xb00c0002, + 0xb420005a, 0x8053005a, 0x98428279, 0x4031b802, + 0x80171024, 0x0028b801, 0x001fa001, 0x80171028, + 0x00000000, 0x001fa001, 0xb5000050, 0xb00b0002, + 0xb4200012, 0xb00a0001, 0xb4200008, 0x80171004, + 0x8033005a, 0x98218279, 0x001fa001, 0x80171034, + 0x00000000, 0x001fa001, 0xb5000008, 0xb00a0003, + 0xb4200006, 0x80171004, 0x00000000, 0x001fa010, + 0x80171034, 0x00000000, 0x001fa010, 0xb00c0001, + 0xb4200025, 0x027f0383, 0x003f0328, 0xb0130007, + 0xb420000b, 0xb00b0003, 0xb4200009, 0xb0010000, + 0xb4200007, 0x80171024, 0x00000000, 0x001fa011, + 0x80171054, 0x80270000, 0x001fa001, 0xb500002b, + 0xb00d0000, 0xb420000a, 0x8033005a, 0x98218279, + 0x4041b811, 0x8017100c, 0x0048b802, 0x001fa002, + 0x8017103c, 0x00000000, 0x001fa002, 0xb500001f, + 0xb00d0002, 0xb420001d, 0x80171054, 0x8033005a, + 0x98218279, 0x001fa001, 0x8017106c, 0x00000000, + 0x001fa001, 0xb5000015, 0xb00c0002, 0xb4200013, + 0xb00d0000, 0xb4200007, 0x8017100c, 0x00000000, + 0x001fa011, 0x80171040, 0x00000000, 0x001fa011, + 0xb500000a, 0xb00d0001, 0xb4200008, 0x80171054, + 0x8033005a, 0x98218279, 0x001fa001, 0x80171058, + 0x00000000, 0x001fa001, 0xb5000000, 0x029f0388, + 0x02bf0321, 0xb0140000, 0xb4000006, 0xb0150000, + 0xb4000004, 0x8017108c, 0x8033007f, 0x9821ffff, + 0x001fa001, 0x8027b078, 0x5c22b801, 0x806f001f, + 0x80af001f, 0x80cf0400, 0x003fb0bc, 0x5822b801, + 0x01afb801, 0x003f90bc, 0xb520ffff, 0x90210020, + 0x806f0003, 0x80af0003, 0x80cf0420, 0x003fb0bc, + 0x5822b801, 0x01afb801, 0x003f90bc, 0xb520ffff, + 0x81270000, 0x8033007f, 0x9821ffff, 0x80171000, + 0xb600060a, 0x80470000, 0xb6000603, 0x015f8020, + 0x0156b80a, 0x1042b80a, 0x3002b801, 0xb4a00001, + 0x81270001, 0x00000000, 0x00000000, 0x015f0323, + 0x00000000, 0xb00a0000, 0xb4200002, 0x81670000, + 0xb5000001, 0x81670001, 0x017f23fb, 0x01ff41ee, + 0x59f0b80f, 0x61f0b80f, 0x021f41ef, 0x5a10b810, + 0x6210b810, 0xb00a0003, 0xb420003b, 0x017f039f, + 0x019f41c5, 0x5990b80c, 0x6190b80c, 0xb00b0000, + 0xb400000c, 0xb00c0000, 0xb4000005, 0xac4c0100, + 0x8033001d, 0x98215500, 0x12c1b802, 0xb500000f, + 0xac4f0100, 0x8033001d, 0x98215500, 0x12c1b802, + 0xb500000a, 0xb0090000, 0xb4000005, 0xac4f0100, + 0x8033ffe2, 0x9821ab00, 0x12c1b802, 0xb5000003, + 0xac4f0100, 0x00000000, 0x02c7b802, 0xb0030000, + 0xb420007e, 0x01bf03a0, 0x01df41c9, 0x59d0b80e, + 0x61d0b80e, 0xb00d0000, 0xb400000c, 0xb00e0000, + 0xb4000005, 0xac4e0100, 0x8033001d, 0x98215500, + 0x12e1b802, 0xb5000071, 0xac500100, 0x8033001d, + 0x98215500, 0x12e1b802, 0xb500006c, 0xb0090000, + 0xb4000005, 0xac500100, 0x8033ffe2, 0x9821ab00, + 0x12e1b802, 0xb5000065, 0xac500100, 0x00000000, + 0x02e7b802, 0xb5000061, 0xb00a0002, 0xb420002f, + 0x023f9002, 0x025f9001, 0xb00f0000, 0xb4a00007, + 0xac4f0100, 0x00000000, 0x4022b811, 0x00000000, + 0x0028b801, 0x02c7b801, 0xb500000c, 0xb0090000, + 0xb4000004, 0xac4f0100, 0x00000000, 0x02c7b802, + 0xb5000006, 0xac4f0100, 0x00000000, 0x4022b812, + 0x00000000, 0x0028b801, 0x02c7b801, 0xb0030000, + 0xb4200046, 0xb0100000, 0xb4a00007, 0xac500100, + 0x00000000, 0x4022b811, 0x00000000, 0x0028b801, + 0x02e7b801, 0xb500003d, 0xb0090000, 0xb4000004, + 0xac500100, 0x00000000, 0x02e7b802, 0xb5000037, + 0xac500100, 0x00000000, 0x4022b812, 0x00000000, + 0x0028b801, 0x02e7b801, 0xb5000030, 0x023f9002, + 0x025f9001, 0xb00f0000, 0xb4a00007, 0xac4f0100, + 0x00000000, 0x4022b811, 0x00000000, 0x0028b801, + 0x02c7b801, 0xb5000006, 0xac4f0100, 0x00000000, + 0x4022b812, 0x00000000, 0x0028b801, 0x02c7b801, + 0xb0090000, 0xb4000005, 0x0047b816, 0x8033ffe2, + 0x9821ab00, 0x1042b801, 0x02c7b802, 0xb0030000, + 0xb4200016, 0xb0100000, 0xb4a00007, 0xac500100, + 0x00000000, 0x4022b811, 0x00000000, 0x0028b801, + 0x02e7b801, 0xb5000006, 0xac500100, 0x00000000, + 0x4022b812, 0x00000000, 0x0028b801, 0x02e7b801, + 0xb0090000, 0xb4000005, 0x0047b817, 0x8033ffe2, + 0x9821ab00, 0x1042b801, 0x02e7b802, 0x00000000, + 0x00000000, 0x02c8b816, 0x02dfb0cf, 0xb0030000, + 0xb4200002, 0x02e8b817, 0x02ffb0c6, 0x00ffb81b, + 0xb6001807, 0x5841b802, 0x3015b800, 0xb4800002, + 0x06b5b800, 0x98420001, 0x5aa1b815, 0x00000000, + 0x00ffb81c, 0x00000000, 0x00000000, 0x00000000, + 0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000, + 0xb4000015, 0x815bb3f0, 0x81070000, 0x812707f8, + 0xb00a0000, 0xb4000006, 0x81070800, 0x81270ff8, + 0xb00a0001, 0xb4000002, 0x81071000, 0x812717f8, + 0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc, + 0x9421ffff, 0x3001b808, 0xb480000f, 0x3001b809, + 0xb4a00031, 0xb500000c, 0xb0040000, 0xb4200003, + 0x802717ff, 0x81070000, 0xb5000007, 0xb0040001, + 0xb4200002, 0x81070800, 0xb5000003, 0x80270001, + 0x003f23f9, 0x81071000, 0xb0040000, 0xb4200001, + 0x8384020c, 0x80af001f, 0x808f0000, 0x806f0000, + 0x80670400, 0x5d22b808, 0x81df0000, 0x00000000, + 0x00000000, 0xb600100a, 0x00cfb803, 0x013fb0bc, + 0x5922b809, 0x01afb809, 0x013f90bc, 0x0047b86f, + 0xb0020001, 0xb4c0fffd, 0x90630020, 0x91290020, + 0x81df0004, 0x801bb3f8, 0x80270001, 0xb0000001, + 0xb4000002, 0x802600a0, 0x803eb3f8, 0x914a0001, + 0xb00a0002, 0xb4a00001, 0x81470000, 0x815eb3f0, + 0x80270001, 0x003f2013, 0x00ffb81b, 0x00000000, + 0x029fb00a, 0x02bfb00b, 0x02dfb00c, 0x02ffb00d, + 0x031fb00e, 0x033fb00f, 0x033f400f, 0x0287b86f, + 0x029fb005, 0x8285009c, 0x96b48000, 0xb0158000, + 0xb4000195, 0x96b40100, 0xb0150100, 0xb40001ab, + 0x96b40400, 0xb0150400, 0xb40001ac, 0x96b40001, + 0xb0150001, 0xb400000c, 0x96b40008, 0xb0150008, + 0xb400019e, 0x96b44000, 0xb0154000, 0xb40001ab, + 0x96b40002, 0xb0150002, 0xb4000162, 0x00000000, + 0x00000000, 0xb50001bd, 0x02bf9017, 0x92b50001, + 0x02bfb017, 0x82850082, 0x5efdb814, 0x96f70001, + 0xb0170001, 0xb420000b, 0x83050069, 0x9718003f, + 0x82e50064, 0x12f7b818, 0x86f70109, 0x82feff74, + 0x02e7b86f, 0x9af74000, 0x01ffb817, 0x96f7bfff, + 0x01ffb817, 0x83050081, 0x82a5009a, 0x96b50001, + 0xb0150001, 0xb4200014, 0x82a70000, 0x02bfb017, + 0x96b41840, 0xb0150800, 0xb420000c, 0x96b40008, + 0x5aa9b815, 0x96d46000, 0x5ec3b816, 0x82f3000f, + 0x9af7c00f, 0x1718b817, 0x1ab5b818, 0x1ab5b816, + 0x9ab50340, 0x82a60081, 0xb5000132, 0x9b180180, + 0x83060081, 0xb500012f, 0x82a5009a, 0x96b50002, + 0xb0150002, 0xb420001b, 0x82a70000, 0x02bfb017, + 0x96b41800, 0xb0151800, 0xb4000013, 0x96b40040, + 0xb0150040, 0xb4200004, 0xa3180c00, 0x9b180340, + 0x83060081, 0xb500011f, 0x96b40008, 0x5aa9b815, + 0x96d46000, 0x5ec3b816, 0x82f3000f, 0x9af7c00f, + 0x1718b817, 0x1ab5b818, 0x1ab5b816, 0x9ab50340, + 0x82a60081, 0xb5000113, 0x9b180180, 0x83060081, + 0xb5000110, 0x82a500c1, 0x96b5000f, 0xb015000b, + 0xb420000e, 0x96b40020, 0xb0150020, 0xb400000b, + 0x96b40200, 0xb0150200, 0xb4000008, 0x82c50086, + 0x82e50094, 0x3016b817, 0xb4400004, 0x06f7b816, + 0xb017ff00, 0xb4400001, 0xb50000fe, 0x96b46000, + 0xb0156000, 0xb4000011, 0x96b41820, 0xb0150820, + 0xb4200004, 0x9b391000, 0x82a5009a, 0x96b5feff, + 0x82a6009a, 0x96b40040, 0xb0150040, 0xb4200001, + 0x9739efff, 0x96b91000, 0xb0151000, 0xb4200003, + 0x82a5009a, 0x9ab50100, 0x82a6009a, 0x96b40040, + 0xb0150040, 0xb4200019, 0x96b41800, 0xb0151800, + 0xb4200006, 0x96b98000, 0xb0158000, 0xb4200003, + 0x9b180180, 0x83060081, 0xb50000de, 0x96d80c00, + 0x82b300ff, 0x9ab5f3ff, 0x1718b815, 0xb0160c00, + 0xb4000007, 0x82e50098, 0x96f70400, 0xb0170400, + 0xb4200002, 0x82c70c00, 0xb5000001, 0xa2d60c00, + 0x1b18b816, 0x9b180340, 0xb50000c4, 0x96b40220, + 0xb0150000, 0xb4e00028, 0x82a5009d, 0x82f3ffff, + 0x16b5b817, 0x82f3000e, 0x3015b817, 0xb4200022, + 0x96f98000, 0xb0178000, 0xb400001f, 0x82a70000, + 0x02bfb017, 0x82c50081, 0x9ab60020, 0x82a60081, + 0x82a50086, 0x92b50bb8, 0x82a60094, 0x82c60081, + 0x82c5009d, 0x96d6ffff, 0x82b30032, 0x9ab58001, + 0x82e500c1, 0x96f7000f, 0xb017000b, 0xb4000002, + 0x82b30022, 0x9ab58001, 0x1ab5b816, 0x82c5009a, + 0x96d60020, 0xb0160020, 0xb4200002, 0x82b30032, + 0x9ab58001, 0x82a6009d, 0x02ff9017, 0x00000000, + 0xb0170040, 0xb4800000, 0x5eb5b814, 0x96b500f0, + 0x96f46000, 0x5eedb817, 0x1ab5b817, 0xb0170003, + 0xb4000004, 0x96b500ef, 0x96f70001, 0x5ae4b817, + 0x1ab5b817, 0x96d41800, 0xb0161800, 0xb400000a, + 0x96f900ff, 0x96b500ff, 0x9739ff00, 0x1b39b815, + 0x02a7b817, 0x96b500f3, 0x96d40008, 0x5ec1b816, + 0x1ab5b816, 0xb500000c, 0x96f98000, 0xb0178000, + 0xb4200007, 0x5efeb814, 0x96f70001, 0xb0170001, + 0xb4000003, 0x9b180180, 0x83060081, 0xb5000081, + 0x96b500f3, 0x9ab50008, 0x9739fff3, 0x96d40020, + 0xb0160020, 0xb4200017, 0x9b398000, 0x82c70000, + 0x02dfb017, 0x96d40010, 0x5ac8b816, 0x82f300ff, + 0x9af7cfff, 0x1718b817, 0x1b18b816, 0x9b180340, + 0x82c5009d, 0x96d6ffff, 0x82f3000e, 0x9af78001, + 0x1af7b816, 0x82c5009a, 0x96d60020, 0xb0160020, + 0xb4200002, 0x82f30032, 0x9af78001, 0x82e6009d, + 0xb500005a, 0x97397fff, 0x96b500ff, 0x5aaab815, + 0x82f300fc, 0x9af703ff, 0x1718b817, 0x1b18b815, + 0x9b180340, 0x82c5009a, 0x96d60010, 0xb0160010, + 0xb4200024, 0x82c70000, 0x02dfb017, 0x82c50086, + 0x92d60bb8, 0x82c60086, 0x82c50094, 0x5eefb818, + 0x96f70003, 0xb0170003, 0xb4200002, 0x82e70bb8, + 0xb5000001, 0x82e70bb8, 0x12d6b817, 0x82e50081, + 0x9af70020, 0x82e60081, 0x82c60094, 0xa2f70020, + 0x82e60081, 0x82f30001, 0x16f7b818, 0x5ef0b817, + 0xb0170001, 0xb4000004, 0x96f84000, 0x5ee4b817, + 0x9718f3ff, 0x1b18b817, 0x82f3000a, 0x9af78000, + 0x82e6009d, 0x83060081, 0x83070001, 0x8306009f, + 0xb5000096, 0x82c5009d, 0x82f3000e, 0x9af78001, + 0x3016b817, 0xb420000f, 0x82b30032, 0x9ab58001, + 0x82e500c1, 0x96f7000f, 0xb017000b, 0xb4000002, + 0x82b30022, 0x9ab58001, 0x82c5009a, 0x96d60020, + 0xb0160020, 0xb4200002, 0x82b30032, 0x9ab58001, + 0x82a6009d, 0x82c5009a, 0x96d60080, 0xb0160080, + 0xb4000011, 0x02df9017, 0x00000000, 0xb0160010, + 0xb480000d, 0x82c500c1, 0x96d6000f, 0xb016000b, + 0xb4000009, 0x82c50087, 0x96d60080, 0x5ac7b816, + 0x96f84000, 0x3017b816, 0xb4200003, 0x033f400f, + 0x9b394000, 0xb500000b, 0x9739bfff, 0x82e50061, + 0x96f70008, 0xb0170008, 0xb4000005, 0x5eefb818, + 0x96f70003, 0xb0170003, 0xb4000001, 0x9718ffff, + 0x83060081, 0x83070001, 0x8306009f, 0x00000000, + 0xb500005e, 0x82850083, 0x96b400ff, 0xb015003c, + 0xb4200019, 0x96b92000, 0xb0152000, 0xb4000002, + 0x9b392000, 0xb5000014, 0x9739d3ff, 0x82870000, + 0x82860087, 0x82870008, 0x82860083, 0x829bff78, + 0x82a7001f, 0xb0140400, 0xb4000001, 0x82a70010, + 0x82a600c9, 0x829bff78, 0x00000000, 0x828600cb, + 0x8285009d, 0x82b3ffff, 0x9ab5fffd, 0x1694b815, + 0x8286009d, 0xb5000000, 0x83070002, 0x8306009f, + 0x00000000, 0xb500003d, 0x96b90800, 0xb0150800, + 0xb4200009, 0x9739f7ff, 0x82a703fd, 0x82a600cb, + 0x82a7003c, 0x82a60083, 0x8285009d, 0x9a940002, + 0x8286009d, 0xb5000004, 0x82850087, 0x5a82b814, + 0xa2940200, 0x82860087, 0xb5000000, 0x83078000, + 0x8306009f, 0x00000000, 0xb5000028, 0x83070008, + 0x8306009f, 0x00000000, 0xb5000024, 0x83070100, + 0x8306009f, 0x00000000, 0xb5000020, 0x83070000, + 0x83050081, 0x9b180180, 0x83060081, 0x83070400, + 0x8306009f, 0x00000000, 0xb5000018, 0x82870000, + 0x82850082, 0x5eb7b814, 0x96b500fc, 0x96d40006, + 0x5ec1b816, 0x1ab5b816, 0x5aacb815, 0x83050081, + 0x82d3001c, 0x9ad600ff, 0x1718b816, 0x1b18b815, + 0x9b180e00, 0x83060081, 0x83074000, 0x8306009f, + 0x8305009d, 0x82d300ff, 0x9ad6bfff, 0x1718b816, + 0x8306009d, 0x00000000, 0xb5000000, 0x029f9005, + 0x01ffb814, 0x033f600f, 0x029f900a, 0x02bf900b, + 0x02df900c, 0x02ff900d, 0x031f900e, 0x033f900f, + 0x00ffb81e, 0x02ff9010, 0x92f70b43, 0x02ffb010, + 0x02ff90cb, 0x82bbffdc, 0x829bffd8, 0x93150004, + 0x3014b815, 0xb400000f, 0x02dbb818, 0x029bb815, + 0x3017b816, 0xb480000b, 0x5a81b814, 0x029fb010, + 0x82860095, 0x8293001f, 0x9294fe00, 0x92b50008, + 0x3015b814, 0xb4800002, 0x82b3001f, 0x92b5fa00, + 0x82beffdc, 0x029f9010, 0x83250094, 0x06d4b819, + 0x02d6b816, 0xb016ffff, 0xb4a0000a, 0x8293000e, + 0x9a948001, 0x82c5009d, 0x96d6ffff, 0x1a94b816, + 0x82c5009a, 0x96d60010, 0xb0160010, 0xb4000001, + 0x8286009d, 0x00ffb81c, 0x82870001, 0x829ef500, + 0x82850086, 0x83250094, 0x06d4b819, 0x02d6b816, + 0xb016ffff, 0xb4a0000b, 0x82870001, 0x829ef504, + 0x82c50081, 0x9ab60020, 0x82a60081, 0x82a50086, + 0x92b50bbb, 0x82a60094, 0x82c60081, 0x86b505df, + 0x82a6009b, 0x00ffb81c, 0x82070028, 0x023f9006, + 0x83a4ef48, 0x80070000, 0x001fb011, 0x001f204f, + 0x003fb800, 0x001f9006, 0x5803b800, 0x80338000, + 0x1800b801, 0x003fb800, 0x005f4193, 0x5c41b802, + 0x80350000, 0x00000000, 0x0027b860, 0x80150010, + 0x5810b800, 0x80750010, 0x1863b800, 0x8087ffff, + 0x80a7770b, 0x80c70000, 0x1403b804, 0x3000b805, + 0xb4000008, 0x5888b804, 0x58a8b805, 0x90c60001, + 0xb0060003, 0xb4a0fff8, 0x84420001, 0xb4e0ffee, + 0xb5000027, 0xb0060003, 0xb4200007, 0x80150010, + 0x5810b800, 0x81150010, 0x950800ff, 0xb0080077, + 0xb4000001, 0xb500fff4, 0x001f400e, 0x98000010, + 0x98004000, 0x9400fffe, 0x001f600e, 0x80e71fe0, + 0x001f4000, 0x94000080, 0xb0000080, 0xb4200001, + 0x80e77580, 0x00ffb008, 0x80e70020, 0xb0060000, + 0xb400000e, 0x58e3b806, 0x90210020, 0x81070000, + 0x5938b803, 0x1908b809, 0x9523ff00, 0x5928b809, + 0x1908b809, 0x5d28b803, 0x9529ff00, 0x1908b809, + 0x5d38b803, 0x1908b809, 0x011fb011, 0x00ff204f, + 0x80137fff, 0x9800ffe7, 0x1421b800, 0x5c23b801, + 0x001f9006, 0x0441b800, 0x3001b800, 0xb4600002, + 0x0440b801, 0xa4422000, 0x007f90cb, 0x1063b802, + 0x007fb0cb, 0x003fb006, 0x803effec, 0x80470001, + 0x005f2013, 0xb500eba6, 0x001f400e, 0x9400000f, + 0xb0000000, 0xb4200001, 0x00ffb81f, 0xb0000001, + 0xb4000005, 0xb0000003, 0xb4000003, 0xb0000002, + 0xb4000001, 0x00ffb81f, 0x80070001, 0x001f2013, + 0xb500eb97, 0x00000000, 0x00000000, 0x00000000, + 0x001f9012, 0x001fb100, 0x001f004c, 0x001f2404, + 0x801bfef0, 0x8058fef4, 0x803bff68, 0x8078ff6c, + 0x2000b801, 0x2042b803, 0x001fb104, 0x005f2414, + 0x82e70001, 0x83640048, 0x029fb014, 0x829efef0, + 0x8286000f, 0x02bf2054, 0x82bcfef4, 0x82a6000e, + 0x00ffb81a, 0x80e70001, 0x801336e3, 0x9800eb76, + 0x001fb100, 0x800700ab, 0x001f2404, 0x801bc3e8, + 0x8058c3ec, 0x83640024, 0x82e70000, 0x83640036, + 0x029fb300, 0x029fb100, 0x02bf2c04, 0x02bf2404, + 0x801bc000, 0x8058c004, 0x8364001b, 0x82e70000, + 0x8364002d, 0x001f9300, 0x3000b814, 0xb420000a, + 0x001f0c04, 0x3000b815, 0xb4200007, 0x829efef0, + 0x82bcfef4, 0x029fb012, 0x02bf204c, 0x82870001, + 0x829cfef5, 0x00ffb81a, 0xb0070000, 0xb4000007, + 0x80e70000, 0x801399fa, 0x9800c92e, 0x001fb100, + 0x800700af, 0x001f2404, 0xb500ffdc, 0x82870000, + 0x829cfef5, 0x00ffb81a, 0x80c700ff, 0x803bff68, + 0x8078ff6c, 0x14a0b806, 0x2063b805, 0x007f2414, + 0x2021b802, 0x58c8b806, 0x14a0b806, 0x58b0b805, + 0x2021b805, 0x58c8b806, 0x14a0b806, 0x2021b805, + 0x58c8b806, 0x14a0b806, 0x5cb0b805, 0x2021b805, + 0x003fb104, 0x00ffb81b, 0x82c70000, 0x83070400, + 0x83270005, 0x8197040c, 0x81d7ffff, 0x83840126, + 0x83840001, 0x00ffb81b, 0x808f0000, 0x806f001f, + 0x80af001f, 0x80270140, 0x81e7ef98, 0x5de2b80f, + 0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, + 0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020, + 0x90210020, 0x80270180, 0x81e7ee90, 0x5de2b80f, + 0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, + 0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020, + 0x90210020, 0x8057ffff, 0x80170430, 0x80070410, + 0x80270408, 0xb6000509, 0x005ff000, 0x90420500, + 0x007ff001, 0x90630600, 0x009ff002, 0x00bff003, + 0x2004a025, 0x90000001, 0x90210001, 0x80070414, + 0x80d7ffff, 0x8097045c, 0x8017043c, 0xb6000404, + 0x005ff000, 0x007f87e0, 0x84000001, 0x2082a7e3, + 0x80970460, 0x80170440, 0x2082b803, 0x007f8000, + 0x2083a004, 0x80170430, 0x80970450, 0x80270408, + 0xb6000508, 0x005f8024, 0x90420500, 0x007ff001, + 0x90630600, 0x009ff002, 0x00bff003, 0x2004a025, + 0x90210001, 0x80170440, 0x00000000, 0x02bf87e0, + 0x80970460, 0x82870000, 0xb6000404, 0x005f87e4, + 0x5a88b814, 0x204287e0, 0x1a94b802, 0x00ffb81c, + 0x001f0a49, 0x001f2709, 0x001f0a41, 0x001f2708, + 0x001f0a46, 0x001f2707, 0x001f0a48, 0x001f2706, + 0x001f0a42, 0x001f2705, 0x001f0a47, 0x001f2704, + 0x001f0a45, 0x001f2703, 0x001f0a43, 0x001f2702, + 0x001f0a40, 0x001f2701, 0x001f0a44, 0x001f2700, + 0x001f0c25, 0xa020000c, 0x94400001, 0x94600002, + 0x94810004, 0x94a10008, 0x94c00010, 0x5943b802, + 0x5861b803, 0x5882b804, 0x5ca2b805, 0x5cc4b806, + 0x194ab803, 0x194ab804, 0x194ab805, 0x194ab806, + 0x015f2738, 0x801bef90, 0x003f91c1, 0x5c28b801, + 0x005f91c2, 0x5858b802, 0x1821b802, 0x2000b801, + 0x001fb1c4, 0x8018ef94, 0x003f0709, 0x2000b801, + 0x001f2714, 0x82c70001, 0x82e70001, 0x83070710, + 0x8327001e, 0x81970735, 0x8384009f, 0x02df0738, + 0x82170a30, 0x838400f1, 0x819efef0, 0x817cfef4, + 0x819eff68, 0x817cff6c, 0x00ffb81b, 0x820f001f, + 0x8018fef8, 0x8057ffff, 0x001f2709, 0x8018fef6, + 0x80d7ffff, 0x001f2708, 0x8018fefa, 0x8157ffff, + 0x001f2707, 0x8018fefd, 0x81d7ffff, 0x001f2706, + 0x8018fefb, 0x802f001f, 0x001f2705, 0x8018fefe, + 0x00000000, 0x001f2704, 0x8018fef9, 0x00000000, + 0x001f2703, 0x8018feff, 0x00000000, 0x001f2702, + 0x8018fef7, 0x00000000, 0x001f2701, 0x8018fefc, + 0x00000000, 0x001f2700, 0x001f0c25, 0xa0200011, + 0x94410001, 0x94600002, 0x94800004, 0x94a00008, + 0x94c10010, 0x5941b802, 0x5861b803, 0x5c82b804, + 0x58a1b805, 0x5cc1b806, 0x194ab803, 0x194ab804, + 0x194ab805, 0x194ab806, 0x015f2738, 0x801bef90, + 0x003f91c1, 0x5c28b801, 0x005f91c2, 0x5858b802, + 0x1821b802, 0x2000b801, 0x001fb1c4, 0x8018ef94, + 0x003f0709, 0x2000b801, 0x001f2714, 0x82c70001, + 0x82e70001, 0x83070710, 0x8327001e, 0x81970735, + 0x83840055, 0x02df0738, 0x82170a20, 0x838400a7, + 0x819efef0, 0x817cfef4, 0x5ac8b80c, 0x02ff0a44, + 0x1ad6b817, 0x02dfb291, 0x5ed8b80c, 0x5968b80b, + 0x1ad6b80b, 0x02df6524, 0x00ffb81b, 0x820f001f, + 0x8018fefe, 0x8057ffff, 0x001f2709, 0x8018fefa, + 0x80d7ffff, 0x001f2708, 0x8018fefc, 0x8157ffff, + 0x001f2707, 0x8018feff, 0x81d7ffff, 0x001f2706, + 0x8018fef8, 0x802f001f, 0x001f2705, 0x8018fefb, + 0x00000000, 0x001f2704, 0x8018fefd, 0x00000000, + 0x001f2703, 0x8018fef6, 0x00000000, 0x001f2702, + 0x8018fef9, 0x00000000, 0x001f2701, 0x8018fef7, + 0x00000000, 0x001f2700, 0x801bef90, 0x003f91c1, + 0x5c28b801, 0x005f91c2, 0x5858b802, 0x1821b802, + 0x2000b801, 0x001fb1c4, 0x8018ef94, 0x003f0709, + 0x2000b801, 0x001f2714, 0x82c70001, 0x82e70001, + 0x83070710, 0x8327001e, 0x81970735, 0x83840016, + 0x83270000, 0x831bfef0, 0x82f8fef4, 0x02c7b819, + 0x82170a28, 0x83840065, 0x300cb818, 0xb4200002, + 0x300bb817, 0xb4000006, 0x93390001, 0xb0190020, + 0xb480fff6, 0x83270000, 0x833cfef5, 0x00ffb81b, + 0x019fb290, 0x017f2a44, 0x033f2c25, 0x83270001, + 0x833cfef5, 0x00ffb81b, 0x0007b818, 0x90000003, + 0x00000000, 0x015ff000, 0x90000001, 0x5949b80a, + 0x013ff000, 0x194ab809, 0x84000002, 0x994a0100, + 0x017ff000, 0x958b00f8, 0x5981b80c, 0x956b0007, + 0x198cb80b, 0x84000002, 0x998c0008, 0x017ff000, + 0x90000001, 0x5971b80b, 0x198cb80b, 0x017ff000, + 0x5969b80b, 0x198cb80b, 0x81a70000, 0x94d90003, + 0x82a70000, 0xb6260019, 0xb6000818, 0x5df0b80a, + 0x5e02b80a, 0x21efb810, 0x95ef0001, 0x5941b80a, + 0x194ab80f, 0x21efb816, 0x5e18b80c, 0x5e35b80c, + 0x5e54b80c, 0x5e6cb80c, 0x2210b811, 0x2252b813, + 0x2210b812, 0x96100001, 0x5981b80c, 0x198cb810, + 0x2210b817, 0x10afb810, 0x10a5b80d, 0x5da1b805, + 0x94a50001, 0x5aa1b815, 0x1ab5b805, 0x019fa7f5, + 0x5cc2b819, 0xb626001c, 0x82870000, 0xb6000419, + 0xb6000818, 0x5df0b80a, 0x5e02b80a, 0x21efb810, + 0x95ef0001, 0x5941b80a, 0x194ab80f, 0x21efb816, + 0x5e18b80c, 0x5e35b80c, 0x5e54b80c, 0x5e6cb80c, + 0x2210b811, 0x2252b813, 0x2210b812, 0x96100001, + 0x5981b80c, 0x198cb810, 0x2210b817, 0x10afb810, + 0x10a5b80d, 0x5da1b805, 0x94a50001, 0x5a81b814, + 0x1a94b805, 0x019fa7f4, 0x00ffb81c, 0x8257ffff, + 0x808f0000, 0x806f001f, 0x80af001f, 0x80270200, + 0x81e7ec70, 0x5de2b80f, 0xb6000208, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0xb520ffff, 0x91ef0020, 0x90210020, 0x80270240, + 0x81e7ed70, 0x5de2b80f, 0xb6000208, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0xb520ffff, 0x91ef0020, 0x90210020, 0x80270180, + 0x81e7ee90, 0x5de2b80f, 0xb6000208, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0xb520ffff, 0x91ef0020, 0x90210020, 0x806f0007, + 0x80af0007, 0x80270280, 0x81e7ee70, 0x5de2b80f, + 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, + 0x01ff90bc, 0xb520ffff, 0x91ef0020, 0x90210020, + 0x80170760, 0x001f0700, 0x001fa020, 0x001f0701, + 0x001fa020, 0x001f0702, 0x001fa020, 0x001f0703, + 0x001fa020, 0x001f0704, 0x001fa000, 0x80970750, + 0x81170770, 0x82a70735, 0x83a40060, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a4005c, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750, + 0x81170750, 0x81970740, 0x82a70730, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a40050, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a4004c, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970750, 0x80170770, + 0x81170770, 0x81970760, 0x82a7072b, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a40040, 0x83a4004e, + 0xb6000407, 0x86b50001, 0x83a4003c, 0x001f8004, + 0x003f87e8, 0x2080a001, 0x83a40047, 0x00000000, + 0x80970770, 0x80170750, 0x81170750, 0x81970740, + 0x82a70726, 0x001f800c, 0x003f8008, 0x2100a001, + 0x83a4002e, 0x83a4003c, 0xb6000407, 0x86b50001, + 0x83a4002a, 0x001f8004, 0x003f87e8, 0x2080a001, + 0x83a40035, 0x00000000, 0x80970750, 0x80170770, + 0x81170770, 0x81970760, 0x82a70721, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a4001c, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a40018, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750, + 0x81170750, 0x81970740, 0x82a7071c, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a4000c, 0x017f87e4, + 0x81870000, 0xb6000406, 0x86b50001, 0x83a40007, + 0x001f87e4, 0x200087e8, 0x5988b80c, 0x198cb800, + 0x021fa02c, 0x021fa00b, 0x00ffb81c, 0x005ff015, + 0x90420600, 0x003f87e0, 0x001ff002, 0x2060b801, + 0x90630800, 0x90960a00, 0x001ff003, 0x003ff004, + 0x20a0b801, 0x90a50900, 0x00000000, 0x001ff005, + 0x009fa000, 0x00ffb81d, 0x001f8004, 0x5c21b800, + 0x5847b800, 0x1821b802, 0x942100ff, 0x2080a7e1, + 0x00ffb81d, 0x00000000, 0x00000000, 0x00000000, + 0x015f400e, 0x944a4000, 0xb0024000, 0xb420001e, + 0x954abfff, 0x015f600e, 0x820f001f, 0x802f001f, + 0x81470000, 0x015f23f9, 0x015fb0ba, 0x8057ffff, + 0x80770000, 0x82970400, 0x82d7ffff, 0x82f70000, + 0x81df0000, 0x00000000, 0x00000000, 0xb6000702, + 0xb6000001, 0x029fa02a, 0x81df0004, 0x80275480, + 0x005fb801, 0x8033001f, 0x9821c000, 0x803effe0, + 0x90212000, 0x803effe4, 0x80d9ff80, 0x00df6001, + 0x81477608, 0x015fb008, 0x003f0324, 0xb0010000, + 0xb420007e, 0x8344ebde, 0xb0180000, 0xb4000004, + 0x011f400e, 0x1908b818, 0x011f600e, 0x00ffb81f, + 0x8344f1d7, 0xb00b0000, 0xb4000006, 0x023f400e, + 0x9a310002, 0x023f600e, 0x82270000, 0x023f2012, + 0x00ffb81f, 0x8364ed6a, 0x82270000, 0x023f2011, + 0x80070000, 0x80170800, 0x81df0000, 0x00000000, + 0x00000000, 0xb6002002, 0xb6003001, 0x001fa020, + 0x81df0004, 0x82270000, 0x003fb811, 0x02bf9006, + 0x5aa3b815, 0x82338000, 0x1a31b815, 0x003fb811, + 0x8067e950, 0x5c62b803, 0x81f50000, 0x019f4193, + 0x0267b80c, 0xadcc0010, 0x80170800, 0x80130000, + 0x9800f872, 0x001fa020, 0x80134e1f, 0x98000001, + 0x001fa020, 0x59d0b80e, 0x81150010, 0x1908b80e, + 0x001fa028, 0x858c0001, 0x5e01b80c, 0x5e25b810, + 0x81df0000, 0x00000000, 0x00000000, 0xb6310006, + 0xb6002005, 0x81150010, 0x5910b808, 0x00000000, + 0x81350010, 0x1808a029, 0x9630001f, 0xb0110000, + 0xb4000006, 0xb6310005, 0x81150010, 0x5910b808, + 0x00000000, 0x81350010, 0x1808a029, 0x81df0004, + 0x962c0001, 0xb0110000, 0xb4000003, 0x81150010, + 0x5910b808, 0x001fa028, 0x019f9006, 0x958cffff, + 0x00df4193, 0x58c1b806, 0x118cb806, 0xb00ce000, + 0xb4800002, 0x858ce000, 0x918cc000, 0x8153001f, + 0x118cb80a, 0x819effec, 0x019fb006, 0x015f4193, + 0x5941b80a, 0x019f90cb, 0x118cb80a, 0x019fb0cb, + 0x019f90ba, 0x918c0001, 0x019fb0ba, 0xb00c0002, + 0xb4200016, 0x019f400e, 0x940c8000, 0xb0008000, + 0xb4200012, 0x958c7fff, 0x019f600e, 0x80070000, + 0x800600a0, 0x80073da1, 0x800600a1, 0x801bff60, + 0x00000000, 0x801eff60, 0x00000000, 0x801bff60, + 0x00000000, 0x801eff60, 0x80130001, 0x98003da1, + 0x800600a1, 0x80070001, 0x800600a0, 0x003f0324, + 0x90210001, 0xb0010005, 0xb4a00001, 0x80270000, + 0x003f2324, 0x00ffb81f, 0x00000000, 0x00000000, + 0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000, + 0xb4000011, 0x815bb3f0, 0x81070000, 0x81270bf4, + 0xb00a0000, 0xb4000002, 0x81070c00, 0x81271800, + 0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc, + 0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809, + 0xb4a00032, 0xb5000008, 0xb0040000, 0xb4200003, + 0x802717ff, 0x81470000, 0xb5000003, 0x80270001, + 0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200001, + 0x8384fbf4, 0x80af001f, 0x808f0002, 0x806f0000, + 0x807bbf34, 0x5d22b80a, 0x81df0000, 0x00000000, + 0x00000000, 0xb600080a, 0x00cfb803, 0x013fb0bc, + 0x5922b809, 0x01afb809, 0x013f90bc, 0x0047b86f, + 0xb0020001, 0xb4c0fffd, 0x90630020, 0x91290060, + 0x81df0004, 0x808f0000, 0x813bb3f8, 0x80270001, + 0xb0090001, 0xb4000002, 0x802600a0, 0x803eb3f8, + 0x81270c00, 0xb00a0000, 0xb4000001, 0x81270000, + 0x813eb3f0, 0xb0030800, 0xb4800001, 0x80670200, + 0x807ebf34, 0x80270001, 0x003f2013, 0x00ffb81b, +}; + +static u32 AC3I2SUcode1f8000[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00020000, 0xffff0005, 0xffffffff, + 0x00050001, 0xffffffff, 0xffffffff, 0x00020000, + 0xffff0005, 0xffffffff, 0x00010000, 0x00050002, + 0xffffffff, 0x00020000, 0x00050003, 0xffffffff, + 0x00010000, 0x00030002, 0xffff0005, 0x00020000, + 0x00040003, 0xffff0005, 0x00010000, 0x00030002, + 0x00050004, 0x0019000d, 0x003d0025, 0x00250019, + 0x00fd003d, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x007fffff, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x007fffff, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x007fffff, 0x00000000, + 0x00000000, 0x00599999, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00599999, + 0x007fffff, 0x00599999, 0x00000000, 0x00599999, + 0x00000000, 0x00000000, 0x00000000, 0x00599999, + 0x00000000, 0x00599999, 0x007fffff, 0x00000000, + 0x00599999, 0x00599999, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00599999, 0x00599999, + 0x007fffff, 0x007fffff, 0x00000000, 0x00599999, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00599999, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x007fffff, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x007fffff, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x007fffff, 0x00000000, + 0x007fffff, 0x00000000, 0x007fffff, 0x00400000, + 0x00200000, 0x00100000, 0x00080000, 0x00040000, + 0x00020000, 0x00010000, 0x00008000, 0x00004000, + 0x00002000, 0x00001000, 0x00000800, 0x00000400, + 0x00000200, 0x00000100, 0x00000080, 0x00000040, + 0x00000020, 0x00000010, 0x00000008, 0x00000004, + 0x00000002, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00010002, + 0x00030002, 0x00030002, 0x00030002, 0x00000000, + 0x00000000, 0x00010001, 0x00020002, 0x4000a000, + 0xe000a000, 0xf000b000, 0xf800b800, 0x005a8279, + 0x004c1bf8, 0x00400000, 0x004c1bf8, 0x005a8279, + 0x00400000, 0x00000000, 0x00400000, 0x03020100, + 0x00000000, 0x00000080, 0x00000020, 0x00000008, + 0x00000000, 0x00000001, 0x00010001, 0x10001000, + 0x10001004, 0x10041004, 0x10041004, 0x10041004, + 0x00000000, 0x00000000, 0x00000000, 0xff80000a, + 0xff80031f, 0xff800b24, 0xff801818, 0xff8029fa, + 0xff8040c9, 0xff805c86, 0xff807d2e, 0xff80a2c1, + 0xff80cd3c, 0xff80fc9f, 0xff8130e8, 0xff816a14, + 0xff81a821, 0xff81eb0e, 0xff8232d6, 0xff827f79, + 0xff82d0f2, 0xff83273e, 0xff83825b, 0xff83e244, + 0xff8446f7, 0xff84b06e, 0xff851ea6, 0xff85919b, + 0xff860949, 0xff8685aa, 0xff8706ba, 0xff878c74, + 0xff8816d3, 0xff88a5d1, 0xff89396a, 0xff89d196, + 0xff8a6e51, 0xff8b0f94, 0xff8bb55a, 0xff8c5f9b, + 0xff8d0e51, 0xff8dc176, 0xff8e7902, 0xff8f34ef, + 0xff8ff535, 0xff90b9cc, 0xff9182ae, 0xff924fd3, + 0xff932132, 0xff93f6c3, 0xff94d07f, 0xff95ae5d, + 0xff969054, 0xff97765b, 0xff98606a, 0xff994e78, + 0xff9a407c, 0xff9b366b, 0xff9c303e, 0xff9d2de9, + 0xff9e2f64, 0xff9f34a4, 0xffa03da0, 0xffa14a4c, + 0xffa25aa0, 0xffa36e8f, 0xffa48610, 0xffa5a118, + 0xffa6bf9c, 0xffa7e191, 0xffa906ec, 0xffaa2fa0, + 0xffab5ba4, 0xffac8aeb, 0xffadbd6a, 0xffaef315, + 0xffb02bdf, 0xffb167be, 0xffb2a6a4, 0xffb3e886, + 0xffb52d56, 0xffb67509, 0xffb7bf92, 0xffb90ce4, + 0xffba5cf2, 0xffbbafb0, 0xffbd050f, 0xffbe5d04, + 0xffbfb780, 0xffc11477, 0xffc273db, 0xffc3d59f, + 0xffc539b4, 0xffc6a00d, 0xffc8089d, 0xffc97355, + 0xffcae027, 0xffcc4f05, 0xffcdbfe2, 0xffcf32af, + 0xffd0a75d, 0xffd21ddf, 0xffd39625, 0xffd51022, + 0xffd68bc7, 0xffd80904, 0xffd987cd, 0xffdb0810, + 0xffdc89c1, 0xffde0cd0, 0xffdf912d, 0xffe116cb, + 0xffe29d9a, 0xffe4258b, 0xffe5ae8f, 0xffe73896, + 0xffe8c392, 0xffea4f74, 0xffebdc2b, 0xffed69aa, + 0xffeef7df, 0xfff086bd, 0xfff21634, 0xfff3a634, + 0xfff536ad, 0xfff6c792, 0xfff858d1, 0xfff9ea5b, + 0xfffb7c22, 0xfffd0e16, 0xfffea026, 0xffffcdbc, + 0xfffe3ba0, 0xfffca995, 0xfffb17ac, 0xfff985f3, + 0xfff7f479, 0xfff6634f, 0xfff4d284, 0xfff34228, + 0xfff1b249, 0xfff022f7, 0xffee9442, 0xffed0638, + 0xffeb78ea, 0xffe9ec67, 0xffe860bd, 0xffe6d5fd, + 0xffe54c35, 0xffe3c374, 0xffe23bcb, 0xffe0b547, + 0xffdf2ff7, 0xffddabec, 0xffdc2933, 0xffdaa7dd, + 0xffd927f6, 0xffd7a98f, 0xffd62cb7, 0xffd4b17b, + 0xffd337ea, 0xffd1c013, 0xffd04a05, 0xffced5ce, + 0xffcd637c, 0xffcbf31d, 0xffca84c1, 0xffc91874, + 0xffc7ae45, 0xffc64641, 0xffc4e078, 0xffc37cf6, + 0xffc21bc9, 0xffc0bcff, 0xffbf60a5, 0xffbe06c9, + 0xffbcaf79, 0xffbb5ac0, 0xffba08ae, 0xffb8b94d, + 0xffb76cac, 0xffb622d8, 0xffb4dbdc, 0xffb397c6, + 0xffb256a2, 0xffb1187d, 0xffafdd62, 0xffaea55f, + 0xffad707e, 0xffac3ecc, 0xffab1054, 0xffa9e523, + 0xffa8bd44, 0xffa798c2, 0xffa677a8, 0xffa55a02, + 0xffa43fdb, 0xffa3293d, 0xffa21634, 0xffa106c9, + 0xff9ffb08, 0xff9ef2fa, 0xff9deeab, 0xff9cee23, + 0xff9bf16c, 0xff9af892, 0xff9a039c, 0xff991295, + 0xff982586, 0xff973c78, 0xff965774, 0xff957683, + 0xff9499ad, 0xff93c0fb, 0xff92ec75, 0xff921c24, + 0xff91500f, 0xff90883f, 0xff8fc4bb, 0xff8f058b, + 0xff8e4ab6, 0xff8d9443, 0xff8ce239, 0xff8c349f, + 0xff8b8b7d, 0xff8ae6d7, 0xff8a46b5, 0xff89ab1e, + 0xff891416, 0xff8881a3, 0xff87f3cc, 0xff876a96, + 0xff86e606, 0xff866621, 0xff85eaed, 0xff85746d, + 0xff8502a6, 0xff84959e, 0xff842d57, 0xff83c9d7, + 0xff836b20, 0xff831138, 0xff82bc20, 0xff826bdc, + 0xff822070, 0xff81d9de, 0xff819829, 0xff815b54, + 0xff812360, 0xff80f051, 0xff80c228, 0xff8098e6, + 0xff80748e, 0xff805521, 0xff803a9f, 0xff80250b, + 0xff801464, 0xff8008ad, 0xff8001e4, 0xff800027, + 0xff800c7e, 0xff802c8f, 0xff806056, 0xff80a7cb, + 0xff8102e4, 0xff817191, 0xff81f3c3, 0xff828964, + 0xff83325f, 0xff83ee98, 0xff84bdf3, 0xff85a04f, + 0xff86958b, 0xff879d7f, 0xff88b804, 0xff89e4ee, + 0xff8b240e, 0xff8c7533, 0xff8dd82a, 0xff8f4cbb, + 0xff90d2ad, 0xff9269c4, 0xff9411c1, 0xff95ca62, + 0xff979365, 0xff996c81, 0xff9b5570, 0xff9d4de4, + 0xff9f5590, 0xffa16c24, 0xffa3914e, 0xffa5c4b8, + 0xffa8060d, 0xffaa54f3, 0xffacb10e, 0xffaf1a03, + 0xffb18f70, 0xffb410f7, 0xffb69e33, 0xffb936c0, + 0xffbbda37, 0xffbe8830, 0xffc14042, 0xffc40201, + 0xffc6cd00, 0xffc9a0d2, 0xffcc7d05, 0xffcf612b, + 0xffd24ccf, 0xffd53f80, 0xffd838c8, 0xffdb3833, + 0xffde3d49, 0xffe14795, 0xffe4569d, 0xffe769e9, + 0xffea80ff, 0xffed9b67, 0xfff0b8a4, 0xfff3d83c, + 0xfff6f9b5, 0xfffa1c91, 0xfffd4056, 0xffff9b78, + 0xfffc7756, 0xfff953c0, 0xfff63130, 0xfff31025, + 0xffeff117, 0xffecd484, 0xffe9bae5, 0xffe6a4b6, + 0xffe39270, 0xffe0848b, 0xffdd7b82, 0xffda77cb, + 0xffd779de, 0xffd48231, 0xffd19138, 0xffcea769, + 0xffcbc535, 0xffc8eb10, 0xffc61969, 0xffc350af, + 0xffc09151, 0xffbddbbb, 0xffbb3059, 0xffb88f92, + 0xffb5f9d0, 0xffb36f78, 0xffb0f0ef, 0xffae7e96, + 0xffac18cf, 0xffa9bff9, 0xffa7746f, 0xffa5368c, + 0xffa306aa, 0xffa0e51e, 0xff9ed23c, 0xff9cce56, + 0xff9ad9bc, 0xff98f4bc, 0xff971f9f, 0xff955aae, + 0xff93a62f, 0xff920266, 0xff906f92, 0xff8eedf3, + 0xff8d7dc4, 0xff8c1f3c, 0xff8ad294, 0xff8997fd, + 0xff886fa8, 0xff8759c3, 0xff865679, 0xff8565f2, + 0xff848852, 0xff83bdbd, 0xff830651, 0xff82622b, + 0xff81d163, 0xff815411, 0xff80ea47, 0xff809416, + 0xff80518b, 0xff8022b1, 0xff80078e, 0x00000475, + 0x000007fe, 0x00000c02, 0x000010a3, 0x000015f5, + 0x00001c08, 0x000022ed, 0x00002ab5, 0x00003371, + 0x00003d32, 0x0000480a, 0x0000540d, 0x0000614b, + 0x00006fda, 0x00007fcd, 0x00009138, 0x0000a431, + 0x0000b8cc, 0x0000cf1f, 0x0000e741, 0x00010148, + 0x00011d4b, 0x00013b61, 0x00015ba2, 0x00017e25, + 0x0001a302, 0x0001ca51, 0x0001f42c, 0x000220a9, + 0x00024fe2, 0x000281f0, 0x0002b6ea, 0x0002eee9, + 0x00032a07, 0x0003685a, 0x0003a9fc, 0x0003ef04, + 0x0004378a, 0x000483a5, 0x0004d36d, 0x000526f7, + 0x00057e5b, 0x0005d9ae, 0x00063904, 0x00069c74, + 0x00070410, 0x00076feb, 0x0007e01a, 0x000854ac, + 0x0008cdb3, 0x00094b40, 0x0009cd61, 0x000a5425, + 0x000adf98, 0x000b6fc8, 0x000c04bf, 0x000c9e87, + 0x000d3d2a, 0x000de0ae, 0x000e891a, 0x000f3674, + 0x000fe8c0, 0x00109fff, 0x00115c34, 0x00121d5d, + 0x0012e37b, 0x0013ae89, 0x00147e84, 0x00155366, + 0x00162d27, 0x00170bbf, 0x0017ef23, 0x0018d748, + 0x0019c421, 0x001ab59f, 0x001babb2, 0x001ca648, + 0x001da54f, 0x001ea8b0, 0x001fb058, 0x0020bc2d, + 0x0021cc18, 0x0022dffd, 0x0023f7c2, 0x00251348, + 0x00263272, 0x00275520, 0x00287b31, 0x0029a482, + 0x002ad0f1, 0x002c0059, 0x002d3294, 0x002e677c, + 0x002f9ee8, 0x0030d8b1, 0x003214ac, 0x003352b0, + 0x00349290, 0x0035d422, 0x00371738, 0x00385ba5, + 0x0039a13b, 0x003ae7cc, 0x003c2f2a, 0x003d7725, + 0x003ebf8d, 0x00400834, 0x004150e9, 0x0042997d, + 0x0043e1c0, 0x00452981, 0x00467092, 0x0047b6c3, + 0x0048fbe3, 0x004a3fc6, 0x004b823b, 0x004cc316, + 0x004e0228, 0x004f3f45, 0x00507a40, 0x0051b2ef, + 0x0052e925, 0x00541cba, 0x00554d85, 0x00567b5e, + 0x0057a61d, 0x0058cd9e, 0x0059f1bb, 0x005b1252, + 0x005c2f3f, 0x005d4863, 0x005e5d9d, 0x005f6ed0, + 0x00607bde, 0x006184ad, 0x00628923, 0x00638927, + 0x006484a3, 0x00657b81, 0x00666daf, 0x00675b19, + 0x006843b1, 0x00692767, 0x006a062d, 0x006adff9, + 0x006bb4c2, 0x006c847d, 0x006d4f27, 0x006e14b8, + 0x006ed52f, 0x006f9089, 0x007046c6, 0x0070f7e9, + 0x0071a3f3, 0x00724aea, 0x0072ecd3, 0x007389b6, + 0x0074219d, 0x0074b490, 0x0075429b, 0x0075cbcc, + 0x00765031, 0x0076cfd8, 0x00774ad3, 0x0077c132, + 0x00783308, 0x0078a068, 0x00790968, 0x00796e1c, + 0x0079ce9a, 0x007a2af9, 0x007a8350, 0x007ad7b8, + 0x007b2849, 0x007b751d, 0x007bbe4c, 0x007c03f1, + 0x007c4625, 0x007c8504, 0x007cc0a8, 0x007cf92c, + 0x007d2eaa, 0x007d613e, 0x007d9101, 0x007dbe10, + 0x007de883, 0x007e1076, 0x007e3603, 0x007e5943, + 0x007e7a4f, 0x007e9942, 0x007eb633, 0x007ed13a, + 0x007eea6f, 0x007f01ea, 0x007f17c0, 0x007f2c08, + 0x007f3ed7, 0x007f5043, 0x007f605e, 0x007f6f3c, + 0x007f7cf1, 0x007f898e, 0x007f9525, 0x007f9fc6, + 0x007fa982, 0x007fb268, 0x007fba86, 0x007fc1eb, + 0x007fc8a4, 0x007fcebe, 0x007fd443, 0x007fd941, + 0x007fddc2, 0x007fe1cf, 0x007fe572, 0x007fe8b4, + 0x007feb9e, 0x007fee36, 0x007ff086, 0x007ff293, + 0x007ff463, 0x007ff5fd, 0x007ff765, 0x007ff8a1, + 0x007ff9b6, 0x007ffaa7, 0x007ffb79, 0x007ffc2f, + 0x007ffccb, 0x007ffd52, 0x007ffdc6, 0x007ffe28, + 0x007ffe7b, 0x007ffec2, 0x007ffefd, 0x007fff2f, + 0x007fff58, 0x007fff7b, 0x007fff97, 0x007fffae, + 0x007fffc0, 0x007fffcf, 0x007fffdb, 0x007fffe4, + 0x007fffec, 0x007ffff1, 0x007ffff6, 0x007ffff9, + 0x007ffffb, 0x007ffffd, 0x007ffffe, 0x007fffff, + 0x007fffff, 0x007fffff, 0x007fffff, 0xff800000, + 0x00000000, 0xffa57d86, 0x005a827a, 0xff89be51, + 0x0030fbc5, 0xffcf043b, 0x007641af, 0xff8275a1, + 0x0018f8b8, 0xffb8e313, 0x006a6d99, 0xff959267, + 0x00471ced, 0xffe70748, 0x007d8a5f, 0xff809dc9, + 0x000c8bd3, 0xffaecc33, 0x0062f202, 0xff8f1d34, + 0x003c56ba, 0xffdad7f4, 0x007a7d05, 0xff8582fb, + 0x0025280c, 0xffc3a946, 0x0070e2cc, 0xff9d0dfe, + 0x005133cd, 0xfff3742d, 0x007f6237, 0xff802778, + 0x000647d9, 0xffaa0a5b, 0x005ed77d, 0xff8c4a14, + 0x0036ba20, 0xffd4e0cb, 0x00788484, 0xff83d604, + 0x001f19f9, 0xffbe31e2, 0x006dca0d, 0xff99307f, + 0x004c3fe0, 0xffed37f0, 0x007e9d56, 0xff8162aa, + 0x0012c810, 0xffb3c020, 0x0066cf81, 0xff9235f3, + 0x0041ce1e, 0xffe0e607, 0x007c29fc, 0xff877b7c, + 0x002b1f35, 0xffc945e0, 0x0073b5ec, 0xffa12883, + 0x0055f5a5, 0xfff9b827, 0x007fd888, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static u32 AC3I2SUcode1fe000[] = { + 0x00000000, 0x03020102, 0x05040403, 0x00400040, + 0x00500050, 0x00600060, 0x00700070, 0x00800080, + 0x00a000a0, 0x00c000c0, 0x00e000e0, 0x01000100, + 0x01400140, 0x01800180, 0x01c001c0, 0x02000200, + 0x02800280, 0x03000300, 0x03800380, 0x04000400, + 0x04800480, 0x05000500, 0x00460045, 0x00580057, + 0x00690068, 0x007a0079, 0x008c008b, 0x00af00ae, + 0x00d100d0, 0x00f400f3, 0x01170116, 0x015d015c, + 0x01a201a1, 0x01e801e7, 0x022e022d, 0x02b902b8, + 0x03440343, 0x03d003cf, 0x045b045a, 0x04e604e5, + 0x05720571, 0x00600060, 0x00780078, 0x00900090, + 0x00a800a8, 0x00c000c0, 0x00f000f0, 0x01200120, + 0x01500150, 0x01800180, 0x01e001e0, 0x02400240, + 0x02a002a0, 0x03000300, 0x03c003c0, 0x04800480, + 0x05400540, 0x06000600, 0x06c006c0, 0x07800780, + 0x7b67533f, 0x1513110f, 0x04d80540, 0x04100478, + 0x07000000, 0x0b000900, 0x02b002f0, 0x02300270, + 0x017001f0, 0xf80000f0, 0x01000080, 0x02000180, + 0x03000280, 0x04000380, 0x2725231f, 0x2c2b2a29, + 0x2e2e2d2d, 0x30302f2f, 0x04030201, 0x08070605, + 0x0c0b0a09, 0x100f0e0d, 0x14131211, 0x18171615, + 0x1c1b1a19, 0x2825221f, 0x37312e2b, 0x4f49433d, + 0x796d6155, 0xcdb59d85, 0x0000fde5, 0x3d3e3f40, + 0x393a3b3c, 0x35363738, 0x32333434, 0x2f2f3031, + 0x2c2c2d2e, 0x29292a2b, 0x26262728, 0x23242425, + 0x21212223, 0x1e1f2020, 0x1c1d1d1e, 0x1a1b1b1c, + 0x1819191a, 0x16171718, 0x15151516, 0x13131414, + 0x12121213, 0x10111111, 0x0f0f1010, 0x0e0e0e0f, + 0x0d0d0d0d, 0x0c0c0c0c, 0x0b0b0b0b, 0x0a0a0a0a, + 0x0909090a, 0x08080909, 0x08080808, 0x07070707, + 0x06060707, 0x06060606, 0x05050606, 0x05050505, + 0x04040505, 0x04040404, 0x04040404, 0x03030304, + 0x03030303, 0x03030303, 0x02030303, 0x02020202, + 0x02020202, 0x02020202, 0x02020202, 0x01010202, + 0x01010101, 0x01010101, 0x01010101, 0x01010101, + 0x01010101, 0x01010101, 0x01010101, 0x00000101, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x04d004d0, + 0x04000440, 0x03c003e0, 0x03b003b0, 0x03a003a0, + 0x03a003a0, 0x039003a0, 0x03900390, 0x03800380, + 0x03700370, 0x03600360, 0x03500350, 0x03400340, + 0x03200330, 0x03000310, 0x02f002f0, 0x02f002f0, + 0x03100300, 0x03900340, 0x042003e0, 0x04900460, + 0x046004a0, 0x04400440, 0x08000520, 0x08400840, + 0x04f004f0, 0x04100460, 0x03d003e0, 0x03b003c0, + 0x03a003b0, 0x03a003a0, 0x03a003a0, 0x03900390, + 0x03800390, 0x03800380, 0x03700370, 0x03600360, + 0x03500350, 0x03400340, 0x03100320, 0x02f00300, + 0x02f002f0, 0x030002f0, 0x03500320, 0x03e00390, + 0x04500420, 0x049004a0, 0x04400460, 0x06300480, + 0x08400840, 0x05800580, 0x045004b0, 0x03f00420, + 0x03d003e0, 0x03b003c0, 0x03b003b0, 0x03a003a0, + 0x03a003a0, 0x03a003a0, 0x03a003a0, 0x03900390, + 0x03900390, 0x03800380, 0x03700380, 0x03500360, + 0x03300340, 0x03100320, 0x02f00300, 0x02f002f0, + 0x03100300, 0x03500330, 0x041003c0, 0x04a00470, + 0x04400460, 0x04e00450, 0xffaaaaab, 0x00000000, + 0x00555555, 0xff99999a, 0xffcccccd, 0x00000000, + 0x00333333, 0x00666666, 0xff924925, 0xffb6db6e, + 0xffdb6db7, 0x00000000, 0x00249249, 0x00492492, + 0x006db6db, 0xff8ba2e9, 0xffa2e8ba, 0xffba2e8c, + 0xffd1745d, 0xffe8ba2f, 0x00000000, 0x001745d1, + 0x002e8ba3, 0x0045d174, 0x005d1746, 0x00745d17, + 0xff888889, 0xff99999a, 0xffaaaaab, 0xffbbbbbc, + 0xffcccccd, 0xffddddde, 0xffeeeeef, 0x00000000, + 0x00111111, 0x00222222, 0x00333333, 0x00444444, + 0x00555555, 0x00666666, 0x00777777, 0x08070605, + 0x0c0b0a09, 0x10100e0e, 0x00000010, 0x00000000, + 0x00000010, 0x00000020, 0x00000100, 0x00000110, + 0x00000120, 0x00000200, 0x00000210, 0x00000220, + 0x00001000, 0x00001010, 0x00001020, 0x00001100, + 0x00001110, 0x00001120, 0x00001200, 0x00001210, + 0x00001220, 0x00002000, 0x00002010, 0x00002020, + 0x00002100, 0x00002110, 0x00002120, 0x00002200, + 0x00002210, 0x00002220, 0x00000000, 0x00000010, + 0x00000020, 0x00000030, 0x00000040, 0x00000100, + 0x00000110, 0x00000120, 0x00000130, 0x00000140, + 0x00000200, 0x00000210, 0x00000220, 0x00000230, + 0x00000240, 0x00000300, 0x00000310, 0x00000320, + 0x00000330, 0x00000340, 0x00000400, 0x00000410, + 0x00000420, 0x00000430, 0x00000440, 0x00001000, + 0x00001010, 0x00001020, 0x00001030, 0x00001040, + 0x00001100, 0x00001110, 0x00001120, 0x00001130, + 0x00001140, 0x00001200, 0x00001210, 0x00001220, + 0x00001230, 0x00001240, 0x00001300, 0x00001310, + 0x00001320, 0x00001330, 0x00001340, 0x00001400, + 0x00001410, 0x00001420, 0x00001430, 0x00001440, + 0x00002000, 0x00002010, 0x00002020, 0x00002030, + 0x00002040, 0x00002100, 0x00002110, 0x00002120, + 0x00002130, 0x00002140, 0x00002200, 0x00002210, + 0x00002220, 0x00002230, 0x00002240, 0x00002300, + 0x00002310, 0x00002320, 0x00002330, 0x00002340, + 0x00002400, 0x00002410, 0x00002420, 0x00002430, + 0x00002440, 0x00003000, 0x00003010, 0x00003020, + 0x00003030, 0x00003040, 0x00003100, 0x00003110, + 0x00003120, 0x00003130, 0x00003140, 0x00003200, + 0x00003210, 0x00003220, 0x00003230, 0x00003240, + 0x00003300, 0x00003310, 0x00003320, 0x00003330, + 0x00003340, 0x00003400, 0x00003410, 0x00003420, + 0x00003430, 0x00003440, 0x00004000, 0x00004010, + 0x00004020, 0x00004030, 0x00004040, 0x00004100, + 0x00004110, 0x00004120, 0x00004130, 0x00004140, + 0x00004200, 0x00004210, 0x00004220, 0x00004230, + 0x00004240, 0x00004300, 0x00004310, 0x00004320, + 0x00004330, 0x00004340, 0x00004400, 0x00004410, + 0x00004420, 0x00004430, 0x00004440, 0x00000000, + 0x00000100, 0x00000200, 0x00000300, 0x00000400, + 0x00000500, 0x00000600, 0x00000700, 0x00000800, + 0x00000900, 0x00000a00, 0x00001000, 0x00001100, + 0x00001200, 0x00001300, 0x00001400, 0x00001500, + 0x00001600, 0x00001700, 0x00001800, 0x00001900, + 0x00001a00, 0x00002000, 0x00002100, 0x00002200, + 0x00002300, 0x00002400, 0x00002500, 0x00002600, + 0x00002700, 0x00002800, 0x00002900, 0x00002a00, + 0x00003000, 0x00003100, 0x00003200, 0x00003300, + 0x00003400, 0x00003500, 0x00003600, 0x00003700, + 0x00003800, 0x00003900, 0x00003a00, 0x00004000, + 0x00004100, 0x00004200, 0x00004300, 0x00004400, + 0x00004500, 0x00004600, 0x00004700, 0x00004800, + 0x00004900, 0x00004a00, 0x00005000, 0x00005100, + 0x00005200, 0x00005300, 0x00005400, 0x00005500, + 0x00005600, 0x00005700, 0x00005800, 0x00005900, + 0x00005a00, 0x00006000, 0x00006100, 0x00006200, + 0x00006300, 0x00006400, 0x00006500, 0x00006600, + 0x00006700, 0x00006800, 0x00006900, 0x00006a00, + 0x00007000, 0x00007100, 0x00007200, 0x00007300, + 0x00007400, 0x00007500, 0x00007600, 0x00007700, + 0x00007800, 0x00007900, 0x00007a00, 0x00008000, + 0x00008100, 0x00008200, 0x00008300, 0x00008400, + 0x00008500, 0x00008600, 0x00008700, 0x00008800, + 0x00008900, 0x00008a00, 0x00009000, 0x00009100, + 0x00009200, 0x00009300, 0x00009400, 0x00009500, + 0x00009600, 0x00009700, 0x00009800, 0x00009900, + 0x00009a00, 0x0000a000, 0x0000a100, 0x0000a200, + 0x0000a300, 0x0000a400, 0x0000a500, 0x0000a600, + 0x0000a700, 0x0000a800, 0x0000a900, 0x0000aa00, + 0xff800000, 0xff800000, 0xffb82995, 0xffaf5d75, + 0xffa57d87, 0xff9a6806, 0xff8df708, 0xff800000, + 0xffb82995, 0xffaf5d75, 0xffa57d87, 0xff9a6806, + 0xff8df708, 0xff800000, 0xffb82995, 0xffaf5d75, + 0xffa57d87, 0xff9a6806, 0xff8df708, 0xff800000, + 0xffb82995, 0xffaf5d75, 0xffa57d87, 0xff9a6806, + 0xff8df708, 0xff800000, 0xffb82995, 0xffaf5d75, + 0xffa57d87, 0xff9a6806, 0xff8df708, 0xff800000, + 0xfffb0000, 0xfffcfffc, 0xfffcfffc, 0xfffcfffc, + 0xfffdfffd, 0xfffdfffd, 0xfffdfffd, 0xfffefffe, + 0xfffefffe, 0xfffefffe, 0xffffffff, 0xffffffff, + 0xffffffff, 0x00000000, 0x00000000, 0x00000000, + 0x80050000, 0x000a800f, 0x001e801b, 0x80110014, + 0x00368033, 0x8039003c, 0x802d0028, 0x00228027, + 0x00668063, 0x8069006c, 0x807d0078, 0x00728077, + 0x80550050, 0x005a805f, 0x004e804b, 0x80410044, + 0x00c680c3, 0x80c900cc, 0x80dd00d8, 0x00d280d7, + 0x80f500f0, 0x00fa80ff, 0x00ee80eb, 0x80e100e4, + 0x80a500a0, 0x00aa80af, 0x00be80bb, 0x80b100b4, + 0x00968093, 0x8099009c, 0x808d0088, 0x00828087, + 0x01868183, 0x8189018c, 0x819d0198, 0x01928197, + 0x81b501b0, 0x01ba81bf, 0x01ae81ab, 0x81a101a4, + 0x81e501e0, 0x01ea81ef, 0x01fe81fb, 0x81f101f4, + 0x01d681d3, 0x81d901dc, 0x81cd01c8, 0x01c281c7, + 0x81450140, 0x014a814f, 0x015e815b, 0x81510154, + 0x01768173, 0x8179017c, 0x816d0168, 0x01628167, + 0x01268123, 0x8129012c, 0x813d0138, 0x01328137, + 0x81150110, 0x011a811f, 0x010e810b, 0x81010104, + 0x03068303, 0x8309030c, 0x831d0318, 0x03128317, + 0x83350330, 0x033a833f, 0x032e832b, 0x83210324, + 0x83650360, 0x036a836f, 0x037e837b, 0x83710374, + 0x03568353, 0x8359035c, 0x834d0348, 0x03428347, + 0x83c503c0, 0x03ca83cf, 0x03de83db, 0x83d103d4, + 0x03f683f3, 0x83f903fc, 0x83ed03e8, 0x03e283e7, + 0x03a683a3, 0x83a903ac, 0x83bd03b8, 0x03b283b7, + 0x83950390, 0x039a839f, 0x038e838b, 0x83810384, + 0x82850280, 0x028a828f, 0x029e829b, 0x82910294, + 0x02b682b3, 0x82b902bc, 0x82ad02a8, 0x02a282a7, + 0x02e682e3, 0x82e902ec, 0x82fd02f8, 0x02f282f7, + 0x82d502d0, 0x02da82df, 0x02ce82cb, 0x82c102c4, + 0x02468243, 0x8249024c, 0x825d0258, 0x02528257, + 0x82750270, 0x027a827f, 0x026e826b, 0x82610264, + 0x82250220, 0x022a822f, 0x023e823b, 0x82310234, + 0x02168213, 0x8219021c, 0x820d0208, 0x02028207, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x00000002, 0x00000002, + 0x00000000, 0xff800000, 0xffa57d86, 0xffa57d86, + 0xffcf043b, 0xff89be51, 0xff89be51, 0xffcf043b, + 0xffe70748, 0xff8275a1, 0xff959267, 0xffb8e313, + 0xffb8e313, 0xff959267, 0xff8275a1, 0xffe70748, + 0xfff3742d, 0xff809dc9, 0xff9d0dfe, 0xffaecc33, + 0xffc3a946, 0xff8f1d34, 0xff8582fb, 0xffdad7f4, + 0xffdad7f4, 0xff8582fb, 0xff8f1d34, 0xffc3a946, + 0xffaecc33, 0xff9d0dfe, 0xff809dc9, 0xfff3742d, + 0xfff9b827, 0xff802778, 0xffa12883, 0xffaa0a5b, + 0xffc945e0, 0xff8c4a14, 0xff877b7c, 0xffd4e0cb, + 0xffe0e607, 0xff83d604, 0xff9235f3, 0xffbe31e2, + 0xffb3c020, 0xff99307f, 0xff8162aa, 0xffed37f0, + 0xffed37f0, 0xff8162aa, 0xff99307f, 0xffb3c020, + 0xffbe31e2, 0xff9235f3, 0xff83d604, 0xffe0e607, + 0xffd4e0cb, 0xff877b7c, 0xff8c4a14, 0xffc945e0, + 0xffaa0a5b, 0xffa12883, 0xff802778, 0xfff9b827, + 0xcbcecdc4, 0xcfcac9c8, 0xc3c6c5cc, 0xc7c2c1c0, + 0x1b1e1d14, 0x1f1a1918, 0x1316151c, 0x17121110, + 0x2b2e2d24, 0x2f2a2928, 0x2326252c, 0x27222120, + 0x3b3e3d34, 0x3f3a3938, 0x3336353c, 0x37323130, + 0x0b0e0d04, 0x0f0a0908, 0x0306050c, 0x07020100, + 0xdbdeddd4, 0xdfdad9d8, 0xd3d6d5dc, 0xd7d2d1d0, + 0xebeeede4, 0xefeae9e8, 0xe3e6e5ec, 0xe7e2e1e0, + 0xfbfefdf4, 0xfffaf9f8, 0xf3f6f5fc, 0xf7f2f1f0, + 0x4b4e4d44, 0x4f4a4948, 0x4346454c, 0x47424140, + 0x9b9e9d94, 0x9f9a9998, 0x9396959c, 0x97929190, + 0xabaeada4, 0xafaaa9a8, 0xa3a6a5ac, 0xa7a2a1a0, + 0xbbbebdb4, 0xbfbab9b8, 0xb3b6b5bc, 0xb7b2b1b0, + 0x8b8e8d84, 0x8f8a8988, 0x8386858c, 0x87828180, + 0x5b5e5d54, 0x5f5a5958, 0x5356555c, 0x57525150, + 0x6b6e6d64, 0x6f6a6968, 0x6366656c, 0x67626160, + 0x7b7e7d74, 0x7f7a7978, 0x7376757c, 0x77727170, + 0x341424c4, 0x3e1e2ece, 0x3d1d2dcd, 0x3b1b2bcb, + 0xb494a444, 0xbe9eae4e, 0xbd9dad4d, 0xbb9bab4b, + 0xf4d4e404, 0xfedeee0e, 0xfddded0d, 0xfbdbeb0b, + 0x74546484, 0x7e5e6e8e, 0x7d5d6d8d, 0x7b5b6b8b, + 0x3c1c2ccc, 0x361626c6, 0x351525c5, 0x331323c3, + 0xbc9cac4c, 0xb696a646, 0xb595a545, 0xb393a343, + 0xfcdcec0c, 0xf6d6e606, 0xf5d5e505, 0xf3d3e303, + 0x7c5c6c8c, 0x76566686, 0x75556585, 0x73536383, + 0x381828c8, 0x3a1a2aca, 0x391929c9, 0x3f1f2fcf, + 0xb898a848, 0xba9aaa4a, 0xb999a949, 0xbf9faf4f, + 0xf8d8e808, 0xfadaea0a, 0xf9d9e909, 0xffdfef0f, + 0x78586888, 0x7a5a6a8a, 0x79596989, 0x7f5f6f8f, + 0x301020c0, 0x321222c2, 0x311121c1, 0x371727c7, + 0xb090a040, 0xb292a242, 0xb191a141, 0xb797a747, + 0xf0d0e000, 0xf2d2e202, 0xf1d1e101, 0xf7d7e707, + 0x70506080, 0x72526282, 0x71516181, 0x77576787, + 0x05040100, 0x15141110, 0x25242120, 0x35343130, + 0x85848180, 0x95949190, 0xa5a4a1a0, 0xb5b4b1b0, + 0xc0408000, 0xe060a020, 0xd0509010, 0xf070b030, + 0xc8488808, 0xe868a828, 0xd8589818, 0xf878b838, + 0xc4448404, 0xe464a424, 0xd4549414, 0xf474b434, + 0xcc4c8c0c, 0xec6cac2c, 0xdc5c9c1c, 0xfc7cbc3c, + 0xc2428202, 0xe262a222, 0xd2529212, 0xf272b232, + 0xca4a8a0a, 0xea6aaa2a, 0xda5a9a1a, 0xfa7aba3a, + 0xc6468606, 0xe666a626, 0xd6569616, 0xf676b636, + 0xce4e8e0e, 0xee6eae2e, 0xde5e9e1e, 0xfe7ebe3e, + 0xc1418101, 0xe161a121, 0xd1519111, 0xf171b131, + 0xc9498909, 0xe969a929, 0xd9599919, 0xf979b939, + 0xc5458505, 0xe565a525, 0xd5559515, 0xf575b535, + 0xcd4d8d0d, 0xed6dad2d, 0xdd5d9d1d, 0xfd7dbd3d, + 0xc3438303, 0xe363a323, 0xd3539313, 0xf373b333, + 0xcb4b8b0b, 0xeb6bab2b, 0xdb5b9b1b, 0xfb7bbb3b, + 0xc7478707, 0xe767a727, 0xd7579717, 0xf777b737, + 0xcf4f8f0f, 0xef6faf2f, 0xdf5f9f1f, 0xff7fbf3f, + 0x1045a3e2, 0x000000f4, 0x263b7333, 0x766b2363, + 0x2b367e3e, 0x7b662e6e, 0x06db93d3, 0x964b0343, + 0x0bd69ede, 0x9b460e4e, 0x825f1757, 0x12cf87c7, + 0x8f521a5a, 0x1fc28aca, 0x00d199d9, 0x90410949, + 0x01d098d8, 0x91400848, 0x24357d3d, 0x74652d6d, + 0x25347c3c, 0x75642c6c, 0x04d59ddd, 0x94450d4d, + 0x05d49cdc, 0x95440c4c, 0x80511959, 0x10c189c9, + 0x81501858, 0x11c088c8, 0x02df97d7, 0x924f0747, + 0x0fd29ada, 0x9f420a4a, 0x865b1353, 0x16cb83c3, + 0x8b561e5e, 0x1bc68ece, 0xa6bbf3b3, 0xf6eba3e3, + 0xabb6febe, 0xfbe6aeee, 0x223f7737, 0x726f2767, + 0x2f327a3a, 0x7f622a6a, 0xa0b1f9b9, 0xf0e1a9e9, + 0xa1b0f8b8, 0xf1e0a8e8, 0x84551d5d, 0x14c58dcd, + 0x85541c5c, 0x15c48ccc, 0xa4b5fdbd, 0xf4e5aded, + 0xa5b4fcbc, 0xf5e4acec, 0x20317939, 0x70612969, + 0x21307838, 0x71602868, 0xa2bff7b7, 0xf2efa7e7, + 0xafb2faba, 0xffe2aaea, 0x00000000, 0x00000000, +}; + +static u32 AC3I2SUcode1fff80[] = { + 0x0000240f, 0x007fffff, 0x007fffff, 0x00000003, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, +}; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/ac3i2s_240.h linux.19pre5-ac1/drivers/media/video/ls220/ac3i2s_240.h --- linux.19p5/drivers/media/video/ls220/ac3i2s_240.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/ls220/ac3i2s_240.h Thu Feb 21 20:41:22 2002 @@ -0,0 +1,2833 @@ +static u32 AC3I2S240Ucode1f1800[] = { + 0xb500000f, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xb5001197, 0x00000000, 0x00000000, 0x00000000, + 0x820f001f, 0x802f001f, 0x80070800, 0x001f6193, + 0x800500d4, 0x8053ffff, 0x9842c7ff, 0x8039ff7c, + 0x1400b802, 0x003f6000, 0x94210007, 0xb0010001, + 0xb4200001, 0x98002800, 0xb0010000, 0xb4200001, + 0x98000800, 0x805300ff, 0x1800b802, 0x800600d4, + 0x8013001f, 0x9020c000, 0x003fb006, 0x803effe0, + 0x803effe8, 0x803effec, 0x9020e000, 0x9021ffe4, + 0x9020fa00, 0x803effd0, 0x803effdc, 0x803effd8, + 0x9020fe00, 0x803effd4, 0x90400000, 0x804600a2, + 0x90421800, 0x804600a3, 0x80134099, 0x98000040, + 0x800600a6, 0x80130000, 0x98003ca1, 0x800600a1, + 0x80050080, 0x98000002, 0x80060080, 0x80070001, + 0x001f2013, 0x001f2324, 0x80070000, 0x001fb0ba, + 0x001f23f9, 0x801eb3f0, 0x80070800, 0x001f600f, + 0x80070000, 0x001f2012, 0x001fb0cb, 0x001fb010, + 0x801efff0, 0x98004000, 0x98008000, 0x001f600e, + 0x83e4012b, 0x80070000, 0x801eb3f8, 0x801eff70, + 0x800500a0, 0xb0000001, 0xb4000009, 0x80070001, + 0x800600a0, 0x80050080, 0x98000020, 0x80060080, + 0x9400ffdf, 0x80060080, 0x80070000, 0x800600a0, + 0x81df0004, 0x00000000, 0x00000000, 0x801bfff0, + 0x00000000, 0x940000ff, 0xb0000000, 0xb420004e, + 0x003f400e, 0x94010010, 0xb0000000, 0xb400fff4, + 0x838413ac, 0x003f0013, 0xb0010001, 0xb420003b, + 0x803bffe8, 0x801bffec, 0x00000000, 0x3001b800, + 0xb4600001, 0x90212000, 0x0421b800, 0x005f4193, + 0x5841b802, 0x3001b802, 0xb460000d, 0x80050086, + 0x005f9016, 0xb0020000, 0xb4200002, 0x001fb016, + 0xb500ffdf, 0x0420b802, 0xb0010b50, 0xb4a0ffdc, + 0x80070000, 0x001fb016, 0x83e400f5, 0xb500ffd8, + 0x80070000, 0x001fb016, 0x001f400e, 0x9400000f, + 0xb0000000, 0xb4000014, 0xb0000001, 0xb4000010, + 0x003f400e, 0x9421fff0, 0x003f600e, 0x003f9006, + 0x9421ffff, 0x90210004, 0xb001e000, 0xb4800002, + 0x8421e000, 0x9021c000, 0x8013001f, 0x1021b800, + 0x003fb006, 0x003f90cb, 0x90210004, 0x003fb0cb, + 0x83e400e7, 0x83e4138b, 0x8007001f, 0x94000003, + 0x5810b800, 0x83e71aa8, 0x1bffb800, 0x003f9008, + 0x1821b800, 0x00ffb801, 0x83e413de, 0x80270000, + 0x003f2013, 0x8007001f, 0x94000003, 0x5810b800, + 0x83671ad4, 0x1b7bb800, 0x003f9009, 0x1821b800, + 0x00ffb801, 0xb500ffaa, 0x803bffc0, 0x805bffc4, + 0x807bffc8, 0x809bffcc, 0x5828b801, 0x5cb8b802, + 0x1821b805, 0x5848b802, 0x5cb8b803, 0x1842b805, + 0x5868b803, 0x5cb8b804, 0x1863b805, 0x5888b804, + 0x1884b800, 0x803effc0, 0x805effc4, 0x807effc8, + 0x809effcc, 0x003f400e, 0xb0000086, 0xb4400048, + 0xb0000084, 0xb4000032, 0xb0000085, 0xb4000038, + 0xb0000086, 0xb400003a, 0x001f4000, 0x94000080, + 0xb0000080, 0xb4000072, 0x800500d4, 0x8053ffff, + 0x9842c7ff, 0x1400b802, 0x805300ff, 0x98422800, + 0x1800b802, 0x800600d4, 0x80130000, 0x98000c7f, + 0x005f4000, 0x94420008, 0xb0020008, 0xb4200001, + 0xa0000080, 0x800600a1, 0x8013001f, 0x9040c000, + 0x005fb006, 0x805effe0, 0x805effe8, 0x805effec, + 0x9040e000, 0x805effe4, 0x9040fa00, 0x805effd0, + 0x805effdc, 0x805effd8, 0x9040fe00, 0x805effd4, + 0x80070001, 0x001f2013, 0x80070000, 0x001fb0cb, + 0x001fb010, 0x001f2058, 0x80071f60, 0x001fb008, + 0x80075d70, 0x001fb009, 0x98214000, 0xb5000010, + 0x94011000, 0xb0001000, 0xb4200001, 0x9421efff, + 0x98210010, 0xb500000a, 0x80070000, 0x001fb0cb, + 0x83e4007f, 0x003f400e, 0x9421ffef, 0xb5000004, + 0x83e4007b, 0x003f400e, 0x98211000, 0x9421ffef, + 0x003f600e, 0x80070100, 0x801efff0, 0xb500ff4c, + 0xb000008b, 0xb400001c, 0xb000008e, 0xb4000022, + 0xb000008d, 0xb400001c, 0xb000008c, 0xb4000021, + 0xb0000087, 0xb400ffe8, 0xb0000088, 0xb4000014, + 0xb000008a, 0xb4000015, 0xb0000089, 0xb400001d, + 0xb00000a0, 0xb400001f, 0xb00000a1, 0xb4000041, + 0xb00000a2, 0xb400004a, 0xb00000a3, 0xb4000046, + 0xb00000a4, 0xb4000048, 0xb00000a5, 0xb4000048, + 0xb00000a6, 0xb4000048, 0x803efff8, 0xb500ffdd, + 0x9421ffdf, 0xb500ffda, 0xb500ffda, 0x80270100, + 0x803efff8, 0xb500ffd7, 0x80070000, 0x001fb017, + 0xb500ffd4, 0x801bffb0, 0x00000000, 0x001fb003, + 0xb500ffd0, 0x803bff80, 0x00000000, 0x003f6001, + 0xb500ffcc, 0x003f90ba, 0x803efff8, 0xb500ffc9, + 0x80130001, 0x98003da1, 0x800600a1, 0x80070200, + 0x801ebf34, 0x83e4002e, 0x8013001f, 0x9840c000, + 0x805effe0, 0x005fb006, 0x805effe8, 0x805effec, + 0x90422000, 0x805effe4, 0x9040fa00, 0x805effd0, + 0x805effdc, 0x805effd8, 0x9040fe00, 0x805effd4, + 0x80070001, 0x001f2013, 0x80070000, 0x001f2324, + 0x001fb0cb, 0x001fb010, 0x001f2058, 0x800774b0, + 0x001fb008, 0x80077730, 0x001fb009, 0x98214000, + 0xb500ffa7, 0x80270000, 0x8047fef0, 0x003eb802, + 0x90420004, 0x003eb802, 0x90420004, 0x003eb802, + 0x90420004, 0x003eb802, 0x83641460, 0xb500ff9d, + 0x8364140e, 0xb500ff9b, 0x836413cd, 0xb500ff99, + 0x83441334, 0xb500ff97, 0x8344131d, 0xb500ff95, + 0x80070000, 0x80470000, 0xb6002003, 0xb6003002, + 0x001eb802, 0x90420004, 0x80171000, 0x8057ffff, + 0xb6002002, 0xb6001801, 0x001fa020, 0x00ffb81f, + 0x001f4000, 0x94000080, 0xb0000080, 0xb4200001, + 0xb500ffef, 0xb500000a, 0x80270000, 0x003f2013, + 0x8007001f, 0x94000003, 0x5810b800, 0x83671e60, + 0x1b7bb800, 0x003f9009, 0x1821b800, 0x00ffb801, + 0x003f0013, 0xb0010001, 0xb420fff3, 0x83a70000, + 0x803bff70, 0x00000000, 0xb0010000, 0xb4000011, + 0x80170300, 0x80070000, 0xb6000601, 0x001fa020, + 0x83640c66, 0x00ff0325, 0x82870000, 0xb6270002, + 0x83640217, 0x92940001, 0x001f033b, 0xb0000000, + 0xb4000002, 0x80270000, 0xb5000001, 0x80270001, + 0x003f233b, 0x80270000, 0x003f2013, 0x8007001f, + 0x94000003, 0x5810b800, 0x83671eec, 0x1b7bb800, + 0x003f9009, 0x1821b800, 0x00ffb801, 0x003f0013, + 0xb0010001, 0xb420fff3, 0x93bd0001, 0xb01d0004, + 0xb480ffdb, 0x803bff70, 0x00000000, 0xb0010000, + 0xb4000001, 0x83640c12, 0x00000000, 0x00000000, + 0x00ffb81f, 0x007f90cb, 0x90630400, 0x007fb0cb, + 0x003f9006, 0x9421ffff, 0x90210400, 0xb001e000, + 0xb4800002, 0x8421e000, 0x9021c000, 0x8013001f, + 0x1021b800, 0x003fb006, 0x803effec, 0x00ffb81f, + 0x015f400e, 0x944a4000, 0xb0024000, 0xb4200084, + 0x954abfff, 0x015f600e, 0x820f001f, 0x802f001f, + 0x81470000, 0x015f23f9, 0x829702ec, 0x82d7ffff, + 0x82f70000, 0xb6000501, 0x029fa02a, 0x82970400, + 0xb6000702, 0xb6000001, 0x029fa02a, 0x8053ff00, + 0x98420000, 0x805ebf14, 0x805ebf18, 0x805ebf1c, + 0x805ebf20, 0x805ebf24, 0x805ebf28, 0x80270000, + 0x003f2328, 0x80275480, 0x005fb801, 0x8033001f, + 0x9821c000, 0x803effe0, 0x90212000, 0x803effe4, + 0x80dbff8c, 0x80fbff90, 0x80debf14, 0x80febf18, + 0x80dbff94, 0x80fbff98, 0x80debf1c, 0x80febf20, + 0x80dbff9c, 0x80fbffa0, 0x80debf24, 0x80febf28, + 0x80dbff84, 0x80e70001, 0x00dfb001, 0x80dbff88, + 0x00ff6191, 0x00dfb002, 0x80dbffb0, 0x80470000, + 0x00dfb003, 0x80d9ff80, 0x005fb0cf, 0x005fb0c6, + 0x00df6001, 0x80470001, 0x005f618f, 0x804700ff, + 0x005f231c, 0x005f231d, 0x80470000, 0x005f204e, + 0x8047e138, 0x5c42b802, 0x814f6300, 0x80cf00a9, + 0x005fb0bc, 0x5842b802, 0x01cfb802, 0x005f90bc, + 0xb520ffff, 0x8067e16c, 0x5c62b803, 0x80270040, + 0xb6000209, 0x814fffc0, 0x00cfb801, 0x007fb0bc, + 0x5862b803, 0x01cfb803, 0x007f90bc, 0xb520ffff, + 0x90210020, 0x90630020, 0x8047e398, 0x5c42b802, + 0x814fce40, 0x80cf0080, 0x005fb0bc, 0x5842b802, + 0x01cfb802, 0x005f90bc, 0xb520ffff, 0x8047e400, + 0x5c42b802, 0x814f7380, 0x80cf009a, 0x005fb0bc, + 0x5842b802, 0x01cfb802, 0x005f90bc, 0xb520ffff, + 0x8047e43c, 0x5c42b802, 0x814f18c0, 0x80cf00b6, + 0x005fb0bc, 0x5842b802, 0x01cfb802, 0x005f90bc, + 0xb520ffff, 0x80e70000, 0x00ffb0ba, 0x808f0000, + 0x806f001f, 0x80af001f, 0x8027b9fc, 0x5c22b801, + 0x80670700, 0xb600080a, 0x00cfb803, 0x003fb0bc, + 0x5822b801, 0x01cfb801, 0x003f90bc, 0x0047b86f, + 0xb0020001, 0xb4c0fffd, 0x90210020, 0x90630020, + 0x834400d3, 0xb0180000, 0xb4200025, 0x83440678, + 0x80c70000, 0x00df2324, 0x83640026, 0x83440220, + 0x00df0324, 0x90c60001, 0x00df2324, 0xb0060006, + 0xb4000003, 0x81472198, 0x015fb008, 0x00ffb81f, + 0x00ff90ba, 0x90e70001, 0x00ffb0ba, 0x019f9006, + 0x958cffff, 0x00df4193, 0x58c1b806, 0x118cb806, + 0xb00ce000, 0xb4800002, 0x858ce000, 0x918cc000, + 0x8153001f, 0x118cb80a, 0x819effec, 0x019fb006, + 0x015f4193, 0x5941b80a, 0x019f90cb, 0x118cb80a, + 0x019fb0cb, 0x81472180, 0x015fb008, 0x00ffb81f, + 0x015f400e, 0x194ab818, 0x015f600e, 0x802500a5, + 0x00ffb81f, 0x803bff8c, 0x805bff90, 0x803ebf14, + 0x805ebf18, 0x803bff94, 0x805bff98, 0x803ebf1c, + 0x805ebf20, 0x803bff9c, 0x805bffa0, 0x803ebf24, + 0x805ebf28, 0x80470003, 0x805ebefc, 0x003f0384, + 0x5822b801, 0x9021eb50, 0x005bb801, 0x00000000, + 0xb0020001, 0xb4200002, 0x80470001, 0x805ebefc, + 0x8073ff80, 0x98630000, 0x8027bf14, 0x8047befc, + 0xb6000609, 0x009bb801, 0x00000000, 0x00a7b804, + 0x6081b804, 0x3004b803, 0xb4000001, 0x00beb802, + 0x90210004, 0x90420004, 0x00ffb81b, 0x00000000, + 0x81150010, 0x00000000, 0x00000000, 0x81350010, + 0x00000000, 0x00000000, 0x81550002, 0x00000000, + 0x015f2380, 0x81550006, 0x00000000, 0x015f2381, + 0x81550005, 0x00000000, 0x015f2382, 0x81550003, + 0x00000000, 0x015f2383, 0x81550003, 0x015f2384, + 0xb00a0001, 0xb4000005, 0x956a0001, 0xb00b0000, + 0xb4000002, 0x81750002, 0x017f2385, 0x956a0004, + 0xb00b0000, 0xb4000002, 0x81750002, 0x017f2386, + 0xb00a0002, 0xb4200003, 0x81750002, 0x00000000, + 0x017f2387, 0x81750001, 0x00000000, 0x017f2388, + 0x81750005, 0x00000000, 0x017f2389, 0x81750001, + 0x017f239f, 0xb00b0001, 0xb4200003, 0x81750008, + 0x5968b80b, 0x017f61c5, 0x81750001, 0x017f238c, + 0xb00b0001, 0xb4200003, 0x81750008, 0x00000000, + 0x017f238d, 0x81750001, 0x017f238e, 0xb00b0001, + 0xb4200005, 0x81750005, 0x00000000, 0x017f238f, + 0x81750002, 0x017f2390, 0xb00a0000, 0xb420001b, + 0x81750005, 0x00000000, 0x017f2391, 0x81750001, + 0x017f23a0, 0xb00b0001, 0xb4200003, 0x81750008, + 0x5968b80b, 0x017f61c9, 0x81750001, 0x017f2394, + 0xb00b0001, 0xb4200003, 0x81750008, 0x00000000, + 0x017f2395, 0x81750001, 0x017f2396, 0xb00b0001, + 0xb4200006, 0x81750005, 0x00000000, 0x017f2397, + 0x81750002, 0x00000000, 0x017f2398, 0x81750001, + 0x00000000, 0x017f2399, 0x81750001, 0x00000000, + 0x017f239a, 0x81750001, 0x017f239b, 0xb00b0001, + 0xb4200003, 0x8175000e, 0x00000000, 0x017f61be, + 0x81750001, 0x017f239c, 0xb00b0001, 0xb4200003, + 0x8175000e, 0x00000000, 0x017f237e, 0x81750001, + 0x017f239d, 0xb00b0001, 0xb4200006, 0x81750006, + 0x017f239e, 0x916b0001, 0x81550008, 0x856b0001, + 0xb4e0fffd, 0x00ffb81c, 0x00000000, 0x00000000, + 0x81470000, 0x015f2385, 0x015f2386, 0x015f2387, + 0x015f238d, 0x015f238f, 0x015f2390, 0x015f2391, + 0x015f2395, 0x015f2396, 0x015f2397, 0x015f2398, + 0x015f61be, 0x015f61bf, 0x82070028, 0x023f9006, + 0x83a4003a, 0x83270000, 0x003fb819, 0x003f9006, + 0x5823b801, 0x83338000, 0x1b39b801, 0x003fb819, + 0x00000000, 0x00000000, 0x81550000, 0x8384ff64, + 0x017f0380, 0xad4b0026, 0x013f0381, 0x114ab809, + 0x5941b80a, 0x914ae00c, 0x0199b80a, 0x00000000, + 0x019f6193, 0xb0080b77, 0xb4200016, 0x015f0380, + 0xb00a0003, 0xb4600017, 0xb0090026, 0xb4600019, + 0x017f90ba, 0xb00b0000, 0xb4200004, 0x017f0384, + 0x017f204d, 0x017f0383, 0x017f2057, 0x015f0383, + 0x017f0057, 0x300ab80b, 0xb4200012, 0x015f0384, + 0x017f004d, 0x300ab80b, 0xb420000e, 0x83070000, + 0x00ffb81a, 0x83070800, 0x031f6193, 0x83070001, + 0x00ffb81a, 0x83070800, 0x031f6193, 0x83070002, + 0x00ffb81a, 0x83070800, 0x031f6193, 0x83070003, + 0x00ffb81a, 0x83070003, 0x00ffb81a, 0x5e02b810, + 0x5a02b810, 0x00bf9011, 0x00df004f, 0xa5260020, + 0x81e70000, 0x82471000, 0x95d1ffff, 0xa5cee000, + 0x300eb810, 0xb4600002, 0x05f0b80e, 0x0207b80e, + 0x8267001f, 0x82c70020, 0x82971000, 0xb0100080, + 0xb480001f, 0x5a8bb813, 0x5aa6b813, 0x1a94b815, + 0x01efb812, 0x014fb814, 0x01cfb811, 0xb520ffff, + 0xb636000f, 0x81470000, 0x039f8014, 0xb6000404, + 0x5948b80a, 0x957c00ff, 0x194ab80b, 0x5f88b81c, + 0xb0060020, 0xb4200001, 0x80a70000, 0x64a6b805, + 0x68e9b80a, 0x18a5b807, 0x029fa025, 0x00a7b80a, + 0x01efb812, 0x014fb814, 0x01afb811, 0xb520ffff, + 0x5ae2b816, 0x1231b817, 0x0610b817, 0xb500ffde, + 0xb0100000, 0xb4000003, 0x5ec2b810, 0x86760001, + 0xb500ffdc, 0xb00f0000, 0xb4000005, 0x0207b80f, + 0x81f3001f, 0x9a2fc000, 0x81e70000, 0xb500ffd0, + 0x015fb011, 0x00ffb81d, 0x00000000, 0x00000000, + 0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x81d7ffff, + 0x8257ffff, 0x82d7ffff, 0x8357ffff, 0x83d7ffff, + 0x80770000, 0x80f70000, 0x81770000, 0x81f70000, + 0x82770000, 0x82f70000, 0x83770000, 0x83f70000, + 0xaeb40080, 0x808f0000, 0x806f001f, 0x80af001f, + 0xb0140000, 0xb4400014, 0x806f001f, 0x80af001f, + 0x8027b9fc, 0x5c22b801, 0x80670700, 0xb6000208, + 0x00cfb803, 0x003fb0bc, 0x5822b801, 0x01cfb801, + 0x003f90bc, 0xb520ffff, 0x90630020, 0x90210020, + 0x80270000, 0x80171000, 0xb6000303, 0xb6000001, + 0x001fa021, 0x00000000, 0x82670000, 0xb6000268, + 0x80170a00, 0x80970afc, 0x81170b00, 0x81970bfc, + 0x80271c00, 0x1021b813, 0x1021b813, 0x0217b801, + 0x80271ffc, 0x0421b813, 0x0421b813, 0x0297b801, + 0x80270c00, 0x1021b813, 0x1021b813, 0x0317b801, + 0x80270ffc, 0x0421b813, 0x0421b813, 0x0397b801, + 0x80478500, 0x1042b813, 0x5c42b802, 0x1022b815, + 0x80670280, 0x00cfb803, 0x003fb0bc, 0x5822b801, + 0x01cfb801, 0x003f90bc, 0xb520ffff, 0x009f033b, + 0x80478480, 0x0442b813, 0x5c42b802, 0x1022b815, + 0x806702a0, 0x00cfb803, 0x003fb0bc, 0x5822b801, + 0x01cfb801, 0x003f90bc, 0xb520ffff, 0xb0040000, + 0xb4000002, 0x80479000, 0xb5000001, 0x80479c00, + 0x1042b813, 0x5c42b802, 0x1022b815, 0x806702c0, + 0x00cfb803, 0x003fb0bc, 0x5822b801, 0x01cfb801, + 0x003f90bc, 0xb520ffff, 0xb0040000, 0xb4000002, + 0x80479180, 0xb5000001, 0x80479d80, 0x0442b813, + 0x5c42b802, 0x1022b815, 0x806702e0, 0x00cfb803, + 0x003fb0bc, 0x5822b801, 0x01cfb801, 0x003f90bc, + 0xb520ffff, 0x81270000, 0x80370000, 0x80b70000, + 0x81370000, 0x81b70000, 0x82370004, 0x82b7fffc, + 0xb6002016, 0x41498008, 0x51498814, 0x51498814, + 0x51418810, 0x51418810, 0x41818814, 0x0308a02a, + 0x49958820, 0x51898810, 0x51918828, 0x414d8814, + 0x0388a7ec, 0x494d8814, 0x49458810, 0x49458810, + 0x418d8810, 0x0308a02a, 0x49918fec, 0x51858814, + 0x51958fe4, 0x00000000, 0x0388a7ec, 0x92730080, + 0x009f033b, 0x5802b814, 0x90400300, 0x001f9802, + 0x00000000, 0xb0000000, 0xb4200016, 0x80170a00, + 0x80070000, 0xb6002001, 0x001fa020, 0xb0040000, + 0xb4200002, 0x80279000, 0xb5000001, 0x80279c00, + 0xac740080, 0x5c22b801, 0x11e1b803, 0x806f001f, + 0x80af001f, 0xb6000407, 0x80cf0280, 0x01ffb0bc, + 0x59e2b80f, 0x01afb80f, 0x01ff90bc, 0xb520ffff, + 0x91ef0020, 0x007f0320, 0x011f90cd, 0xaca30006, + 0x80c7b004, 0x10a5b814, 0x58a1b805, 0x10a5b806, + 0x0099b805, 0x8027b3dc, 0x5841b804, 0x1021b802, + 0x0159b801, 0x8027b3d0, 0x5841b804, 0x1021b802, + 0x0139b801, 0x80170c00, 0x0097b80a, 0xb6000002, + 0x59478020, 0x009fa04a, 0x00ffb81b, 0x00000000, + 0x009f0011, 0x015f0012, 0xb0060000, 0xb4200007, + 0x968a0001, 0xb0140000, 0xb400000d, 0x80870001, + 0x009f2011, 0x954a0002, 0x015f2012, 0xb0060002, + 0xb4200007, 0x968a0002, 0xb0140000, 0xb4000004, + 0x80870001, 0x009f2011, 0x81470000, 0x015f2012, + 0x8364002b, 0x00bf2010, 0xb0060000, 0xb4200003, + 0xb0050000, 0xb4200001, 0x8364008d, 0xb0050000, + 0xb4200001, 0x836400b2, 0x00bf0010, 0xb0050000, + 0xb4200006, 0x83640983, 0x8364029d, 0x00000000, + 0x8364092b, 0x00000000, 0xb5000005, 0x00bf0010, + 0xb0050001, 0xb4000002, 0x00000000, 0x83640924, + 0x00ff0325, 0x82870000, 0xb6270002, 0x8364ff08, + 0x92940001, 0x80070001, 0x801eff70, 0x001f0010, + 0xb0000001, 0xb4000007, 0x001f033b, 0xb0000000, + 0xb4000002, 0x80270000, 0xb5000001, 0x80270001, + 0x003f233b, 0x00ffb81a, 0x00000000, 0x00000000, + 0x027f4001, 0x5e2ab813, 0x96310003, 0x81c70000, + 0x820700ff, 0xb0110000, 0xb4000005, 0x5a21b811, + 0x81c70200, 0x8207000e, 0x69d1b80e, 0x1210b811, + 0x01dfb0cd, 0x5e2cb813, 0x96310003, 0x023f2323, + 0x5e28b813, 0x96310003, 0x023f2322, 0x5e27b813, + 0x96310001, 0x023f2328, 0x5e23b813, 0x96310001, + 0x023f2321, 0x95f30007, 0x01ff2320, 0x920fe004, + 0x0258b810, 0x00000000, 0x1252b811, 0x025f2325, + 0x8167befc, 0x017f6195, 0x021f031c, 0x01df031d, + 0x3010b80f, 0xb4200003, 0x3011b80e, 0xb4200001, + 0xb5000021, 0x80270000, 0x80471000, 0x0017b802, + 0x8057ffff, 0xb6002001, 0x001fa021, 0x80270400, + 0x80679000, 0x5c62b803, 0xb6001809, 0x00cfb801, + 0x007fb0bc, 0x5862b803, 0x01afb803, 0x007f90bc, + 0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x90630020, + 0x80679c00, 0x5c62b803, 0xb6001809, 0x00cfb801, + 0x007fb0bc, 0x5862b803, 0x01afb803, 0x007f90bc, + 0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x90630020, + 0x01ff231c, 0x023f231d, 0x83970300, 0x82070000, + 0xb6320001, 0x039fa030, 0x00bf0010, 0x021f0324, + 0xb0100000, 0xb4200001, 0x80a70000, 0xb0050000, + 0xb4200008, 0xb0040000, 0xb4a00002, 0x80a70001, + 0xb5000004, 0x82070000, 0x021f204e, 0xb4000001, + 0x80a70002, 0xb0050001, 0xb4200007, 0x021f004e, + 0xb0100002, 0xb4a00002, 0x80a70002, 0x00ffb81b, + 0x92100001, 0x021f204e, 0x00000000, 0x00ffb81b, + 0x81530000, 0x003fb80a, 0x00000000, 0x00000000, + 0x003fb819, 0x00000000, 0x00000000, 0x81550000, + 0x8384fd7b, 0x81470000, 0x015f61ee, 0x015f61ef, + 0x015f23a4, 0x8297050c, 0x82d7ffff, 0xb6000501, + 0x029fa02a, 0x8167e004, 0x116b0384, 0x0158b80b, + 0x019f0382, 0x015f237b, 0x017f0388, 0x116bb80a, + 0xb00c0008, 0xb4a00003, 0x80a70003, 0x00bf2010, + 0x00ffb81b, 0xb00a0005, 0xb4400003, 0xb00b0006, + 0xb4400001, 0x00ffb81b, 0x80a70004, 0x00bf2010, + 0x00ffb81b, 0x00000000, 0x00000000, 0x00000000, + 0x027f0388, 0x02bf037b, 0x02df0384, 0x02ff03a1, + 0x82970400, 0x8257ffff, 0x82d7ffff, 0xb6350003, + 0x81550001, 0x8357ffff, 0x029fa02a, 0x82970414, + 0xb6350003, 0x81550001, 0x83d7ffff, 0x029fa02a, + 0x81550001, 0xb00a0001, 0xb4200004, 0x814d0008, + 0x6149b80a, 0x954affff, 0x015f61ee, 0xb0160000, + 0xb4200007, 0x81550001, 0xb00a0001, 0xb4200004, + 0x814d0008, 0x6149b80a, 0x954affff, 0x015f61ef, + 0x81550001, 0xb00a0001, 0xb4200036, 0x82f50001, + 0x02ff23a1, 0xb0170001, 0xb420002c, 0x82970428, + 0xb6350003, 0x81550001, 0x00000000, 0x029fa02a, + 0x82970428, 0x81470000, 0x017f8034, 0xb00b0001, + 0xb4000004, 0x914a0001, 0x300ab815, 0xb480fffa, + 0xb5000001, 0x015f23a5, 0x81670000, 0xb0160002, + 0xb4200002, 0x81750001, 0x00000000, 0x017f233a, + 0x81550004, 0xadaa000c, 0x015f23a2, 0x81750004, + 0x916b0003, 0x017f23a3, 0x91ad0025, 0x01bf23a6, + 0xadab000c, 0x81e70000, 0x91ad0025, 0x01bf23a7, + 0x920a0001, 0x05abb810, 0xb00d0000, 0xb400000d, + 0xb62d0004, 0x81b50001, 0x65b0b80d, 0x19efb80d, + 0x92100001, 0x01ffb0be, 0xb5000006, 0x81a70000, + 0x82970428, 0xb6350001, 0x029fa02d, 0x01bf233a, + 0x01bf23a5, 0x82070000, 0x82270000, 0x82170428, + 0xb635003a, 0x01bf8030, 0xb00d0001, 0xb4200036, + 0x81d50001, 0x65b1b80e, 0x1a10b80d, 0xb00e0001, + 0xb4200031, 0x81b50002, 0xadad0003, 0xae510048, + 0x91cd000f, 0x91320868, 0x015f03a2, 0xad4a0004, + 0x92920700, 0x1189b80a, 0x0297b80c, 0x1194b80a, + 0x0317b80c, 0x01ff90be, 0x015f03a2, 0x017f03a3, + 0x064bb80a, 0x0107b80a, 0xb0120000, 0xb400001e, + 0xb632001d, 0x6928b80f, 0x95290001, 0xb0090000, + 0xb420000e, 0x81350004, 0x1129b80d, 0x029fa029, + 0x824d0004, 0x5a48b812, 0x5e48b812, 0x3009b80e, + 0xb4200002, 0x5e41b812, 0xb500000d, 0x5e42b812, + 0x81330040, 0x1a52b809, 0xb5000009, 0x0127b854, + 0x85290004, 0x0397b809, 0x0287b858, 0x86940004, + 0x013f803c, 0x0397b814, 0x029fa029, 0x025f803c, + 0x031fa032, 0x91080001, 0x92310001, 0x015f03a2, + 0x017f03a3, 0x013f033a, 0xb0090001, 0xb420001f, + 0x95300002, 0x95900001, 0x1929b80c, 0xb0090000, + 0xb400001a, 0x064bb80a, 0x0107b80a, 0xb6320017, + 0x6928b80f, 0x95290001, 0xb0090000, 0xb4200002, + 0x81350001, 0x013f23f8, 0x81a70700, 0x91ad0048, + 0x5982b808, 0x11adb80c, 0x0397b80d, 0x013f03f8, + 0xb0090001, 0xb4200005, 0x019f801c, 0x0196b80c, + 0x81b3ff80, 0x418cb80d, 0xb5000002, 0x019f801c, + 0x0196b80c, 0x039fa00c, 0x91080001, 0xb0160002, + 0xb420001a, 0xb0170001, 0xb4200008, 0xb00a0000, + 0xb4200002, 0x81270002, 0xb5000005, 0xb00a0002, + 0xb4400002, 0x81270003, 0xb5000001, 0x81270004, + 0x013f23a9, 0x81950001, 0xb00c0001, 0xb420000d, + 0x81a70000, 0x8397043c, 0xb6290006, 0x81150001, + 0x039fa028, 0xb0080001, 0xb4200001, 0x81a70001, + 0x00000000, 0x01bf23a8, 0xb5000002, 0x81a70000, + 0x01bf23a8, 0xb0170001, 0xb4200001, 0x81b50002, + 0x82970c20, 0xb6350003, 0x81550002, 0x00000000, + 0x029fa02a, 0xb0130001, 0xb4200001, 0x81150001, + 0x81c70000, 0xb6350014, 0x922e0c20, 0x015ff011, + 0xb00a0000, 0xb400000f, 0x922e0428, 0x015ff011, + 0xb00a0001, 0xb4200005, 0x922e044c, 0x0297b811, + 0x015f03a6, 0x029fa00a, 0xb5000006, 0x81550006, + 0xad4a0003, 0x922e044c, 0x0297b811, 0x914a0049, + 0x029fa00a, 0x91ce0004, 0xb0170001, 0xb420001e, + 0xb00d0000, 0xb400001c, 0x852d0001, 0x81470001, + 0x6549b80a, 0xad6a0003, 0x019f03a7, 0x058c03a6, + 0x81270000, 0xb00b0000, 0xb4000005, 0x300cb80b, + 0xb4800003, 0x058cb80b, 0x91290001, 0xb500fffb, + 0x81750004, 0x5961b80b, 0x839704ec, 0x0187b860, + 0x039fa02c, 0x039fa02a, 0x039fa029, 0x039fa02b, + 0xb0090000, 0xb4000004, 0xb6290003, 0x81550007, + 0x00000000, 0x00000000, 0x81c70000, 0xb635002e, + 0x922e0c20, 0x01fff011, 0xb00f0000, 0xb4000029, + 0x852f0001, 0x81470001, 0x6549b80a, 0xad6a0003, + 0x922e044c, 0x025fd811, 0x86520001, 0x0227b812, + 0x81270000, 0xb00b0000, 0xb4000005, 0x3012b80b, + 0xb4800003, 0x0652b80b, 0x91290001, 0xb500fffb, + 0x2e09b80b, 0x00000000, 0x3010b811, 0xb4600001, + 0x91290001, 0xae4e0004, 0x82150004, 0x9232049c, + 0x0297b811, 0x0187b860, 0x029fa02c, 0x029fa02a, + 0x029fa029, 0x029fa030, 0xb0090000, 0xb4000004, + 0xb6290003, 0x81550007, 0x00000000, 0x00000000, + 0x82270460, 0x1231b80e, 0x0217b811, 0x81550002, + 0x021fa00a, 0x91ce0004, 0xb0130001, 0xb420000c, + 0xb0080000, 0xb400000a, 0x81550004, 0x839704fc, + 0x0167b860, 0x039fa02b, 0x81670001, 0x039fa02b, + 0x8175000e, 0x81670002, 0x039fa02b, 0x039fa02a, + 0x81150001, 0xb0080001, 0xb420000a, 0x8135000b, + 0x5d2923aa, 0x95490180, 0x5d4723ab, 0x95490060, + 0x5d4523ac, 0x95490018, 0x5d4323ad, 0x95490007, + 0x015f23ae, 0x81350001, 0xb0090001, 0xb4200017, + 0x81350006, 0x013f23af, 0xb0170001, 0xb4200005, + 0x81550004, 0x00000000, 0x015f23b0, 0x81550003, + 0x015f23b1, 0x82970474, 0x83170488, 0xb6350004, + 0x81550007, 0x5e83a02a, 0x954a0007, 0x031fa02a, + 0xb0130001, 0xb4200005, 0x81750004, 0x00000000, + 0x017f23b2, 0x81750003, 0x017f23b3, 0xb0170001, + 0xb420000b, 0x81b50001, 0xb00d0001, 0xb4200008, + 0x81d50003, 0x59c8b80e, 0x91ce0300, 0x01df61da, + 0x81d50003, 0x59c8b80e, 0x91ce0300, 0x01df61db, + 0x81550001, 0xb00a0001, 0xb420004b, 0xb0170001, + 0xb4200001, 0x81550002, 0x82470000, 0x82270000, + 0xb6350004, 0x81750002, 0x6571b80b, 0x92310002, + 0x1a52b80b, 0xb0170001, 0xb4200017, 0xb00a0001, + 0xb4200011, 0x81150003, 0x91080001, 0x011f23a4, + 0x829709d0, 0x831709f0, 0x83970060, 0xb6280009, + 0x81750005, 0x00000000, 0x029fa02b, 0x81750004, + 0x00000000, 0x031fa02b, 0x81750003, 0x00000000, + 0x039fa02b, 0xb5000004, 0xb00a0002, 0xb4800002, + 0x81070000, 0x011f23a4, 0x82270000, 0x81270000, + 0xb6350025, 0x6a11b812, 0x92310002, 0x96100003, + 0xb0100001, 0xb4200018, 0xada90020, 0x81750003, + 0x920d0520, 0x0217b810, 0x920d05c0, 0x0297b810, + 0x920d0660, 0x0317b810, 0x5942b809, 0x920a050c, + 0x0397b810, 0x916b0001, 0x039fa02b, 0xb62b0009, + 0x81750005, 0x00000000, 0x021fa02b, 0x81750004, + 0x00000000, 0x029fa02b, 0x81750003, 0x00000000, + 0x031fa02b, 0xb5000007, 0xb0100002, 0xb4800005, + 0x59a2b809, 0x91ad050c, 0x0397b80d, 0x82070000, + 0x039fa010, 0x91290001, 0x81550001, 0xb00a0001, + 0xb4200007, 0x81550009, 0xb00a0000, 0xb4000004, + 0xb62a0003, 0x82150008, 0x00000000, 0x00000000, + 0xb00a0100, 0xb4a00007, 0x954aff00, 0xb6008003, + 0x82150010, 0x00000000, 0x00000000, 0x854a0100, + 0xb4e0fffa, 0x00ffb81b, 0x00000000, 0x00000000, + 0x81070000, 0x011f61dc, 0x011f61de, 0x011f61e0, + 0x011f03aa, 0x9108e0f4, 0x0138b808, 0x011f03ab, + 0x013f61ac, 0x9108e0f0, 0x0138b808, 0x011f03ac, + 0x013f61ad, 0x5901b808, 0x9108e0f8, 0x0139b808, + 0x011f03ad, 0x013f61ae, 0x5901b808, 0x9108e100, + 0x0139b808, 0x011f03ae, 0x013f61b0, 0x5901b808, + 0x9108e108, 0x0179b808, 0x013f03af, 0x017f61b1, + 0x02bf037b, 0x82970474, 0xb6350002, 0x015f8034, + 0x1929b80a, 0x011f03a1, 0xb0080001, 0xb4200002, + 0x015f03b0, 0x1929b80a, 0x019f0388, 0xb00c0001, + 0xb4200002, 0x015f03b2, 0x1929b80a, 0x013f61b3, + 0x015f03a8, 0xb00a0001, 0xb420003a, 0x81a70000, + 0x01bf237a, 0x83840056, 0x806f001f, 0x80af001f, + 0x80270300, 0x8067a800, 0x5c62b803, 0xb600080a, + 0x00cfb801, 0x007fb0bc, 0x5862b803, 0x01afb803, + 0x007f90bc, 0x0047b86f, 0xb0020001, 0xb4c0fffd, + 0x90210020, 0x90630020, 0x81a70001, 0x01bf237a, + 0x83840043, 0x838403c6, 0x81a70000, 0x01bf237a, + 0x82470400, 0x01bff012, 0x01bf23fa, 0x83840418, + 0x8384048f, 0x8384053e, 0x83840595, 0x806f001f, + 0x80af001f, 0x80270300, 0x8067ac00, 0x5c62b803, + 0xb600080a, 0x00cfb801, 0x007fb0bc, 0x5862b803, + 0x01cfb803, 0x007f90bc, 0x0047b86f, 0xb0020001, + 0xb4c0fffd, 0x90210020, 0x90630020, 0x81a70001, + 0x01bf237a, 0x82470404, 0x015ff012, 0x015f23fa, + 0x838403ff, 0x83840476, 0x83840525, 0x8384057c, + 0xb5000011, 0x81a70000, 0x01bf237a, 0xb635000e, + 0x8384001b, 0x01bf037a, 0xad4d0004, 0x00000000, + 0x914a0400, 0x01bff00a, 0x01bf23fa, 0x838403f0, + 0x83840467, 0x83840516, 0x8384056d, 0x01df037a, + 0x91ce0001, 0x01df237a, 0x019f0388, 0xb00c0001, + 0xb4200009, 0x02bf037b, 0x02bf237a, 0x838400e8, + 0x82470000, 0x025f23fa, 0x838403e1, 0x83840458, + 0x83840507, 0x8384055e, 0x00ffb81b, 0x00000000, + 0x80770000, 0x80f70000, 0x81770000, 0x81f70000, + 0x82770000, 0x82f70000, 0x83770000, 0x83f70000, + 0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x81d7ffff, + 0x8257ffff, 0x82d7ffff, 0x8357ffff, 0x83d7ffff, + 0x017f037a, 0x5a42b80b, 0x01bf03a8, 0xb00d0001, + 0xb4200004, 0x011f9118, 0x013f9119, 0x7929b808, + 0xb5000002, 0x91b20460, 0x013ff00d, 0x91b20340, + 0x0297b80d, 0x00000000, 0x029fa009, 0x01df0384, + 0xb00e0000, 0xb4200005, 0xb00b0001, 0xb4200003, + 0x009f90c6, 0x00bf0391, 0xb5000002, 0x009f90cf, + 0x00bf0389, 0x83a4013a, 0x81870000, 0x019f61b5, + 0x019f61b4, 0x5a02b80b, 0x9190044c, 0x01dfd80c, + 0x01df61b6, 0x91900488, 0x01dff00c, 0x59c1b80e, + 0x918ee118, 0x01d9b80c, 0x019f03af, 0x01df61af, + 0x858c000f, 0x5986b80c, 0x91d00474, 0x01bff00e, + 0x59c2b80d, 0x11cc61b2, 0x81870000, 0x019f61b8, + 0x91900414, 0x01dfd80c, 0x01df61b7, 0xadab0010, + 0x00000000, 0x908d049c, 0x83a40189, 0xadcb0020, + 0x5982b80b, 0x908e0520, 0x90ae05c0, 0x90ce0660, + 0x928c050c, 0x00ff9814, 0x83a40161, 0x83a401b0, + 0x017f037a, 0x59c2b80b, 0x918e0428, 0x01fff00c, + 0xb00f0001, 0xb4200081, 0x023f03a5, 0x3011b80b, + 0xb420000f, 0x01c7b860, 0x01dfb0fa, 0x01df41dc, + 0x01df61e8, 0x01df41de, 0x01df61ea, 0x01df41e0, + 0x01df61ec, 0x01df41dd, 0x01df61e9, 0x01df41df, + 0x01df61eb, 0x01df41e1, 0x01df61ed, 0xb5000024, + 0x01c7b860, 0x01dfb0f9, 0x01df41dc, 0x01df61e2, + 0x01df41de, 0x01df61e4, 0x01df41e0, 0x01df61e6, + 0x01df41dd, 0x01df61e3, 0x01df41df, 0x01df61e5, + 0x01df41e1, 0x01df61e7, 0x803f0000, 0x00000000, + 0x00000000, 0x01df90fa, 0x003fb80e, 0x00000000, + 0x00000000, 0x81d50000, 0x00000000, 0x00000000, + 0x01df41e8, 0x01df61dc, 0x01df41ea, 0x01df61de, + 0x01df41ec, 0x01df61e0, 0x01df41e9, 0x01df61dd, + 0x01df41eb, 0x01df61df, 0x01df41ed, 0x01df61e1, + 0x029f03a6, 0x029f236a, 0x029f03a7, 0x029f236c, + 0x027f03a2, 0x92b3e128, 0x0298b815, 0x019f03b0, + 0x029f2368, 0x5982b80c, 0x01df03af, 0x85ce000f, + 0x59c6b80e, 0x11cc61b2, 0x82a70001, 0x02bf61b8, + 0x82a70000, 0x02bf61b9, 0x029f41da, 0x029f61ba, + 0x029f41db, 0x029f61bb, 0x019f03b1, 0x5981b80c, + 0x918ce118, 0x0299b80c, 0xad8b0048, 0x029f61af, + 0x59a2b813, 0x118cb80d, 0x928c0868, 0x029fb0fb, + 0x928c0700, 0x029fb0fc, 0x019f41bc, 0x918c0003, + 0x019f61bc, 0x5a02b80b, 0x91900414, 0x029fd80c, + 0x029f236e, 0x808704ec, 0x83a40119, 0x808709d0, + 0x80a709f0, 0x80c70060, 0x00ff03a4, 0x83a400f4, + 0x83a40143, 0x021f037a, 0x019f03a5, 0x300cb810, + 0xb4000016, 0x803f0000, 0x00000000, 0x00000000, + 0x01df90f9, 0x003fb80e, 0x00000000, 0x00000000, + 0x81d50000, 0x00000000, 0x00000000, 0x01df41e2, + 0x01df61dc, 0x01df41e4, 0x01df61de, 0x01df41e6, + 0x01df61e0, 0x01df41e3, 0x01df61dd, 0x01df41e5, + 0x01df61df, 0x01df41e7, 0x01df61e1, 0x029f41b6, + 0xa6d40100, 0xaeb40004, 0x81870000, 0x92b50c00, + 0x0397b815, 0xb6360001, 0x039fa02c, 0x00ffb81c, + 0x009f90cf, 0x00bf0389, 0x019f037a, 0x5982b80c, + 0x918c0340, 0x0397b80c, 0x81870000, 0x039fa00c, + 0x83a4007b, 0x81870000, 0x019f61b5, 0x019f61b4, + 0x81870007, 0x019f61b6, 0x019f03b3, 0x5981b80c, + 0x918ce118, 0x01b9b80c, 0x019f03af, 0x01bf61af, + 0x858c000f, 0x5986b80c, 0x01bf03b2, 0x59a2b80d, + 0x118cb80d, 0x019f61b2, 0x81870000, 0x019f61b7, + 0x019f61b8, 0x808704fc, 0x83a400d1, 0x80870000, + 0x80a70000, 0x80c70000, 0x80e70000, 0x83a400ac, + 0x83a400fb, 0x81470000, 0x81e70c1c, 0x0397b80f, + 0xb600f901, 0x039fa02a, 0x00ffb81c, 0x00000000, + 0x82270000, 0x023f2011, 0x0227b860, 0x023fb0ff, + 0x02bf9006, 0x92350028, 0x8213001f, 0x9210e000, + 0x3011b810, 0xb4800001, 0x86312000, 0x021f4193, + 0x5a01b810, 0x86100028, 0x83a4fa94, 0x82270000, + 0x003fb811, 0x02bf9006, 0x5aa3b815, 0x82338000, + 0x1a31b815, 0x003fb811, 0x8067e950, 0x5c62b803, + 0x81f50000, 0x80270400, 0xb6000409, 0x814fffc0, + 0x00cfb801, 0x007fb0bc, 0x5862b803, 0x01cfb803, + 0x007f90bc, 0xb520ffff, 0x90210020, 0x90630020, + 0x82870000, 0x81f50010, 0x019f4193, 0x5d61b80c, + 0x5d43b80c, 0x114ab80b, 0x0187b80a, 0x960cff00, + 0x92100100, 0x858c0001, 0xb62c000c, 0x81f50010, + 0x5e28b80f, 0xb6000209, 0x5a48b814, 0x9652ff00, + 0x5e68b814, 0x5981b813, 0x918c1000, 0x01dfd80c, + 0x2252b811, 0x2292b80e, 0x962f00ff, 0x81870000, + 0x86100100, 0xb4e0fff0, 0xb00a0000, 0xb4000009, + 0x81670000, 0xb0140000, 0xb4000001, 0x81670001, + 0x017f2012, 0x258a4193, 0x918c0001, 0x81470000, + 0xb500ffe2, 0x81670000, 0xb0140000, 0xb4000001, + 0x81670002, 0x116b0012, 0x803f0000, 0x00000000, + 0x00000000, 0x003fb811, 0x00000000, 0x00000000, + 0x81f50000, 0x017f2012, 0x00ffb81a, 0x00000000, + 0x61f4b804, 0x91ef0001, 0x8233003f, 0x9a31ffff, + 0x5a02b804, 0x1610b811, 0x92510001, 0x1a10b812, + 0x029f03fb, 0xb0140001, 0xb4200012, 0x5a21b805, + 0x92b1e910, 0x0299b815, 0x5a22b805, 0x5a90b814, + 0x6290b814, 0x92b1e890, 0x11efb814, 0x029bb815, + 0x8233ff80, 0x3011b814, 0xb4000006, 0x4294b811, + 0x00000000, 0x0288b814, 0x4210b814, 0x00000000, + 0x0208b810, 0x029f9003, 0x82f3007f, 0x9af7ffff, + 0x3017b814, 0xb4000003, 0x4210b814, 0x00000000, + 0x0208b810, 0x82270000, 0x02c7b810, 0xb0160000, + 0xb400000a, 0x1676b812, 0x3013b812, 0xb4000003, + 0x5ac1b816, 0x92310001, 0xb500fffa, 0x81d3ff80, + 0x3010b80e, 0xb4200001, 0x1ad6b80e, 0x05efb811, + 0x027f037a, 0x5a62b813, 0x92730340, 0x0397b813, + 0x023fd813, 0x02dfb0fd, 0x5a30b811, 0x6230b811, + 0x0631b80f, 0x3010b812, 0xb4200001, 0x92310001, + 0x82470000, 0xb0110000, 0xb4800004, 0x82470003, + 0xb0110003, 0xb4400001, 0x0247b811, 0x039fa012, + 0x124f61bc, 0x00ffb81d, 0x00000000, 0x00000000, + 0x83970a10, 0x82070000, 0xb6003201, 0x039fa030, + 0xb0070000, 0xb4000019, 0x029f41b4, 0x0297b804, + 0x0317b805, 0x0397b806, 0xb6270014, 0x12948034, + 0x01df8038, 0xb00e0000, 0xb4a0000e, 0x02bf803c, + 0x5a02b814, 0x91b00a10, 0x0217b80d, 0xb62e0008, + 0x96150003, 0x91f00001, 0xadef0080, 0xb0150004, + 0xb4600001, 0x85ef0280, 0x021fa02f, 0x92940001, + 0xb5000001, 0x021f803c, 0x00000000, 0x00ffb81d, + 0x0397b804, 0x021f036a, 0x027f803c, 0x029f803c, + 0x02bf803c, 0x02df803c, 0x5a22b810, 0x92311000, + 0x0397b811, 0xb0100000, 0xb4200001, 0x039fa036, + 0xb0150000, 0xb4000021, 0x0227b860, 0x023fb0ff, + 0xb520ffff, 0x803f0000, 0x82138000, 0x1a10b813, + 0x003fb810, 0x00000000, 0x00000000, 0x82150000, + 0x00000000, 0xb635000d, 0x82550007, 0x5a42b812, + 0x9212e4b8, 0x025bb810, 0x8227000c, 0xb6000307, + 0x68d1b812, 0x94c6000f, 0x84c60002, 0x12d6b806, + 0xb6340001, 0x039fa036, 0x86310004, 0x803f0000, + 0x82138000, 0x023f90ff, 0x1a31b810, 0x003fb811, + 0x00000000, 0x00000000, 0x82150000, 0x00ffb81d, + 0x00ff41b5, 0x011f41b4, 0x019f41af, 0x01bf41ae, + 0x01df41ba, 0x01ff41bb, 0x82070000, 0x023f0380, + 0x82470000, 0xae310032, 0x029f41b3, 0x5862b807, + 0x90431000, 0x81970ad8, 0x0217b802, 0x90430c00, + 0x0297b802, 0x0317b802, 0x912802a4, 0x007ff009, + 0x58478030, 0x792341b6, 0x0529b807, 0x019fa029, + 0xb0080014, 0xb4800011, 0xa5420c00, 0x031fa02a, + 0x84690001, 0xb4a00011, 0xb623000b, 0x58678030, + 0xa4030c00, 0x031fa020, 0x044ab800, 0x0056b802, + 0x5c41b802, 0xf84200ff, 0x90620100, 0x005ff003, + 0x7d40b80a, 0x114ab802, 0xb5000004, 0xa5420c00, + 0x58478010, 0xa5620c00, 0x031fa02a, 0xb0080016, + 0xb4400043, 0xb0080013, 0xb440002c, 0xb0080006, + 0xb4400024, 0xb0080005, 0xb4400014, 0xb0080002, + 0xb4400006, 0x80440030, 0x015f619c, 0x05cab80c, + 0x05eab80d, 0x066eb810, 0xb500003c, 0x8044002a, + 0x300a419c, 0xb4800001, 0x82470001, 0x015f619c, + 0xb0120001, 0xb4200001, 0xb500001a, 0x05cab80c, + 0x05eab80d, 0x066eb810, 0xb5000030, 0x001f41b6, + 0xb0000007, 0xb4000001, 0x8044001b, 0x300a419c, + 0xb4800001, 0x82470001, 0xb0120001, 0xb4200001, + 0xb500000c, 0x05cab80c, 0x05eab80d, 0x066eb810, + 0xb5000022, 0x80440010, 0x840b0100, 0x300ab800, + 0xb4200001, 0x86100040, 0xb5000002, 0x86100080, + 0xfe100000, 0x046e41ad, 0x042ab80c, 0x7dc1b803, + 0x044f41ac, 0x042ab80d, 0x7de1b802, 0x046eb810, + 0x7e6fb803, 0xb5000011, 0x840b0100, 0x3000b80a, + 0xb4200002, 0x82070180, 0x00ffb802, 0x300ab80b, + 0xb4a00002, 0x86100040, 0xfe100000, 0x00ffb802, + 0x046e41ad, 0x042ab80c, 0x7dc1b803, 0x044f41ac, + 0x042ab80d, 0x7de1b802, 0x7e6eb80f, 0x380a41b0, + 0xb4600003, 0x242a41b0, 0x5c22b801, 0x1273b801, + 0xb0140000, 0xb4200002, 0x80071fe0, 0xb5000016, + 0x1011b808, 0x5801b800, 0x9020e26c, 0x0079b801, + 0x5842b808, 0x90420a10, 0x7c03b813, 0x003f9802, + 0x1000b801, 0x003f41b2, 0x5830b801, 0x6030b801, + 0x0400b801, 0x003f41b1, 0x5830b801, 0x6030b801, + 0x0400b801, 0xfc000000, 0xf8001fe0, 0x94001fe0, + 0x100041b1, 0x9400ffff, 0x8067003f, 0xb6290008, + 0x005f8014, 0x0442b800, 0x9442ffff, 0x5850b802, + 0x6050b802, 0xfc420000, 0x5c45b802, 0x7a82a023, + 0x10e7b809, 0x91080001, 0x300741b6, 0xb420ff6a, + 0x019f61af, 0x01bf61ae, 0x01df61ba, 0x01ff61bb, + 0x00ff41b5, 0x011f41b4, 0x019f41b8, 0x01bf41b7, + 0x01df41dd, 0x01ff41df, 0x021f41e1, 0x027f90fd, + 0x029f41bc, 0x02ff41dc, 0x031f41de, 0x033f41e0, + 0x5822b807, 0x91210c00, 0x0117b809, 0x81970ad8, + 0x91211000, 0x0217b809, 0x91210c00, 0x0317b809, + 0x80170ba0, 0x013f802c, 0xb629005f, 0x003f8038, + 0xb001000e, 0xb440001e, 0xb001000c, 0xb4400054, + 0xb001000a, 0xb4400043, 0xb0010007, 0xb440003c, + 0xb0010005, 0xb440002b, 0xb0010000, 0xb440001a, + 0xb00d0001, 0xb4200010, 0x005f418f, 0xac42bb75, + 0x8073005a, 0x9442ffff, 0x005f618f, 0x95628000, + 0x5848b802, 0xb00b8000, 0xb4200002, 0x8173ff00, + 0x1842b80b, 0x9863827a, 0x4043b802, 0x00000000, + 0x0048b802, 0xb500003f, 0x80470000, 0xb500003d, + 0x8401000f, 0x5c22b800, 0x902102d8, 0x001ff001, + 0x004db800, 0xb5000037, 0x86f70001, 0xb4600005, + 0x80750005, 0x5862b803, 0x9043e44c, 0x01d9b802, + 0x82e70002, 0x5c4cb80e, 0x9462000f, 0x5862b803, + 0x90630200, 0x005f9803, 0x59c4b80e, 0x95ceffff, + 0xb5000028, 0x87180001, 0xb4600005, 0x80750007, + 0x5862b803, 0x9043e4b8, 0x01f9b802, 0x83070002, + 0x5c4cb80f, 0x9462000f, 0x5862b803, 0x9063020c, + 0x005f9803, 0x59e4b80f, 0x95efffff, 0xb5000019, + 0x80750003, 0x5862b803, 0x90630220, 0x005f9803, + 0xb5000014, 0x87390001, 0xb4600005, 0x80750007, + 0x5862b803, 0x9043e6ac, 0x0219b802, 0x83270001, + 0x5c4cb810, 0x9462000f, 0x5862b803, 0x9063023c, + 0x005f9803, 0x5a04b810, 0x9610ffff, 0xb5000005, + 0x80750004, 0x5862b803, 0x90630268, 0x005f9803, + 0x00000000, 0x001fa022, 0x80170ba0, 0xb00c0001, + 0xb4200035, 0x023f90fb, 0x007f9811, 0x025f90fc, + 0x06d4b803, 0x007f9812, 0x4083b813, 0x00000000, + 0x0088b804, 0xb629002b, 0x24368030, 0x9421ffff, + 0x5830b801, 0x6030b801, 0x40448020, 0xb0010020, + 0xb4800003, 0x80470000, 0x80670000, 0xb500000e, + 0xb0010000, 0xb4a00004, 0x82b30080, 0x6aa1b815, + 0x4042b815, 0xb5000008, 0x6c41b802, 0x82a70017, + 0x12b5b801, 0x6875b803, 0x1842b803, 0x00000000, + 0x00000000, 0x00000000, 0x0108a022, 0x007f41b9, + 0x90630001, 0x007f61b9, 0xb003000c, 0xb420000c, + 0x92310004, 0x023fb0fb, 0x007f9811, 0x92520004, + 0x06d4b803, 0x025fb0fc, 0x007f9812, 0x80470000, + 0x4083b813, 0x00000000, 0x0088b804, 0x005f61b9, + 0x00000000, 0xb500001a, 0xb6290019, 0x24348030, + 0x9421ffff, 0x5830b801, 0x6030b801, 0x40538020, + 0xb0010020, 0xb4800003, 0x80470000, 0x80670000, + 0xb500000e, 0xb0010000, 0xb4a00004, 0x82b30080, + 0x6aa1b815, 0x4042b815, 0xb5000008, 0x6c41b802, + 0x82a70017, 0x12b5b801, 0x6875b803, 0x1842b803, + 0x00000000, 0x00000000, 0x00000000, 0x0108a022, + 0x10e7b809, 0x91080001, 0x300741b6, 0xb420ff48, + 0x00ff61b5, 0x011f61b4, 0x01df61dd, 0x01ff61df, + 0x021f61e1, 0x02ff61dc, 0x031f61de, 0x033f61e0, + 0x00ffb81d, 0x00000000, 0x00000000, 0x00000000, + 0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x81d7ffff, + 0x8257ffff, 0x808f0000, 0x003f9113, 0x005f9114, + 0x7141b802, 0x80cf0700, 0x8027b064, 0x5c22b801, + 0x003fb0bc, 0x5822b801, 0x01cfb801, 0x003f90bc, + 0xb520ffff, 0x80cf0704, 0x8027b06c, 0x5c22b801, + 0x003fb0bc, 0x5822b801, 0x01cfb801, 0x003f90bc, + 0xb520ffff, 0x81e7043c, 0x82071c00, 0x82271c10, + 0x019f03a9, 0x806f001f, 0x80af001f, 0x80270400, + 0x8067a800, 0x5c62b803, 0xb6000808, 0x00cfb801, + 0x007fb0bc, 0x5862b803, 0x01cfb803, 0x007f90bc, + 0xb520ffff, 0x90210020, 0x90630020, 0x81971000, + 0x82170c00, 0xb6000004, 0x003f800c, 0x005f8010, + 0x021fa021, 0x019fa022, 0x00bfd810, 0x003fd811, + 0x70c1b80a, 0x001f980f, 0x91ef0004, 0x92100002, + 0x92310002, 0x5822b805, 0x90411000, 0x0197b802, + 0x90410c00, 0x0217b802, 0x0466b805, 0xb0000000, + 0xb4000005, 0xb6230004, 0x003f8010, 0x005f800c, + 0x1201a022, 0x0581a022, 0x858c0001, 0xb4e0ffea, + 0x80270400, 0x8067ac00, 0x5c62b803, 0xb6000808, + 0x00cfb801, 0x007fb0bc, 0x5862b803, 0x01afb803, + 0x007f90bc, 0xb520ffff, 0x90210020, 0x90630020, + 0x00ffb81c, 0x00000000, 0x00000000, 0x00000000, + 0x808f0000, 0x806f001f, 0x80af001f, 0x003f037a, + 0xb0010000, 0xb4400030, 0x81a7b7fc, 0x5da2b80d, + 0x80670500, 0xb6000208, 0x00cfb803, 0x01bfb0bc, + 0x59a2b80d, 0x01cfb80d, 0x01bf90bc, 0xb520ffff, + 0x90630020, 0x91ad0020, 0x81c7b8fc, 0x5dc2b80e, + 0x80670540, 0xb6000208, 0x00cfb803, 0x01dfb0bc, + 0x59c2b80e, 0x01cfb80e, 0x01df90bc, 0xb520ffff, + 0x90630020, 0x91ce0020, 0x81a7b3fc, 0x5da2b80d, + 0x80670600, 0xb6000408, 0x00cfb803, 0x01bfb0bc, + 0x59a2b80d, 0x01cfb80d, 0x01bf90bc, 0xb520ffff, + 0x90630020, 0x91ad0020, 0x81c7b5fc, 0x5dc2b80e, + 0x80670680, 0xb6000408, 0x00cfb803, 0x01dfb0bc, + 0x59c2b80e, 0x01cfb80e, 0x01df90bc, 0xb520ffff, + 0x90630020, 0x91ce0020, 0x005f03fa, 0xb0020000, + 0xb4000024, 0x8057ffff, 0x80d7ffff, 0x8157ffff, + 0x81d7ffff, 0x8257ffff, 0x82d7ffff, 0x8357ffff, + 0x83d7ffff, 0x83971300, 0x83171200, 0x82971100, + 0x82171000, 0x81170c00, 0x81970ff8, 0x80171400, + 0x80971500, 0x005f802c, 0x001f8028, 0xb6004010, + 0x41028000, 0x51008004, 0x007f876c, 0x0208a028, + 0x41008000, 0x49028004, 0x003f8068, 0x0388a028, + 0x41038000, 0x51018004, 0x005f802c, 0x0288a028, + 0x41018020, 0x49038024, 0x001f8028, 0x0308a028, + 0x00ffb81c, 0x83d7ffff, 0x8357ffff, 0x82d7ffff, + 0x8257ffff, 0x8157ffff, 0x81d7ffff, 0x8057ffff, + 0x80d7ffff, 0x82971200, 0x82171000, 0x81170c00, + 0x81970ffc, 0x83171800, 0x83971a00, 0x83370000, + 0x83b70000, 0x81370008, 0x81b7fff8, 0x4119880c, + 0xb6008006, 0x511d8808, 0x41498838, 0x0208a028, + 0x494d883c, 0x4119880c, 0x0288a02a, 0x00ffb81c, + 0x82670000, 0x82a70000, 0x003f037a, 0xb0010000, + 0xb4400018, 0x81a7bdfc, 0x5da2b80d, 0x80670580, + 0xb6000208, 0x00cfb803, 0x01bfb0bc, 0x59a2b80d, + 0x01cfb80d, 0x01bf90bc, 0xb520ffff, 0x90630020, + 0x91ad0020, 0x81a7eb70, 0x5da2b80d, 0x806705c0, + 0xb6000208, 0x00cfb803, 0x01bfb0bc, 0x59a2b80d, + 0x01cfb80d, 0x01bf90bc, 0xb520ffff, 0x90630020, + 0x91ad0020, 0x02bf03fa, 0x808f0000, 0xb0150000, + 0xb4000006, 0x81470040, 0x81670003, 0x81870002, + 0x81a71000, 0x81c71300, 0xb5000005, 0x81470080, + 0x81670004, 0x81870001, 0x81a71000, 0x81c71200, + 0x0017b80d, 0x0097b80e, 0x108db80a, 0x0117b804, + 0x108eb80a, 0x0197b804, 0x5841b80a, 0x108db802, + 0x0217b804, 0x108eb802, 0x0297b804, 0x106ab802, + 0x108db803, 0x0317b804, 0x108eb803, 0x0397b804, + 0x5ea2b80a, 0xb6350020, 0x001f8000, 0x003f8008, + 0x005f8004, 0x007f800c, 0x10c08010, 0x10a18018, + 0x10828014, 0x10e3801c, 0x1246b805, 0x0686b805, + 0x10c4b807, 0x0484b807, 0x80e70000, 0x80a70000, + 0x0008a032, 0x0108a034, 0x0088a026, 0x0188a024, + 0x04c08010, 0x04a18018, 0x04828014, 0x04e3801c, + 0x0646b807, 0x1286b807, 0x10c4b805, 0x0484b805, + 0x80e70000, 0x80a70000, 0x0208a032, 0x0308a034, + 0x0288a026, 0x0388a024, 0x5de1b80a, 0x82070004, + 0xb62b002a, 0x0017b80d, 0x0097b80e, 0x102db80f, + 0x0117b801, 0x104eb80f, 0x0197b802, 0x82171600, + 0x82971700, 0x0037b80f, 0x00b7b80f, 0x0137b80f, + 0x01b7b80f, 0xb630001b, 0x003f8030, 0x005f8034, + 0x5ee2b80f, 0x8013007f, 0x9800ffff, 0xb6370011, + 0x41008000, 0x51018008, 0x4902800c, 0x40c08000, + 0x0008a028, 0x48c18008, 0x50c2800c, 0x42808004, + 0x00c8b806, 0x52828008, 0x5281800c, 0x41008004, + 0x0088a034, 0x49028008, 0x4901800c, 0x011fa026, + 0x0188a028, 0x001f8001, 0x001f8005, 0x001f8009, + 0x001f800d, 0x5de1b80f, 0x5a01b810, 0x0017b80d, + 0x0097b80e, 0x902d0004, 0x0117b801, 0x904e0004, + 0x0197b802, 0x82171600, 0x82971700, 0x5ea1b80a, + 0x8013007f, 0x9800ffff, 0xb6350013, 0x003f8030, + 0x005f8034, 0x42408000, 0x52418008, 0x4a42800c, + 0x41008000, 0x0008a052, 0x49018008, 0x5102800c, + 0x42808004, 0x0108b808, 0x52828008, 0x5281800c, + 0x40c08004, 0x0088a054, 0x48c28008, 0x48c1800c, + 0x011fa048, 0x0188a046, 0x81a71100, 0x81c71200, + 0x858c0001, 0xb4e0ff7e, 0x00ffb81c, 0x00000000, + 0x005f03fa, 0x00000000, 0xb0020000, 0xb4000034, + 0x81b70080, 0x81d7ffff, 0x81f70001, 0x82370080, + 0x8257ffff, 0x82770001, 0x82b70080, 0x82d7ffff, + 0x82f70001, 0x83370080, 0x8357ffff, 0x83770001, + 0x81971000, 0x82171100, 0x82971200, 0x83171300, + 0x815703fc, 0x81370200, 0x81170c00, 0x83d703fc, + 0x83b70200, 0x83970f00, 0x8057ffff, 0x80d7ffff, + 0x80171400, 0x80971500, 0x001f800d, 0x003f8019, + 0xb6004012, 0x41008000, 0x51018004, 0x007f8011, + 0x0128a008, 0x41018000, 0x49008004, 0x009f8015, + 0x03a8a008, 0x41038000, 0x51048004, 0x001f800d, + 0x03a8a008, 0x41048020, 0x49038024, 0x003f8019, + 0x0128a008, 0x005f8028, 0x005f803c, 0x81f70000, + 0x82770000, 0x82f70000, 0x83770000, 0x00ffb81c, + 0x82370040, 0x8257ffff, 0x82770001, 0x82b70040, + 0x82d7ffff, 0x82f70001, 0x82171000, 0x82971200, + 0x8157ffff, 0x81170c00, 0x81d7ffff, 0x81970e00, + 0x8057ffff, 0x80d7ffff, 0x80171800, 0x80971a00, + 0xb600800a, 0x001f8011, 0x003f8015, 0x41008000, + 0x51018004, 0x00000000, 0x0108a028, 0x41018020, + 0x49008024, 0x00000000, 0x0188a028, 0x82770000, + 0x82f70000, 0x00ffb81c, 0x00000000, 0x00000000, + 0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x808f0000, + 0x015f0384, 0x017f037a, 0xac4a0006, 0x8027b004, + 0x1042b80b, 0x5841b802, 0x1021b802, 0x0159b801, + 0x013f0325, 0x01bf0320, 0x5822b80b, 0x90210340, + 0x00ff9801, 0x8027b2e8, 0x5842b807, 0x1021b802, + 0x025bb801, 0x80070000, 0xac4d0006, 0x8027b004, + 0x1042b800, 0x5841b802, 0x1021b802, 0x0199b801, + 0x00000000, 0xac4c0006, 0x8027b078, 0x1042b80a, + 0x5842b802, 0x1021b802, 0x011bb801, 0x00000000, + 0x40d2b808, 0x00000000, 0xb0060000, 0xb4000080, + 0x005f033b, 0x80278400, 0xac600080, 0x5c22b801, + 0x10a1b803, 0xb0020000, 0xb4200002, 0x80279000, + 0xb5000001, 0x80279c00, 0x5c22b801, 0x11e1b803, + 0x80470300, 0x5822b800, 0x1042b801, 0x003f9802, + 0x806f001f, 0x80af001f, 0xb0010000, 0xb4200024, + 0x80170c00, 0x80971000, 0x003f8020, 0xb6000003, + 0x4201b806, 0x003f8020, 0x0088a030, 0x80270400, + 0xb6000208, 0x00cfb801, 0x00bfb0bc, 0x58a2b805, + 0x01afb805, 0x00bf90bc, 0xb520ffff, 0x90210020, + 0x90a50020, 0xb6000408, 0x00cfb801, 0x01ffb0bc, + 0x59e2b80f, 0x01afb80f, 0x01ff90bc, 0xb520ffff, + 0x90210020, 0x91ef0020, 0xb6000208, 0x00cfb801, + 0x00bfb0bc, 0x58a2b805, 0x01afb805, 0x00bf90bc, + 0xb520ffff, 0x90210020, 0x90a50020, 0xb5000043, + 0x80270400, 0x0087b805, 0x01c7b80f, 0xb6000208, + 0x00cfb801, 0x009fb0bc, 0x5882b804, 0x01cfb804, + 0x009f90bc, 0xb520ffff, 0x90210020, 0x90840020, + 0xb6000408, 0x00cfb801, 0x01dfb0bc, 0x59c2b80e, + 0x01cfb80e, 0x01df90bc, 0xb520ffff, 0x90210020, + 0x91ce0020, 0xb6000208, 0x00cfb801, 0x009fb0bc, + 0x5882b804, 0x01cfb804, 0x009f90bc, 0xb520ffff, + 0x90210020, 0x90840020, 0x80170c00, 0x80971000, + 0x8053007f, 0x9842ffff, 0xb6000004, 0x42028004, + 0x4a068020, 0x00000000, 0x0088a030, 0x80270400, + 0xb6000208, 0x00cfb801, 0x00bfb0bc, 0x58a2b805, + 0x01afb805, 0x00bf90bc, 0xb520ffff, 0x90210020, + 0x90a50020, 0xb6000408, 0x00cfb801, 0x01ffb0bc, + 0x59e2b80f, 0x01afb80f, 0x01ff90bc, 0xb520ffff, + 0x90210020, 0x91ef0020, 0xb6000208, 0x00cfb801, + 0x00bfb0bc, 0x58a2b805, 0x01afb805, 0x00bf90bc, + 0xb520ffff, 0x90210020, 0x90a50020, 0x5822b800, + 0x90210300, 0x0117b801, 0x80470001, 0x011fa002, + 0x90000001, 0x3000b809, 0xb480ff6b, 0x00ffb81c, + 0x8057ffff, 0x013f0325, 0x015f033b, 0x80171000, + 0x80070000, 0xb6002001, 0x001fa020, 0xb00a0001, + 0xb4c00002, 0x81679000, 0xb5000001, 0x81679c00, + 0x5d62b80b, 0x81878400, 0x5d82b80c, 0x80070000, + 0x5822b800, 0x90410300, 0x003f9802, 0x00000000, + 0xb0010000, 0xb4200019, 0xac400080, 0x00000000, + 0x10ccb802, 0x10abb802, 0x806f001f, 0x80af001f, + 0x80cf0400, 0xb6000408, 0xb520ffff, 0x00dfb0bc, + 0x58c2b806, 0x01afb806, 0x00df90bc, 0xb520ffff, + 0x80cf0400, 0x90c60020, 0x80cf0400, 0xb6000407, + 0x00bfb0bc, 0x58a2b805, 0x01afb805, 0x00bf90bc, + 0xb520ffff, 0x80cf0400, 0x90a50020, 0x90000001, + 0x3000b809, 0xb480ffde, 0x00ffb81b, 0x8057ffff, + 0x013f0325, 0x80171000, 0x80070000, 0xb6002001, + 0x001fa020, 0x81878400, 0x5d82b80c, 0x80070000, + 0x5822b800, 0x90410300, 0x003f9802, 0x00000000, + 0xb0010000, 0xb420000f, 0xac400080, 0x00000000, + 0x10ccb802, 0x806f001f, 0x80af001f, 0x80cf0400, + 0xb6000408, 0xb520ffff, 0x00dfb0bc, 0x58c2b806, + 0x01afb806, 0x00df90bc, 0xb520ffff, 0x80cf0400, + 0x90c60020, 0x90000001, 0x3000b809, 0xb480ffe8, + 0x00ffb81b, 0x8057ffff, 0x80d7ffff, 0x8157ffff, + 0x8139b000, 0x00000000, 0xb0090000, 0xb4000012, + 0x806f001f, 0x80af001f, 0x80cf0400, 0x013fb0bc, + 0x5922b809, 0x01cfb809, 0x013f90bc, 0xb520ffff, + 0x806f0003, 0x80af0003, 0x80cf0420, 0x91290020, + 0x013fb0bc, 0x5922b809, 0x01cfb809, 0x013f90bc, + 0xb520ffff, 0xb5000233, 0x80270000, 0x80171000, + 0xb6002401, 0x001fa021, 0x007f0384, 0x009f0320, + 0x00bf0385, 0x00df0386, 0x80e7b36c, 0x5821b803, + 0x1021b807, 0x0159b801, 0x5821b804, 0x1021b807, + 0x0179b801, 0x80e7b37c, 0x5821b803, 0x1021b807, + 0x0199b801, 0x5821b804, 0x1021b807, 0x01b9b801, + 0x80e7b38c, 0x5821b803, 0x1021b807, 0x01d9b801, + 0x5821b804, 0x1021b807, 0x01f9b801, 0x005f0385, + 0x8027b39c, 0x5842b802, 0x1021b802, 0x021bb801, + 0x005f0386, 0x8027b3ac, 0x5842b802, 0x1021b802, + 0x023bb801, 0x027f0383, 0x003f0328, 0x005f4195, + 0xb0130007, 0xb42000df, 0xb0010000, 0xb42000dd, + 0xb0020000, 0xb40000db, 0xb0030002, 0xb48000d9, + 0x029bb802, 0x82a7b108, 0xb00b0001, 0xb4200001, + 0xb5000005, 0xb00b0002, 0xb4200002, 0x92b500a0, + 0xb5000001, 0x92b50140, 0xb0030004, 0xb4600002, + 0x82870000, 0xb5000006, 0xb0030006, 0xb4600004, + 0xb0140001, 0xb4a00002, 0x82870001, 0xb5000000, + 0xac54000a, 0x806f0009, 0x80af0009, 0x5c22b815, + 0x80cf0440, 0x1021b802, 0x003fb0bc, 0x5822b801, + 0x01cfb801, 0x003f90bc, 0xb520ffff, 0xb0030003, + 0xb400000f, 0xb0030004, 0xb400001d, 0xb0030005, + 0xb400002b, 0xb0030006, 0xb4000042, 0xb0030007, + 0xb4000059, 0x80171000, 0x005f9440, 0x001fa002, + 0x80171038, 0x005f9440, 0x001fa002, 0xb5000073, + 0x80171000, 0x005f9440, 0x001fa002, 0x80171004, + 0x005f9443, 0x001fa002, 0x8017101c, 0x005f9446, + 0x001fa002, 0x80171034, 0x005f9449, 0x001fa002, + 0x80171038, 0x005f9440, 0x001fa002, 0xb5000063, + 0x80171000, 0x005f9440, 0x001fa002, 0x80171008, + 0x005f9441, 0x001fa002, 0x80171020, 0x005f9444, + 0x001fa002, 0x80171034, 0x005f9440, 0x001fa002, + 0x80171038, 0x005f9447, 0x001fa002, 0xb5000053, + 0x80171000, 0x005f9440, 0x001fa002, 0x80171004, + 0x005f9443, 0x001fa002, 0x8017100c, 0x005f9441, + 0x001fa002, 0x8017101c, 0x005f9446, 0x001fa002, + 0x80171024, 0x005f9444, 0x001fa002, 0x80171034, + 0x005f9449, 0x001fa002, 0x80171038, 0x005f9440, + 0x001fa002, 0x8017103c, 0x005f9447, 0x001fa002, + 0xb500003a, 0x80171000, 0x005f9440, 0x001fa002, + 0x80171008, 0x005f9441, 0x001fa002, 0x8017100c, + 0x005f9442, 0x001fa002, 0x80171020, 0x005f9444, + 0x001fa002, 0x80171024, 0x005f9445, 0x001fa002, + 0x80171034, 0x005f9440, 0x001fa002, 0x80171038, + 0x005f9447, 0x001fa002, 0x8017103c, 0x005f9448, + 0x001fa002, 0xb5000021, 0x80171000, 0x005f9440, + 0x001fa002, 0x80171004, 0x005f9443, 0x001fa002, + 0x8017100c, 0x005f9441, 0x001fa002, 0x80171010, + 0x005f9442, 0x001fa002, 0x8017101c, 0x005f9446, + 0x001fa002, 0x80171024, 0x005f9444, 0x001fa002, + 0x80171028, 0x005f9445, 0x001fa002, 0x80171034, + 0x005f9449, 0x001fa002, 0x80171038, 0x005f9440, + 0x001fa002, 0x8017103c, 0x005f9447, 0x001fa002, + 0x80171040, 0x005f9448, 0x001fa002, 0x80270001, + 0x803eff90, 0x80171000, 0x82b30020, 0x9ab50000, + 0x40158020, 0xb6000501, 0x48158020, 0x82b30020, + 0x9ab50000, 0x80470000, 0x3015b800, 0xb4600006, + 0x80171000, 0x83840226, 0xb6000603, 0x40028000, + 0x00000000, 0x0008a020, 0x80171018, 0x82b30020, + 0x9ab50000, 0x40158020, 0xb6000501, 0x48158020, + 0x82b30020, 0x9ab50000, 0x80470000, 0x3015b800, + 0xb4600006, 0x80171018, 0x83840215, 0xb6000603, + 0x40028000, 0x00000000, 0x0008a020, 0x80171030, + 0x82b30020, 0x9ab50000, 0x40158020, 0xb6000501, + 0x48158020, 0x82b30020, 0x9ab50000, 0x80470000, + 0x3015b800, 0xb4600006, 0x80171030, 0x83840204, + 0xb6000603, 0x40028000, 0x00000000, 0x0008a020, + 0xb500011e, 0x80270000, 0x803eff90, 0xb0030000, + 0xb4200067, 0x025f0322, 0xb00b0001, 0xb4200016, + 0xb0120001, 0xb4200005, 0x80171018, 0x8033007f, + 0x9821ffff, 0x001fa001, 0xb5000110, 0xb0120002, + 0xb4200005, 0x80171020, 0x8033007f, 0x9821ffff, + 0x001fa001, 0xb5000109, 0x80171018, 0x80330040, + 0x98210000, 0x001fa001, 0x80171020, 0x00000000, + 0x001fa001, 0xb5000101, 0xb00b0002, 0xb420002c, + 0xb0120000, 0xb4200008, 0x80171000, 0x8033007f, + 0x9821ffff, 0x001fa001, 0x80171038, 0x00000000, + 0x001fa001, 0xb50000f5, 0xb0120001, 0xb4200008, + 0x80171000, 0x8033005a, 0x98218279, 0x001fa001, + 0x80171030, 0x00000000, 0x001fa001, 0xb50000eb, + 0xb0120002, 0xb4200008, 0x80171008, 0x8033005a, + 0x98218279, 0x001fa001, 0x80171038, 0x00000000, + 0x001fa001, 0xb50000e1, 0x80171000, 0x80330040, + 0x98210000, 0x001fa001, 0x80171008, 0x00000000, + 0x001fa001, 0x8017100c, 0x00000000, 0x001fa001, + 0x80171038, 0x00000000, 0x001fa001, 0xb50000d3, + 0xb0120000, 0xb4200008, 0x80171000, 0x8033007f, + 0x9821ffff, 0x001fa001, 0x80171038, 0x00000000, + 0x001fa001, 0xb50000c9, 0xb0120001, 0xb4200005, + 0x80171018, 0x8033007f, 0x9821ffff, 0x001fa001, + 0xb50000c2, 0xb0120002, 0xb4200005, 0x80171020, + 0x8033007f, 0x9821ffff, 0x001fa001, 0xb50000bb, + 0x80171018, 0x80330040, 0x98210000, 0x001fa001, + 0x80171020, 0x00000000, 0x001fa001, 0xb50000b3, + 0x80070000, 0x8033007f, 0x9821ffff, 0xb600050e, + 0x144eb80f, 0xb0028000, 0xb4c00008, 0xac400006, + 0x00000000, 0x1042b800, 0x5842b802, 0x90421000, + 0x0017b802, 0x00000000, 0x001fa001, 0x90000001, + 0x59c1b80e, 0x59e1b80f, 0xb0040000, 0xb4200023, + 0xb00a0002, 0xb4000007, 0x80171004, 0x8033005a, + 0x98218279, 0x001fa001, 0x80171034, 0x00000000, + 0x001fa001, 0xb00c0002, 0xb4000009, 0x8017100c, + 0x8033ffa5, 0x98217d87, 0x001fa001, 0x8017103c, + 0x8033005a, 0x98218279, 0x001fa001, 0xb500008b, + 0x8017100c, 0x8033ffa5, 0x98217d87, 0x001fa001, + 0x80171010, 0x00000000, 0x001fa001, 0x8017103c, + 0x8033005a, 0x98218279, 0x001fa001, 0x80171040, + 0x00000000, 0x001fa001, 0xb500007c, 0xb0040001, + 0xb420002a, 0xb00a0001, 0xb4000007, 0x80171018, + 0x8033005a, 0x98218279, 0x001fa001, 0x80171020, + 0x00000000, 0x001fa001, 0xb00a0003, 0xb420000a, + 0x8053005a, 0x98428279, 0x4030b802, 0x8017101c, + 0x5821b801, 0x00000000, 0x00000000, 0x00000000, + 0x0028b801, 0x001fa001, 0xb00c0001, 0xb4200007, + 0x8053005a, 0x98428279, 0x4031b802, 0x80171024, + 0x0028b801, 0x001fa001, 0xb500005c, 0xb00c0002, + 0xb420005a, 0x8053005a, 0x98428279, 0x4031b802, + 0x80171024, 0x0028b801, 0x001fa001, 0x80171028, + 0x00000000, 0x001fa001, 0xb5000050, 0xb00b0002, + 0xb4200012, 0xb00a0001, 0xb4200008, 0x80171004, + 0x8033005a, 0x98218279, 0x001fa001, 0x80171034, + 0x00000000, 0x001fa001, 0xb5000008, 0xb00a0003, + 0xb4200006, 0x80171004, 0x00000000, 0x001fa010, + 0x80171034, 0x00000000, 0x001fa010, 0xb00c0001, + 0xb4200025, 0x027f0383, 0x003f0328, 0xb0130007, + 0xb420000b, 0xb00b0003, 0xb4200009, 0xb0010000, + 0xb4200007, 0x80171024, 0x00000000, 0x001fa011, + 0x80171054, 0x80270000, 0x001fa001, 0xb500002b, + 0xb00d0000, 0xb420000a, 0x8033005a, 0x98218279, + 0x4041b811, 0x8017100c, 0x0048b802, 0x001fa002, + 0x8017103c, 0x00000000, 0x001fa002, 0xb500001f, + 0xb00d0002, 0xb420001d, 0x80171054, 0x8033005a, + 0x98218279, 0x001fa001, 0x8017106c, 0x00000000, + 0x001fa001, 0xb5000015, 0xb00c0002, 0xb4200013, + 0xb00d0000, 0xb4200007, 0x8017100c, 0x00000000, + 0x001fa011, 0x80171040, 0x00000000, 0x001fa011, + 0xb500000a, 0xb00d0001, 0xb4200008, 0x80171054, + 0x8033005a, 0x98218279, 0x001fa001, 0x80171058, + 0x00000000, 0x001fa001, 0xb5000000, 0x029f0388, + 0x02bf0321, 0xb0140000, 0xb4000006, 0xb0150000, + 0xb4000004, 0x8017108c, 0x8033007f, 0x9821ffff, + 0x001fa001, 0x8027b078, 0x5c22b801, 0x806f001f, + 0x80af001f, 0x80cf0400, 0x003fb0bc, 0x5822b801, + 0x01afb801, 0x003f90bc, 0xb520ffff, 0x90210020, + 0x806f0003, 0x80af0003, 0x80cf0420, 0x003fb0bc, + 0x5822b801, 0x01afb801, 0x003f90bc, 0xb520ffff, + 0x81270000, 0x8033007f, 0x9821ffff, 0x80171000, + 0xb600060a, 0x80470000, 0xb6000603, 0x015f8020, + 0x0156b80a, 0x1042b80a, 0x3002b801, 0xb4a00001, + 0x81270001, 0x00000000, 0x00000000, 0x015f0323, + 0x00000000, 0xb00a0000, 0xb4200002, 0x81670000, + 0xb5000001, 0x81670001, 0x017f23fb, 0x01ff41ee, + 0x59f0b80f, 0x61f0b80f, 0x021f41ef, 0x5a10b810, + 0x6210b810, 0xb00a0003, 0xb420003b, 0x017f039f, + 0x019f41c5, 0x5990b80c, 0x6190b80c, 0xb00b0000, + 0xb400000c, 0xb00c0000, 0xb4000005, 0xac4c0100, + 0x8033001d, 0x98215500, 0x12c1b802, 0xb500000f, + 0xac4f0100, 0x8033001d, 0x98215500, 0x12c1b802, + 0xb500000a, 0xb0090000, 0xb4000005, 0xac4f0100, + 0x8033ffe2, 0x9821ab00, 0x12c1b802, 0xb5000003, + 0xac4f0100, 0x00000000, 0x02c7b802, 0xb0030000, + 0xb420007e, 0x01bf03a0, 0x01df41c9, 0x59d0b80e, + 0x61d0b80e, 0xb00d0000, 0xb400000c, 0xb00e0000, + 0xb4000005, 0xac4e0100, 0x8033001d, 0x98215500, + 0x12e1b802, 0xb5000071, 0xac500100, 0x8033001d, + 0x98215500, 0x12e1b802, 0xb500006c, 0xb0090000, + 0xb4000005, 0xac500100, 0x8033ffe2, 0x9821ab00, + 0x12e1b802, 0xb5000065, 0xac500100, 0x00000000, + 0x02e7b802, 0xb5000061, 0xb00a0002, 0xb420002f, + 0x023f9002, 0x025f9001, 0xb00f0000, 0xb4a00007, + 0xac4f0100, 0x00000000, 0x4022b811, 0x00000000, + 0x0028b801, 0x02c7b801, 0xb500000c, 0xb0090000, + 0xb4000004, 0xac4f0100, 0x00000000, 0x02c7b802, + 0xb5000006, 0xac4f0100, 0x00000000, 0x4022b812, + 0x00000000, 0x0028b801, 0x02c7b801, 0xb0030000, + 0xb4200046, 0xb0100000, 0xb4a00007, 0xac500100, + 0x00000000, 0x4022b811, 0x00000000, 0x0028b801, + 0x02e7b801, 0xb500003d, 0xb0090000, 0xb4000004, + 0xac500100, 0x00000000, 0x02e7b802, 0xb5000037, + 0xac500100, 0x00000000, 0x4022b812, 0x00000000, + 0x0028b801, 0x02e7b801, 0xb5000030, 0x023f9002, + 0x025f9001, 0xb00f0000, 0xb4a00007, 0xac4f0100, + 0x00000000, 0x4022b811, 0x00000000, 0x0028b801, + 0x02c7b801, 0xb5000006, 0xac4f0100, 0x00000000, + 0x4022b812, 0x00000000, 0x0028b801, 0x02c7b801, + 0xb0090000, 0xb4000005, 0x0047b816, 0x8033ffe2, + 0x9821ab00, 0x1042b801, 0x02c7b802, 0xb0030000, + 0xb4200016, 0xb0100000, 0xb4a00007, 0xac500100, + 0x00000000, 0x4022b811, 0x00000000, 0x0028b801, + 0x02e7b801, 0xb5000006, 0xac500100, 0x00000000, + 0x4022b812, 0x00000000, 0x0028b801, 0x02e7b801, + 0xb0090000, 0xb4000005, 0x0047b817, 0x8033ffe2, + 0x9821ab00, 0x1042b801, 0x02e7b802, 0x00000000, + 0x00000000, 0x02c8b816, 0x02dfb0cf, 0xb0030000, + 0xb4200002, 0x02e8b817, 0x02ffb0c6, 0x00ffb81b, + 0xb6001807, 0x5841b802, 0x3015b800, 0xb4800002, + 0x06b5b800, 0x98420001, 0x5aa1b815, 0x00000000, + 0x00ffb81c, 0x00000000, 0x00000000, 0x00000000, + 0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000, + 0xb4000015, 0x815bb3f0, 0x81070000, 0x812707f8, + 0xb00a0000, 0xb4000006, 0x81070800, 0x81270ff8, + 0xb00a0001, 0xb4000002, 0x81071000, 0x812717f8, + 0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc, + 0x9421ffff, 0x3001b808, 0xb480000f, 0x3001b809, + 0xb4a0002d, 0xb500000c, 0xb0040000, 0xb4200003, + 0x802717ff, 0x81070000, 0xb5000007, 0xb0040001, + 0xb4200002, 0x81070800, 0xb5000003, 0x80270001, + 0x003f23f9, 0x81071000, 0xb0040000, 0xb4200001, + 0x8384026c, 0x80af001f, 0x808f0000, 0x806f0000, + 0x80670400, 0x5d22b808, 0xb600100a, 0x00cfb803, + 0x013fb0bc, 0x5922b809, 0x01afb809, 0x013f90bc, + 0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x90630020, + 0x91290020, 0x801bb3f8, 0x80270001, 0xb0000001, + 0xb4000002, 0x802600a0, 0x803eb3f8, 0x914a0001, + 0xb00a0002, 0xb4a00001, 0x81470000, 0x815eb3f0, + 0x80270001, 0x003f2013, 0x00ffb81b, 0x00000000, + 0x029fb00a, 0x02bfb00b, 0x02dfb00c, 0x02ffb00d, + 0x031fb00e, 0x033fb00f, 0x033f400f, 0x0287b86f, + 0x029fb005, 0x8285009d, 0x9a940008, 0x8286009d, + 0x8285009c, 0x96b48000, 0xb0158000, 0xb40001b5, + 0x96b40100, 0xb0150100, 0xb400020c, 0x96b40400, + 0xb0150400, 0xb400020d, 0x96b40001, 0xb0150001, + 0xb400000c, 0x96b40008, 0xb0150008, 0xb40001ad, + 0x96b44000, 0xb0154000, 0xb400020c, 0x96b40002, + 0xb0150002, 0xb4000182, 0x00000000, 0x00000000, + 0xb500021e, 0x02bf9017, 0x92b50001, 0x02bfb017, + 0x82850082, 0x96f40001, 0xb0170000, 0xb4000171, + 0x5efdb814, 0x96f70001, 0xb0170001, 0xb420000b, + 0x83050069, 0x9718003f, 0x82e50064, 0x12f7b818, + 0x86f70109, 0x82feff74, 0x02e7b86f, 0x9af74000, + 0x01ffb817, 0x96f7bfff, 0x01ffb817, 0x83050081, + 0x82a5009a, 0x96b50001, 0xb0150001, 0xb4200014, + 0x82a70000, 0x02bfb017, 0x96b41840, 0xb0150800, + 0xb420000c, 0x96b40008, 0x5aa9b815, 0x96d46000, + 0x5ec3b816, 0x82f3000f, 0x9af7c00f, 0x1718b817, + 0x1ab5b818, 0x1ab5b816, 0x9ab50340, 0x82a60081, + 0xb500014c, 0x9b180180, 0x83060081, 0xb5000149, + 0x82a5009a, 0x96b50002, 0xb0150002, 0xb420001b, + 0x82a70000, 0x02bfb017, 0x96b41800, 0xb0151800, + 0xb4000013, 0x96b40040, 0xb0150040, 0xb4200004, + 0xa3180c00, 0x9b180340, 0x83060081, 0xb5000139, + 0x96b40008, 0x5aa9b815, 0x96d46000, 0x5ec3b816, + 0x82f3000f, 0x9af7c00f, 0x1718b817, 0x1ab5b818, + 0x1ab5b816, 0x9ab50340, 0x82a60081, 0xb500012d, + 0x9b180180, 0x83060081, 0xb500012a, 0x82a500c1, + 0x96b5000f, 0xb015000b, 0xb420000e, 0x96b40020, + 0xb0150020, 0xb400000b, 0x96b40200, 0xb0150200, + 0xb4000008, 0x82c50086, 0x82e50094, 0x3016b817, + 0xb4400004, 0x06f7b816, 0xb017ff00, 0xb4400001, + 0xb5000118, 0x96b46000, 0xb0156000, 0xb4000011, + 0x96b41820, 0xb0150820, 0xb4200004, 0x9b391000, + 0x82a5009a, 0x96b5feff, 0x82a6009a, 0x96b40040, + 0xb0150040, 0xb4200001, 0x9739efff, 0x96b91000, + 0xb0151000, 0xb4200003, 0x82a5009a, 0x9ab50100, + 0x82a6009a, 0x96b40040, 0xb0150040, 0xb4200019, + 0x96b41800, 0xb0151800, 0xb4200006, 0x96b98000, + 0xb0158000, 0xb4200003, 0x9b180180, 0x83060081, + 0xb50000f8, 0x96d80c00, 0x82b300ff, 0x9ab5f3ff, + 0x1718b815, 0xb0160c00, 0xb4000007, 0x82e50098, + 0x96f70400, 0xb0170400, 0xb4200002, 0x82c70c00, + 0xb5000001, 0xa2d60c00, 0x1b18b816, 0x9b180340, + 0xb50000c4, 0x96b40220, 0xb0150000, 0xb4e00021, + 0x82a5009d, 0x82f3ffff, 0x16b5b817, 0x82f33800, + 0x3015b817, 0xb420001b, 0x96f98000, 0xb0178000, + 0xb4000018, 0x82a70000, 0x02bfb017, 0x82c5009d, + 0x96d6ffff, 0x82b3c800, 0x9ab58001, 0x82e500c1, + 0x96f7000f, 0xb017000b, 0xb4000002, 0x82b38800, + 0x9ab58001, 0x1ab5b816, 0x82c5009a, 0x96d60020, + 0xb0160020, 0xb4200002, 0x82b3c800, 0x9ab58001, + 0x82a6009d, 0x02ff9017, 0x00000000, 0xb0170040, + 0xb4800000, 0x5eb5b814, 0x96b500f0, 0x96f46000, + 0x5eedb817, 0x1ab5b817, 0xb0170003, 0xb4000004, + 0x96b500ef, 0x96f70001, 0x5ae4b817, 0x1ab5b817, + 0x96d41800, 0xb0161800, 0xb400000a, 0x96f900ff, + 0x96b500ff, 0x9739ff00, 0x1b39b815, 0x02a7b817, + 0x96b500f3, 0x96d40008, 0x5ec1b816, 0x1ab5b816, + 0xb500000c, 0x96f98000, 0xb0178000, 0xb4200007, + 0x5efeb814, 0x96f70001, 0xb0170001, 0xb4000003, + 0x9b180180, 0x83060081, 0xb50000a2, 0x96b500f3, + 0x9ab50008, 0x9739fff3, 0x96d40020, 0xb0160020, + 0xb4200019, 0x82c7001f, 0x82c600c9, 0x9b398000, + 0x82c70000, 0x02dfb017, 0x96d40010, 0x5ac8b816, + 0x82f300ff, 0x9af7cfff, 0x1718b817, 0x1b18b816, + 0x9b180340, 0x82c5009d, 0x96d6ffff, 0x82f33800, + 0x9af78001, 0x1af7b816, 0x82c5009a, 0x96d60020, + 0xb0160020, 0xb4200002, 0x82f3c800, 0x9af78001, + 0x82e6009d, 0xb500005f, 0x97397fff, 0x96b500ff, + 0x5aaab815, 0x82f300fc, 0x9af703ff, 0x1718b817, + 0x1b18b815, 0x9b180340, 0x82c5009a, 0x96d60010, + 0xb0160010, 0xb4200027, 0x82c70000, 0x02dfb017, + 0x82c50086, 0x92d60bb8, 0x82c60086, 0x82c50094, + 0x5eefb818, 0x96f70003, 0xb0170003, 0xb4200002, + 0x82e70bb8, 0xb5000001, 0x82e70bb8, 0x12d6b817, + 0x82e50081, 0x9af70020, 0x82e60081, 0x82c60094, + 0xa2f70020, 0x82e60081, 0x82f30001, 0x16f7b818, + 0x5ef0b817, 0xb0170001, 0xb4000004, 0x96f84000, + 0x5ee4b817, 0x9718f3ff, 0x1b18b817, 0x82f32800, + 0x9af78000, 0x82e6009d, 0x83060081, 0x83070001, + 0x8306009f, 0x8305009c, 0xb0180001, 0xb4e0fffb, + 0xb50000f6, 0x82c5009d, 0x82f33800, 0x9af78001, + 0x3016b817, 0xb420000f, 0x82b3c800, 0x9ab58001, + 0x82e500c1, 0x96f7000f, 0xb017000b, 0xb4000002, + 0x82b38800, 0x9ab58001, 0x82c5009a, 0x96d60020, + 0xb0160020, 0xb4200002, 0x82b3c800, 0x9ab58001, + 0x82a6009d, 0x82c5009a, 0x96d60080, 0xb0160080, + 0xb4000013, 0x02df9017, 0x00000000, 0xb0160010, + 0xb480000f, 0x82c500c1, 0x96d6000f, 0xb016000b, + 0xb400000b, 0x82c50087, 0x96d60080, 0x5ac7b816, + 0x82c50098, 0x96d60800, 0x5ac3b816, 0x96f84000, + 0x3017b816, 0xb4200002, 0x033f400f, 0x9b394000, + 0x9739bfff, 0x82e50061, 0x96f70008, 0xb0170008, + 0xb4000005, 0x5eefb818, 0x96f70003, 0xb0170003, + 0xb4000001, 0x9718ffff, 0x96b41800, 0xb0151800, + 0xb4000008, 0x5eb9b814, 0x96b5000f, 0x82c50099, + 0x5ed0b816, 0x96f6000f, 0x5ab0b815, 0x82a60099, + 0xb5000002, 0x5ef9b814, 0x96f7000f, 0x5aecb817, + 0x82c5009a, 0x96d60fff, 0x1ad6b817, 0x82c6009a, + 0x96b46000, 0xb0156000, 0xb4200005, 0x5ae2b817, + 0x82d30ffc, 0x9ad63fff, 0x1718b816, 0x1b18b817, + 0x83060081, 0x83070001, 0x8306009f, 0x8305009c, + 0xb0180001, 0xb4e0fffb, 0x00000000, 0xb500009f, + 0x82850083, 0x96b400ff, 0xb015003c, 0xb4200019, + 0x96b92000, 0xb0152000, 0xb4000002, 0x9b392000, + 0xb5000014, 0x9739d3ff, 0x82870000, 0x82860087, + 0x82870008, 0x82860083, 0x829bff78, 0x82a7001f, + 0xb0140400, 0xb4000001, 0x82a70010, 0x82a600c9, + 0x829bff78, 0x00000000, 0x828600cb, 0x8285009d, + 0x82b3ffff, 0x9ab5fffd, 0x1694b815, 0x8286009d, + 0xb5000000, 0x83070002, 0x8306009f, 0x00000000, + 0xb500007e, 0x83078000, 0x8306009f, 0x00000000, + 0xb500007a, 0x82850094, 0x82a50086, 0x06b5b814, + 0x02b6b815, 0xb0151700, 0xb440004c, 0x8285006c, + 0x969400ff, 0xb0140024, 0xb4000019, 0xb0140012, + 0xb4000017, 0x8285009a, 0x5eedb814, 0x96f70003, + 0xb0170003, 0xb4000009, 0x82a50083, 0x5ea8b815, + 0x96b500ff, 0xb0150020, 0xb4400002, 0x82c70bbc, + 0xb5000001, 0x82c70bb8, 0xb5000008, 0x82a50083, + 0x5ea8b815, 0x96b500ff, 0xb0150020, 0xb4400002, + 0x82c71199, 0xb5000001, 0x82c71197, 0xb5000017, + 0xb500002e, 0x8285009a, 0x5eedb814, 0x96f70003, + 0xb0170003, 0xb4000009, 0x82a50083, 0x5ea8b815, + 0x96b500ff, 0xb0150020, 0xb4400002, 0x82c70e12, + 0xb5000001, 0x82c70e0e, 0xb5000008, 0x82a50083, + 0x5ea8b815, 0x96b500ff, 0xb0150020, 0xb4400002, + 0x82c70e12, 0xb5000001, 0x82c70e0e, 0x82e50086, + 0x12f7b816, 0x02bf9017, 0xb0150020, 0xb480000b, + 0x82a5009a, 0x96b56000, 0xb0156000, 0xb4000007, + 0x82a50098, 0x96d50a00, 0xb0160a00, 0xb4000002, + 0xb0160000, 0xb4200001, 0x92f705dc, 0x82850081, + 0x9ab40020, 0x82a60081, 0x82c50094, 0x82e60094, + 0x82860081, 0x86b705dc, 0x82a6009b, 0x83070008, + 0x8306009f, 0x00000000, 0xb5000024, 0x83070100, + 0x8306009f, 0x00000000, 0xb5000020, 0x83070000, + 0x83050081, 0x9b180180, 0x83060081, 0x83070400, + 0x8306009f, 0x00000000, 0xb5000018, 0x82870000, + 0x82850082, 0x5eb7b814, 0x96b500fc, 0x96d40006, + 0x5ec1b816, 0x1ab5b816, 0x5aacb815, 0x83050081, + 0x82d3001c, 0x9ad600ff, 0x1718b816, 0x1b18b815, + 0x9b180e00, 0x83060081, 0x83074000, 0x8306009f, + 0x8305009d, 0x82d3ffff, 0x9ad6bfff, 0x1718b816, + 0x8306009d, 0x00000000, 0xb5000000, 0x029f9005, + 0x01ffb814, 0x033f600f, 0x029f900a, 0x02bf900b, + 0x02df900c, 0x02ff900d, 0x031f900e, 0x033f900f, + 0x00ffb81e, 0x02ff9010, 0x92f70b43, 0x02ffb010, + 0x02ff90cb, 0x82bbffdc, 0x829bffd8, 0x93150004, + 0x3014b815, 0xb400000f, 0x02dbb818, 0x029bb815, + 0x3017b816, 0xb480000b, 0x5a81b814, 0x029fb010, + 0x82860095, 0x8293001f, 0x9294fe00, 0x92b50008, + 0x3015b814, 0xb4800002, 0x82b3001f, 0x92b5fa00, + 0x82beffdc, 0x82850086, 0x83250094, 0x06d4b819, + 0x02d6b816, 0xb016ffff, 0xb4a00009, 0x82c50081, + 0x9ab60020, 0x82a60081, 0x82a50086, 0x92b50bbb, + 0x82a60094, 0x82c60081, 0x86b505df, 0x82a6009b, + 0x00ffb81c, 0x82870001, 0x829ef500, 0x82850086, + 0x83250094, 0x06d4b819, 0x02d6b816, 0xb016ffff, + 0xb4a0000b, 0x82870001, 0x829ef504, 0x82c50081, + 0x9ab60020, 0x82a60081, 0x82a50086, 0x92b50bbb, + 0x82a60094, 0x82c60081, 0x86b505df, 0x82a6009b, + 0x00ffb81c, 0x82070028, 0x023f9006, 0x83a4ef4f, + 0x80070000, 0x001fb011, 0x001f204f, 0x003fb800, + 0x001f9006, 0x5803b800, 0x80338000, 0x1800b801, + 0x003fb800, 0x005f4193, 0x5c41b802, 0x80350000, + 0x00000000, 0x0027b860, 0x80150010, 0x5810b800, + 0x80750010, 0x1863b800, 0x8087ffff, 0x80a7770b, + 0x80c70000, 0x1403b804, 0x3000b805, 0xb4000008, + 0x5888b804, 0x58a8b805, 0x90c60001, 0xb0060003, + 0xb4a0fff8, 0x84420001, 0xb4e0ffee, 0xb5000027, + 0xb0060003, 0xb4200007, 0x80150010, 0x5810b800, + 0x81150010, 0x950800ff, 0xb0080077, 0xb4000001, + 0xb500fff4, 0x001f400e, 0x98000010, 0x98004000, + 0x9400fffe, 0x001f600e, 0x80e71f60, 0x001f4000, + 0x94000080, 0xb0000080, 0xb4200001, 0x80e774b0, + 0x00ffb008, 0x80e70020, 0xb0060000, 0xb400000e, + 0x58e3b806, 0x90210020, 0x81070000, 0x5938b803, + 0x1908b809, 0x9523ff00, 0x5928b809, 0x1908b809, + 0x5d28b803, 0x9529ff00, 0x1908b809, 0x5d38b803, + 0x1908b809, 0x011fb011, 0x00ff204f, 0x80137fff, + 0x9800ffe7, 0x1421b800, 0x5c23b801, 0x001f9006, + 0x0441b800, 0x3001b800, 0xb4600002, 0x0440b801, + 0xa4422000, 0x007f90cb, 0x1063b802, 0x007fb0cb, + 0x003fb006, 0x803effec, 0x80470001, 0x005f2013, + 0xb500ebd7, 0x001f400e, 0x9400000f, 0xb0000000, + 0xb4200001, 0x00ffb81f, 0xb0000001, 0xb4000005, + 0xb0000003, 0xb4000003, 0xb0000002, 0xb4000001, + 0x00ffb81f, 0x80070001, 0x001f2013, 0xb500ebc8, + 0x001f9012, 0x001fb100, 0x001f004c, 0x001f2404, + 0x801bfef0, 0x8058fef4, 0x803bff68, 0x8078ff6c, + 0x2000b801, 0x2042b803, 0x001fb104, 0x005f2414, + 0x82e70001, 0x83640048, 0x029fb014, 0x829efef0, + 0x8286000f, 0x02bf2054, 0x82bcfef4, 0x82a6000e, + 0x00ffb81a, 0x80e70001, 0x801336e3, 0x9800eb76, + 0x001fb100, 0x800700ab, 0x001f2404, 0x801bc3e8, + 0x8058c3ec, 0x83640024, 0x82e70000, 0x83640036, + 0x029fb300, 0x029fb100, 0x02bf2c04, 0x02bf2404, + 0x801bc000, 0x8058c004, 0x8364001b, 0x82e70000, + 0x8364002d, 0x001f9300, 0x3000b814, 0xb420000a, + 0x001f0c04, 0x3000b815, 0xb4200007, 0x829efef0, + 0x82bcfef4, 0x029fb012, 0x02bf204c, 0x82870001, + 0x829cfef5, 0x00ffb81a, 0xb0070000, 0xb4000007, + 0x80e70000, 0x801399fa, 0x9800c92e, 0x001fb100, + 0x800700af, 0x001f2404, 0xb500ffdc, 0x82870000, + 0x829cfef5, 0x00ffb81a, 0x80c700ff, 0x803bff68, + 0x8078ff6c, 0x14a0b806, 0x2063b805, 0x007f2414, + 0x2021b802, 0x58c8b806, 0x14a0b806, 0x58b0b805, + 0x2021b805, 0x58c8b806, 0x14a0b806, 0x2021b805, + 0x58c8b806, 0x14a0b806, 0x5cb0b805, 0x2021b805, + 0x003fb104, 0x00ffb81b, 0x82c70000, 0x83070400, + 0x83270005, 0x8197040c, 0x81d7ffff, 0x83840126, + 0x83840001, 0x00ffb81b, 0x808f0000, 0x806f001f, + 0x80af001f, 0x80270140, 0x81e7ef98, 0x5de2b80f, + 0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, + 0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020, + 0x90210020, 0x80270180, 0x81e7ee90, 0x5de2b80f, + 0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, + 0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020, + 0x90210020, 0x8057ffff, 0x80170430, 0x80070410, + 0x80270408, 0xb6000509, 0x005ff000, 0x90420500, + 0x007ff001, 0x90630600, 0x009ff002, 0x00bff003, + 0x2004a025, 0x90000001, 0x90210001, 0x80070414, + 0x80d7ffff, 0x8097045c, 0x8017043c, 0xb6000404, + 0x005ff000, 0x007f87e0, 0x84000001, 0x2082a7e3, + 0x80970460, 0x80170440, 0x2082b803, 0x007f8000, + 0x2083a004, 0x80170430, 0x80970450, 0x80270408, + 0xb6000508, 0x005f8024, 0x90420500, 0x007ff001, + 0x90630600, 0x009ff002, 0x00bff003, 0x2004a025, + 0x90210001, 0x80170440, 0x00000000, 0x02bf87e0, + 0x80970460, 0x82870000, 0xb6000404, 0x005f87e4, + 0x5a88b814, 0x204287e0, 0x1a94b802, 0x00ffb81c, + 0x001f0a49, 0x001f2709, 0x001f0a41, 0x001f2708, + 0x001f0a46, 0x001f2707, 0x001f0a48, 0x001f2706, + 0x001f0a42, 0x001f2705, 0x001f0a47, 0x001f2704, + 0x001f0a45, 0x001f2703, 0x001f0a43, 0x001f2702, + 0x001f0a40, 0x001f2701, 0x001f0a44, 0x001f2700, + 0x001f0c25, 0xa020000c, 0x94400001, 0x94600002, + 0x94810004, 0x94a10008, 0x94c00010, 0x5943b802, + 0x5861b803, 0x5882b804, 0x5ca2b805, 0x5cc4b806, + 0x194ab803, 0x194ab804, 0x194ab805, 0x194ab806, + 0x015f2738, 0x801bef90, 0x003f91c1, 0x5c28b801, + 0x005f91c2, 0x5858b802, 0x1821b802, 0x2000b801, + 0x001fb1c4, 0x8018ef94, 0x003f0709, 0x2000b801, + 0x001f2714, 0x82c70001, 0x82e70001, 0x83070710, + 0x8327001e, 0x81970735, 0x8384009f, 0x02df0738, + 0x82170a30, 0x838400f1, 0x819efef0, 0x817cfef4, + 0x819eff68, 0x817cff6c, 0x00ffb81b, 0x820f001f, + 0x8018fef8, 0x8057ffff, 0x001f2709, 0x8018fef6, + 0x80d7ffff, 0x001f2708, 0x8018fefa, 0x8157ffff, + 0x001f2707, 0x8018fefd, 0x81d7ffff, 0x001f2706, + 0x8018fefb, 0x802f001f, 0x001f2705, 0x8018fefe, + 0x00000000, 0x001f2704, 0x8018fef9, 0x00000000, + 0x001f2703, 0x8018feff, 0x00000000, 0x001f2702, + 0x8018fef7, 0x00000000, 0x001f2701, 0x8018fefc, + 0x00000000, 0x001f2700, 0x001f0c25, 0xa0200011, + 0x94410001, 0x94600002, 0x94800004, 0x94a00008, + 0x94c10010, 0x5941b802, 0x5861b803, 0x5c82b804, + 0x58a1b805, 0x5cc1b806, 0x194ab803, 0x194ab804, + 0x194ab805, 0x194ab806, 0x015f2738, 0x801bef90, + 0x003f91c1, 0x5c28b801, 0x005f91c2, 0x5858b802, + 0x1821b802, 0x2000b801, 0x001fb1c4, 0x8018ef94, + 0x003f0709, 0x2000b801, 0x001f2714, 0x82c70001, + 0x82e70001, 0x83070710, 0x8327001e, 0x81970735, + 0x83840055, 0x02df0738, 0x82170a20, 0x838400a7, + 0x819efef0, 0x817cfef4, 0x5ac8b80c, 0x02ff0a44, + 0x1ad6b817, 0x02dfb291, 0x5ed8b80c, 0x5968b80b, + 0x1ad6b80b, 0x02df6524, 0x00ffb81b, 0x820f001f, + 0x8018fefe, 0x8057ffff, 0x001f2709, 0x8018fefa, + 0x80d7ffff, 0x001f2708, 0x8018fefc, 0x8157ffff, + 0x001f2707, 0x8018feff, 0x81d7ffff, 0x001f2706, + 0x8018fef8, 0x802f001f, 0x001f2705, 0x8018fefb, + 0x00000000, 0x001f2704, 0x8018fefd, 0x00000000, + 0x001f2703, 0x8018fef6, 0x00000000, 0x001f2702, + 0x8018fef9, 0x00000000, 0x001f2701, 0x8018fef7, + 0x00000000, 0x001f2700, 0x801bef90, 0x003f91c1, + 0x5c28b801, 0x005f91c2, 0x5858b802, 0x1821b802, + 0x2000b801, 0x001fb1c4, 0x8018ef94, 0x003f0709, + 0x2000b801, 0x001f2714, 0x82c70001, 0x82e70001, + 0x83070710, 0x8327001e, 0x81970735, 0x83840016, + 0x83270000, 0x831bfef0, 0x82f8fef4, 0x02c7b819, + 0x82170a28, 0x83840065, 0x300cb818, 0xb4200002, + 0x300bb817, 0xb4000006, 0x93390001, 0xb0190020, + 0xb480fff6, 0x83270000, 0x833cfef5, 0x00ffb81b, + 0x019fb290, 0x017f2a44, 0x033f2c25, 0x83270001, + 0x833cfef5, 0x00ffb81b, 0x0007b818, 0x90000003, + 0x00000000, 0x015ff000, 0x90000001, 0x5949b80a, + 0x013ff000, 0x194ab809, 0x84000002, 0x994a0100, + 0x017ff000, 0x958b00f8, 0x5981b80c, 0x956b0007, + 0x198cb80b, 0x84000002, 0x998c0008, 0x017ff000, + 0x90000001, 0x5971b80b, 0x198cb80b, 0x017ff000, + 0x5969b80b, 0x198cb80b, 0x81a70000, 0x94d90003, + 0x82a70000, 0xb6260019, 0xb6000818, 0x5df0b80a, + 0x5e02b80a, 0x21efb810, 0x95ef0001, 0x5941b80a, + 0x194ab80f, 0x21efb816, 0x5e18b80c, 0x5e35b80c, + 0x5e54b80c, 0x5e6cb80c, 0x2210b811, 0x2252b813, + 0x2210b812, 0x96100001, 0x5981b80c, 0x198cb810, + 0x2210b817, 0x10afb810, 0x10a5b80d, 0x5da1b805, + 0x94a50001, 0x5aa1b815, 0x1ab5b805, 0x019fa7f5, + 0x5cc2b819, 0xb626001c, 0x82870000, 0xb6000419, + 0xb6000818, 0x5df0b80a, 0x5e02b80a, 0x21efb810, + 0x95ef0001, 0x5941b80a, 0x194ab80f, 0x21efb816, + 0x5e18b80c, 0x5e35b80c, 0x5e54b80c, 0x5e6cb80c, + 0x2210b811, 0x2252b813, 0x2210b812, 0x96100001, + 0x5981b80c, 0x198cb810, 0x2210b817, 0x10afb810, + 0x10a5b80d, 0x5da1b805, 0x94a50001, 0x5a81b814, + 0x1a94b805, 0x019fa7f4, 0x00ffb81c, 0x8257ffff, + 0x808f0000, 0x806f001f, 0x80af001f, 0x80270200, + 0x81e7ec70, 0x5de2b80f, 0xb6000208, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0xb520ffff, 0x91ef0020, 0x90210020, 0x80270240, + 0x81e7ed70, 0x5de2b80f, 0xb6000208, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0xb520ffff, 0x91ef0020, 0x90210020, 0x80270180, + 0x81e7ee90, 0x5de2b80f, 0xb6000208, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0xb520ffff, 0x91ef0020, 0x90210020, 0x806f0007, + 0x80af0007, 0x80270280, 0x81e7ee70, 0x5de2b80f, + 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, + 0x01ff90bc, 0xb520ffff, 0x91ef0020, 0x90210020, + 0x80170760, 0x001f0700, 0x001fa020, 0x001f0701, + 0x001fa020, 0x001f0702, 0x001fa020, 0x001f0703, + 0x001fa020, 0x001f0704, 0x001fa000, 0x80970750, + 0x81170770, 0x82a70735, 0x83a40060, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a4005c, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750, + 0x81170750, 0x81970740, 0x82a70730, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a40050, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a4004c, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970750, 0x80170770, + 0x81170770, 0x81970760, 0x82a7072b, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a40040, 0x83a4004e, + 0xb6000407, 0x86b50001, 0x83a4003c, 0x001f8004, + 0x003f87e8, 0x2080a001, 0x83a40047, 0x00000000, + 0x80970770, 0x80170750, 0x81170750, 0x81970740, + 0x82a70726, 0x001f800c, 0x003f8008, 0x2100a001, + 0x83a4002e, 0x83a4003c, 0xb6000407, 0x86b50001, + 0x83a4002a, 0x001f8004, 0x003f87e8, 0x2080a001, + 0x83a40035, 0x00000000, 0x80970750, 0x80170770, + 0x81170770, 0x81970760, 0x82a70721, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a4001c, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a40018, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750, + 0x81170750, 0x81970740, 0x82a7071c, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a4000c, 0x017f87e4, + 0x81870000, 0xb6000406, 0x86b50001, 0x83a40007, + 0x001f87e4, 0x200087e8, 0x5988b80c, 0x198cb800, + 0x021fa02c, 0x021fa00b, 0x00ffb81c, 0x005ff015, + 0x90420600, 0x003f87e0, 0x001ff002, 0x2060b801, + 0x90630800, 0x90960a00, 0x001ff003, 0x003ff004, + 0x20a0b801, 0x90a50900, 0x00000000, 0x001ff005, + 0x009fa000, 0x00ffb81d, 0x001f8004, 0x5c21b800, + 0x5847b800, 0x1821b802, 0x942100ff, 0x2080a7e1, + 0x00ffb81d, 0x00000000, 0x00000000, 0x00000000, + 0x015f400e, 0x944a4000, 0xb0024000, 0xb420001a, + 0x954abfff, 0x015f600e, 0x820f001f, 0x802f001f, + 0x81470000, 0x015f23f9, 0x015fb0ba, 0x8057ffff, + 0x80770000, 0x82970400, 0x82d7ffff, 0x82f70000, + 0xb6000702, 0xb6000001, 0x029fa02a, 0x80275480, + 0x005fb801, 0x8033001f, 0x9821c000, 0x803effe0, + 0x90212000, 0x803effe4, 0x80d9ff80, 0x00df6001, + 0x81477528, 0x015fb008, 0x003f0324, 0xb0010000, + 0xb4200076, 0x8344ebe6, 0xb0180000, 0xb4000004, + 0x011f400e, 0x1908b818, 0x011f600e, 0x00ffb81f, + 0x8344f187, 0xb00b0000, 0xb4000006, 0x023f400e, + 0x9a310002, 0x023f600e, 0x82270000, 0x023f2012, + 0x00ffb81f, 0x8364ed6a, 0x82270000, 0x023f2011, + 0x80070000, 0x80170800, 0xb6002002, 0xb6003001, + 0x001fa020, 0x82270000, 0x003fb811, 0x02bf9006, + 0x5aa3b815, 0x82338000, 0x1a31b815, 0x003fb811, + 0x8067e950, 0x5c62b803, 0x81f50000, 0x019f4193, + 0x0267b80c, 0xadcc0010, 0x80170800, 0x80130000, + 0x9800f872, 0x001fa020, 0x80134e1f, 0x98000001, + 0x001fa020, 0x59d0b80e, 0x81150010, 0x1908b80e, + 0x001fa028, 0x858c0001, 0x5e01b80c, 0x5e25b810, + 0xb6310006, 0xb6002005, 0x81150010, 0x5910b808, + 0x00000000, 0x81350010, 0x1808a029, 0x9630001f, + 0xb0110000, 0xb4000006, 0xb6310005, 0x81150010, + 0x5910b808, 0x00000000, 0x81350010, 0x1808a029, + 0x962c0001, 0xb0110000, 0xb4000003, 0x81150010, + 0x5910b808, 0x001fa028, 0x019f9006, 0x958cffff, + 0x00df4193, 0x58c1b806, 0x118cb806, 0xb00ce000, + 0xb4800002, 0x858ce000, 0x918cc000, 0x8153001f, + 0x118cb80a, 0x819effec, 0x019fb006, 0x015f4193, + 0x5941b80a, 0x019f90cb, 0x118cb80a, 0x019fb0cb, + 0x019f90ba, 0x918c0001, 0x019fb0ba, 0xb00c0002, + 0xb4200016, 0x019f400e, 0x940c8000, 0xb0008000, + 0xb4200012, 0x958c7fff, 0x019f600e, 0x80070000, + 0x800600a0, 0x80073da1, 0x800600a1, 0x801bff60, + 0x00000000, 0x801eff60, 0x00000000, 0x801bff60, + 0x00000000, 0x801eff60, 0x80130001, 0x98003da1, + 0x800600a1, 0x80070001, 0x800600a0, 0x003f0324, + 0x90210001, 0xb0010005, 0xb4a00001, 0x80270000, + 0x003f2324, 0x00ffb81f, 0x00000000, 0x00000000, + 0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000, + 0xb4000011, 0x815bb3f0, 0x81070000, 0x81270bf4, + 0xb00a0000, 0xb4000002, 0x81070c00, 0x81271800, + 0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc, + 0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809, + 0xb4a0002e, 0xb5000008, 0xb0040000, 0xb4200003, + 0x802717ff, 0x81470000, 0xb5000003, 0x80270001, + 0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200001, + 0x8384fc04, 0x80af001f, 0x808f0002, 0x806f0000, + 0x807bbf34, 0x5d22b80a, 0xb600080a, 0x00cfb803, + 0x013fb0bc, 0x5922b809, 0x01afb809, 0x013f90bc, + 0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x90630020, + 0x91290060, 0x808f0000, 0x813bb3f8, 0x80270001, + 0xb0090001, 0xb4000002, 0x802600a0, 0x803eb3f8, + 0x81270c00, 0xb00a0000, 0xb4000001, 0x81270000, + 0x813eb3f0, 0xb0030800, 0xb4800001, 0x80670200, + 0x807ebf34, 0x80270001, 0x003f2013, 0x00ffb81b, +}; + +static u32 AC3I2S240Ucode1f8000[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00020000, 0xffff0005, 0xffffffff, + 0x00050001, 0xffffffff, 0xffffffff, 0x00020000, + 0xffff0005, 0xffffffff, 0x00010000, 0x00050002, + 0xffffffff, 0x00020000, 0x00050003, 0xffffffff, + 0x00010000, 0x00030002, 0xffff0005, 0x00020000, + 0x00040003, 0xffff0005, 0x00010000, 0x00030002, + 0x00050004, 0x0019000d, 0x003d0025, 0x00250019, + 0x00fd003d, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x007fffff, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x007fffff, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x007fffff, 0x00000000, + 0x00000000, 0x00599999, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00599999, + 0x007fffff, 0x00599999, 0x00000000, 0x00599999, + 0x00000000, 0x00000000, 0x00000000, 0x00599999, + 0x00000000, 0x00599999, 0x007fffff, 0x00000000, + 0x00599999, 0x00599999, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00599999, 0x00599999, + 0x007fffff, 0x007fffff, 0x00000000, 0x00599999, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00599999, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x007fffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x007fffff, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x007fffff, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x007fffff, 0x00000000, + 0x007fffff, 0x00000000, 0x007fffff, 0x00400000, + 0x00200000, 0x00100000, 0x00080000, 0x00040000, + 0x00020000, 0x00010000, 0x00008000, 0x00004000, + 0x00002000, 0x00001000, 0x00000800, 0x00000400, + 0x00000200, 0x00000100, 0x00000080, 0x00000040, + 0x00000020, 0x00000010, 0x00000008, 0x00000004, + 0x00000002, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00010002, + 0x00030002, 0x00030002, 0x00030002, 0x00000000, + 0x00000000, 0x00010001, 0x00020002, 0x4000a000, + 0xe000a000, 0xf000b000, 0xf800b800, 0x005a8279, + 0x004c1bf8, 0x00400000, 0x004c1bf8, 0x005a8279, + 0x00400000, 0x00000000, 0x00400000, 0x03020100, + 0x00000000, 0x00000080, 0x00000020, 0x00000008, + 0x00000000, 0x00000001, 0x00010001, 0x10001000, + 0x10001004, 0x10041004, 0x10041004, 0x10041004, + 0x00000000, 0x00000000, 0x00000000, 0xff80000a, + 0xff80031f, 0xff800b24, 0xff801818, 0xff8029fa, + 0xff8040c9, 0xff805c86, 0xff807d2e, 0xff80a2c1, + 0xff80cd3c, 0xff80fc9f, 0xff8130e8, 0xff816a14, + 0xff81a821, 0xff81eb0e, 0xff8232d6, 0xff827f79, + 0xff82d0f2, 0xff83273e, 0xff83825b, 0xff83e244, + 0xff8446f7, 0xff84b06e, 0xff851ea6, 0xff85919b, + 0xff860949, 0xff8685aa, 0xff8706ba, 0xff878c74, + 0xff8816d3, 0xff88a5d1, 0xff89396a, 0xff89d196, + 0xff8a6e51, 0xff8b0f94, 0xff8bb55a, 0xff8c5f9b, + 0xff8d0e51, 0xff8dc176, 0xff8e7902, 0xff8f34ef, + 0xff8ff535, 0xff90b9cc, 0xff9182ae, 0xff924fd3, + 0xff932132, 0xff93f6c3, 0xff94d07f, 0xff95ae5d, + 0xff969054, 0xff97765b, 0xff98606a, 0xff994e78, + 0xff9a407c, 0xff9b366b, 0xff9c303e, 0xff9d2de9, + 0xff9e2f64, 0xff9f34a4, 0xffa03da0, 0xffa14a4c, + 0xffa25aa0, 0xffa36e8f, 0xffa48610, 0xffa5a118, + 0xffa6bf9c, 0xffa7e191, 0xffa906ec, 0xffaa2fa0, + 0xffab5ba4, 0xffac8aeb, 0xffadbd6a, 0xffaef315, + 0xffb02bdf, 0xffb167be, 0xffb2a6a4, 0xffb3e886, + 0xffb52d56, 0xffb67509, 0xffb7bf92, 0xffb90ce4, + 0xffba5cf2, 0xffbbafb0, 0xffbd050f, 0xffbe5d04, + 0xffbfb780, 0xffc11477, 0xffc273db, 0xffc3d59f, + 0xffc539b4, 0xffc6a00d, 0xffc8089d, 0xffc97355, + 0xffcae027, 0xffcc4f05, 0xffcdbfe2, 0xffcf32af, + 0xffd0a75d, 0xffd21ddf, 0xffd39625, 0xffd51022, + 0xffd68bc7, 0xffd80904, 0xffd987cd, 0xffdb0810, + 0xffdc89c1, 0xffde0cd0, 0xffdf912d, 0xffe116cb, + 0xffe29d9a, 0xffe4258b, 0xffe5ae8f, 0xffe73896, + 0xffe8c392, 0xffea4f74, 0xffebdc2b, 0xffed69aa, + 0xffeef7df, 0xfff086bd, 0xfff21634, 0xfff3a634, + 0xfff536ad, 0xfff6c792, 0xfff858d1, 0xfff9ea5b, + 0xfffb7c22, 0xfffd0e16, 0xfffea026, 0xffffcdbc, + 0xfffe3ba0, 0xfffca995, 0xfffb17ac, 0xfff985f3, + 0xfff7f479, 0xfff6634f, 0xfff4d284, 0xfff34228, + 0xfff1b249, 0xfff022f7, 0xffee9442, 0xffed0638, + 0xffeb78ea, 0xffe9ec67, 0xffe860bd, 0xffe6d5fd, + 0xffe54c35, 0xffe3c374, 0xffe23bcb, 0xffe0b547, + 0xffdf2ff7, 0xffddabec, 0xffdc2933, 0xffdaa7dd, + 0xffd927f6, 0xffd7a98f, 0xffd62cb7, 0xffd4b17b, + 0xffd337ea, 0xffd1c013, 0xffd04a05, 0xffced5ce, + 0xffcd637c, 0xffcbf31d, 0xffca84c1, 0xffc91874, + 0xffc7ae45, 0xffc64641, 0xffc4e078, 0xffc37cf6, + 0xffc21bc9, 0xffc0bcff, 0xffbf60a5, 0xffbe06c9, + 0xffbcaf79, 0xffbb5ac0, 0xffba08ae, 0xffb8b94d, + 0xffb76cac, 0xffb622d8, 0xffb4dbdc, 0xffb397c6, + 0xffb256a2, 0xffb1187d, 0xffafdd62, 0xffaea55f, + 0xffad707e, 0xffac3ecc, 0xffab1054, 0xffa9e523, + 0xffa8bd44, 0xffa798c2, 0xffa677a8, 0xffa55a02, + 0xffa43fdb, 0xffa3293d, 0xffa21634, 0xffa106c9, + 0xff9ffb08, 0xff9ef2fa, 0xff9deeab, 0xff9cee23, + 0xff9bf16c, 0xff9af892, 0xff9a039c, 0xff991295, + 0xff982586, 0xff973c78, 0xff965774, 0xff957683, + 0xff9499ad, 0xff93c0fb, 0xff92ec75, 0xff921c24, + 0xff91500f, 0xff90883f, 0xff8fc4bb, 0xff8f058b, + 0xff8e4ab6, 0xff8d9443, 0xff8ce239, 0xff8c349f, + 0xff8b8b7d, 0xff8ae6d7, 0xff8a46b5, 0xff89ab1e, + 0xff891416, 0xff8881a3, 0xff87f3cc, 0xff876a96, + 0xff86e606, 0xff866621, 0xff85eaed, 0xff85746d, + 0xff8502a6, 0xff84959e, 0xff842d57, 0xff83c9d7, + 0xff836b20, 0xff831138, 0xff82bc20, 0xff826bdc, + 0xff822070, 0xff81d9de, 0xff819829, 0xff815b54, + 0xff812360, 0xff80f051, 0xff80c228, 0xff8098e6, + 0xff80748e, 0xff805521, 0xff803a9f, 0xff80250b, + 0xff801464, 0xff8008ad, 0xff8001e4, 0xff800027, + 0xff800c7e, 0xff802c8f, 0xff806056, 0xff80a7cb, + 0xff8102e4, 0xff817191, 0xff81f3c3, 0xff828964, + 0xff83325f, 0xff83ee98, 0xff84bdf3, 0xff85a04f, + 0xff86958b, 0xff879d7f, 0xff88b804, 0xff89e4ee, + 0xff8b240e, 0xff8c7533, 0xff8dd82a, 0xff8f4cbb, + 0xff90d2ad, 0xff9269c4, 0xff9411c1, 0xff95ca62, + 0xff979365, 0xff996c81, 0xff9b5570, 0xff9d4de4, + 0xff9f5590, 0xffa16c24, 0xffa3914e, 0xffa5c4b8, + 0xffa8060d, 0xffaa54f3, 0xffacb10e, 0xffaf1a03, + 0xffb18f70, 0xffb410f7, 0xffb69e33, 0xffb936c0, + 0xffbbda37, 0xffbe8830, 0xffc14042, 0xffc40201, + 0xffc6cd00, 0xffc9a0d2, 0xffcc7d05, 0xffcf612b, + 0xffd24ccf, 0xffd53f80, 0xffd838c8, 0xffdb3833, + 0xffde3d49, 0xffe14795, 0xffe4569d, 0xffe769e9, + 0xffea80ff, 0xffed9b67, 0xfff0b8a4, 0xfff3d83c, + 0xfff6f9b5, 0xfffa1c91, 0xfffd4056, 0xffff9b78, + 0xfffc7756, 0xfff953c0, 0xfff63130, 0xfff31025, + 0xffeff117, 0xffecd484, 0xffe9bae5, 0xffe6a4b6, + 0xffe39270, 0xffe0848b, 0xffdd7b82, 0xffda77cb, + 0xffd779de, 0xffd48231, 0xffd19138, 0xffcea769, + 0xffcbc535, 0xffc8eb10, 0xffc61969, 0xffc350af, + 0xffc09151, 0xffbddbbb, 0xffbb3059, 0xffb88f92, + 0xffb5f9d0, 0xffb36f78, 0xffb0f0ef, 0xffae7e96, + 0xffac18cf, 0xffa9bff9, 0xffa7746f, 0xffa5368c, + 0xffa306aa, 0xffa0e51e, 0xff9ed23c, 0xff9cce56, + 0xff9ad9bc, 0xff98f4bc, 0xff971f9f, 0xff955aae, + 0xff93a62f, 0xff920266, 0xff906f92, 0xff8eedf3, + 0xff8d7dc4, 0xff8c1f3c, 0xff8ad294, 0xff8997fd, + 0xff886fa8, 0xff8759c3, 0xff865679, 0xff8565f2, + 0xff848852, 0xff83bdbd, 0xff830651, 0xff82622b, + 0xff81d163, 0xff815411, 0xff80ea47, 0xff809416, + 0xff80518b, 0xff8022b1, 0xff80078e, 0x00000475, + 0x000007fe, 0x00000c02, 0x000010a3, 0x000015f5, + 0x00001c08, 0x000022ed, 0x00002ab5, 0x00003371, + 0x00003d32, 0x0000480a, 0x0000540d, 0x0000614b, + 0x00006fda, 0x00007fcd, 0x00009138, 0x0000a431, + 0x0000b8cc, 0x0000cf1f, 0x0000e741, 0x00010148, + 0x00011d4b, 0x00013b61, 0x00015ba2, 0x00017e25, + 0x0001a302, 0x0001ca51, 0x0001f42c, 0x000220a9, + 0x00024fe2, 0x000281f0, 0x0002b6ea, 0x0002eee9, + 0x00032a07, 0x0003685a, 0x0003a9fc, 0x0003ef04, + 0x0004378a, 0x000483a5, 0x0004d36d, 0x000526f7, + 0x00057e5b, 0x0005d9ae, 0x00063904, 0x00069c74, + 0x00070410, 0x00076feb, 0x0007e01a, 0x000854ac, + 0x0008cdb3, 0x00094b40, 0x0009cd61, 0x000a5425, + 0x000adf98, 0x000b6fc8, 0x000c04bf, 0x000c9e87, + 0x000d3d2a, 0x000de0ae, 0x000e891a, 0x000f3674, + 0x000fe8c0, 0x00109fff, 0x00115c34, 0x00121d5d, + 0x0012e37b, 0x0013ae89, 0x00147e84, 0x00155366, + 0x00162d27, 0x00170bbf, 0x0017ef23, 0x0018d748, + 0x0019c421, 0x001ab59f, 0x001babb2, 0x001ca648, + 0x001da54f, 0x001ea8b0, 0x001fb058, 0x0020bc2d, + 0x0021cc18, 0x0022dffd, 0x0023f7c2, 0x00251348, + 0x00263272, 0x00275520, 0x00287b31, 0x0029a482, + 0x002ad0f1, 0x002c0059, 0x002d3294, 0x002e677c, + 0x002f9ee8, 0x0030d8b1, 0x003214ac, 0x003352b0, + 0x00349290, 0x0035d422, 0x00371738, 0x00385ba5, + 0x0039a13b, 0x003ae7cc, 0x003c2f2a, 0x003d7725, + 0x003ebf8d, 0x00400834, 0x004150e9, 0x0042997d, + 0x0043e1c0, 0x00452981, 0x00467092, 0x0047b6c3, + 0x0048fbe3, 0x004a3fc6, 0x004b823b, 0x004cc316, + 0x004e0228, 0x004f3f45, 0x00507a40, 0x0051b2ef, + 0x0052e925, 0x00541cba, 0x00554d85, 0x00567b5e, + 0x0057a61d, 0x0058cd9e, 0x0059f1bb, 0x005b1252, + 0x005c2f3f, 0x005d4863, 0x005e5d9d, 0x005f6ed0, + 0x00607bde, 0x006184ad, 0x00628923, 0x00638927, + 0x006484a3, 0x00657b81, 0x00666daf, 0x00675b19, + 0x006843b1, 0x00692767, 0x006a062d, 0x006adff9, + 0x006bb4c2, 0x006c847d, 0x006d4f27, 0x006e14b8, + 0x006ed52f, 0x006f9089, 0x007046c6, 0x0070f7e9, + 0x0071a3f3, 0x00724aea, 0x0072ecd3, 0x007389b6, + 0x0074219d, 0x0074b490, 0x0075429b, 0x0075cbcc, + 0x00765031, 0x0076cfd8, 0x00774ad3, 0x0077c132, + 0x00783308, 0x0078a068, 0x00790968, 0x00796e1c, + 0x0079ce9a, 0x007a2af9, 0x007a8350, 0x007ad7b8, + 0x007b2849, 0x007b751d, 0x007bbe4c, 0x007c03f1, + 0x007c4625, 0x007c8504, 0x007cc0a8, 0x007cf92c, + 0x007d2eaa, 0x007d613e, 0x007d9101, 0x007dbe10, + 0x007de883, 0x007e1076, 0x007e3603, 0x007e5943, + 0x007e7a4f, 0x007e9942, 0x007eb633, 0x007ed13a, + 0x007eea6f, 0x007f01ea, 0x007f17c0, 0x007f2c08, + 0x007f3ed7, 0x007f5043, 0x007f605e, 0x007f6f3c, + 0x007f7cf1, 0x007f898e, 0x007f9525, 0x007f9fc6, + 0x007fa982, 0x007fb268, 0x007fba86, 0x007fc1eb, + 0x007fc8a4, 0x007fcebe, 0x007fd443, 0x007fd941, + 0x007fddc2, 0x007fe1cf, 0x007fe572, 0x007fe8b4, + 0x007feb9e, 0x007fee36, 0x007ff086, 0x007ff293, + 0x007ff463, 0x007ff5fd, 0x007ff765, 0x007ff8a1, + 0x007ff9b6, 0x007ffaa7, 0x007ffb79, 0x007ffc2f, + 0x007ffccb, 0x007ffd52, 0x007ffdc6, 0x007ffe28, + 0x007ffe7b, 0x007ffec2, 0x007ffefd, 0x007fff2f, + 0x007fff58, 0x007fff7b, 0x007fff97, 0x007fffae, + 0x007fffc0, 0x007fffcf, 0x007fffdb, 0x007fffe4, + 0x007fffec, 0x007ffff1, 0x007ffff6, 0x007ffff9, + 0x007ffffb, 0x007ffffd, 0x007ffffe, 0x007fffff, + 0x007fffff, 0x007fffff, 0x007fffff, 0xff800000, + 0x00000000, 0xffa57d86, 0x005a827a, 0xff89be51, + 0x0030fbc5, 0xffcf043b, 0x007641af, 0xff8275a1, + 0x0018f8b8, 0xffb8e313, 0x006a6d99, 0xff959267, + 0x00471ced, 0xffe70748, 0x007d8a5f, 0xff809dc9, + 0x000c8bd3, 0xffaecc33, 0x0062f202, 0xff8f1d34, + 0x003c56ba, 0xffdad7f4, 0x007a7d05, 0xff8582fb, + 0x0025280c, 0xffc3a946, 0x0070e2cc, 0xff9d0dfe, + 0x005133cd, 0xfff3742d, 0x007f6237, 0xff802778, + 0x000647d9, 0xffaa0a5b, 0x005ed77d, 0xff8c4a14, + 0x0036ba20, 0xffd4e0cb, 0x00788484, 0xff83d604, + 0x001f19f9, 0xffbe31e2, 0x006dca0d, 0xff99307f, + 0x004c3fe0, 0xffed37f0, 0x007e9d56, 0xff8162aa, + 0x0012c810, 0xffb3c020, 0x0066cf81, 0xff9235f3, + 0x0041ce1e, 0xffe0e607, 0x007c29fc, 0xff877b7c, + 0x002b1f35, 0xffc945e0, 0x0073b5ec, 0xffa12883, + 0x0055f5a5, 0xfff9b827, 0x007fd888, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static u32 AC3I2S240Ucode1fe000[] = { + 0x00000000, 0x03020102, 0x05040403, 0x00400040, + 0x00500050, 0x00600060, 0x00700070, 0x00800080, + 0x00a000a0, 0x00c000c0, 0x00e000e0, 0x01000100, + 0x01400140, 0x01800180, 0x01c001c0, 0x02000200, + 0x02800280, 0x03000300, 0x03800380, 0x04000400, + 0x04800480, 0x05000500, 0x00460045, 0x00580057, + 0x00690068, 0x007a0079, 0x008c008b, 0x00af00ae, + 0x00d100d0, 0x00f400f3, 0x01170116, 0x015d015c, + 0x01a201a1, 0x01e801e7, 0x022e022d, 0x02b902b8, + 0x03440343, 0x03d003cf, 0x045b045a, 0x04e604e5, + 0x05720571, 0x00600060, 0x00780078, 0x00900090, + 0x00a800a8, 0x00c000c0, 0x00f000f0, 0x01200120, + 0x01500150, 0x01800180, 0x01e001e0, 0x02400240, + 0x02a002a0, 0x03000300, 0x03c003c0, 0x04800480, + 0x05400540, 0x06000600, 0x06c006c0, 0x07800780, + 0x7b67533f, 0x1513110f, 0x04d80540, 0x04100478, + 0x07000000, 0x0b000900, 0x02b002f0, 0x02300270, + 0x017001f0, 0xf80000f0, 0x01000080, 0x02000180, + 0x03000280, 0x04000380, 0x2725231f, 0x2c2b2a29, + 0x2e2e2d2d, 0x30302f2f, 0x04030201, 0x08070605, + 0x0c0b0a09, 0x100f0e0d, 0x14131211, 0x18171615, + 0x1c1b1a19, 0x2825221f, 0x37312e2b, 0x4f49433d, + 0x796d6155, 0xcdb59d85, 0x0000fde5, 0x3d3e3f40, + 0x393a3b3c, 0x35363738, 0x32333434, 0x2f2f3031, + 0x2c2c2d2e, 0x29292a2b, 0x26262728, 0x23242425, + 0x21212223, 0x1e1f2020, 0x1c1d1d1e, 0x1a1b1b1c, + 0x1819191a, 0x16171718, 0x15151516, 0x13131414, + 0x12121213, 0x10111111, 0x0f0f1010, 0x0e0e0e0f, + 0x0d0d0d0d, 0x0c0c0c0c, 0x0b0b0b0b, 0x0a0a0a0a, + 0x0909090a, 0x08080909, 0x08080808, 0x07070707, + 0x06060707, 0x06060606, 0x05050606, 0x05050505, + 0x04040505, 0x04040404, 0x04040404, 0x03030304, + 0x03030303, 0x03030303, 0x02030303, 0x02020202, + 0x02020202, 0x02020202, 0x02020202, 0x01010202, + 0x01010101, 0x01010101, 0x01010101, 0x01010101, + 0x01010101, 0x01010101, 0x01010101, 0x00000101, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x04d004d0, + 0x04000440, 0x03c003e0, 0x03b003b0, 0x03a003a0, + 0x03a003a0, 0x039003a0, 0x03900390, 0x03800380, + 0x03700370, 0x03600360, 0x03500350, 0x03400340, + 0x03200330, 0x03000310, 0x02f002f0, 0x02f002f0, + 0x03100300, 0x03900340, 0x042003e0, 0x04900460, + 0x046004a0, 0x04400440, 0x08000520, 0x08400840, + 0x04f004f0, 0x04100460, 0x03d003e0, 0x03b003c0, + 0x03a003b0, 0x03a003a0, 0x03a003a0, 0x03900390, + 0x03800390, 0x03800380, 0x03700370, 0x03600360, + 0x03500350, 0x03400340, 0x03100320, 0x02f00300, + 0x02f002f0, 0x030002f0, 0x03500320, 0x03e00390, + 0x04500420, 0x049004a0, 0x04400460, 0x06300480, + 0x08400840, 0x05800580, 0x045004b0, 0x03f00420, + 0x03d003e0, 0x03b003c0, 0x03b003b0, 0x03a003a0, + 0x03a003a0, 0x03a003a0, 0x03a003a0, 0x03900390, + 0x03900390, 0x03800380, 0x03700380, 0x03500360, + 0x03300340, 0x03100320, 0x02f00300, 0x02f002f0, + 0x03100300, 0x03500330, 0x041003c0, 0x04a00470, + 0x04400460, 0x04e00450, 0xffaaaaab, 0x00000000, + 0x00555555, 0xff99999a, 0xffcccccd, 0x00000000, + 0x00333333, 0x00666666, 0xff924925, 0xffb6db6e, + 0xffdb6db7, 0x00000000, 0x00249249, 0x00492492, + 0x006db6db, 0xff8ba2e9, 0xffa2e8ba, 0xffba2e8c, + 0xffd1745d, 0xffe8ba2f, 0x00000000, 0x001745d1, + 0x002e8ba3, 0x0045d174, 0x005d1746, 0x00745d17, + 0xff888889, 0xff99999a, 0xffaaaaab, 0xffbbbbbc, + 0xffcccccd, 0xffddddde, 0xffeeeeef, 0x00000000, + 0x00111111, 0x00222222, 0x00333333, 0x00444444, + 0x00555555, 0x00666666, 0x00777777, 0x08070605, + 0x0c0b0a09, 0x10100e0e, 0x00000010, 0x00000000, + 0x00000010, 0x00000020, 0x00000100, 0x00000110, + 0x00000120, 0x00000200, 0x00000210, 0x00000220, + 0x00001000, 0x00001010, 0x00001020, 0x00001100, + 0x00001110, 0x00001120, 0x00001200, 0x00001210, + 0x00001220, 0x00002000, 0x00002010, 0x00002020, + 0x00002100, 0x00002110, 0x00002120, 0x00002200, + 0x00002210, 0x00002220, 0x00000000, 0x00000010, + 0x00000020, 0x00000030, 0x00000040, 0x00000100, + 0x00000110, 0x00000120, 0x00000130, 0x00000140, + 0x00000200, 0x00000210, 0x00000220, 0x00000230, + 0x00000240, 0x00000300, 0x00000310, 0x00000320, + 0x00000330, 0x00000340, 0x00000400, 0x00000410, + 0x00000420, 0x00000430, 0x00000440, 0x00001000, + 0x00001010, 0x00001020, 0x00001030, 0x00001040, + 0x00001100, 0x00001110, 0x00001120, 0x00001130, + 0x00001140, 0x00001200, 0x00001210, 0x00001220, + 0x00001230, 0x00001240, 0x00001300, 0x00001310, + 0x00001320, 0x00001330, 0x00001340, 0x00001400, + 0x00001410, 0x00001420, 0x00001430, 0x00001440, + 0x00002000, 0x00002010, 0x00002020, 0x00002030, + 0x00002040, 0x00002100, 0x00002110, 0x00002120, + 0x00002130, 0x00002140, 0x00002200, 0x00002210, + 0x00002220, 0x00002230, 0x00002240, 0x00002300, + 0x00002310, 0x00002320, 0x00002330, 0x00002340, + 0x00002400, 0x00002410, 0x00002420, 0x00002430, + 0x00002440, 0x00003000, 0x00003010, 0x00003020, + 0x00003030, 0x00003040, 0x00003100, 0x00003110, + 0x00003120, 0x00003130, 0x00003140, 0x00003200, + 0x00003210, 0x00003220, 0x00003230, 0x00003240, + 0x00003300, 0x00003310, 0x00003320, 0x00003330, + 0x00003340, 0x00003400, 0x00003410, 0x00003420, + 0x00003430, 0x00003440, 0x00004000, 0x00004010, + 0x00004020, 0x00004030, 0x00004040, 0x00004100, + 0x00004110, 0x00004120, 0x00004130, 0x00004140, + 0x00004200, 0x00004210, 0x00004220, 0x00004230, + 0x00004240, 0x00004300, 0x00004310, 0x00004320, + 0x00004330, 0x00004340, 0x00004400, 0x00004410, + 0x00004420, 0x00004430, 0x00004440, 0x00000000, + 0x00000100, 0x00000200, 0x00000300, 0x00000400, + 0x00000500, 0x00000600, 0x00000700, 0x00000800, + 0x00000900, 0x00000a00, 0x00001000, 0x00001100, + 0x00001200, 0x00001300, 0x00001400, 0x00001500, + 0x00001600, 0x00001700, 0x00001800, 0x00001900, + 0x00001a00, 0x00002000, 0x00002100, 0x00002200, + 0x00002300, 0x00002400, 0x00002500, 0x00002600, + 0x00002700, 0x00002800, 0x00002900, 0x00002a00, + 0x00003000, 0x00003100, 0x00003200, 0x00003300, + 0x00003400, 0x00003500, 0x00003600, 0x00003700, + 0x00003800, 0x00003900, 0x00003a00, 0x00004000, + 0x00004100, 0x00004200, 0x00004300, 0x00004400, + 0x00004500, 0x00004600, 0x00004700, 0x00004800, + 0x00004900, 0x00004a00, 0x00005000, 0x00005100, + 0x00005200, 0x00005300, 0x00005400, 0x00005500, + 0x00005600, 0x00005700, 0x00005800, 0x00005900, + 0x00005a00, 0x00006000, 0x00006100, 0x00006200, + 0x00006300, 0x00006400, 0x00006500, 0x00006600, + 0x00006700, 0x00006800, 0x00006900, 0x00006a00, + 0x00007000, 0x00007100, 0x00007200, 0x00007300, + 0x00007400, 0x00007500, 0x00007600, 0x00007700, + 0x00007800, 0x00007900, 0x00007a00, 0x00008000, + 0x00008100, 0x00008200, 0x00008300, 0x00008400, + 0x00008500, 0x00008600, 0x00008700, 0x00008800, + 0x00008900, 0x00008a00, 0x00009000, 0x00009100, + 0x00009200, 0x00009300, 0x00009400, 0x00009500, + 0x00009600, 0x00009700, 0x00009800, 0x00009900, + 0x00009a00, 0x0000a000, 0x0000a100, 0x0000a200, + 0x0000a300, 0x0000a400, 0x0000a500, 0x0000a600, + 0x0000a700, 0x0000a800, 0x0000a900, 0x0000aa00, + 0xff800000, 0xff800000, 0xffb82995, 0xffaf5d75, + 0xffa57d87, 0xff9a6806, 0xff8df708, 0xff800000, + 0xffb82995, 0xffaf5d75, 0xffa57d87, 0xff9a6806, + 0xff8df708, 0xff800000, 0xffb82995, 0xffaf5d75, + 0xffa57d87, 0xff9a6806, 0xff8df708, 0xff800000, + 0xffb82995, 0xffaf5d75, 0xffa57d87, 0xff9a6806, + 0xff8df708, 0xff800000, 0xffb82995, 0xffaf5d75, + 0xffa57d87, 0xff9a6806, 0xff8df708, 0xff800000, + 0xfffb0000, 0xfffcfffc, 0xfffcfffc, 0xfffcfffc, + 0xfffdfffd, 0xfffdfffd, 0xfffdfffd, 0xfffefffe, + 0xfffefffe, 0xfffefffe, 0xffffffff, 0xffffffff, + 0xffffffff, 0x00000000, 0x00000000, 0x00000000, + 0x80050000, 0x000a800f, 0x001e801b, 0x80110014, + 0x00368033, 0x8039003c, 0x802d0028, 0x00228027, + 0x00668063, 0x8069006c, 0x807d0078, 0x00728077, + 0x80550050, 0x005a805f, 0x004e804b, 0x80410044, + 0x00c680c3, 0x80c900cc, 0x80dd00d8, 0x00d280d7, + 0x80f500f0, 0x00fa80ff, 0x00ee80eb, 0x80e100e4, + 0x80a500a0, 0x00aa80af, 0x00be80bb, 0x80b100b4, + 0x00968093, 0x8099009c, 0x808d0088, 0x00828087, + 0x01868183, 0x8189018c, 0x819d0198, 0x01928197, + 0x81b501b0, 0x01ba81bf, 0x01ae81ab, 0x81a101a4, + 0x81e501e0, 0x01ea81ef, 0x01fe81fb, 0x81f101f4, + 0x01d681d3, 0x81d901dc, 0x81cd01c8, 0x01c281c7, + 0x81450140, 0x014a814f, 0x015e815b, 0x81510154, + 0x01768173, 0x8179017c, 0x816d0168, 0x01628167, + 0x01268123, 0x8129012c, 0x813d0138, 0x01328137, + 0x81150110, 0x011a811f, 0x010e810b, 0x81010104, + 0x03068303, 0x8309030c, 0x831d0318, 0x03128317, + 0x83350330, 0x033a833f, 0x032e832b, 0x83210324, + 0x83650360, 0x036a836f, 0x037e837b, 0x83710374, + 0x03568353, 0x8359035c, 0x834d0348, 0x03428347, + 0x83c503c0, 0x03ca83cf, 0x03de83db, 0x83d103d4, + 0x03f683f3, 0x83f903fc, 0x83ed03e8, 0x03e283e7, + 0x03a683a3, 0x83a903ac, 0x83bd03b8, 0x03b283b7, + 0x83950390, 0x039a839f, 0x038e838b, 0x83810384, + 0x82850280, 0x028a828f, 0x029e829b, 0x82910294, + 0x02b682b3, 0x82b902bc, 0x82ad02a8, 0x02a282a7, + 0x02e682e3, 0x82e902ec, 0x82fd02f8, 0x02f282f7, + 0x82d502d0, 0x02da82df, 0x02ce82cb, 0x82c102c4, + 0x02468243, 0x8249024c, 0x825d0258, 0x02528257, + 0x82750270, 0x027a827f, 0x026e826b, 0x82610264, + 0x82250220, 0x022a822f, 0x023e823b, 0x82310234, + 0x02168213, 0x8219021c, 0x820d0208, 0x02028207, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x00000002, 0x00000002, + 0x00000000, 0xff800000, 0xffa57d86, 0xffa57d86, + 0xffcf043b, 0xff89be51, 0xff89be51, 0xffcf043b, + 0xffe70748, 0xff8275a1, 0xff959267, 0xffb8e313, + 0xffb8e313, 0xff959267, 0xff8275a1, 0xffe70748, + 0xfff3742d, 0xff809dc9, 0xff9d0dfe, 0xffaecc33, + 0xffc3a946, 0xff8f1d34, 0xff8582fb, 0xffdad7f4, + 0xffdad7f4, 0xff8582fb, 0xff8f1d34, 0xffc3a946, + 0xffaecc33, 0xff9d0dfe, 0xff809dc9, 0xfff3742d, + 0xfff9b827, 0xff802778, 0xffa12883, 0xffaa0a5b, + 0xffc945e0, 0xff8c4a14, 0xff877b7c, 0xffd4e0cb, + 0xffe0e607, 0xff83d604, 0xff9235f3, 0xffbe31e2, + 0xffb3c020, 0xff99307f, 0xff8162aa, 0xffed37f0, + 0xffed37f0, 0xff8162aa, 0xff99307f, 0xffb3c020, + 0xffbe31e2, 0xff9235f3, 0xff83d604, 0xffe0e607, + 0xffd4e0cb, 0xff877b7c, 0xff8c4a14, 0xffc945e0, + 0xffaa0a5b, 0xffa12883, 0xff802778, 0xfff9b827, + 0xcbcecdc4, 0xcfcac9c8, 0xc3c6c5cc, 0xc7c2c1c0, + 0x1b1e1d14, 0x1f1a1918, 0x1316151c, 0x17121110, + 0x2b2e2d24, 0x2f2a2928, 0x2326252c, 0x27222120, + 0x3b3e3d34, 0x3f3a3938, 0x3336353c, 0x37323130, + 0x0b0e0d04, 0x0f0a0908, 0x0306050c, 0x07020100, + 0xdbdeddd4, 0xdfdad9d8, 0xd3d6d5dc, 0xd7d2d1d0, + 0xebeeede4, 0xefeae9e8, 0xe3e6e5ec, 0xe7e2e1e0, + 0xfbfefdf4, 0xfffaf9f8, 0xf3f6f5fc, 0xf7f2f1f0, + 0x4b4e4d44, 0x4f4a4948, 0x4346454c, 0x47424140, + 0x9b9e9d94, 0x9f9a9998, 0x9396959c, 0x97929190, + 0xabaeada4, 0xafaaa9a8, 0xa3a6a5ac, 0xa7a2a1a0, + 0xbbbebdb4, 0xbfbab9b8, 0xb3b6b5bc, 0xb7b2b1b0, + 0x8b8e8d84, 0x8f8a8988, 0x8386858c, 0x87828180, + 0x5b5e5d54, 0x5f5a5958, 0x5356555c, 0x57525150, + 0x6b6e6d64, 0x6f6a6968, 0x6366656c, 0x67626160, + 0x7b7e7d74, 0x7f7a7978, 0x7376757c, 0x77727170, + 0x341424c4, 0x3e1e2ece, 0x3d1d2dcd, 0x3b1b2bcb, + 0xb494a444, 0xbe9eae4e, 0xbd9dad4d, 0xbb9bab4b, + 0xf4d4e404, 0xfedeee0e, 0xfddded0d, 0xfbdbeb0b, + 0x74546484, 0x7e5e6e8e, 0x7d5d6d8d, 0x7b5b6b8b, + 0x3c1c2ccc, 0x361626c6, 0x351525c5, 0x331323c3, + 0xbc9cac4c, 0xb696a646, 0xb595a545, 0xb393a343, + 0xfcdcec0c, 0xf6d6e606, 0xf5d5e505, 0xf3d3e303, + 0x7c5c6c8c, 0x76566686, 0x75556585, 0x73536383, + 0x381828c8, 0x3a1a2aca, 0x391929c9, 0x3f1f2fcf, + 0xb898a848, 0xba9aaa4a, 0xb999a949, 0xbf9faf4f, + 0xf8d8e808, 0xfadaea0a, 0xf9d9e909, 0xffdfef0f, + 0x78586888, 0x7a5a6a8a, 0x79596989, 0x7f5f6f8f, + 0x301020c0, 0x321222c2, 0x311121c1, 0x371727c7, + 0xb090a040, 0xb292a242, 0xb191a141, 0xb797a747, + 0xf0d0e000, 0xf2d2e202, 0xf1d1e101, 0xf7d7e707, + 0x70506080, 0x72526282, 0x71516181, 0x77576787, + 0x05040100, 0x15141110, 0x25242120, 0x35343130, + 0x85848180, 0x95949190, 0xa5a4a1a0, 0xb5b4b1b0, + 0xc0408000, 0xe060a020, 0xd0509010, 0xf070b030, + 0xc8488808, 0xe868a828, 0xd8589818, 0xf878b838, + 0xc4448404, 0xe464a424, 0xd4549414, 0xf474b434, + 0xcc4c8c0c, 0xec6cac2c, 0xdc5c9c1c, 0xfc7cbc3c, + 0xc2428202, 0xe262a222, 0xd2529212, 0xf272b232, + 0xca4a8a0a, 0xea6aaa2a, 0xda5a9a1a, 0xfa7aba3a, + 0xc6468606, 0xe666a626, 0xd6569616, 0xf676b636, + 0xce4e8e0e, 0xee6eae2e, 0xde5e9e1e, 0xfe7ebe3e, + 0xc1418101, 0xe161a121, 0xd1519111, 0xf171b131, + 0xc9498909, 0xe969a929, 0xd9599919, 0xf979b939, + 0xc5458505, 0xe565a525, 0xd5559515, 0xf575b535, + 0xcd4d8d0d, 0xed6dad2d, 0xdd5d9d1d, 0xfd7dbd3d, + 0xc3438303, 0xe363a323, 0xd3539313, 0xf373b333, + 0xcb4b8b0b, 0xeb6bab2b, 0xdb5b9b1b, 0xfb7bbb3b, + 0xc7478707, 0xe767a727, 0xd7579717, 0xf777b737, + 0xcf4f8f0f, 0xef6faf2f, 0xdf5f9f1f, 0xff7fbf3f, + 0x1045a3e2, 0x000000f4, 0x263b7333, 0x766b2363, + 0x2b367e3e, 0x7b662e6e, 0x06db93d3, 0x964b0343, + 0x0bd69ede, 0x9b460e4e, 0x825f1757, 0x12cf87c7, + 0x8f521a5a, 0x1fc28aca, 0x00d199d9, 0x90410949, + 0x01d098d8, 0x91400848, 0x24357d3d, 0x74652d6d, + 0x25347c3c, 0x75642c6c, 0x04d59ddd, 0x94450d4d, + 0x05d49cdc, 0x95440c4c, 0x80511959, 0x10c189c9, + 0x81501858, 0x11c088c8, 0x02df97d7, 0x924f0747, + 0x0fd29ada, 0x9f420a4a, 0x865b1353, 0x16cb83c3, + 0x8b561e5e, 0x1bc68ece, 0xa6bbf3b3, 0xf6eba3e3, + 0xabb6febe, 0xfbe6aeee, 0x223f7737, 0x726f2767, + 0x2f327a3a, 0x7f622a6a, 0xa0b1f9b9, 0xf0e1a9e9, + 0xa1b0f8b8, 0xf1e0a8e8, 0x84551d5d, 0x14c58dcd, + 0x85541c5c, 0x15c48ccc, 0xa4b5fdbd, 0xf4e5aded, + 0xa5b4fcbc, 0xf5e4acec, 0x20317939, 0x70612969, + 0x21307838, 0x71602868, 0xa2bff7b7, 0xf2efa7e7, + 0xafb2faba, 0xffe2aaea, 0x00000000, 0x00000000, +}; + +static u32 AC3I2S240Ucode1fff80[] = { + 0x0000240f, 0x007fffff, 0x007fffff, 0x00000003, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0x00000000, 0x00000000, 0x00000000, + 0x007fffff, 0x00000000, 0x00000000, 0x00000000, +}; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/lpcm.h linux.19pre5-ac1/drivers/media/video/ls220/lpcm.h --- linux.19p5/drivers/media/video/ls220/lpcm.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/ls220/lpcm.h Thu Feb 21 21:26:27 2002 @@ -0,0 +1,818 @@ +static u32 PCMUcode1f1800[] = { + 0xb500000f, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xb50001f7, 0x00000000, 0x00000000, 0x00000000, + 0x820f001f, 0x802f001f, 0x029f9014, 0x829efef0, + 0x8286000f, 0x02bf0054, 0x82bcfef4, 0x82a6000e, + 0x80074000, 0x001f6193, 0x8013001f, 0x9020c000, + 0x003fb006, 0x803effe8, 0x803effec, 0x9020fa00, + 0x803effd0, 0x803effdc, 0x803effd8, 0x9020fe00, + 0x803effd4, 0x90400000, 0x804600a2, 0x90421800, + 0x804600a3, 0x80132000, 0x98000040, 0x800600a6, + 0x80050080, 0x98000002, 0x80060080, 0x80070001, + 0x001f2013, 0x80070000, 0x001f23f9, 0x801e4b0c, + 0x001f210c, 0x80070001, 0x001f2324, 0x80070800, + 0x001f600f, 0x001fb0cb, 0x001fb010, 0x801efff0, + 0x98004000, 0x001f600e, 0x83e40121, 0x80070000, + 0x801e4b14, 0x800500a0, 0xb0000001, 0xb4000009, + 0x80070001, 0x800600a0, 0x80050080, 0x98000020, + 0x80060080, 0x9400ffdf, 0x80060080, 0x80070000, + 0x800600a0, 0x80074000, 0x801e4b04, 0x81df0004, + 0x801bfff0, 0x00000000, 0x940000ff, 0xb0000000, + 0xb4200033, 0x003f400e, 0x94010010, 0xb0000000, + 0xb400fff7, 0x003f0013, 0xb0010001, 0xb420001f, + 0x803bffe8, 0x801bffec, 0x805b4b04, 0x00000000, + 0x3001b800, 0xb4600001, 0x9021a000, 0x0421b800, + 0x3001b802, 0xb460000d, 0x80050086, 0x005f9044, + 0x0420b802, 0xb00101e0, 0xb4a0ffe5, 0x001fb010, + 0x001f010c, 0xb0000001, 0xb400ffe1, 0x80070001, + 0x001f210c, 0x83e400ee, 0xb500ffdd, 0x8007001f, + 0x94000003, 0x5810b800, 0x83e719ec, 0x1bffb800, + 0x003f9008, 0x1821b800, 0x00ffb801, 0x80270000, + 0x003f2013, 0x8007001f, 0x94000003, 0x5810b800, + 0x83671a14, 0x1b7bb800, 0x003f9009, 0x1821b800, + 0x00ffb801, 0x80070000, 0x001f210c, 0xb500ffc8, + 0x003f400e, 0xb0000086, 0xb4400056, 0xb0000084, + 0xb4000040, 0xb0000085, 0xb4000046, 0xb0000086, + 0xb4000048, 0xb0000083, 0xb4000000, 0x815bff7c, + 0x00000000, 0x940a0080, 0x5c07b800, 0xb0000001, + 0xb4000074, 0x81674b18, 0x940a0007, 0x5803b800, + 0x116bb800, 0x005bb80b, 0x916b0004, 0x001bb80b, + 0x80530030, 0x98422000, 0x8013ffcf, 0x9800cfff, + 0x806500d4, 0x1463b800, 0x1863b802, 0x806600d4, + 0x80073cfb, 0x801e4b00, 0x800600a1, 0x80074000, + 0x801e4b04, 0x8013001f, 0x98405000, 0x805effe0, + 0x005fb006, 0x805effe8, 0x805effec, 0x9042a000, + 0x805effe4, 0x9040fa00, 0x805effd0, 0x805effdc, + 0x805effd8, 0x9040fe00, 0x805effd4, 0x8013007f, + 0x9800ffff, 0x001fb040, 0x80070001, 0x001f2013, + 0x80070000, 0x001f2324, 0x001f600f, 0x001fb0cb, + 0x001fb010, 0x001fb041, 0x001fb042, 0x80073470, + 0x001fb008, 0x80071e50, 0x001fb009, 0x98214000, + 0xb5000010, 0x94011000, 0xb0001000, 0xb4200001, + 0x9421efff, 0x98210010, 0xb500000a, 0x80070000, + 0x001fb0cb, 0x83e4009a, 0x003f400e, 0x9421ffef, + 0xb5000004, 0x83e40096, 0x003f400e, 0x98211000, + 0x9421ffef, 0x003f600e, 0x80070100, 0x801efff0, + 0xb500ff6f, 0xb000008b, 0xb4000018, 0xb0000087, + 0xb400ffee, 0xb0000088, 0xb4000016, 0xb000008a, + 0xb4000016, 0xb000008c, 0xb4000017, 0xb0000089, + 0xb4000019, 0xb00000a0, 0xb400001b, 0xb00000a1, + 0xb4000048, 0xb00000a2, 0xb4000055, 0xb00000a3, + 0xb400004d, 0xb00000a4, 0xb4000057, 0xb00000a5, + 0xb400005b, 0xb00000a6, 0xb400005f, 0x803efff8, + 0xb500ffe1, 0x9421ffdf, 0xb500ffde, 0x80270100, + 0x803efff8, 0xb500ffdc, 0x803bffb0, 0x00000000, + 0x003fb040, 0xb500ffd8, 0x803bff80, 0x00000000, + 0x003f6001, 0xb500ffd4, 0x003f90ba, 0x803efff8, + 0xb500ffd1, 0x81674b18, 0x940a0007, 0x5803b800, + 0x116bb800, 0x005bb80b, 0x916b0004, 0x001bb80b, + 0x806500d4, 0x1463b800, 0x1863b802, 0x806600d4, + 0x80130001, 0x98003d21, 0x800600a1, 0x801e4b00, + 0x80074000, 0x801e4b04, 0x8013001f, 0x98405000, + 0x805effe0, 0x005fb006, 0x805effe8, 0x805effec, + 0x9042a000, 0x805effe4, 0x9040fa00, 0x805effd0, + 0x805effdc, 0x805effd8, 0x9040fe00, 0x805effd4, + 0x80070001, 0x001f2013, 0x80070000, 0x001f2324, + 0x001f600f, 0x001fb0cb, 0x001fb010, 0x80073cb0, + 0x001fb008, 0x800744a0, 0x001fb009, 0x98214000, + 0xb500ffa4, 0x80270000, 0x8047fef0, 0x003eb802, + 0x90420004, 0x003eb802, 0x90420004, 0x003eb802, + 0x90420004, 0x003eb802, 0x81df0000, 0x00000000, + 0x00000000, 0x83640475, 0x81df0004, 0xb500ff96, + 0x81df0000, 0x00000000, 0x00000000, 0x8364041f, + 0x81df0004, 0xb500ff90, 0x81df0000, 0x00000000, + 0x00000000, 0x836403da, 0x81df0004, 0xb500ff8a, + 0x81df0000, 0x00000000, 0x00000000, 0x83440339, + 0x81df0004, 0xb500ff84, 0x81df0000, 0x00000000, + 0x00000000, 0x8344031e, 0x81df0004, 0xb500ff7e, + 0x80070000, 0x80470000, 0x81df0000, 0x00000000, + 0x00000000, 0xb6002003, 0xb6003002, 0x001eb802, + 0x90420004, 0x80171000, 0x8057ffff, 0xb6002002, + 0xb6001801, 0x001fa020, 0x81df0004, 0x00ffb81f, + 0x83a70000, 0x8057ffff, 0x80770000, 0x8073007a, + 0x9863e7d2, 0x0207b803, 0x81df0000, 0x00000000, + 0x00000000, 0x80171000, 0xb6008007, 0x003fc0c0, + 0x005fc740, 0x40c1b810, 0x4102b810, 0x001fe0c6, + 0x001fe0c8, 0x4210b803, 0x81df0004, 0x80270000, + 0x003f2013, 0x8007001f, 0x94000003, 0x5810b800, + 0x83671e34, 0x1b7bb800, 0x003f9009, 0x1821b800, + 0x00ffb801, 0x003f0013, 0xb0010001, 0xb420fff3, + 0x93bd0001, 0xb01d0004, 0xb480ffe3, 0x00ffb81f, + 0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000, + 0xb4000011, 0x815b4b0c, 0x81070000, 0x81270be8, + 0xb00a0000, 0xb4000002, 0x81070c00, 0x812717e8, + 0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc, + 0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809, + 0xb4a00059, 0xb5000008, 0xb0040000, 0xb4200003, + 0x802717ff, 0x81470000, 0xb5000003, 0x80270001, + 0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200006, + 0x039f4193, 0x5b81b81c, 0x003f90cb, 0x1021b81c, + 0x003fb0cb, 0x83840237, 0x829bff80, 0x801300e0, + 0x1434b800, 0x5c35b801, 0x8013001f, 0x1454b800, + 0x5c50b802, 0x8073007f, 0x9863ffff, 0xb002000f, + 0xb4800001, 0x90210001, 0x84210004, 0xb0010000, + 0xb4a00001, 0x6861b803, 0x005f9040, 0x4082b803, + 0x80af001f, 0x808f0000, 0x806f0000, 0x8007ffff, + 0x8033ffff, 0x80171000, 0x81df0000, 0x00000000, + 0x00000000, 0xb600180a, 0xb6002009, 0x58708000, + 0x6068b803, 0x40c4b803, 0x00000000, 0x00c8b806, + 0x00000000, 0x00000000, 0x00000000, 0x5807a026, + 0x81df0004, 0x80670400, 0x5d22b80a, 0x81df0000, + 0x00000000, 0x00000000, 0xb600180a, 0x00cfb803, + 0x013fb0bc, 0x5922b809, 0x01afb809, 0x013f90bc, + 0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x90630020, + 0x91290020, 0x81df0004, 0x808f0000, 0x801b4b14, + 0x80270001, 0xb0000001, 0xb4000002, 0x802600a0, + 0x803e4b14, 0x81270c00, 0xb00a0000, 0xb4000001, + 0x81270000, 0x813e4b0c, 0x80270001, 0x003f2013, + 0x80050086, 0x001fb044, 0x00ffb81b, 0x00000000, + 0x029fb00a, 0x02bfb00b, 0x02dfb00c, 0x02ffb00d, + 0x031fb00e, 0x033fb00f, 0x033f400f, 0x0287b86f, + 0x029fb005, 0x8285009c, 0x96b48000, 0xb0158000, + 0xb400018d, 0x96b40100, 0xb0150100, 0xb40001a9, + 0x96b40400, 0xb0150400, 0xb40001b0, 0x96b40001, + 0xb0150001, 0xb400000c, 0x96b40008, 0xb0150008, + 0xb4000196, 0x96b44000, 0xb0154000, 0xb40001af, + 0x96b40002, 0xb0150002, 0xb400015e, 0x00000000, + 0x00000000, 0xb50001c1, 0x02bf9017, 0x92b50001, + 0x02bfb017, 0x82850082, 0x83050081, 0x82a5009a, + 0x96b50001, 0xb0150001, 0xb4200014, 0x82a70000, + 0x02bfb017, 0x96b41840, 0xb0150800, 0xb420000c, + 0x96b40008, 0x5aa9b815, 0x96d46000, 0x5ec3b816, + 0x82f3000f, 0x9af7c00f, 0x1718b817, 0x1ab5b818, + 0x1ab5b816, 0x9ab50340, 0x82a60081, 0xb500013d, + 0x9b180180, 0x83060081, 0xb500013a, 0x82a5009a, + 0x96b50002, 0xb0150002, 0xb420001b, 0x82a70000, + 0x02bfb017, 0x96b41800, 0xb0151800, 0xb4000013, + 0x96b40040, 0xb0150040, 0xb4200004, 0xa3180c00, + 0x9b180340, 0x83060081, 0xb500012a, 0x96b40008, + 0x5aa9b815, 0x96d46000, 0x5ec3b816, 0x82f3000f, + 0x9af7c00f, 0x1718b817, 0x1ab5b818, 0x1ab5b816, + 0x9ab50340, 0x82a60081, 0xb500011e, 0x9b180180, + 0x83060081, 0xb500011b, 0x82a500c1, 0x96b5000f, + 0xb015000b, 0xb420000e, 0x96b40020, 0xb0150020, + 0xb400000b, 0x96b40200, 0xb0150200, 0xb4000008, + 0x82c50086, 0x82e50094, 0x3016b817, 0xb4400004, + 0x06f7b816, 0xb017ff00, 0xb4400001, 0xb5000109, + 0x96b46000, 0xb0156000, 0xb4000011, 0x96b41820, + 0xb0150820, 0xb4200004, 0x9b391000, 0x82a5009a, + 0x96b5feff, 0x82a6009a, 0x96b40040, 0xb0150040, + 0xb4200001, 0x9739efff, 0x96b91000, 0xb0151000, + 0xb4200003, 0x82a5009a, 0x9ab50100, 0x82a6009a, + 0x96b40040, 0xb0150040, 0xb4200019, 0x96b41800, + 0xb0151800, 0xb4200006, 0x96b98000, 0xb0158000, + 0xb4200003, 0x9b180180, 0x83060081, 0xb50000e9, + 0x96d80c00, 0x82b300ff, 0x9ab5f3ff, 0x1718b815, + 0xb0160c00, 0xb4000007, 0x82e50098, 0x96f70400, + 0xb0170400, 0xb4200002, 0x82c70c00, 0xb5000001, + 0xa2d60c00, 0x1b18b816, 0x9b180340, 0xb50000cf, + 0x96b40220, 0xb0150000, 0xb4e00033, 0x82a5009d, + 0x82f3ffff, 0x16b5b817, 0x82f3000e, 0x3015b817, + 0xb420002d, 0x96f98000, 0xb0178000, 0xb400002a, + 0x82a70000, 0x02bfb017, 0x82c50081, 0x9ab60020, + 0x82a60081, 0x82a50086, 0x92b50bb8, 0x82a60094, + 0x82c60081, 0x82c5009d, 0x96d6ffff, 0x82b30032, + 0x9ab58001, 0x82e500c1, 0x96f7000f, 0xb017000b, + 0xb4000002, 0x82b30022, 0x9ab58001, 0x1ab5b816, + 0x82c5009a, 0x96d60020, 0xb0160020, 0xb4200002, + 0x82b30032, 0x9ab58001, 0x82a6009d, 0x02ff9017, + 0x00000000, 0xb0170040, 0xb480000b, 0x96f41c00, + 0xb0171c00, 0xb4200008, 0x82e50086, 0x82c50094, + 0x92d63000, 0x3016b817, 0xb4400003, 0x9b180180, + 0x83060081, 0xb50000a3, 0x5eb5b814, 0x96b500f0, + 0x96f46000, 0x5eedb817, 0x1ab5b817, 0xb0170003, + 0xb4000004, 0x96b500ef, 0x96f70001, 0x5ae4b817, + 0x1ab5b817, 0x96d41800, 0xb0161800, 0xb400000a, + 0x96f900ff, 0x96b500ff, 0x9739ff00, 0x1b39b815, + 0x02a7b817, 0x96b500f3, 0x96d40008, 0x5ec1b816, + 0x1ab5b816, 0xb500000c, 0x96f98000, 0xb0178000, + 0xb4200007, 0x5efeb814, 0x96f70001, 0xb0170001, + 0xb4000003, 0x9b180180, 0x83060081, 0xb5000081, + 0x96b500f3, 0x9ab50008, 0x9739fff3, 0x96d40020, + 0xb0160020, 0xb4200017, 0x9b398000, 0x82c70000, + 0x02dfb017, 0x96d40010, 0x5ac8b816, 0x82f300ff, + 0x9af7cfff, 0x1718b817, 0x1b18b816, 0x9b180340, + 0x82c5009d, 0x96d6ffff, 0x82f3000e, 0x9af78001, + 0x1af7b816, 0x82c5009a, 0x96d60020, 0xb0160020, + 0xb4200002, 0x82f30032, 0x9af78001, 0x82e6009d, + 0xb500005a, 0x97397fff, 0x96b500ff, 0x5aaab815, + 0x82f300fc, 0x9af703ff, 0x1718b817, 0x1b18b815, + 0x9b180340, 0x82c5009a, 0x96d60010, 0xb0160010, + 0xb4200024, 0x82c70000, 0x02dfb017, 0x82c50086, + 0x92d60bb8, 0x82c60086, 0x82c50094, 0x5eefb818, + 0x96f70003, 0xb0170003, 0xb4200002, 0x82e70bb8, + 0xb5000001, 0x82e70bb8, 0x12d6b817, 0x82e50081, + 0x9af70020, 0x82e60081, 0x82c60094, 0xa2f70020, + 0x82e60081, 0x82f30001, 0x16f7b818, 0x5ef0b817, + 0xb0170001, 0xb4000004, 0x96f84000, 0x5ee4b817, + 0x9718f3ff, 0x1b18b817, 0x82f3000a, 0x9af78000, + 0x82e6009d, 0x83060081, 0x83070001, 0x8306009f, + 0xb500009e, 0x82c5009d, 0x82f3000e, 0x9af78001, + 0x3016b817, 0xb420000f, 0x82b30032, 0x9ab58001, + 0x82e500c1, 0x96f7000f, 0xb017000b, 0xb4000002, + 0x82b30022, 0x9ab58001, 0x82c5009a, 0x96d60020, + 0xb0160020, 0xb4200002, 0x82b30032, 0x9ab58001, + 0x82a6009d, 0x82c5009a, 0x96d60080, 0xb0160080, + 0xb4000011, 0x02df9017, 0x00000000, 0xb0160010, + 0xb480000d, 0x82c500c1, 0x96d6000f, 0xb016000b, + 0xb4000009, 0x82c50087, 0x96d60080, 0x5ac7b816, + 0x96f84000, 0x3017b816, 0xb4200003, 0x033f400f, + 0x9b394000, 0xb500000b, 0x9739bfff, 0x82e50061, + 0x96f70008, 0xb0170008, 0xb4000005, 0x5eefb818, + 0x96f70003, 0xb0170003, 0xb4000001, 0x9718ffff, + 0x83060081, 0x83070001, 0x8306009f, 0x00000000, + 0xb5000066, 0x82850083, 0x96b400ff, 0xb015003c, + 0xb4200015, 0x96b92000, 0xb0152000, 0xb4000002, + 0x9b392000, 0xb5000010, 0x9739d3ff, 0x82870000, + 0x82860087, 0x82870008, 0x82860083, 0x8287001f, + 0x828600c9, 0x829bff78, 0x00000000, 0x828600cb, + 0x8285009d, 0x82b3ffff, 0x9ab5fffd, 0x1694b815, + 0x8286009d, 0xb5000000, 0x83070002, 0x8306009f, + 0x00000000, 0xb5000049, 0x96b90800, 0xb0150800, + 0xb4200009, 0x9739f7ff, 0x82a703fd, 0x82a600cb, + 0x82a7003c, 0x82a60083, 0x8285009d, 0x9a940002, + 0x8286009d, 0xb5000004, 0x82850087, 0x5a82b814, + 0xa2940200, 0x82860087, 0xb5000000, 0x83078000, + 0x8306009f, 0x00000000, 0xb5000034, 0x82850086, + 0x82a50094, 0x3015b814, 0xb4800002, 0x86b50bb8, + 0x82a60086, 0x83070008, 0x8306009f, 0x00000000, + 0xb500002a, 0x83050081, 0x82f3001c, 0x9af703ff, + 0x1718b817, 0x9b180140, 0x83060081, 0x83070100, + 0x8306009f, 0x00000000, 0xb5000020, 0x83070000, + 0x83050081, 0x9b180180, 0x83060081, 0x83070400, + 0x8306009f, 0x00000000, 0xb5000018, 0x82870000, + 0x82850082, 0x5eb7b814, 0x96b500fc, 0x96d40006, + 0x5ec1b816, 0x1ab5b816, 0x5aacb815, 0x83050081, + 0x82d3001c, 0x9ad600ff, 0x1718b816, 0x1b18b815, + 0x9b180e00, 0x83060081, 0x83074000, 0x8306009f, + 0x8305009d, 0x82d300ff, 0x9ad6bfff, 0x1718b816, + 0x8306009d, 0x00000000, 0xb5000000, 0x029f9005, + 0x01ffb814, 0x033f600f, 0x029f900a, 0x02bf900b, + 0x02df900c, 0x02ff900d, 0x031f900e, 0x033f900f, + 0x00ffb81e, 0x02ff9010, 0x92f70b43, 0x02ffb010, + 0x02ff90cb, 0x82bbffdc, 0x829bffd8, 0x93150004, + 0x3014b815, 0xb4000010, 0x02dbb818, 0x029bb815, + 0x3017b816, 0xb480000c, 0x5a81b814, 0x029fb010, + 0x82860095, 0x8293001f, 0x9294fe00, 0x92b50008, + 0x3015b814, 0xb4800002, 0x82b3001f, 0x92b5fa00, + 0x82beffdc, 0xb500ffeb, 0x029f9010, 0x83250094, + 0x06d4b819, 0x02d6b816, 0xb016ffff, 0xb4a0000a, + 0x8293000e, 0x9a948001, 0x82c5009d, 0x96d6ffff, + 0x1a94b816, 0x82c5009a, 0x96d60010, 0xb0160010, + 0xb4000001, 0x8286009d, 0x00ffb81c, 0x80070000, + 0x001fb0bf, 0x001f2329, 0x003fb800, 0x001f9006, + 0x5803b800, 0x80338000, 0x1800b801, 0x003fb800, + 0x005f4193, 0x5c41b802, 0x80350000, 0x00000000, + 0x0027b860, 0x80150010, 0x5810b800, 0x80750010, + 0x1863b800, 0x8087ffff, 0x80a7770b, 0x80c70000, + 0x1403b804, 0x3000b805, 0xb4000008, 0x5888b804, + 0x58a8b805, 0x90c60001, 0xb0060003, 0xb4a0fff8, + 0x84420001, 0xb4e0ffee, 0xb5000020, 0xb0060003, + 0xb4200007, 0x80150010, 0x5810b800, 0x81150010, + 0x950800ff, 0xb0080077, 0xb4000001, 0xb500fff4, + 0x001f400e, 0x98000010, 0x98004000, 0x9400fffe, + 0x001f600e, 0x80e70020, 0xb0060000, 0xb400000e, + 0x58e3b806, 0x90210020, 0x81070000, 0x5938b803, + 0x1908b809, 0x9523ff00, 0x5928b809, 0x1908b809, + 0x5d28b803, 0x9529ff00, 0x1908b809, 0x5d38b803, + 0x1908b809, 0x011fb0bf, 0x00ff2329, 0x80137fff, + 0x9800ffe7, 0x1421b800, 0x5c23b801, 0x001f9006, + 0x0441b800, 0x3001b800, 0xb4600002, 0x0440b801, + 0xa4422000, 0x007f90cb, 0x1063b802, 0x007fb0cb, + 0x003fb006, 0x803effec, 0x80470001, 0x005f2013, + 0xb500fbe3, 0x001f400e, 0x9400000f, 0xb0000000, + 0xb4200001, 0x00ffb81f, 0xb0000001, 0xb4000005, + 0xb0000003, 0xb4000003, 0xb0000002, 0xb4000001, + 0x00ffb81f, 0x80070001, 0x001f2013, 0xb500fbd4, + 0x001f9012, 0x001fb100, 0x001f004c, 0x001f2404, + 0x801bfef0, 0x8058fef4, 0x003f9304, 0x007f0c14, + 0x2000b801, 0x2042b803, 0x001fb104, 0x005f2414, + 0x82e70001, 0x83640048, 0x029fb014, 0x829efef0, + 0x8286000f, 0x02bf2054, 0x82bcfef4, 0x82a6000e, + 0x00ffb81a, 0x80e70001, 0x801336e3, 0x9800eb76, + 0x001fb100, 0x800700ab, 0x001f2404, 0x801bc3e8, + 0x8058c3ec, 0x83640024, 0x82e70000, 0x83640036, + 0x029fb300, 0x029fb100, 0x02bf2c04, 0x02bf2404, + 0x801bc000, 0x8058c004, 0x8364001b, 0x82e70000, + 0x8364002d, 0x001f9300, 0x3000b814, 0xb420000a, + 0x001f0c04, 0x3000b815, 0xb4200007, 0x829efef0, + 0x82bcfef4, 0x029fb012, 0x02bf204c, 0x82870001, + 0x829cfef5, 0x00ffb81a, 0xb0070000, 0xb4000007, + 0x80e70000, 0x801399fa, 0x9800c92e, 0x001fb100, + 0x800700af, 0x001f2404, 0xb500ffdc, 0x82870000, + 0x829cfef5, 0x00ffb81a, 0x80c700ff, 0x003f9304, + 0x007f0c14, 0x14a0b806, 0x2063b805, 0x007f2414, + 0x2021b802, 0x58c8b806, 0x14a0b806, 0x58b0b805, + 0x2021b805, 0x58c8b806, 0x14a0b806, 0x2021b805, + 0x58c8b806, 0x14a0b806, 0x5cb0b805, 0x2021b805, + 0x003fb104, 0x00ffb81b, 0x82c70000, 0x83070400, + 0x83270005, 0x8197040c, 0x81d7ffff, 0x8384012a, + 0x83840001, 0x00ffb81b, 0x808f0000, 0x806f001f, + 0x80af001f, 0x80270140, 0x81e74e58, 0x5de2b80f, + 0xb600020a, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, + 0x01cfb80f, 0x01ff90bc, 0x0047b86f, 0xb0020001, + 0xb4c0fffd, 0x91ef0020, 0x90210020, 0x80270180, + 0x81e74d50, 0x5de2b80f, 0xb600020a, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x91ef0020, + 0x90210020, 0x8057ffff, 0x80170430, 0x80070410, + 0x80270408, 0xb6000509, 0x005ff000, 0x90420500, + 0x007ff001, 0x90630600, 0x009ff002, 0x00bff003, + 0x2004a025, 0x90000001, 0x90210001, 0x80070414, + 0x80d7ffff, 0x8097045c, 0x8017043c, 0xb6000404, + 0x005ff000, 0x007f87e0, 0x84000001, 0x2082a7e3, + 0x80970460, 0x80170440, 0x2082b803, 0x007f8000, + 0x2083a004, 0x80170430, 0x80970450, 0x80270408, + 0xb6000508, 0x005f8024, 0x90420500, 0x007ff001, + 0x90630600, 0x009ff002, 0x00bff003, 0x2004a025, + 0x90210001, 0x80170440, 0x00000000, 0x02bf87e0, + 0x80970460, 0x82870000, 0xb6000404, 0x005f87e4, + 0x5a88b814, 0x204287e0, 0x1a94b802, 0x00ffb81c, + 0x001f0a49, 0x001f2709, 0x001f0a41, 0x001f2708, + 0x001f0a46, 0x001f2707, 0x001f0a48, 0x001f2706, + 0x001f0a42, 0x001f2705, 0x001f0a47, 0x001f2704, + 0x001f0a45, 0x001f2703, 0x001f0a43, 0x001f2702, + 0x001f0a40, 0x001f2701, 0x001f0a44, 0x001f2700, + 0x001f0c25, 0xa020000c, 0x94400001, 0x94600002, + 0x94810004, 0x94a10008, 0x94c00010, 0x5943b802, + 0x5861b803, 0x5882b804, 0x5ca2b805, 0x5cc4b806, + 0x194ab803, 0x194ab804, 0x194ab805, 0x194ab806, + 0x015f2738, 0x801b4e50, 0x003f91c1, 0x5c28b801, + 0x005f91c2, 0x5858b802, 0x1821b802, 0x2000b801, + 0x001fb1c4, 0x80184e54, 0x003f0709, 0x2000b801, + 0x001f2714, 0x82c70001, 0x82e70001, 0x83070710, + 0x8327001e, 0x81970735, 0x8384009f, 0x02df0738, + 0x82170a30, 0x838400f1, 0x819efef0, 0x817cfef4, + 0x019fb304, 0x017f2c14, 0x00ffb81b, 0x820f001f, + 0x8018fef8, 0x8057ffff, 0x001f2709, 0x8018fef6, + 0x80d7ffff, 0x001f2708, 0x8018fefa, 0x8157ffff, + 0x001f2707, 0x8018fefd, 0x81d7ffff, 0x001f2706, + 0x8018fefb, 0x802f001f, 0x001f2705, 0x8018fefe, + 0x00000000, 0x001f2704, 0x8018fef9, 0x00000000, + 0x001f2703, 0x8018feff, 0x00000000, 0x001f2702, + 0x8018fef7, 0x00000000, 0x001f2701, 0x8018fefc, + 0x00000000, 0x001f2700, 0x001f0c25, 0xa0200011, + 0x94410001, 0x94600002, 0x94800004, 0x94a00008, + 0x94c10010, 0x5941b802, 0x5861b803, 0x5c82b804, + 0x58a1b805, 0x5cc1b806, 0x194ab803, 0x194ab804, + 0x194ab805, 0x194ab806, 0x015f2738, 0x801b4e50, + 0x003f91c1, 0x5c28b801, 0x005f91c2, 0x5858b802, + 0x1821b802, 0x2000b801, 0x001fb1c4, 0x80184e54, + 0x003f0709, 0x2000b801, 0x001f2714, 0x82c70001, + 0x82e70001, 0x83070710, 0x8327001e, 0x81970735, + 0x83840055, 0x02df0738, 0x82170a20, 0x838400a7, + 0x819efef0, 0x817cfef4, 0x5ac8b80c, 0x02ff0a44, + 0x1ad6b817, 0x02dfb291, 0x5ed8b80c, 0x5968b80b, + 0x1ad6b80b, 0x02df6524, 0x00ffb81b, 0x820f001f, + 0x8018fefe, 0x8057ffff, 0x001f2709, 0x8018fefa, + 0x80d7ffff, 0x001f2708, 0x8018fefc, 0x8157ffff, + 0x001f2707, 0x8018feff, 0x81d7ffff, 0x001f2706, + 0x8018fef8, 0x802f001f, 0x001f2705, 0x8018fefb, + 0x00000000, 0x001f2704, 0x8018fefd, 0x00000000, + 0x001f2703, 0x8018fef6, 0x00000000, 0x001f2702, + 0x8018fef9, 0x00000000, 0x001f2701, 0x8018fef7, + 0x00000000, 0x001f2700, 0x801b4e50, 0x003f91c1, + 0x5c28b801, 0x005f91c2, 0x5858b802, 0x1821b802, + 0x2000b801, 0x001fb1c4, 0x80184e54, 0x003f0709, + 0x2000b801, 0x001f2714, 0x82c70001, 0x82e70001, + 0x83070710, 0x8327001e, 0x81970735, 0x83840016, + 0x83270000, 0x831bfef0, 0x82f8fef4, 0x02c7b819, + 0x82170a28, 0x83840065, 0x300cb818, 0xb4200002, + 0x300bb817, 0xb4000006, 0x93390001, 0xb0190020, + 0xb480fff6, 0x83270000, 0x833cfef5, 0x00ffb81b, + 0x019fb290, 0x017f2a44, 0x033f2c25, 0x83270001, + 0x833cfef5, 0x00ffb81b, 0x0007b818, 0x90000003, + 0x00000000, 0x015ff000, 0x90000001, 0x5949b80a, + 0x013ff000, 0x194ab809, 0x84000002, 0x994a0100, + 0x017ff000, 0x958b00f8, 0x5981b80c, 0x956b0007, + 0x198cb80b, 0x84000002, 0x998c0008, 0x017ff000, + 0x90000001, 0x5971b80b, 0x198cb80b, 0x017ff000, + 0x5969b80b, 0x198cb80b, 0x81a70000, 0x94d90003, + 0x82a70000, 0xb6260019, 0xb6000818, 0x5df0b80a, + 0x5e02b80a, 0x21efb810, 0x95ef0001, 0x5941b80a, + 0x194ab80f, 0x21efb816, 0x5e18b80c, 0x5e35b80c, + 0x5e54b80c, 0x5e6cb80c, 0x2210b811, 0x2252b813, + 0x2210b812, 0x96100001, 0x5981b80c, 0x198cb810, + 0x2210b817, 0x10afb810, 0x10a5b80d, 0x5da1b805, + 0x94a50001, 0x5aa1b815, 0x1ab5b805, 0x019fa7f5, + 0x5cc2b819, 0xb626001c, 0x82870000, 0xb6000419, + 0xb6000818, 0x5df0b80a, 0x5e02b80a, 0x21efb810, + 0x95ef0001, 0x5941b80a, 0x194ab80f, 0x21efb816, + 0x5e18b80c, 0x5e35b80c, 0x5e54b80c, 0x5e6cb80c, + 0x2210b811, 0x2252b813, 0x2210b812, 0x96100001, + 0x5981b80c, 0x198cb810, 0x2210b817, 0x10afb810, + 0x10a5b80d, 0x5da1b805, 0x94a50001, 0x5a81b814, + 0x1a94b805, 0x019fa7f4, 0x00ffb81c, 0x8257ffff, + 0x808f0000, 0x806f001f, 0x80af001f, 0x80270200, + 0x81e74b30, 0x5de2b80f, 0xb600020a, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x91ef0020, + 0x90210020, 0x80270240, 0x81e74c30, 0x5de2b80f, + 0xb600020a, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, + 0x01cfb80f, 0x01ff90bc, 0x0047b86f, 0xb0020001, + 0xb4c0fffd, 0x91ef0020, 0x90210020, 0x80270180, + 0x81e74d50, 0x5de2b80f, 0xb600020a, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x91ef0020, + 0x90210020, 0x806f0007, 0x80af0007, 0x80270280, + 0x81e74d30, 0x5de2b80f, 0x00cfb801, 0x01ffb0bc, + 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, 0x0047b86f, + 0xb0020001, 0xb4c0fffd, 0x91ef0020, 0x90210020, + 0x80170760, 0x001f0700, 0x001fa020, 0x001f0701, + 0x001fa020, 0x001f0702, 0x001fa020, 0x001f0703, + 0x001fa020, 0x001f0704, 0x001fa000, 0x80970750, + 0x81170770, 0x82a70735, 0x83a40060, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a4005c, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750, + 0x81170750, 0x81970740, 0x82a70730, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a40050, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a4004c, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970750, 0x80170770, + 0x81170770, 0x81970760, 0x82a7072b, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a40040, 0x83a4004e, + 0xb6000407, 0x86b50001, 0x83a4003c, 0x001f8004, + 0x003f87e8, 0x2080a001, 0x83a40047, 0x00000000, + 0x80970770, 0x80170750, 0x81170750, 0x81970740, + 0x82a70726, 0x001f800c, 0x003f8008, 0x2100a001, + 0x83a4002e, 0x83a4003c, 0xb6000407, 0x86b50001, + 0x83a4002a, 0x001f8004, 0x003f87e8, 0x2080a001, + 0x83a40035, 0x00000000, 0x80970750, 0x80170770, + 0x81170770, 0x81970760, 0x82a70721, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a4001c, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a40018, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750, + 0x81170750, 0x81970740, 0x82a7071c, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a4000c, 0x017f87e4, + 0x81870000, 0xb6000406, 0x86b50001, 0x83a40007, + 0x001f87e4, 0x200087e8, 0x5988b80c, 0x198cb800, + 0x021fa02c, 0x021fa00b, 0x00ffb81c, 0x005ff015, + 0x90420600, 0x003f87e0, 0x001ff002, 0x2060b801, + 0x90630800, 0x90960a00, 0x001ff003, 0x003ff004, + 0x20a0b801, 0x90a50900, 0x00000000, 0x001ff005, + 0x009fa000, 0x00ffb81d, 0x001f8004, 0x5c21b800, + 0x5847b800, 0x1821b802, 0x942100ff, 0x2080a7e1, + 0x00ffb81d, 0x00000000, 0x00000000, 0x00000000, + 0x829bff80, 0x80af000f, 0x808f0000, 0x806f0000, + 0x82bbffec, 0x82fbffe4, 0x00000000, 0x82beffb8, + 0x95540700, 0x5d48b80a, 0x914a0001, 0x0227b80a, + 0x94343000, 0x5c2cb801, 0xb0010000, 0xb4000001, + 0x5a21b811, 0x9574c000, 0x5d6eb80b, 0x918b4b08, + 0x01b8b80c, 0x96d5ffff, 0x5ec2b816, 0x96f7ffff, + 0x5ee2b817, 0x8057ffff, 0x80d7ffff, 0x8157ffff, + 0x81d7ffff, 0x81f3ff00, 0x99efff00, 0x821300ff, + 0x9a1000ff, 0x81971000, 0x82670000, 0x82470000, + 0x80270280, 0x81df0000, 0x00000000, 0x00000000, + 0xb62d000d, 0x3016b817, 0xb4800001, 0x86d62800, + 0x00cfb801, 0x02dfb0bc, 0x5ac2b816, 0x01cfb816, + 0x02df90bc, 0x0067b86f, 0xb0030001, 0xb4c0fffd, + 0x92d60010, 0x90210010, 0x81df0004, 0x80170a00, + 0x81df0000, 0x00000000, 0x00000000, 0xb62d0006, + 0xb6001005, 0x146f8000, 0x14908000, 0x5c68b803, + 0x5888b804, 0x1803a024, 0x81df0004, 0x80170a00, + 0x80970d00, 0xb00b0000, 0xb4000004, 0xb00b0001, + 0xb400000a, 0xb00b0002, 0xb4000027, 0x81df0000, + 0x00000000, 0x00000000, 0xb6004002, 0x007f8020, + 0x009fa023, 0x81df0004, 0xb5000029, 0x80d3ffff, + 0x81df0000, 0x00000000, 0x00000000, 0xb6001018, + 0x5c648000, 0x9463ffff, 0x5c888020, 0x58b88000, + 0x1884b805, 0x1484b806, 0x1883a024, 0x5c6c8020, + 0x9463ffff, 0x58908000, 0x1883a024, 0x5c748020, + 0x588c8000, 0x1863b804, 0x9463ffff, 0x58888000, + 0x1484b806, 0x1883a024, 0x5c7c8020, 0x58848000, + 0x1863b804, 0x9463ffff, 0x14868020, 0x1883a024, + 0x81df0004, 0xb500000a, 0x80d3ffff, 0x81df0000, + 0x00000000, 0x00000000, 0xb6002004, 0x007f8020, + 0x009fa023, 0x007f8040, 0x009fa023, 0x81df0004, + 0x00000000, 0x81170d00, 0x80070000, 0x94343000, + 0x5c2cb801, 0xb0010001, 0xb4000099, 0xb00a0001, + 0xb400000e, 0xb00a0002, 0xb4000022, 0xb00a0003, + 0xb400002f, 0xb00a0004, 0xb400005d, 0xb00a0005, + 0xb4000066, 0xb00a0006, 0xb400008a, 0xb00a0007, + 0xb4000088, 0xb00a0008, 0xb4000086, 0x81df0000, + 0x00000000, 0x00000000, 0xb6004010, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020, + 0x019fa020, 0x019fa020, 0x019fa020, 0x5c708028, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020, + 0x019fa020, 0x019fa020, 0x019fa020, 0x81df0004, + 0xb5000070, 0x81df0000, 0x00000000, 0x00000000, + 0x8027ffff, 0xb6004008, 0x14618008, 0x019fa023, + 0x019fa020, 0x019fa020, 0x5c708028, 0x019fa023, + 0x019fa020, 0x019fa020, 0x81df0004, 0xb5000061, + 0xb0130000, 0xb4000004, 0xb0130001, 0xb4000009, + 0xb0130002, 0xb400001a, 0x83a40102, 0x80170f00, + 0x007f8028, 0x001fa023, 0x007f8028, 0x001fa023, + 0xb5000054, 0x80170f00, 0x00000000, 0x007f8020, + 0x019fa023, 0x007f8000, 0x9463ffff, 0x019fa023, + 0x019fa020, 0x5c708020, 0x58908008, 0x1983a024, + 0x5c708028, 0x019fa023, 0x019fa020, 0x83a400ed, + 0x80170f00, 0x007f8028, 0x001fa023, 0xb5000041, + 0x80170f00, 0x00000000, 0x007f8020, 0x019fa023, + 0x007f8008, 0x9463ffff, 0x019fa023, 0x019fa020, + 0x5c708028, 0x58908008, 0x1983a024, 0x5c708028, + 0x019fa023, 0x019fa020, 0x83a400da, 0xb5000031, + 0x81df0000, 0x00000000, 0x00000000, 0xb6002005, + 0x007f8008, 0x019fa023, 0x007f8008, 0x019fa023, + 0x019fa020, 0x81df0004, 0xb5000026, 0xb0130000, + 0xb4000008, 0xb0130001, 0xb4000012, 0xb0130002, + 0xb400001f, 0xb0130003, 0xb400001d, 0xb0130004, + 0xb400001b, 0x83a400d5, 0x007f8028, 0x019fa023, + 0x007f8028, 0x019fa023, 0x007f8008, 0x9463ffff, + 0x019fa023, 0x80170f00, 0x007f8028, 0x001fa023, + 0xb5000010, 0x80170f00, 0x00000000, 0x5c708020, + 0x58908008, 0x1983a024, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x83a400bf, + 0x80170f00, 0x007f8028, 0x001fa023, 0xb5000001, + 0xb5000000, 0x00000000, 0x00000000, 0xb500008e, + 0xb00a0001, 0xb400000e, 0xb00a0002, 0xb400001a, + 0xb00a0003, 0xb4000027, 0xb00a0004, 0xb4000055, + 0xb00a0005, 0xb400005e, 0xb00a0006, 0xb4000082, + 0xb00a0007, 0xb4000080, 0xb00a0008, 0xb400007e, + 0x81df0000, 0x00000000, 0x00000000, 0xb6004008, + 0x007f8028, 0x9463ffff, 0x019fa023, 0x019fa020, + 0x019fa020, 0x019fa020, 0x019fa020, 0x019fa020, + 0x81df0004, 0xb5000070, 0x81df0000, 0x00000000, + 0x00000000, 0x8027ffff, 0xb6002008, 0x14618008, + 0x019fa023, 0x019fa020, 0x019fa020, 0x5c708048, + 0x019fa023, 0x019fa020, 0x019fa020, 0x81df0004, + 0xb5000061, 0xb0130000, 0xb4000004, 0xb0130001, + 0xb4000009, 0xb0130002, 0xb400001a, 0x83a40098, + 0x80170f00, 0x007f8028, 0x001fa023, 0x007f8028, + 0x001fa023, 0xb5000054, 0x80170f00, 0x00000000, + 0x007f8020, 0x019fa023, 0x007f8000, 0x9463ffff, + 0x019fa023, 0x019fa020, 0x5c708020, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020, + 0x83a40083, 0x80170f00, 0x007f8028, 0x001fa023, + 0xb5000041, 0x80170f00, 0x00000000, 0x007f8020, + 0x019fa023, 0x007f8008, 0x9463ffff, 0x019fa023, + 0x019fa020, 0x5c708028, 0x58908008, 0x1983a024, + 0x5c708028, 0x019fa023, 0x019fa020, 0x83a40070, + 0xb5000031, 0x81df0000, 0x00000000, 0x00000000, + 0xb6002005, 0x007f8008, 0x019fa023, 0x007f8008, + 0x019fa023, 0x019fa020, 0x81df0004, 0xb5000026, + 0xb0130000, 0xb4000008, 0xb0130001, 0xb4000012, + 0xb0130002, 0xb400001f, 0xb0130003, 0xb400001d, + 0xb0130004, 0xb400001b, 0x83a4006b, 0x007f8028, + 0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x80170f00, 0x007f8028, + 0x001fa023, 0xb5000010, 0x80170f00, 0x00000000, + 0x5c708020, 0x58908008, 0x1983a024, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x83a40055, 0x80170f00, 0x007f8028, 0x001fa023, + 0xb5000001, 0xb5000000, 0x92730001, 0x92520001, + 0x3012b811, 0xb480fe76, 0x003f0324, 0x90210001, + 0xb0010006, 0xb4a00001, 0x80270001, 0x003f2324, + 0x2c8db811, 0x803bffe0, 0x805bffe4, 0x5886b804, + 0x1015b804, 0xad440003, 0x3000b802, 0xb4800001, + 0x8400a000, 0x801effec, 0x015f6193, 0x809e4b04, + 0x00ffb81f, 0x81df0000, 0x00000000, 0x00000000, + 0xb6002a0c, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x019fa020, 0x81df0004, 0x00ffb81d, 0x81df0000, + 0x00000000, 0x00000000, 0xb600190f, 0x007f8028, + 0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x58908008, 0x1983a024, + 0x5c708028, 0x019fa023, 0x81df0004, 0x00ffb81d, + 0x81df0000, 0x00000000, 0x00000000, 0xb6002a0c, + 0x007f8028, 0x019fa023, 0x007f8008, 0x9463ffff, + 0x019fa023, 0x019fa020, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020, + 0x81df0004, 0x00ffb81d, 0x81df0000, 0x00000000, + 0x00000000, 0xb600190f, 0x007f8028, 0x019fa023, + 0x007f8028, 0x019fa023, 0x007f8008, 0x9463ffff, + 0x019fa023, 0x5c708028, 0x58908008, 0x1983a024, + 0x5c708028, 0x58908008, 0x1983a024, 0x5c708028, + 0x019fa023, 0x81df0004, 0x00ffb81d, 0x00000000, + 0x829bff80, 0x80af001f, 0x808f0000, 0x806f0000, + 0x82bbffec, 0x82fbffe4, 0x00000000, 0x82beffb8, + 0x95540700, 0x5d48b80a, 0x914a0001, 0x0227b80a, + 0x94343000, 0x5c2cb801, 0xb0010000, 0xb4000001, + 0x5a21b811, 0x9574c000, 0x5d6eb80b, 0x918b4b08, + 0x01b8b80c, 0x96d5ffff, 0x5ec2b816, 0x96f7ffff, + 0x5ee2b817, 0x8057ffff, 0x80d7ffff, 0x8157ffff, + 0x81d7ffff, 0x81f3ff00, 0x99efff00, 0x821300ff, + 0x9a1000ff, 0x81971000, 0x82670000, 0x82470000, + 0x80270280, 0x81df0000, 0x00000000, 0x00000000, + 0xb62d000d, 0x3016b817, 0xb4800001, 0x86d62800, + 0x00cfb801, 0x02dfb0bc, 0x5ac2b816, 0x01cfb816, + 0x02df90bc, 0x0067b86f, 0xb0030001, 0xb4c0fffd, + 0x92d60020, 0x90210020, 0x81df0004, 0x80170a00, + 0x81df0000, 0x00000000, 0x00000000, 0xb62d0006, + 0xb6002005, 0x146f8000, 0x14908000, 0x5c68b803, + 0x5888b804, 0x1803a024, 0x81df0004, 0x80170a00, + 0x80970d00, 0xb00b0000, 0xb4000004, 0xb00b0001, + 0xb400000a, 0xb00b0002, 0xb4000027, 0x81df0000, + 0x00000000, 0x00000000, 0xb6008002, 0x007f8020, + 0x009fa023, 0x81df0004, 0xb5000029, 0x80d3ffff, + 0x81df0000, 0x00000000, 0x00000000, 0xb6002018, + 0x5c648000, 0x9463ffff, 0x5c888020, 0x58b88000, + 0x1884b805, 0x1484b806, 0x1883a024, 0x5c6c8020, + 0x9463ffff, 0x58908000, 0x1883a024, 0x5c748020, + 0x588c8000, 0x1863b804, 0x9463ffff, 0x58888000, + 0x1484b806, 0x1883a024, 0x5c7c8020, 0x58848000, + 0x1863b804, 0x9463ffff, 0x14868020, 0x1883a024, + 0x81df0004, 0xb500000a, 0x80d3ffff, 0x81df0000, + 0x00000000, 0x00000000, 0xb6004004, 0x007f8020, + 0x009fa023, 0x007f8040, 0x009fa023, 0x81df0004, + 0x00000000, 0x81170d00, 0x80070000, 0x94343000, + 0x5c2cb801, 0xb0010001, 0xb400008e, 0xb00a0001, + 0xb400000e, 0xb00a0002, 0xb400001c, 0xb00a0003, + 0xb4000024, 0xb00a0004, 0xb4000052, 0xb00a0005, + 0xb400005b, 0xb00a0006, 0xb400007f, 0xb00a0007, + 0xb400007d, 0xb00a0008, 0xb400007b, 0x81df0000, + 0x00000000, 0x00000000, 0xb600800a, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020, + 0x5c708028, 0x9463ffff, 0x019fa023, 0x019fa020, + 0x019fa020, 0x81df0004, 0xb500006b, 0x81df0000, + 0x00000000, 0x00000000, 0xb6008004, 0x007f8028, + 0x019fa023, 0x019fa020, 0x019fa020, 0x81df0004, + 0xb5000061, 0xb0130000, 0xb4000004, 0xb0130001, + 0xb4000009, 0xb0130002, 0xb400001a, 0x83a400fa, + 0x80170f00, 0x007f8028, 0x001fa023, 0x007f8028, + 0x001fa023, 0xb5000054, 0x80170f00, 0x00000000, + 0x007f8020, 0x019fa023, 0x007f8000, 0x9463ffff, + 0x019fa023, 0x019fa020, 0x5c708020, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020, + 0x83a400e5, 0x80170f00, 0x007f8028, 0x001fa023, + 0xb5000041, 0x80170f00, 0x00000000, 0x007f8020, + 0x019fa023, 0x007f8008, 0x9463ffff, 0x019fa023, + 0x019fa020, 0x5c708028, 0x58908008, 0x1983a024, + 0x5c708028, 0x019fa023, 0x019fa020, 0x83a400d2, + 0xb5000031, 0x81df0000, 0x00000000, 0x00000000, + 0xb6004005, 0x007f8008, 0x019fa023, 0x007f8008, + 0x019fa023, 0x019fa020, 0x81df0004, 0xb5000026, + 0xb0130000, 0xb4000008, 0xb0130001, 0xb4000012, + 0xb0130002, 0xb400001f, 0xb0130003, 0xb400001d, + 0xb0130004, 0xb400001b, 0x83a400cd, 0x007f8028, + 0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x80170f00, 0x007f8028, + 0x001fa023, 0xb5000010, 0x80170f00, 0x00000000, + 0x5c708020, 0x58908008, 0x1983a024, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x83a400b7, 0x80170f00, 0x007f8028, 0x001fa023, + 0xb5000001, 0xb5000000, 0x00000000, 0x00000000, + 0xb5000086, 0xb00a0001, 0xb400000e, 0xb00a0002, + 0xb4000017, 0xb00a0003, 0xb400001f, 0xb00a0004, + 0xb400004d, 0xb00a0005, 0xb4000056, 0xb00a0006, + 0xb400007a, 0xb00a0007, 0xb4000078, 0xb00a0008, + 0xb4000076, 0x81df0000, 0x00000000, 0x00000000, + 0xb6008005, 0x007f8028, 0x9463ffff, 0x019fa023, + 0x019fa020, 0x019fa020, 0x81df0004, 0xb500006b, + 0x81df0000, 0x00000000, 0x00000000, 0xb6004004, + 0x007f8048, 0x019fa023, 0x019fa020, 0x019fa020, + 0x81df0004, 0xb5000061, 0xb0130000, 0xb4000004, + 0xb0130001, 0xb4000009, 0xb0130002, 0xb400001a, + 0x83a40098, 0x80170f00, 0x007f8028, 0x001fa023, + 0x007f8028, 0x001fa023, 0xb5000054, 0x80170f00, + 0x00000000, 0x007f8020, 0x019fa023, 0x007f8000, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708020, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x019fa020, 0x83a40083, 0x80170f00, 0x007f8028, + 0x001fa023, 0xb5000041, 0x80170f00, 0x00000000, + 0x007f8020, 0x019fa023, 0x007f8008, 0x9463ffff, + 0x019fa023, 0x019fa020, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020, + 0x83a40070, 0xb5000031, 0x81df0000, 0x00000000, + 0x00000000, 0xb6004005, 0x007f8008, 0x019fa023, + 0x007f8008, 0x019fa023, 0x019fa020, 0x81df0004, + 0xb5000026, 0xb0130000, 0xb4000008, 0xb0130001, + 0xb4000012, 0xb0130002, 0xb400001f, 0xb0130003, + 0xb400001d, 0xb0130004, 0xb400001b, 0x83a4006b, + 0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023, + 0x007f8008, 0x9463ffff, 0x019fa023, 0x80170f00, + 0x007f8028, 0x001fa023, 0xb5000010, 0x80170f00, + 0x00000000, 0x5c708020, 0x58908008, 0x1983a024, + 0x5c708028, 0x58908008, 0x1983a024, 0x5c708028, + 0x019fa023, 0x83a40055, 0x80170f00, 0x007f8028, + 0x001fa023, 0xb5000001, 0xb5000000, 0x92730001, + 0x92520001, 0x3012b811, 0xb480fe89, 0x003f0324, + 0x90210001, 0xb0010006, 0xb4a00001, 0x80270001, + 0x003f2324, 0x2c8db811, 0x803bffe0, 0x805bffe4, + 0x5887b804, 0x1015b804, 0xad440003, 0x3000b802, + 0xb4800001, 0x8400a000, 0x801effec, 0x015f6193, + 0x809e4b04, 0x00ffb81f, 0x81df0000, 0x00000000, + 0x00000000, 0xb6002a0c, 0x007f8028, 0x019fa023, + 0x007f8008, 0x9463ffff, 0x019fa023, 0x019fa020, + 0x5c708028, 0x58908008, 0x1983a024, 0x5c708028, + 0x019fa023, 0x019fa020, 0x81df0004, 0x00ffb81d, + 0x81df0000, 0x00000000, 0x00000000, 0xb600190f, + 0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023, + 0x007f8008, 0x9463ffff, 0x019fa023, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x81df0004, + 0x00ffb81d, 0x81df0000, 0x00000000, 0x00000000, + 0xb6002a0c, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x019fa020, 0x81df0004, 0x00ffb81d, 0x81df0000, + 0x00000000, 0x00000000, 0xb600190f, 0x007f8028, + 0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x58908008, 0x1983a024, + 0x5c708028, 0x019fa023, 0x81df0004, 0x00ffb81d, + 0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000, + 0xb4000011, 0x815b4b0c, 0x81070000, 0x81270be8, + 0xb00a0000, 0xb4000002, 0x81070c00, 0x812717e8, + 0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc, + 0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809, + 0xb4a0005d, 0xb5000008, 0xb0040000, 0xb4200003, + 0x802717ff, 0x81470000, 0xb5000003, 0x80270001, + 0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200006, + 0x039f4193, 0x5b81b81c, 0x003f90cb, 0x1021b81c, + 0x003fb0cb, 0x8384f8a3, 0x829bff80, 0x801300e0, + 0x1434b800, 0x5c35b801, 0x8013001f, 0x1454b800, + 0x5c50b802, 0x8073007f, 0x9863ffff, 0xb002000f, + 0xb4800001, 0x90210001, 0x84210004, 0xb0010000, + 0xb4a00001, 0x6861b803, 0x005f9040, 0x4082b803, + 0x80af001f, 0x808f0000, 0x806f0000, 0x8007ffff, + 0x8033ffff, 0x80171000, 0x81df0000, 0x00000000, + 0x00000000, 0xb6001811, 0xb6002010, 0x14618000, + 0x6068b803, 0x40c4b803, 0x14608000, 0x00c8b806, + 0x5870b803, 0x6068b803, 0x4104b803, 0x58c8b806, + 0x0108b808, 0x14c6b801, 0x00000000, 0x00000000, + 0x5d08b808, 0x1508b800, 0x1806a028, 0x81df0004, + 0x80670400, 0x5d22b80a, 0x81df0000, 0x00000000, + 0x00000000, 0xb600180a, 0x00cfb803, 0x013fb0bc, + 0x5922b809, 0x01afb809, 0x013f90bc, 0x0047b86f, + 0xb0020001, 0xb4c0fffd, 0x90630020, 0x91290020, + 0x81df0004, 0x808f0000, 0x803b4b00, 0x00000000, + 0x802600a1, 0x80270001, 0x802600a0, 0x81270c00, + 0xb00a0000, 0xb4000001, 0x81270000, 0x813e4b0c, + 0x80270001, 0x003f2013, 0x00ffb81b, 0x00000000, +}; + +static u32 PCMUcode1f4b00[] = { + 0x00000000, 0x00000000, 0x00060504, 0x00000000, + 0x00000000, 0x00000000, 0x00300000, 0xffcfcfff, + 0x00302000, 0xffcfcfff, 0x00380000, 0xffc7c7ff, + 0xcbcecdc4, 0xcfcac9c8, 0xc3c6c5cc, 0xc7c2c1c0, + 0x1b1e1d14, 0x1f1a1918, 0x1316151c, 0x17121110, + 0x2b2e2d24, 0x2f2a2928, 0x2326252c, 0x27222120, + 0x3b3e3d34, 0x3f3a3938, 0x3336353c, 0x37323130, + 0x0b0e0d04, 0x0f0a0908, 0x0306050c, 0x07020100, + 0xdbdeddd4, 0xdfdad9d8, 0xd3d6d5dc, 0xd7d2d1d0, + 0xebeeede4, 0xefeae9e8, 0xe3e6e5ec, 0xe7e2e1e0, + 0xfbfefdf4, 0xfffaf9f8, 0xf3f6f5fc, 0xf7f2f1f0, + 0x4b4e4d44, 0x4f4a4948, 0x4346454c, 0x47424140, + 0x9b9e9d94, 0x9f9a9998, 0x9396959c, 0x97929190, + 0xabaeada4, 0xafaaa9a8, 0xa3a6a5ac, 0xa7a2a1a0, + 0xbbbebdb4, 0xbfbab9b8, 0xb3b6b5bc, 0xb7b2b1b0, + 0x8b8e8d84, 0x8f8a8988, 0x8386858c, 0x87828180, + 0x5b5e5d54, 0x5f5a5958, 0x5356555c, 0x57525150, + 0x6b6e6d64, 0x6f6a6968, 0x6366656c, 0x67626160, + 0x7b7e7d74, 0x7f7a7978, 0x7376757c, 0x77727170, + 0x341424c4, 0x3e1e2ece, 0x3d1d2dcd, 0x3b1b2bcb, + 0xb494a444, 0xbe9eae4e, 0xbd9dad4d, 0xbb9bab4b, + 0xf4d4e404, 0xfedeee0e, 0xfddded0d, 0xfbdbeb0b, + 0x74546484, 0x7e5e6e8e, 0x7d5d6d8d, 0x7b5b6b8b, + 0x3c1c2ccc, 0x361626c6, 0x351525c5, 0x331323c3, + 0xbc9cac4c, 0xb696a646, 0xb595a545, 0xb393a343, + 0xfcdcec0c, 0xf6d6e606, 0xf5d5e505, 0xf3d3e303, + 0x7c5c6c8c, 0x76566686, 0x75556585, 0x73536383, + 0x381828c8, 0x3a1a2aca, 0x391929c9, 0x3f1f2fcf, + 0xb898a848, 0xba9aaa4a, 0xb999a949, 0xbf9faf4f, + 0xf8d8e808, 0xfadaea0a, 0xf9d9e909, 0xffdfef0f, + 0x78586888, 0x7a5a6a8a, 0x79596989, 0x7f5f6f8f, + 0x301020c0, 0x321222c2, 0x311121c1, 0x371727c7, + 0xb090a040, 0xb292a242, 0xb191a141, 0xb797a747, + 0xf0d0e000, 0xf2d2e202, 0xf1d1e101, 0xf7d7e707, + 0x70506080, 0x72526282, 0x71516181, 0x77576787, + 0x05040100, 0x15141110, 0x25242120, 0x35343130, + 0x85848180, 0x95949190, 0xa5a4a1a0, 0xb5b4b1b0, + 0xc0408000, 0xe060a020, 0xd0509010, 0xf070b030, + 0xc8488808, 0xe868a828, 0xd8589818, 0xf878b838, + 0xc4448404, 0xe464a424, 0xd4549414, 0xf474b434, + 0xcc4c8c0c, 0xec6cac2c, 0xdc5c9c1c, 0xfc7cbc3c, + 0xc2428202, 0xe262a222, 0xd2529212, 0xf272b232, + 0xca4a8a0a, 0xea6aaa2a, 0xda5a9a1a, 0xfa7aba3a, + 0xc6468606, 0xe666a626, 0xd6569616, 0xf676b636, + 0xce4e8e0e, 0xee6eae2e, 0xde5e9e1e, 0xfe7ebe3e, + 0xc1418101, 0xe161a121, 0xd1519111, 0xf171b131, + 0xc9498909, 0xe969a929, 0xd9599919, 0xf979b939, + 0xc5458505, 0xe565a525, 0xd5559515, 0xf575b535, + 0xcd4d8d0d, 0xed6dad2d, 0xdd5d9d1d, 0xfd7dbd3d, + 0xc3438303, 0xe363a323, 0xd3539313, 0xf373b333, + 0xcb4b8b0b, 0xeb6bab2b, 0xdb5b9b1b, 0xfb7bbb3b, + 0xc7478707, 0xe767a727, 0xd7579717, 0xf777b737, + 0xcf4f8f0f, 0xef6faf2f, 0xdf5f9f1f, 0xff7fbf3f, + 0x1045a3e2, 0x000000f4, 0x263b7333, 0x766b2363, + 0x2b367e3e, 0x7b662e6e, 0x06db93d3, 0x964b0343, + 0x0bd69ede, 0x9b460e4e, 0x825f1757, 0x12cf87c7, + 0x8f521a5a, 0x1fc28aca, 0x00d199d9, 0x90410949, + 0x01d098d8, 0x91400848, 0x24357d3d, 0x74652d6d, + 0x25347c3c, 0x75642c6c, 0x04d59ddd, 0x94450d4d, + 0x05d49cdc, 0x95440c4c, 0x80511959, 0x10c189c9, + 0x81501858, 0x11c088c8, 0x02df97d7, 0x924f0747, + 0x0fd29ada, 0x9f420a4a, 0x865b1353, 0x16cb83c3, + 0x8b561e5e, 0x1bc68ece, 0xa6bbf3b3, 0xf6eba3e3, + 0xabb6febe, 0xfbe6aeee, 0x223f7737, 0x726f2767, + 0x2f327a3a, 0x7f622a6a, 0xa0b1f9b9, 0xf0e1a9e9, + 0xa1b0f8b8, 0xf1e0a8e8, 0x84551d5d, 0x14c58dcd, + 0x85541c5c, 0x15c48ccc, 0xa4b5fdbd, 0xf4e5aded, + 0xa5b4fcbc, 0xf5e4acec, 0x20317939, 0x70612969, + 0x21307838, 0x71602868, 0xa2bff7b7, 0xf2efa7e7, + 0xafb2faba, 0xffe2aaea, 0x00000000, 0x00000000, +}; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/mpg.h linux.19pre5-ac1/drivers/media/video/ls220/mpg.h --- linux.19p5/drivers/media/video/ls220/mpg.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/ls220/mpg.h Thu Feb 21 21:27:25 2002 @@ -0,0 +1,1612 @@ +static u32 MPGUcode1f1800[] = { +0x820f001f,0x802f001f,0x81df0000,0xb500000c, +0x00ffb81e,0x00000000,0x00000000,0x00000000, +0x00ffb81e,0x00000000,0x00000000,0x00000000, +0xb5000c13,0x00000000,0x00000000,0x00000000, +0x80070800,0x001f6047,0x8013001f,0x90208000, +0x003fb174,0x803effe8,0x803effec,0x9020fa00, +0x803effd0,0x803effdc,0x803effd8,0x9020fe00, +0x803effd4,0x805bff7c,0x802500d4,0x94020080, +0xb0000000,0xb4200023,0x8013ffcf,0x9800cfff, +0x80730030,0x98631000,0x94420007,0xb0020002, +0xb4200005,0x8013ffc7,0x9800c7ff,0x80730038, +0x98631000,0xb5000006,0xb0020001,0xb4200004, +0x8013ffcf,0x9800cfff,0x80730030,0x98631000, +0x1421b800,0x1821b803,0x802600d4,0x8033001f, +0x98210000,0x802600a2,0x8033001f,0x98210300, +0x802600a3,0x80270225,0x80530001,0x98420100, +0x1821b802,0x80530200,0x98420000,0x804600a6, +0xb500001d,0x805bff7c,0x8013ffcf,0x9800cfff, +0x80730030,0x98631000,0x94420007,0xb0020002, +0xb4200005,0x8013ffc7,0x9800c7ff,0x80730038, +0x98631000,0xb5000006,0xb0020001,0xb4200004, +0x8013ffcf,0x9800cfff,0x80730030,0x98631000, +0x1421b800,0x1821b803,0x802600d4,0x8033001f, +0x98210000,0x802600a2,0x8033001f,0x98210300, +0x802600a3,0x80270c25,0x802600a1,0x80270002, +0x803eff84,0x80070000,0x801effc0,0x801effc4, +0x801effc8,0x801effcc,0x801eff88,0x80770000, +0x8057ffff,0x80170080,0x80070000,0xb6003f02, +0xb6002001,0x001fa020,0x8007ffff,0x801eff84, +0x80070001,0x001f25dc,0x001f20b1,0x80070000, +0x001f6046,0x001fb17c,0x001fb17d,0x80070000, +0x801e78d0,0x98004000,0x001f62ea,0x80070100, +0x801efff0,0x81df0004,0x00000000,0x00000000, +0x801bfff0,0x00000000,0x940000ff,0xb0000000, +0xb420005b,0x003f42ea,0x94010010,0xb0000000, +0xb400fff7,0x003f05dc,0xb0010001,0xb4200034, +0x803bffe8,0x801bffec,0x00000000,0x3001b800, +0xb4600001,0x90214000,0x0421b800,0xb0010800, +0xb460000d,0x80050086,0x005f902e,0xb0020000, +0xb4200002,0x001fb02e,0xb5000006,0x0420b802, +0xb0010930,0xb4a0ffe2,0x80070000,0x001fb02e, +0x83e40162,0xb500ffde,0x83e40129,0x80070000, +0x001fb02e,0x001f42ea,0x9400000f,0xb0000000, +0xb4000010,0x9400fff0,0x001f62ea,0x003f9174, +0x9421ffff,0x90210004,0xb001c000,0xb4800002, +0x8421c000,0x90218000,0x8013001f,0x1821b800, +0x003fb174,0x003f917c,0x90210004,0x003fb17c, +0x83e4014a,0x8013001f,0x83e71b0c,0x1bffb800, +0x003f9179,0x1821b800,0x00ffb801,0xb5000008, +0x80270000,0x003f25dc,0x8013001f,0x83e71b30, +0x1bffb800,0x003f917a,0x1821b800,0x00ffb801, +0x80070000,0x001f20b1,0x001f42ea,0x9420000f, +0xb0010000,0xb4200003,0x98000800,0x001f62ea, +0xb500ffaf,0x9400fff0,0x001f62ea,0x80270000, +0x8057ffff,0x80770000,0x80171800,0x81df0000, +0x00000000,0x00000000,0xb6000302,0xb6002001, +0x001fa021,0x81df0004,0xb500ffa1,0xb500ffa0, +0x803bffc0,0x805bffc4,0x807bffc8,0x809bffcc, +0x5828b801,0x5cb8b802,0x1821b805,0x5848b802, +0x5cb8b803,0x1842b805,0x5868b803,0x5cb8b804, +0x1863b805,0x5888b804,0x1884b800,0x803effc0, +0x805effc4,0x807effc8,0x809effcc,0x003f42ea, +0xb0000086,0xb4400079,0xb0000084,0xb4000049, +0xb0000085,0xb4000063,0xb0000086,0xb400006c, +0xb0000081,0xb4000005,0xb0000082,0xb4000003, +0xb0000080,0xb4000001,0xb5000069,0x8013007f, +0x9800ffff,0x001fb02d,0x80070000,0x001fb17c, +0x8013001f,0x9040fa00,0x805effd0,0x805effdc, +0x805effd8,0x9040fe00,0x805effd4,0x9040c000, +0x805effe4,0x90008000,0x801effe0,0x001fb174, +0x801effe8,0x801effec,0x80078000,0x801e78d4, +0x80070000,0x001fb17c,0x001fb17d,0x001fb02e, +0x83e400e6,0x8013001f,0x98000000,0x800600a2, +0x8013001f,0x98000300,0x800600a3,0x805bff7c, +0x80070c25,0x94420080,0xb0020080,0xb420000d, +0x8013001f,0x98000000,0x800600a2,0x8013001f, +0x98000300,0x800600a3,0x80070225,0x80530001, +0x98420100,0x1800b802,0x80530200,0x98420000, +0x804600a6,0x800600a1,0x80050080,0x98000022, +0x80060080,0x80072080,0x001fb179,0x80074618, +0x001fb17a,0x80070001,0x001f25dc,0x98214000, +0xb5000029,0x8047ffff,0x805eff84,0x805bff88, +0x00000000,0xb0020001,0xb4200002,0x80470000, +0x805eff88,0x805bff7c,0x80070c25,0x94420080, +0xb0020080,0xb4200007,0x80070225,0x80530001, +0x98420100,0x1800b802,0x80530200,0x98420000, +0x804600a6,0x800600a1,0x80070001,0x800600a0, +0x9421efff,0x98210010,0xb500000f,0x80070000, +0x001fb17c,0x80070001,0x001f25dc,0x83e400a3, +0x80050081,0x80330008,0x98210000,0x1800b801, +0x80060081,0x003f42ea,0x9421ffef,0xb5000002, +0x98211000,0x9421ffef,0x83e40098,0x003f62ea, +0x80070100,0x801efff0,0xb500ff11,0xb000008b, +0xb400001c,0xb0000087,0xb400ffe8,0xb0000088, +0xb4000023,0xb000008a,0xb4000024,0xb000008c, +0xb4000019,0xb000008e,0xb4000014,0xb000008d, +0xb400001d,0xb0000089,0xb400001f,0xb00000a0, +0xb4000021,0xb00000a1,0xb4000022,0xb00000a2, +0xb400002f,0xb00000a3,0xb4000027,0xb00000a4, +0xb4000031,0xb00000a5,0xb4000035,0xb00000a6, +0xb4000039,0x803efff8,0xb500ffdd,0x80070000, +0x001fb17e,0xb500ffda,0x803bffb0,0x00000000, +0x003fb02d,0xb500ffd6,0x98210020,0xb500ffd2, +0x9421ffdf,0xb500ffd0,0xb500ffd1,0x80270341, +0x803efff8,0xb500ffce,0x803bff80,0x00000000, +0x003f62ef,0xb500ffca,0x003f917b,0x803efff8, +0xb500ffc7,0x80270000,0x8047fef0,0x003eb802, +0x90420004,0x003eb802,0x90420004,0x003eb802, +0x90420004,0x003eb802,0x81df0000,0x00000000, +0x00000000,0x83640dbd,0x81df0004,0xb500ffb8, +0x81df0000,0x00000000,0x00000000,0x83640d67, +0x81df0004,0xb500ffb2,0x81df0000,0x00000000, +0x00000000,0x83640d22,0x81df0004,0xb500ffac, +0x81df0000,0x00000000,0x00000000,0x83440c85, +0x81df0004,0xb500ffa6,0x81df0000,0x00000000, +0x00000000,0x83440c6a,0x81df0004,0xb500ffa0, +0x817bffe8,0x815b78d4,0x00000000,0x956bffff, +0x300bb80a,0xb4600001,0x916b4000,0x056bb80a, +0xb00b0080,0xb4a0002a,0x80af001f,0x808f0000, +0x806f0000,0x81b300ff,0x8057ffff,0x5d67b80b, +0x5d42b80a,0x81df0000,0x00000000,0x00000000, +0xb62b001c,0xb00a3000,0xb4800001,0x854a1000, +0x80cf0400,0x015fb178,0x5942b80a,0x01cfb80a, +0x015f9178,0xb520ffff,0x80171000,0xb600200a, +0x01ff8000,0x5a18b80f,0x5a28b80f,0x1631b80d, +0x5e48b80f,0x9652ff00,0x5e78b80f,0x1a73b810, +0x1a73b811,0x1813a032,0x80cf0400,0x015fb178, +0x5942b80a,0x01afb80a,0x015f9178,0xb520ffff, +0x914a0020,0x81df0004,0x5942b80a,0x815e78d4, +0x00000000,0x00000000,0x00ffb81f,0x81df0000, +0x80070000,0x80470000,0x81171800,0xb6002003, +0xb6003002,0x001eb802,0x90420004,0xb6002003, +0x011fa020,0x011fa020,0x011fa020,0x81df0004, +0x00ffb81f,0x80070000,0x80478000,0x81df0000, +0x00000000,0x00000000,0xb6002003,0xb6008002, +0x001eb802,0x90420004,0x81df0004,0x00ffb81f, +0x015f42ea,0x944a4000,0xb0024000,0xb4200081, +0x954abfff,0x015f62ea,0x808f0000,0x80ef007c, +0x80171000,0x80971400,0x80270000,0xb6001003, +0xb6002002,0x001fa021,0x009fa021,0x80a76604, +0x80271400,0x81df0000,0x00000000,0x00000000, +0xb6001004,0x01efb801,0x01afb805,0xb520ffff, +0x90a50080,0x81df0004,0x80a76e04,0x80271400, +0x81df0000,0x00000000,0x00000000,0xb6001004, +0x01efb801,0x01afb805,0xb520ffff,0x90a50080, +0x81df0004,0x806f001f,0x80af001f,0x80276400, +0x5c22b801,0x806701e1,0x00cfb803,0x003fb178, +0x5822b801,0x01cfb801,0x003f9178,0x0047b86f, +0xb0020001,0xb4c0fffd,0x80275c00,0x5c22b801, +0x80670200,0x81df0000,0x00000000,0x00000000, +0xb600100a,0x00cfb803,0x003fb178,0x5822b801, +0x01cfb801,0x003f9178,0x0047b86f,0xb0020001, +0xb4c0fffd,0x90210020,0x90630020,0x81df0004, +0x808f0000,0x806f001f,0x80af001f,0x8027647c, +0x5c22b801,0x8067017e,0x81df0000,0x00000000, +0x00000000,0xb600020a,0x00cfb803,0x003fb178, +0x5822b801,0x01cfb801,0x003f9178,0x0047b86f, +0xb0020001,0xb4c0fffd,0x90210020,0x90630020, +0x81df0004,0x806f0010,0x80af0010,0x8027657c, +0x5c22b801,0x806701be,0x00cfb803,0x003fb178, +0x5822b801,0x01cfb801,0x003f9178,0x0047b86f, +0xb0020001,0xb4c0fffd,0x802765c0,0x5c22b801, +0x806701cf,0x00cfb803,0x003fb178,0x5822b801, +0x01cfb801,0x003f9178,0x0047b86f,0xb0020001, +0xb4c0fffd,0x80276000,0x005fb801,0x8033001f, +0x98218000,0x803effe0,0x90214000,0x803effe4, +0x8193001f,0x998c8000,0x019fb174,0x83270000, +0x003fb819,0x003f9174,0x5823b801,0x83338000, +0x1b39b801,0x003fb819,0x00000000,0x00000000, +0x81550000,0x0187b860,0x858c0040,0x81b380fc, +0x99ad0000,0x300cb80d,0xb4600003,0x81b30002, +0x99ad0000,0x118cb80d,0x003fb80c,0x00000000, +0x00000000,0x81550000,0x8257ffff,0x82d7ffff, +0x8357ffff,0x81672000,0x83440191,0xb00a0001, +0xb4000141,0x0187b860,0x858c0010,0x5988b80c, +0x5d8bb80c,0x958cffff,0xb00cc000,0xb4800002, +0x858cc000,0x918c8000,0x81b3001f,0x198cb80d, +0x801bffec,0x00000000,0x819effec,0x819e78d8, +0x019fb174,0x05acb800,0x300cb800,0xb4600001, +0x91ad4000,0x001f917c,0x1000b80d,0x001fb17c, +0x8344019c,0xb00a0000,0xb4200127,0x015f0081, +0xb00a0002,0xb4200124,0x037f0082,0xb01b0000, +0xb400001e,0x0367b860,0x5b68b81b,0x5f68b81b, +0x017f4047,0x916b0010,0x5963b80b,0x83440168, +0x801bff84,0xb00a0001,0xb400000b,0xb00b00c0, +0xb460fffa,0x803f0000,0x80138000,0x1b7bb800, +0x003fb81b,0x00000000,0x00000000,0x80150000, +0x801bff84,0xb5000009,0x803f0000,0x80138000, +0x1b7bb800,0x003fb81b,0x00000000,0x00000000, +0x80150000,0x801bff84,0xb5000103,0x801bff84, +0x003f0084,0x3000b801,0x803eff84,0xb4000073, +0x801bff7c,0x00000000,0x94800080,0xb0040080, +0xb4200036,0x94800007,0x80730200,0xb0010002, +0xb420000e,0x80270265,0xb0040001,0xb4200003, +0x80130030,0x98000000,0xb5000006,0x80130030, +0x98000000,0xb0040000,0xb4000002,0x80130038, +0x98000000,0x98630060,0xb500001f,0xb0010000, +0xb420000e,0x80270225,0xb0040001,0xb4200003, +0x80130030,0x98001000,0xb5000006,0x80130030, +0x98001000,0xb0040000,0xb4000002,0x80130038, +0x98001000,0x98630000,0xb500000f,0xb0010001, +0xb420004a,0x80270225,0xb0040001,0xb4200003, +0x80130030,0x98002000,0xb5000006,0x80130030, +0x98000000,0xb0040000,0xb4000002,0x80130038, +0x98000000,0x98630040,0x806600a6,0x80530001, +0x98420100,0x1821b802,0xb500002d,0x94800007, +0xb0010002,0xb420000d,0x80270c65,0xb0040001, +0xb4200003,0x80130030,0x98000000,0xb5000006, +0x80130030,0x98000000,0xb0040000,0xb4000002, +0x80130038,0x98000000,0xb500001d,0xb0010000, +0xb420000d,0x80270c25,0xb0040001,0xb4200003, +0x80130030,0x98001000,0xb5000006,0x80130030, +0x98001000,0xb0040000,0xb4000002,0x80130038, +0x98001000,0xb500000e,0xb0010001,0xb4200017, +0x80270c25,0xb0040001,0xb4200003,0x80130030, +0x98002000,0xb5000006,0x80130030,0x98000000, +0xb0040000,0xb4000002,0x80130038,0x98000000, +0x806500d4,0x8053ffcf,0x9842cfff,0xb0040002, +0xb4200002,0x8053ffc7,0x9842c7ff,0x802600a1, +0x1463b802,0x1863b800,0x806600d4,0x807bff7c, +0x00000000,0x94630080,0xb0030080,0xb420000b, +0x807bff88,0x00000000,0xb0030001,0xb4000007, +0x802500a1,0x80670001,0x807eff88,0x80530001, +0x98420100,0x1821b802,0x802600a1,0x81070000, +0x011f62e2,0x011f62e3,0x011f0082,0xb0080000, +0xb4200004,0x81150010,0x00000000,0x00000000, +0x011f62de,0x011f0081,0xb0080001,0xb4200026, +0x81070020,0x011f25c1,0x81070180,0x011f62e1, +0x8344023e,0x8344026a,0x011f0082,0xb0080000, +0xb4200004,0x834401bd,0x834401aa,0xb00a0000, +0xb4200061,0x80c70000,0x00df25cb,0x83440281, +0x8344064f,0x02ff05b9,0x82a70000,0x82870000, +0x83440407,0x92940001,0x3014b817,0xb480fffc, +0x834406ef,0x80270000,0x003f25dc,0x834407de, +0x003f05dc,0xb0010001,0xb4000003,0x80272694, +0x003fb17a,0x00ffb81f,0x80d3001f,0x8347266c, +0x1b5ab806,0xb500002d,0xb0080002,0x81470004, +0xb4200045,0x81070008,0x011f25c1,0x81070480, +0x011f62e1,0x8344029e,0x834402dc,0x011f0082, +0xb0080000,0xb4200004,0x834401aa,0x83440181, +0xb00a0000,0xb4200038,0x80c70000,0x00df25cb, +0x83440368,0x02df05cb,0x5ec2b816,0x8344066b, +0x02ff05b9,0x82a70000,0x82870000,0x834403dc, +0x92940001,0x3014b817,0xb480fffc,0x92b50001, +0xb0150003,0xb480fff8,0x834406c1,0x80270000, +0x003f25dc,0x834407b0,0x003f05dc,0xb0010001, +0xb4000003,0x8027274c,0x003fb17a,0x00ffb81f, +0x80d3001f,0x83472710,0x1b5ab806,0x80db78d8, +0x80fbffec,0x00000000,0x3006b807,0xb4200007, +0x00df05cb,0x90c60001,0x00df25cb,0xb006000c, +0xb4000002,0x035fb179,0x00ffb81f,0x80c70000, +0x00df25cb,0x80fb78dc,0x00000000,0x90e70001, +0xb00701b9,0xb4a00001,0x80e70001,0x80fe78dc, +0xb500feb0,0x802500a5,0x8153001f,0x3001b80a, +0xb420fffc,0x00ffb81f,0x001f42ea,0x1800b80a, +0x001f62ea,0x017f4047,0x5963b80b,0x0187b860, +0x118cb80b,0x81b380fe,0x99ad0000,0x300cb80d, +0xb4800003,0x81b30002,0x99ad0000,0x058cb80d, +0x003fb80c,0x00000000,0x00000000,0x81550000, +0x0187b860,0x5988b80c,0x5d8bb80c,0x958cffff, +0xb00cc000,0xb4800002,0x858cc000,0x918c8000, +0x81b3001f,0x198cb80d,0x801bffec,0x00000000, +0x819effec,0x019fb174,0x05acb800,0x300cb800, +0xb4600001,0x91ad4000,0x001f917c,0x1000b80d, +0x001fb17c,0x80171000,0x80971400,0x80270000, +0xb6001003,0xb6002002,0x001fa021,0x009fa021, +0x80171800,0xb6000602,0xb6002001,0x001fa021, +0x806f001f,0x80af001f,0x80a76604,0x80271400, +0x81df0000,0x00000000,0x00000000,0xb6001004, +0x01efb801,0x01afb805,0xb520ffff,0x90a50080, +0x81df0004,0x80a76e04,0x80271400,0x81df0000, +0x00000000,0x00000000,0xb6001004,0x01efb801, +0x01afb805,0xb520ffff,0x90a50080,0x81df0004, +0x81472080,0x015fb179,0x00ffb81f,0x00000000, +0x811be024,0x0107b860,0x95080007,0xb0080000, +0xb4000004,0xa5080008,0x00000000,0x0155b808, +0x00000000,0x8115000c,0x856b000c,0xb0080fff, +0xb400000b,0x81550004,0x856b0004,0x5904b808, +0x1908b80a,0x95080fff,0xb0080fff,0xb4000004, +0x81470001,0xb00b0020,0xb440fff6,0xb500000c, +0x81d50004,0x856b0004,0x00000000,0xb00e000f, +0xb400fffb,0x940b0007,0xb0000000,0xb420ffed, +0x001f42ea,0x9400fffe,0x81470000,0x001f62ea, +0x00ffb81a,0x950e0008,0x5d03b808,0x00000000, +0xb0080000,0xb40000cd,0x011f2080,0x950e0006, +0x5d01b808,0x81270004,0x0529b808,0x950e0001, +0x013f2081,0x011f2082,0x81150004,0x00000000, +0xb0080000,0xb40000c1,0xb008000f,0xb40000bf, +0x011f2083,0x81150002,0x00000000,0x81670004, +0xb0080002,0xb46000b9,0x011f2084,0x013f0081, +0xb0090002,0xb4200011,0x013f0083,0xb0080000, +0xb4200002,0x81077844,0xb5000005,0xb0080001, +0xb4200002,0x81077884,0xb5000001,0x81077824, +0x013f0083,0x5921b809,0x1129b808,0x0119b809, +0x00000000,0x00000000,0x011f6047,0x81150001, +0x00000000,0x011f2085,0x81150001,0x00000000, +0x011f2086,0x81350002,0x00000000,0x013f2087, +0x81150002,0x00000000,0x011f2088,0x81150001, +0x00000000,0x011f2089,0x81150001,0x00000000, +0x011f208a,0x81150002,0x00000000,0x011f208b, +0x81070001,0xb0090003,0xb4000001,0x81070002, +0x011f25b9,0x81070020,0x013f0081,0xb0090002, +0xb4200069,0x85290001,0xad29000f,0x00000000, +0x011f0083,0x1108b809,0x5901b808,0x910877c8, +0x0139b808,0x011f05b9,0x85080001,0x6928b809, +0x011f0084,0xb0090038,0xb4800007,0xb0080001, +0xb4000002,0xb0090050,0xb4400003,0x81270000, +0x8107001b,0xb5000010,0xb0080001,0xb4000005, +0xb0090060,0xb4800003,0x81270001,0x8107001e, +0xb5000009,0xb0080002,0xb4000005,0xb0090030, +0xb4400003,0x81270002,0x81070008,0xb5000002, +0x81270003,0x8107000c,0x011f25bb,0x013f25c0, +0xb0090002,0xb460001b,0x80477604,0x5c42b802, +0x814fffc0,0x80cf0037,0x005fb178,0x5842b802, +0x01cfb802,0x005f9178,0xb520ffff,0x90420020, +0x814fb580,0x80cf0057,0x005fb178,0x5842b802, +0x01cfb802,0x005f9178,0xb520ffff,0x804778a4, +0x5c42b802,0x814f39c0,0x80cf002f,0x005fb178, +0x5842b802,0x01cfb802,0x005f9178,0xb520ffff, +0xb5000025,0x804776e0,0x5c42b802,0x814fef40, +0x80cf0037,0x005fb178,0x5842b802,0x01cfb802, +0x005f9178,0xb520ffff,0x8297013c,0x8317018c, +0x81df0000,0x00000000,0x00000000,0xb6000602, +0x005f8034,0x031fa022,0x82970124,0x83170160, +0xb6000602,0x005f8034,0x031fa022,0x8297010c, +0x83170134,0xb6000602,0x005f8034,0x031fa022, +0x81df0004,0x804778c4,0x5c42b802,0x814f1080, +0x80cf002f,0x005fb178,0x5842b802,0x01cfb802, +0x005f9178,0xb520ffff,0x013f0081,0xb0090001, +0xb420000e,0x808f0000,0x806f001b,0x80af001b, +0x80277758,0x5c22b801,0x80670037,0x00cfb803, +0x003fb178,0x5822b801,0x01cfb801,0x003f9178, +0x0047b86f,0xb0020001,0xb4c0fffd,0x011f25bb, +0x011f0087,0xb0080001,0xb4000002,0x011f05bb, +0xb5000003,0x011f0088,0x91080001,0x5902b808, +0x011f25ba,0x81470000,0x00ffb81a,0x81470008, +0x00ffb81a,0x81270000,0x81470000,0x300842de, +0xb400000b,0x013f42e2,0x91290001,0x013f62e2, +0x013f42e3,0x91290001,0x013f62e3,0x83640006, +0x00000000,0x00000000,0x013f42e2,0x81470002, +0x013f62e2,0x00ffb81a,0x00ffb81b,0x83640049, +0x80c70004,0x80270000,0x81df0000,0x00000000, +0x00000000,0xb600200d,0x00ff05b9,0x5c42b801, +0x300205ba,0xb4800001,0x80e70001,0x80470000, +0xb6270005,0x1062b801,0x914301b8,0x00fff00a, +0x83840055,0x90420080,0x90210004,0x81df0004, +0x00ffb81a,0x83640033,0x017f05bb,0x800700bc, +0x80270000,0x81df0000,0xb00b0000,0xb4000015, +0xb62b0014,0x00ff05b9,0x5c42b801,0x300205ba, +0xb4800001,0x80e70001,0x80470000,0xb0070000, +0xb400000b,0xb627000a,0x1062b801,0x914301b8, +0x00fff00a,0x5c62b801,0x1063b800,0x00bff003, +0x90650134,0x00dff003,0x83840037,0x90420080, +0x90210004,0x81df0004,0x019f05b9,0x80c70002, +0x80270000,0x81df0000,0xb00b0000,0xb400000f, +0xb62b000e,0x80470000,0xb00c0000,0xb400000a, +0xb62c0009,0x1062b801,0x914301b8,0x00fff00a, +0xb0070000,0xb4000003,0x906302b8,0x00fff003, +0x83840021,0x90420080,0x90210004,0x81df0004, +0x00ffb81a,0x8107ffff,0x80c70004,0x00ff0083, +0x83840019,0x80c70002,0x00ff0084,0x83840016, +0x80c70001,0x00ff0085,0x83840013,0x80c70001, +0x00ff0086,0x83840010,0x80c70002,0x00ff0087, +0x8384000d,0x80c70002,0x00ff0088,0x8384000a, +0x80c70001,0x00ff0089,0x83840007,0x80c70001, +0x00ff008a,0x83840004,0x80c70002,0x00ff008b, +0x83840001,0x00ffb81b,0x80a70001,0x64a6b805, +0x5ca1b805,0xb0050000,0xb400000e,0x95288000, +0xb0090000,0xb4000001,0x81270001,0x5901b808, +0x1547b805,0xb00a0000,0xb4000001,0x81470001, +0x2129b80a,0xb0090000,0xb4000001,0xa1088005, +0xb500ffef,0x9508ffff,0x00ffb81c,0x015f05ba, +0x013f05b9,0x800700bc,0xb0090000,0xb4000012, +0xb00a0000,0xb4000010,0x80270000,0x81df0000, +0x00000000,0x00000000,0xb62a000b,0x80470000, +0xb6290008,0x80950004,0x5865b802,0x1063b801, +0x5862b803,0x906301b8,0x0217b803,0x90420001, +0x021fa004,0x90210001,0x81df0004,0xa54a0020, +0xb4c00011,0xb0090000,0xb400000f,0x81df0000, +0x00000000,0x00000000,0xb62a000b,0x80950004, +0x80470000,0xb6290007,0x5865b802,0x1063b801, +0x5862b803,0x906301b8,0x0217b803,0x90420001, +0x021fa004,0x90210001,0x81df0004,0x00ffb81a, +0x013f05b9,0xb0090000,0xb400001c,0x80270000, +0x81df0000,0x00000000,0x00000000,0xb6002017, +0x80470000,0xb6290014,0x5865b802,0x1063b801, +0x5862b803,0x914301b8,0x009ff00a,0xad420060, +0x00000000,0x114ab801,0x5942b80a,0x914a1c80, +0x0217b80a,0xb0040000,0xb4000004,0x80950006, +0x00000000,0x021fa004,0xb5000002,0x8087003f, +0x021fa004,0x90420001,0x90210001,0x81df0004, +0x00ffb81a,0x8257ffff,0x82d7ffff,0x011f05ba, +0x013f05b9,0x80270000,0xb0090000,0xb4000033, +0x81df0000,0x00000000,0x00000000,0xb6280015, +0x80470000,0xb6290012,0x5865b802,0x1063b801, +0x5862b803,0x914301b8,0xaca20060,0x009ff00a, +0x10a5b801,0x58a2b805,0x90a502b8,0x0217b805, +0x80670000,0xb0040000,0xb4000003,0x90840001, +0x0075b804,0x00000000,0x021fa003,0x90420001, +0x90210001,0x81df0004,0xa5480020,0xb4000017, +0x5822b801,0x81df0000,0x00000000,0x00000000, +0xb62a0011,0x914101b8,0x90a102b8,0x0217b805, +0x009ff00a,0xb0040000,0x80670000,0xb4000002, +0x90840001,0x0075b804,0xb6290006,0x021fa203, +0x009f8210,0x009f8210,0x009f8210,0x009f8210, +0x009f8210,0x90210004,0x81df0004,0x00ffb81a, +0x015f05ba,0x013f05b9,0x800700bc,0xb0090000, +0xb4000016,0xb00a0000,0xb4000014,0x80270000, +0x81df0000,0x00000000,0x00000000,0xb62a000f, +0x80470000,0xb629000c,0x1080b801,0x007ff004, +0x90830134,0x007ff004,0x0095b803,0x5865b802, +0x1063b801,0x5862b803,0x906301b8,0x0217b803, +0x90420001,0x021fa004,0x90210001,0x011f05bb, +0x254ab808,0xb4c0000d,0xb62a000c,0x1080b801, +0x007ff004,0x90830134,0x007ff004,0x0095b803, +0x5862b801,0x906301b8,0x0217b803,0x90210001, +0x021fa204,0x007f8210,0x021fa004,0xa5480020, +0xb4c0000e,0xb0090000,0xb400000c,0x80870000, +0xb62a000a,0x80470000,0xb6290007,0x5865b802, +0x1063b801,0x5862b803,0x906301b8,0x0217b803, +0x90420001,0x021fa004,0x90210001,0x81df0004, +0x00000000,0x00000000,0x00ffb81a,0x011f05bb, +0x013f05b9,0xb0080000,0xb4000016,0xb0090000, +0xb4000014,0x81df0000,0x00000000,0x80270000, +0xb6280010,0x80470000,0xb629000d,0x5865b802, +0x1063b801,0x5862b803,0x914301b8,0x009ff00a, +0xb0040000,0xb4000005,0x80950002,0x906302b8, +0x0217b803,0x00000000,0x021fa004,0x90420001, +0x90210001,0x81df0004,0xa5480020,0xb00a0000, +0xb4000011,0xb0090000,0xb400000f,0x81df0000, +0x00000000,0x80870000,0xb62a000b,0x80470000, +0xb6290008,0x5865b802,0x1063b801,0x5862b803, +0x906302b8,0x0217b803,0x00000000,0x021fa004, +0x90420001,0x90210001,0x81df0004,0xb0080000, +0xb400004d,0xb0090000,0xb400004b,0x81df0000, +0x00000000,0x80270000,0xb6280047,0x80470000, +0xb6290044,0x5865b802,0x1063b801,0x5862b803, +0x914301b8,0x009ff00a,0xad420060,0x00000000, +0x00000000,0x00000000,0x114ab801,0x5942b80a, +0x914a1c80,0x0217b80a,0xb0040000,0xb400002e, +0x906302b8,0x009ff003,0xb0040000,0xb420000a, +0x80950006,0x00000000,0x021fa204,0x80950006, +0x015f8210,0x021fa204,0x80950006,0x015f8210, +0x021fa004,0xb5000026,0xb0040001,0xb4200009, +0x80950006,0x00000000,0x021fa204,0x015f8210, +0x021fa204,0x80950006,0x015f8210,0x021fa004, +0xb500001b,0xb0040003,0xb4200009,0x80950006, +0x00000000,0x021fa204,0x80950006,0x015f8210, +0x021fa204,0x015f8210,0x021fa004,0xb5000010, +0xb0040002,0xb420000e,0x80950006,0x00000000, +0x021fa204,0x015f8210,0x021fa204,0x015f8210, +0x021fa004,0xb5000006,0x8087003f,0x021fa204, +0x015f8210,0x021fa204,0x015f8210,0x021fa004, +0x90420001,0x90210001,0x81df0004,0xa5480020, +0xb4c00012,0xb0090000,0xb4000010,0x8087003f, +0x81df0000,0x5862b801,0x90631afc,0xb62a000b, +0x90630004,0x0047b803,0xb6290008,0x90420180, +0x0217b802,0x00000000,0x021fa204,0x003f8210, +0x021fa204,0x003f8210,0x021fa004,0x81df0004, +0x00ffb81a,0x8257ffff,0x82d7ffff,0x011f05bb, +0x013f05b9,0x80270000,0x00e7b809,0x300105ba, +0xb4800001,0x80e70001,0x800700bc,0x80470000, +0x81df0000,0xb0070000,0xb400004c,0xb627004b, +0x5865b802,0x1063b801,0x5862b803,0x914301b8, +0xaca20060,0x009ff00a,0x10a5b801,0x58a2b805, +0x90a502b8,0x0217b805,0xb0040000,0xb400002b, +0x1060b801,0x00bff003,0x10a5b804,0x90650160, +0x00dff003,0xb0060003,0xb4200007,0x90650134, +0x00dff003,0xb6000303,0x0075b806,0x021fa203, +0x007f8210,0xb5000021,0x5861b805,0x906300dc, +0x009fd803,0x90650134,0x00dff003,0xaca20060, +0x00000000,0x00000000,0x00000000,0x0075b806, +0x10a5b801,0x58a2b805,0x90a502b8,0x0217b805, +0x588fb804,0xb600030c,0xb6001007,0x04a3b804, +0xb4600002,0x58a1b803,0xb5000002,0x58a1b805, +0x90a50001,0x0067b805,0x9465ffff,0x5d50b805, +0x021fa20a,0x015f8210,0xb5000004,0x81470000, +0xb6000302,0x021fa20a,0x009f8210,0x009f05b9, +0xb0040002,0xb420000c,0x300105ba,0xb480000a, +0x58a2b801,0x90a502b8,0x0217b805,0x90a50180, +0x0297b805,0xb6000304,0x00bf8210,0x009f8210, +0x029fa205,0x009f8214,0x90420001,0x81df0004, +0x90210001,0x3001b808,0xb480ffa7,0xa5480020, +0xb00a0000,0xb4000019,0xb0090000,0xb4000017, +0x58a2b801,0x90a502b8,0x81df0000,0x00000000, +0x00000000,0xb62a0010,0x80470000,0xb629000d, +0xaca20060,0x00000000,0x00000000,0x00000000, +0x80670000,0x10a5b801,0x58a2b805,0x90a502b8, +0x0217b805,0xb6000302,0x021fa203,0x00bf8210, +0x90420001,0x90210001,0x81df0004,0x00ffb81a, +0x80770000,0x8057ffff,0x80f70000,0x80d7ffff, +0x81770000,0x8157ffff,0x81f70000,0x81d7ffff, +0xac140060,0xac350020,0x00000000,0x00000000, +0x12c0b801,0x5ac2b816,0x92d61980,0x83a400bd, +0xad940400,0x009f9173,0x013f05ca,0x914c6604, +0x114ab804,0x001f97e0,0x001eb80a,0xb0090000, +0xb4000003,0x80a76e44,0x80c76644,0xb5000002, +0x80a76644,0x80c76e44,0x808f000f,0x806f0000, +0x80af000e,0x80cf07e1,0x11e5b80c,0x11efb804, +0x5de2b80f,0x01ffb178,0x59e2b80f,0x01afb80f, +0x01ff9178,0x0047b86f,0xb0020001,0xb4c0fffd, +0x80cf07f0,0x1206b80c,0x1210b804,0x5e02b810, +0x021fb178,0x5a02b810,0x01afb810,0x021f9178, +0x0047b86f,0xb0020001,0xb4c0fffd,0x916c6e04, +0x116bb804,0x001f97ff,0x001eb80b,0x808f0000, +0x806f001f,0x80af001f,0x90ac6604,0x5ca2b805, +0x80270400,0x81df0000,0x00000000,0x00000000, +0xb600080a,0x00cfb801,0x00bfb178,0x58a2b805, +0x01cfb805,0x00bf9178,0x0047b86f,0xb0020001, +0xb4c0fffd,0x90210020,0x90a50020,0x81df0004, +0x90ac6e04,0x5ca2b805,0x80270500,0x81df0000, +0x00000000,0x00000000,0xb600080a,0x00cfb801, +0x00bfb178,0x58a2b805,0x01cfb805,0x00bf9178, +0x0047b86f,0xb0020001,0xb4c0fffd,0x90210020, +0x90a50020,0x81df0004,0x81530020,0xac140060, +0xac350020,0x80170800,0x80d7003c,0x12c0b801, +0x5ac2b816,0x92d602b8,0x0117b816,0x90241000, +0x0097b801,0x80470000,0x4002b803,0x81df0000, +0x00000000,0x00000000,0xb6000804,0x005f8020, +0x480287e4,0x005f8020,0x500287e4,0x81df0004, +0x00000000,0x00000000,0x00000000,0x1021b80a, +0x5c36b801,0x5801b800,0x18c0b801,0xb0090000, +0xb4000002,0x90641440,0xb5000001,0x90641040, +0x81df0000,0x00000000,0x00000000,0xb6000f0d, +0x0097b803,0x80470000,0x4002b803,0xb6001002, +0x005f8020,0x480287e4,0x0108a026,0x90630040, +0x00000000,0x1021b80a,0x5c36b801,0x5801b800, +0x18c0b801,0x81df0004,0x90641400,0x0097b803, +0x80470000,0x4002b803,0x005f8020,0x005f87e4, +0x81df0000,0x00000000,0x00000000,0xb6000802, +0x005f8040,0x480287c4,0x81df0004,0x005f87e0, +0x0108a026,0x00000000,0x1021b80a,0x5c36b801, +0x5801b800,0x18c0b801,0xb0090000,0xb4000002, +0x906417c0,0xb5000001,0x906413c0,0x81df0000, +0x00000000,0x00000000,0xb6000f0f,0x0097b803, +0x80470000,0x4002b803,0xb6000804,0x005f8020, +0x500287e4,0x005f8020,0x480287e4,0x0108a026, +0x84630040,0x00000000,0x1021b80a,0x5c36b801, +0x5801b800,0x18c0b801,0x81df0004,0xb0140000, +0xb4200005,0x90840004,0x9484003f,0x009fb173, +0xa1290001,0x013f25ca,0x80d7ffff,0x0108a026, +0x00ffb81a,0x81330004,0x8093007f,0x9884ffff, +0x80b3ff80,0x0017b816,0x90360040,0x0097b801, +0x81530010,0x81df0000,0x00000000,0x00000000, +0xb6001004,0x400a8000,0x404a8004,0x0008a020, +0x0088a022,0x81df0004,0x0017b816,0x9036007c, +0x0097b801,0x81171000,0x81df0000,0x00000000, +0x00000000,0xb6001004,0x40048020,0x480487e4, +0x00000000,0x0108a020,0x81df0004,0x81470000, +0x81670001,0x81870008,0x81a70040,0x81c707c4, +0x81e70040,0x81df0000,0x00000000,0x00000000, +0xb6000432,0xb00a0001,0xb4e00004,0x80c71000, +0x80e71000,0x81171040,0xb5000003,0x80c71040, +0x80e71040,0x81171000,0x844d0004,0x10e7b802, +0xb62b001f,0x0017b806,0x0097b807,0xb62c0004, +0x40048020,0x480487e4,0x00000000,0x0108a020, +0x0017b806,0x0097b807,0x0197b80e,0x00000000, +0x001f8020,0x042087e4,0xb62c000f,0x4041800c, +0x001f8020,0x0048b802,0x5e38802c,0x2e11b801, +0x042087e4,0x1042b810,0x0462b804,0xb4a00002, +0x0047b804,0xb5000003,0x0462b805,0xb4600001, +0x0047b805,0x011fa022,0x10c6b80f,0x10e7b80f, +0x5961b80b,0x5d81b80c,0x5da1b80d,0x5de1b80f, +0x914a0001,0x954a0001,0x11ceb80f,0x81df0004, +0x80171018,0x81171fcc,0x80470000,0x41448020, +0x494487c0,0x00000000,0x0188b80a,0x494487e0, +0x00000000,0x0148b80a,0x0502a10a,0x4145b80c, +0x494580e0,0x00000000,0x0108a5ea,0x41448080, +0x494487c0,0x00000000,0x0108a78a,0x49448020, +0x00000000,0x0108a2ea,0x41448020,0x49448720, +0x00000000,0x0188b80a,0x4145b80c,0x49458080, +0x494587a0,0x00000000,0x0108a68a,0x4145b80c, +0x49458080,0x494587a0,0x00000000,0x0108a08a, +0x4145b80c,0x49458020,0x49458040,0x00000000, +0x0188b80a,0x494587e0,0x00000000,0x0108a08a, +0x4144b80c,0x494587a0,0x00000000,0x0108a52a, +0x41448080,0x49448040,0x494486c0,0x00000000, +0x0108a04a,0x41448040,0x49448720,0x00000000, +0x0108a36a,0x04028020,0x011fa420,0x001f8040, +0x011fa100,0x001f8080,0x011fa080,0x001f8100, +0x011fa040,0x001f8660,0x011fa120,0x41458020, +0x49458000,0x00000000,0x0108a00a,0x0017b816, +0x9036007c,0x0097b801,0x81171000,0x81970784, +0x00000000,0x001f8020,0x042087e4,0x81df0000, +0x00000000,0x00000000,0xb600100f,0x4041800c, +0x001f8020,0x0048b802,0x5e38802c,0x2e11b801, +0x042087e4,0x1042b810,0x0462b804,0xb4a00002, +0x0047b804,0xb5000003,0x0462b805,0xb4600001, +0x0047b805,0x011fa022,0x81df0004,0x81470000, +0x81670001,0x81870008,0x81a70040,0x81c707c4, +0x81e70040,0x81df0000,0x00000000,0x00000000, +0xb6000432,0xb00a0001,0xb4e00004,0x80c71000, +0x80e71000,0x81171040,0xb5000003,0x80c71040, +0x80e71040,0x81171000,0x844d0004,0x10e7b802, +0xb62b001f,0x0017b806,0x0097b807,0xb62c0004, +0x40048020,0x480487e4,0x00000000,0x0108a020, +0x0017b806,0x0097b807,0x0197b80e,0x00000000, +0x001f8020,0x042087e4,0xb62c000f,0x4041800c, +0x001f8020,0x0048b802,0x5e38802c,0x2e11b801, +0x042087e4,0x1042b810,0x0462b804,0xb4a00002, +0x0047b804,0xb5000003,0x0462b805,0xb4600001, +0x0047b805,0x011fa022,0x10c6b80f,0x10e7b80f, +0x5961b80b,0x5d81b80c,0x5da1b80d,0x5de1b80f, +0x914a0001,0x954a0001,0x11ceb80f,0x81df0004, +0x80171034,0x81171f84,0x80470000,0x41448040, +0x49448640,0x00000000,0x0188b80a,0x49448100, +0x49448780,0x00000000,0x0108a08a,0x4144b80c, +0x49448040,0x49448080,0x494487c0,0x00000000, +0x0108a16a,0x4145b80c,0x49458700,0x00000000, +0x0188b80a,0x494581a0,0x494586e0,0x00000000, +0x0108a66a,0x4145b80c,0x49448040,0x494487e0, +0x00000000,0x0188b80a,0x011fa1ec,0x4145b80c, +0x49458100,0x49458780,0x00000000,0x0108a08a, +0x41458720,0x49458100,0x494586e0,0x49458160, +0x49458020,0x49458020,0x49458760,0x00000000, +0x0108a08a,0x414587a0,0x49458080,0x49458760, +0x494580c0,0x49458700,0x49458140,0x49458020, +0x49458760,0x00000000,0x0108a74a,0x414587a0, +0x49458080,0x49458760,0x494580e0,0x49458700, +0x49458120,0x49458020,0x49458760,0x00000000, +0x0108a08a,0x41458720,0x49458100,0x494586e0, +0x49458140,0x49458040,0x49458020,0x49458720, +0x00000000,0x0108a0ca,0x41458080,0x49458040, +0x49458020,0x49458620,0x00000000,0x0188b80a, +0x49458080,0x00000000,0x0108a7ca,0x4144b80c, +0x49458040,0x49458020,0x49458080,0x00000000, +0x0108a5ea,0x41448080,0x49448700,0x00000000, +0x0188b80a,0x49448780,0x00000000,0x0108a7ca, +0x4144b80c,0x49448140,0x00000000,0x0108a7ca, +0x49448040,0x00000000,0x0108a0ca,0x41448700, +0x00000000,0x0188b80a,0x49448000,0x00000000, +0x0108a04a,0x011fa00c,0x80171f80,0x81df0000, +0x00000000,0x00000000,0xb6002006,0x40048000, +0x48048000,0x48048000,0x48048000,0x00000000, +0x0008a020,0x81df0004,0x00ffb81d,0x00000000, +0x80770000,0x8057ffff,0x015f05b9,0x017f05bb, +0x8293ffff,0x9a94ffff,0x81a70000,0x81df0000, +0x00000000,0x00000000,0xb62a003a,0xaded0180, +0xae0d0180,0xadcd0080,0x902f1980,0x0017b801, +0xb6002033,0x904e01b8,0x00000000,0x013ff002, +0xb0090000,0xb400001f,0x904f02b8,0x80c70000, +0x011fd802,0x6829b808,0x94210001,0xb0010001, +0xb4e00001,0x00c7b814,0x6429b806,0x80470001, +0x6449b802,0x84420001,0x1442b808,0x84690001, +0x5863b803,0x906300dc,0x1042b801,0x003f9803, +0x90420001,0x4082b801,0x90630004,0x003f9803, +0x00000000,0x5897b804,0x1804b805,0x4082b801, +0x00000000,0x00000000,0x00000000,0x10a4b800, +0xb5000001,0x80a70000,0x90501c80,0x00000000, +0x007ff002,0x5842b803,0x904205f8,0x0097b802, +0x00000000,0x40058004,0x48058004,0x00000000, +0x0008a020,0x91ce0004,0x91ef0004,0x92100004, +0x91ad0001,0x81df0004,0x00ffb81a,0x80770000, +0x8057ffff,0x80d7ffff,0x015f05b9,0x017f05bb, +0x8293ff80,0x9a940000,0x82a70020,0x81a70000, +0x81e702b8,0x80171980,0x81df0000,0x00000000, +0x00000000,0xb62a004f,0xb600034d,0xac0d0080, +0xac4d0180,0xac960080,0x822700bc,0x91c001b8, +0x00000000,0x1042b804,0x92021c80,0xb62b003a, +0x013ff00e,0x00fff011,0xb0090000,0xb4000027, +0x10e7b809,0x5821b807,0x902100dc,0x00000000, +0x001fd801,0x82470000,0x80270001,0x6452b801, +0x3002b800,0xb4600002,0x92520001,0xb500fffb, +0x86520001,0x80c70000,0x011fd80f,0x6832b808, +0xb0010001,0xb4e00001,0x00c7b814,0x84520017, +0x0056b802,0x80270001,0x6432b801,0x84210001, +0x1408b801,0x6402b800,0x10c6b800,0x9027018c, +0x00000000,0x001ff001,0x5802b800,0x9020073c, +0x904006f8,0x007f9801,0x0097b802,0x10c6b803, +0x40868004,0x48868004,0xb5000003,0x80c70000, +0x40868004,0x00000000,0x0088b804,0x003ff010, +0x5822b801,0x902105f8,0x0097b801,0x91ce0004, +0x91ef0004,0x40448004,0x48448004,0x92100004, +0x0008a022,0x92310001,0x0435b80b,0xb4000007, +0x80870000,0xb6210005,0x001fa024,0x91ce0004, +0x91ef0004,0x92100004,0x92310001,0x00000000, +0x91ad0001,0x81df0004,0x00ffb81a,0x00000000, +0x007f05b9,0x001f0081,0xb0000001,0xb440002d, +0x001f05d8,0xac400080,0x801702b8,0x80970438, +0x90421800,0x0117b802,0x8087ffff,0x80b3ffff, +0x80d3007f,0x98c6ff00,0x80f3ff80,0x81070080, +0x81df0000,0x00000000,0x00000000,0xb6002018, +0x10088020,0x0056b800,0x0442b806,0xb4a00004, +0xb0000000,0x0007b806,0xb4400001,0x0007b807, +0x0027b800,0x5c08b800,0x1400b804,0xb0030001, +0xb4000008,0x10288024,0x0056b801,0x0442b806, +0xb4a00004,0xb0010000,0x0027b806,0xb4400001, +0x0027b807,0x5828b801,0x1421b805,0x1900a021, +0x81df0004,0x001f05d8,0x90000001,0x001f25d8, +0x00ffb81a,0x801702b8,0x80970438,0x81171800, +0x8087ffff,0x80b3ffff,0x80d3007f,0x98c6ff00, +0x80f3ff80,0x81070080,0x81df0000,0x00000000, +0x00000000,0xb6006018,0x10088020,0x0056b800, +0x0442b806,0xb4a00004,0xb0000000,0x0007b806, +0xb4400001,0x0007b807,0x0027b800,0x5c08b800, +0x1400b804,0xb0030001,0xb4000008,0x10288024, +0x0056b801,0x0442b806,0xb4a00004,0xb0010000, +0x0027b806,0xb4400001,0x0027b807,0x5828b801, +0x1421b805,0x1900a021,0x81df0004,0x00ffb81a, +0x001f0081,0xb0000001,0xb4400006,0x001f05d8, +0xb0000003,0xb4000003,0x80270001,0x003f25dc, +0x00ffb81a,0x003f05d9,0x009f05cb,0xb0010000, +0xb400000e,0x015f42ed,0x81070000,0x8127017c, +0xb00a0000,0xb4000002,0x81070180,0x812702fc, +0x802500a5,0x9421ffff,0x3001b808,0xb4800011, +0x3001b809,0xb4a0007f,0xb500000e,0x001f0081, +0xb0000001,0xb4400003,0xb0040002,0xb4200006, +0xb5000002,0xb0040000,0xb4200003,0x802702ff, +0x81470000,0xb5000003,0x80270001,0x003f25d9, +0x81470180,0xb0040000,0xb4200001,0x838402ea, +0x80070000,0x001f25d8,0x009f902d,0x80af001f, +0x808f0000,0x806f0000,0x8007ffff,0x8033ffff, +0x80171800,0x81df0000,0x807bff8c,0x94630003, +0xb0030003,0xb4000016,0xb0030002,0xb4000035, +0xb0030001,0xb4000024,0xb6006010,0x14618000, +0x6068b803,0x40c4b803,0x14608000,0x00c8b806, +0x5870b803,0x6068b803,0x4104b803,0x58c8b806, +0x0108b808,0x14c6b801,0x00000000,0x00000000, +0x5d08b808,0x1508b800,0x1806a028,0xb5000030, +0xb6006010,0x14618000,0x6068b803,0x40c4b803, +0x14608000,0x00c8b806,0x5870b803,0x6068b803, +0x4104b803,0x5cc8b806,0x0108b808,0x14c6b800, +0x00000000,0x00000000,0x5908b808,0x1508b801, +0x1806a028,0xb500001e,0xb600600d,0x14618000, +0x6068b803,0x40c4b803,0x00000000,0x00c8b806, +0x00000000,0x00000000,0x00000000,0x5d08b806, +0x1508b800,0x58c8b806,0x14c6b801,0x1806a028, +0xb500000f,0xb600600e,0x14608000,0x5868b803, +0x6068b803,0x40c4b803,0x00000000,0x00c8b806, +0x00000000,0x00000000,0x00000000,0x5d08b806, +0x1508b800,0x58c8b806,0x14c6b801,0x1806a028, +0x81df0004,0x80670600,0x5d22b80a,0x81df0000, +0x00000000,0x00000000,0xb600030a,0x00cfb803, +0x013fb178,0x5922b809,0x01afb809,0x013f9178, +0x0047b86f,0xb0020001,0xb4c0fffd,0x90630020, +0x91290020,0x81df0004,0x81270180,0xb00a0000, +0xb4000001,0x81270000,0x013f62ed,0x80270001, +0x003f25dc,0x00ffb81a,0x001f0081,0xb0000001, +0xb4400006,0x001f05d8,0xb0000003,0xb4000003, +0x80270001,0x003f25dc,0x00ffb81a,0x003f05d9, +0x009f05cb,0xb0010000,0xb400000e,0x015f42ed, +0x81070000,0x8127017c,0xb00a0000,0xb4000002, +0x81070180,0x812702fc,0x802500a5,0x9421ffff, +0x3001b808,0xb4800011,0x3001b809,0xb4a0007f, +0xb500000e,0x001f0081,0xb0000001,0xb4400003, +0xb0040002,0xb4200006,0xb5000002,0xb0040000, +0xb4200003,0x802702ff,0x81470000,0xb5000003, +0x80270001,0x003f25d9,0x81470180,0xb0040000, +0xb4200001,0x83840250,0x80070000,0x001f25d8, +0x009f902d,0x80af001f,0x808f0000,0x806f0000, +0x8007ffff,0x8033ffff,0x80171800,0x807bff8c, +0x81df0000,0x94630003,0xb0030003,0xb4000016, +0xb0030002,0xb4000035,0xb0030001,0xb4000024, +0xb6006010,0x14618000,0x6068b803,0x40c4b803, +0x14608000,0x00c8b806,0x5870b803,0x6068b803, +0x4104b803,0x58c8b806,0x0108b808,0x14c6b801, +0x00000000,0x00000000,0x5d08b808,0x1508b800, +0x1806a028,0xb5000030,0xb6006010,0x14618000, +0x6068b803,0x40c4b803,0x14608000,0x00c8b806, +0x5870b803,0x6068b803,0x4104b803,0x5cc8b806, +0x0108b808,0x14c6b800,0x00000000,0x00000000, +0x5908b808,0x1508b801,0x1806a028,0xb500001e, +0xb600600d,0x14618000,0x6068b803,0x40c4b803, +0x00000000,0x00c8b806,0x00000000,0x00000000, +0x00000000,0x5908b806,0x1508b801,0x5cc8b806, +0x14c6b800,0x1806a028,0xb500000f,0xb600600e, +0x14608000,0x5870b803,0x6068b803,0x40c4b803, +0x00000000,0x00c8b806,0x00000000,0x00000000, +0x00000000,0x5908b806,0x1508b801,0x5cc8b806, +0x14c6b800,0x1806a028,0x81df0004,0x80670600, +0x5d22b80a,0x81df0000,0x00000000,0x00000000, +0xb600030a,0x00cfb803,0x013fb178,0x5922b809, +0x01afb809,0x013f9178,0x0047b86f,0xb0020001, +0xb4c0fffd,0x90630020,0x91290020,0x81df0004, +0x81270180,0xb00a0000,0xb4000001,0x81270000, +0x013f62ed,0x80270001,0x003f25dc,0x00ffb81a, +0x029fb024,0x02bfb025,0x02dfb026,0x02ffb027, +0x031fb028,0x033fb029,0x033f4046,0x0287b86f, +0x029fb02a,0x8285009c,0x96b48000,0xb0158000, +0xb400018e,0x96b40100,0xb0150100,0xb40001a4, +0x96b40400,0xb0150400,0xb40001a5,0x96b40001, +0xb0150001,0xb400000c,0x96b40008,0xb0150008, +0xb4000197,0x96b44000,0xb0154000,0xb40001a4, +0x96b40002,0xb0150002,0xb400015b,0x00000000, +0x00000000,0xb50001b6,0x02bf917e,0x92b50001, +0x02bfb17e,0x82850082,0x5efdb814,0x96f70001, +0xb0170001,0xb420000b,0x83050069,0x9718003f, +0x82e50064,0x12f7b818,0x86f70109,0x82feff74, +0x02e7b86f,0x9af74000,0x01ffb817,0x96f7bfff, +0x01ffb817,0x83050081,0x82a5009a,0x96b50001, +0xb0150001,0xb4200014,0x82a70000,0x02bfb17e, +0x96b41840,0xb0150800,0xb420000c,0x96b40008, +0x5aa9b815,0x96d46000,0x5ec3b816,0x82f3000f, +0x9af7c00f,0x1718b817,0x1ab5b818,0x1ab5b816, +0x9ab50340,0x82a60081,0xb500012b,0x9b180180, +0x83060081,0xb5000128,0x82a5009a,0x96b50002, +0xb0150002,0xb420001b,0x82a70000,0x02bfb17e, +0x96b41800,0xb0151800,0xb4000013,0x96b40040, +0xb0150040,0xb4200004,0xa3180c00,0x9b180340, +0x83060081,0xb5000118,0x96b40008,0x5aa9b815, +0x96d46000,0x5ec3b816,0x82f3000f,0x9af7c00f, +0x1718b817,0x1ab5b818,0x1ab5b816,0x9ab50340, +0x82a60081,0xb500010c,0x9b180180,0x83060081, +0xb5000109,0x82a500c1,0x96b5000f,0xb015000b, +0xb420000e,0x96b40020,0xb0150020,0xb400000b, +0x96b40200,0xb0150200,0xb4000008,0x82c50086, +0x82e50094,0x3016b817,0xb4400004,0x06f7b816, +0xb017ff00,0xb4400001,0xb50000f7,0x96b46000, +0xb0156000,0xb4000011,0x96b41820,0xb0150820, +0xb4200004,0x9b391000,0x82a5009a,0x96b5feff, +0x82a6009a,0x96b40040,0xb0150040,0xb4200001, +0x9739efff,0x96b91000,0xb0151000,0xb4200003, +0x82a5009a,0x9ab50100,0x82a6009a,0x96b40040, +0xb0150040,0xb4200019,0x96b41800,0xb0151800, +0xb4200006,0x96b98000,0xb0158000,0xb4200003, +0x9b180180,0x83060081,0xb50000d7,0x96d80c00, +0x82b300ff,0x9ab5f3ff,0x1718b815,0xb0160c00, +0xb4000007,0x82e50098,0x96f70400,0xb0170400, +0xb4200002,0x82c70c00,0xb5000001,0xa2d60c00, +0x1b18b816,0x9b180340,0xb50000bd,0x96b40220, +0xb0150000,0xb4e00021,0x82a5009d,0x82f3ffff, +0x16b5b817,0x82f3000e,0x3015b817,0xb420001b, +0x96f98000,0xb0178000,0xb4000018,0x82a70000, +0x02bfb17e,0x82c5009d,0x96d6ffff,0x82b30032, +0x9ab58001,0x82e500c1,0x96f7000f,0xb017000b, +0xb4000002,0x82b30022,0x9ab58001,0x1ab5b816, +0x82c5009a,0x96d60020,0xb0160020,0xb4200002, +0x82b30032,0x9ab58001,0x82a6009d,0x02ff917e, +0x00000000,0xb0170040,0xb4800000,0x5eb5b814, +0x96b500f0,0x96f46000,0x5eedb817,0x1ab5b817, +0xb0170003,0xb4000004,0x96b500ef,0x96f70001, +0x5ae4b817,0x1ab5b817,0x96d41800,0xb0161800, +0xb400000a,0x96f900ff,0x96b500ff,0x9739ff00, +0x1b39b815,0x02a7b817,0x96b500f3,0x96d40008, +0x5ec1b816,0x1ab5b816,0xb500000c,0x96f98000, +0xb0178000,0xb4200007,0x5efeb814,0x96f70001, +0xb0170001,0xb4000003,0x9b180180,0x83060081, +0xb5000081,0x96b500f3,0x9ab50008,0x9739fff3, +0x96d40020,0xb0160020,0xb4200017,0x9b398000, +0x82c70000,0x02dfb17e,0x96d40010,0x5ac8b816, +0x82f300ff,0x9af7cfff,0x1718b817,0x1b18b816, +0x9b180340,0x82c5009d,0x96d6ffff,0x82f3000e, +0x9af78001,0x1af7b816,0x82c5009a,0x96d60020, +0xb0160020,0xb4200002,0x82f30032,0x9af78001, +0x82e6009d,0xb500005a,0x97397fff,0x96b500ff, +0x5aaab815,0x82f300fc,0x9af703ff,0x1718b817, +0x1b18b815,0x9b180340,0x82c5009a,0x96d60010, +0xb0160010,0xb4200024,0x82c70000,0x02dfb17e, +0x82c50086,0x92d60e10,0x82c60086,0x82c50094, +0x5eefb818,0x96f70003,0xb0170003,0xb4200002, +0x82e70e10,0xb5000001,0x82e70e10,0x12d6b817, +0x82e50081,0x9af70020,0x82e60081,0x82c60094, +0xa2f70020,0x82e60081,0x82f30001,0x16f7b818, +0x5ef0b817,0xb0170001,0xb4000004,0x96f84000, +0x5ee4b817,0x9718f3ff,0x1b18b817,0x82f3000a, +0x9af78000,0x82e6009d,0x83060081,0x83070001, +0x8306009f,0xb5000096,0x82c5009d,0x82f3000e, +0x9af78001,0x3016b817,0xb420000f,0x82b30032, +0x9ab58001,0x82e500c1,0x96f7000f,0xb017000b, +0xb4000002,0x82b30022,0x9ab58001,0x82c5009a, +0x96d60020,0xb0160020,0xb4200002,0x82b30032, +0x9ab58001,0x82a6009d,0x82c5009a,0x96d60080, +0xb0160080,0xb4000011,0x02df917e,0x00000000, +0xb0160010,0xb480000d,0x82c500c1,0x96d6000f, +0xb016000b,0xb4000009,0x82c50087,0x96d60080, +0x5ac7b816,0x96f84000,0x3017b816,0xb4200003, +0x033f4046,0x9b394000,0xb500000b,0x9739bfff, +0x82e50061,0x96f70008,0xb0170008,0xb4000005, +0x5eefb818,0x96f70003,0xb0170003,0xb4000001, +0x9718ffff,0x83060081,0x83070001,0x8306009f, +0x00000000,0xb500005e,0x82850083,0x96b400ff, +0xb015003c,0xb4200019,0x96b92000,0xb0152000, +0xb4000002,0x9b392000,0xb5000014,0x9739d3ff, +0x82870000,0x82860087,0x82870008,0x82860083, +0x829bff78,0x82a7001f,0xb0140400,0xb4000001, +0x82a70010,0x82a600c9,0x829bff78,0x00000000, +0x828600cb,0x8285009d,0x82b3ffff,0x9ab5fffd, +0x1694b815,0x8286009d,0xb5000000,0x83070002, +0x8306009f,0x00000000,0xb500003d,0x96b90800, +0xb0150800,0xb4200009,0x9739f7ff,0x82a703fd, +0x82a600cb,0x82a7003c,0x82a60083,0x8285009d, +0x9a940002,0x8286009d,0xb5000004,0x82850087, +0x5a82b814,0xa2940200,0x82860087,0xb5000000, +0x83078000,0x8306009f,0x00000000,0xb5000028, +0x83070008,0x8306009f,0x00000000,0xb5000024, +0x83070100,0x8306009f,0x00000000,0xb5000020, +0x83070000,0x83050081,0x9b180180,0x83060081, +0x83070400,0x8306009f,0x00000000,0xb5000018, +0x82870000,0x82850082,0x5eb7b814,0x96b500fc, +0x96d40006,0x5ec1b816,0x1ab5b816,0x5aacb815, +0x83050081,0x82d3001c,0x9ad600ff,0x1718b816, +0x1b18b815,0x9b180e00,0x83060081,0x83074000, +0x8306009f,0x8305009d,0x82d300ff,0x9ad6bfff, +0x1718b816,0x8306009d,0x00000000,0xb5000000, +0x029f902a,0x01ffb814,0x033f6046,0x029f9024, +0x02bf9025,0x02df9026,0x02ff9027,0x031f9028, +0x033f9029,0x00ffb81e,0x02ff917d,0x92f7092f, +0x031f0084,0xb0180001,0xb4200002,0x02ff917d, +0x92f70870,0x02ffb17d,0x02ff917c,0x82bbffdc, +0x829bffd8,0x93150004,0x3014b815,0xb4000017, +0x02dbb818,0x029bb815,0x3017b816,0xb4800013, +0x5a81b814,0x029fb17d,0x82def200,0x82fef204, +0x82e50086,0x06f7b814,0x02f6b817,0x82fef208, +0x82860095,0x82870001,0x829ef220,0x8293001f, +0x9294fe00,0x92b50008,0x3015b814,0xb4800002, +0x82b3001f,0x92b5fa00,0x82beffdc,0x82850086, +0x83250094,0x06d4b819,0x02d6b816,0xb016ffff, +0xb4a00009,0x82c50081,0x9ab60020,0x82a60081, +0x82a50086,0x92b50e10,0x82a60094,0x82c60081, +0x86b50704,0x82a6009b,0x00ffb81c,0x00000000, +0x001f9012,0x001fb200,0x001f004c,0x001f2804, +0x801bfef0,0x8058fef4,0x803bff68,0x8078ff6c, +0x2000b801,0x2042b803,0x001fb204,0x005f2814, +0x82e70001,0x83640048,0x029fb014,0x829efef0, +0x8286000f,0x02bf2054,0x82bcfef4,0x82a6000e, +0x00ffb81a,0x80e70001,0x801336e3,0x9800eb76, +0x001fb200,0x800700ab,0x001f2804,0x801bc3e8, +0x8058c3ec,0x83640024,0x82e70000,0x83640036, +0x029fb3c0,0x029fb200,0x02bf2f04,0x02bf2804, +0x801bc000,0x8058c004,0x8364001b,0x82e70000, +0x8364002d,0x001f93c0,0x3000b814,0xb420000a, +0x001f0f04,0x3000b815,0xb4200007,0x829efef0, +0x82bcfef4,0x029fb012,0x02bf204c,0x82870001, +0x829cfef5,0x00ffb81a,0xb0070000,0xb4000007, +0x80e70000,0x801399fa,0x9800c92e,0x001fb200, +0x800700af,0x001f2804,0xb500ffdc,0x82870000, +0x829cfef5,0x00ffb81a,0x80c700ff,0x803bff68, +0x8078ff6c,0x14a0b806,0x2063b805,0x007f2814, +0x2021b802,0x58c8b806,0x14a0b806,0x58b0b805, +0x2021b805,0x58c8b806,0x14a0b806,0x2021b805, +0x58c8b806,0x14a0b806,0x5cb0b805,0x2021b805, +0x003fb204,0x00ffb81b,0x82c70000,0x83070800, +0x83270005,0x8197080c,0x81d7ffff,0x83840126, +0x83840001,0x00ffb81b,0x808f0000,0x806f001f, +0x80af001f,0x80270240,0x81e77c08,0x5de2b80f, +0xb6000208,0x00cfb801,0x01ffb178,0x59e2b80f, +0x01cfb80f,0x01ff9178,0xb520ffff,0x91ef0020, +0x90210020,0x80270280,0x81e77b00,0x5de2b80f, +0xb6000208,0x00cfb801,0x01ffb178,0x59e2b80f, +0x01cfb80f,0x01ff9178,0xb520ffff,0x91ef0020, +0x90210020,0x8057ffff,0x80170830,0x80070810, +0x80270808,0xb6000509,0x005ff000,0x90420900, +0x007ff001,0x90630a00,0x009ff002,0x00bff003, +0x2004a025,0x90000001,0x90210001,0x80070814, +0x80d7ffff,0x8097085c,0x8017083c,0xb6000404, +0x005ff000,0x007f87e0,0x84000001,0x2082a7e3, +0x80970860,0x80170840,0x2082b803,0x007f8000, +0x2083a004,0x80170830,0x80970850,0x80270808, +0xb6000508,0x005f8024,0x90420900,0x007ff001, +0x90630a00,0x009ff002,0x00bff003,0x2004a025, +0x90210001,0x80170840,0x00000000,0x02bf87e0, +0x80970860,0x82870000,0xb6000404,0x005f87e4, +0x5a88b814,0x204287e0,0x1a94b802,0x00ffb81c, +0x001f0e49,0x001f2b09,0x001f0e41,0x001f2b08, +0x001f0e46,0x001f2b07,0x001f0e48,0x001f2b06, +0x001f0e42,0x001f2b05,0x001f0e47,0x001f2b04, +0x001f0e45,0x001f2b03,0x001f0e43,0x001f2b02, +0x001f0e40,0x001f2b01,0x001f0e44,0x001f2b00, +0x001f0f25,0xa020000c,0x94400001,0x94600002, +0x94810004,0x94a10008,0x94c00010,0x5943b802, +0x5861b803,0x5882b804,0x5ca2b805,0x5cc4b806, +0x194ab803,0x194ab804,0x194ab805,0x194ab806, +0x015f2b38,0x801b7c00,0x003f92c1,0x5c28b801, +0x005f92c2,0x5858b802,0x1821b802,0x2000b801, +0x001fb2c4,0x80187c04,0x003f0b09,0x2000b801, +0x001f2b14,0x82c70001,0x82e70001,0x83070b10, +0x8327001e,0x81970b35,0x8384009f,0x02df0b38, +0x82170e30,0x838400f1,0x819efef0,0x817cfef4, +0x819eff68,0x817cff6c,0x00ffb81b,0x820f001f, +0x8018fef8,0x8057ffff,0x001f2b09,0x8018fef6, +0x80d7ffff,0x001f2b08,0x8018fefa,0x8157ffff, +0x001f2b07,0x8018fefd,0x81d7ffff,0x001f2b06, +0x8018fefb,0x802f001f,0x001f2b05,0x8018fefe, +0x00000000,0x001f2b04,0x8018fef9,0x00000000, +0x001f2b03,0x8018feff,0x00000000,0x001f2b02, +0x8018fef7,0x00000000,0x001f2b01,0x8018fefc, +0x00000000,0x001f2b00,0x001f0f25,0xa0200011, +0x94410001,0x94600002,0x94800004,0x94a00008, +0x94c10010,0x5941b802,0x5861b803,0x5c82b804, +0x58a1b805,0x5cc1b806,0x194ab803,0x194ab804, +0x194ab805,0x194ab806,0x015f2b38,0x801b7c00, +0x003f92c1,0x5c28b801,0x005f92c2,0x5858b802, +0x1821b802,0x2000b801,0x001fb2c4,0x80187c04, +0x003f0b09,0x2000b801,0x001f2b14,0x82c70001, +0x82e70001,0x83070b10,0x8327001e,0x81970b35, +0x83840055,0x02df0b38,0x82170e20,0x838400a7, +0x819efef0,0x817cfef4,0x5ac8b80c,0x02ff0e44, +0x1ad6b817,0x02dfb391,0x5ed8b80c,0x5968b80b, +0x1ad6b80b,0x02df6724,0x00ffb81b,0x820f001f, +0x8018fefe,0x8057ffff,0x001f2b09,0x8018fefa, +0x80d7ffff,0x001f2b08,0x8018fefc,0x8157ffff, +0x001f2b07,0x8018feff,0x81d7ffff,0x001f2b06, +0x8018fef8,0x802f001f,0x001f2b05,0x8018fefb, +0x00000000,0x001f2b04,0x8018fefd,0x00000000, +0x001f2b03,0x8018fef6,0x00000000,0x001f2b02, +0x8018fef9,0x00000000,0x001f2b01,0x8018fef7, +0x00000000,0x001f2b00,0x801b7c00,0x003f92c1, +0x5c28b801,0x005f92c2,0x5858b802,0x1821b802, +0x2000b801,0x001fb2c4,0x80187c04,0x003f0b09, +0x2000b801,0x001f2b14,0x82c70001,0x82e70001, +0x83070b10,0x8327001e,0x81970b35,0x83840016, +0x83270000,0x831bfef0,0x82f8fef4,0x02c7b819, +0x82170e28,0x83840065,0x300cb818,0xb4200002, +0x300bb817,0xb4000006,0x93390001,0xb0190020, +0xb480fff6,0x83270000,0x833cfef5,0x00ffb81b, +0x019fb390,0x017f2e44,0x033f2f25,0x83270001, +0x833cfef5,0x00ffb81b,0x0007b818,0x90000003, +0x00000000,0x015ff000,0x90000001,0x5949b80a, +0x013ff000,0x194ab809,0x84000002,0x994a0100, +0x017ff000,0x958b00f8,0x5981b80c,0x956b0007, +0x198cb80b,0x84000002,0x998c0008,0x017ff000, +0x90000001,0x5971b80b,0x198cb80b,0x017ff000, +0x5969b80b,0x198cb80b,0x81a70000,0x94d90003, +0x82a70000,0xb6260019,0xb6000818,0x5df0b80a, +0x5e02b80a,0x21efb810,0x95ef0001,0x5941b80a, +0x194ab80f,0x21efb816,0x5e18b80c,0x5e35b80c, +0x5e54b80c,0x5e6cb80c,0x2210b811,0x2252b813, +0x2210b812,0x96100001,0x5981b80c,0x198cb810, +0x2210b817,0x10afb810,0x10a5b80d,0x5da1b805, +0x94a50001,0x5aa1b815,0x1ab5b805,0x019fa7f5, +0x5cc2b819,0xb626001c,0x82870000,0xb6000419, +0xb6000818,0x5df0b80a,0x5e02b80a,0x21efb810, +0x95ef0001,0x5941b80a,0x194ab80f,0x21efb816, +0x5e18b80c,0x5e35b80c,0x5e54b80c,0x5e6cb80c, +0x2210b811,0x2252b813,0x2210b812,0x96100001, +0x5981b80c,0x198cb810,0x2210b817,0x10afb810, +0x10a5b80d,0x5da1b805,0x94a50001,0x5a81b814, +0x1a94b805,0x019fa7f4,0x00ffb81c,0x8257ffff, +0x808f0000,0x806f001f,0x80af001f,0x80270300, +0x81e778e0,0x5de2b80f,0xb6000208,0x00cfb801, +0x01ffb178,0x59e2b80f,0x01cfb80f,0x01ff9178, +0xb520ffff,0x91ef0020,0x90210020,0x80270340, +0x81e779e0,0x5de2b80f,0xb6000208,0x00cfb801, +0x01ffb178,0x59e2b80f,0x01cfb80f,0x01ff9178, +0xb520ffff,0x91ef0020,0x90210020,0x80270280, +0x81e77b00,0x5de2b80f,0xb6000208,0x00cfb801, +0x01ffb178,0x59e2b80f,0x01cfb80f,0x01ff9178, +0xb520ffff,0x91ef0020,0x90210020,0x806f0007, +0x80af0007,0x80270380,0x81e77ae0,0x5de2b80f, +0x00cfb801,0x01ffb178,0x59e2b80f,0x01cfb80f, +0x01ff9178,0xb520ffff,0x91ef0020,0x90210020, +0x80170b60,0x001f0b00,0x001fa020,0x001f0b01, +0x001fa020,0x001f0b02,0x001fa020,0x001f0b03, +0x001fa020,0x001f0b04,0x001fa000,0x80970b50, +0x81170b70,0x82a70b35,0x83a40060,0x001f87e4, +0xb6000405,0x86b50001,0x83a4005c,0x001f8004, +0x003f87e8,0x2080a7e1,0x80970b70,0x80170b50, +0x81170b50,0x81970b40,0x82a70b30,0x001f800c, +0x003f8008,0x2100a001,0x83a40050,0x001f87e4, +0xb6000405,0x86b50001,0x83a4004c,0x001f8004, +0x003f87e8,0x2080a7e1,0x80970b50,0x80170b70, +0x81170b70,0x81970b60,0x82a70b2b,0x001f800c, +0x003f8008,0x2100a001,0x83a40040,0x83a4004e, +0xb6000407,0x86b50001,0x83a4003c,0x001f8004, +0x003f87e8,0x2080a001,0x83a40047,0x00000000, +0x80970b70,0x80170b50,0x81170b50,0x81970b40, +0x82a70b26,0x001f800c,0x003f8008,0x2100a001, +0x83a4002e,0x83a4003c,0xb6000407,0x86b50001, +0x83a4002a,0x001f8004,0x003f87e8,0x2080a001, +0x83a40035,0x00000000,0x80970b50,0x80170b70, +0x81170b70,0x81970b60,0x82a70b21,0x001f800c, +0x003f8008,0x2100a001,0x83a4001c,0x001f87e4, +0xb6000405,0x86b50001,0x83a40018,0x001f8004, +0x003f87e8,0x2080a7e1,0x80970b70,0x80170b50, +0x81170b50,0x81970b40,0x82a70b1c,0x001f800c, +0x003f8008,0x2100a001,0x83a4000c,0x017f87e4, +0x81870000,0xb6000406,0x86b50001,0x83a40007, +0x001f87e4,0x200087e8,0x5988b80c,0x198cb800, +0x021fa02c,0x021fa00b,0x00ffb81c,0x005ff015, +0x90420a00,0x003f87e0,0x001ff002,0x2060b801, +0x90630c00,0x90960e00,0x001ff003,0x003ff004, +0x20a0b801,0x90a50d00,0x00000000,0x001ff005, +0x009fa000,0x00ffb81d,0x001f8004,0x5c21b800, +0x5847b800,0x1821b802,0x942100ff,0x2080a7e1, +0x00ffb81d,0x00000000,0x00000000,0x00000000, + +}; + +static u32 MPGUcode1f5c00[] = { +0x00000000,0xfffff8c0,0x00003540,0xffff8d40, +0x0001fd40,0xfffaf7c0,0x00066b80,0xffdb63c0, +0x00494780,0x00249c40,0x00066b80,0x00050840, +0x0001fd40,0x000072c0,0x00003540,0x00000740, +0xffffffc0,0xfffff840,0x00003680,0xffff7e40, +0x0001f400,0xfffa9cc0,0x0005d1c0,0xffd99600, +0x00493c00,0x0022ce00,0x0006f780,0x0004ad00, +0x000203c0,0x00006440,0x00003400,0x00000680, +0xffffffc0,0xfffff740,0x00003780,0xffff6ec0, +0x0001e800,0xfffa4240,0x00052a00,0xffd7ca00, +0x00491a00,0x0020ffc0,0x00077600,0x00045240, +0x00020800,0x000056c0,0x00003280,0x00000600, +0xffffffc0,0xfffff680,0x00003840,0xffff5ec0, +0x0001d940,0xfff9e8c0,0x00047440,0xffd60080, +0x0048e180,0x001f32c0,0x0007e700,0x0003f7c0, +0x000209c0,0x00004980,0x00003100,0x00000540, +0xffffffc0,0xfffff5c0,0x000038c0,0xffff4e40, +0x0001c780,0xfff990c0,0x0003b000,0xffd43ac0, +0x00489240,0x001d6800,0x00084b00,0x00039e40, +0x00020940,0x00003d00,0x00002f80,0x000004c0, +0xffffffc0,0xfffff4c0,0x00003900,0xffff3d40, +0x0001b2c0,0xfff93a40,0x0002ddc0,0xffd279c0, +0x00482d00,0x001ba040,0x0008a200,0x000345c0, +0x000206c0,0x00003140,0x00002dc0,0x00000440, +0xffffffc0,0xfffff3c0,0x00003900,0xffff2c00, +0x00019b00,0xfff8e640,0x0001fd40,0xffd0be80, +0x0047b1c0,0x0019dc80,0x0008ecc0,0x0002ef00, +0x00020240,0x00002640,0x00002c00,0x00000400, +0xffffff80,0xfffff2c0,0x000038c0,0xffff1a40, +0x00017fc0,0xfff894c0,0x00010e80,0xffcf09c0, +0x004720c0,0x00181d80,0x00092b40,0x000299c0, +0x0001fc00,0x00001bc0,0x00002a40,0x00000380, +0xffffff80,0xfffff180,0x00003800,0xffff0840, +0x00016180,0xfff84680,0x00001180,0xffcd5cc0, +0x00467a40,0x00166440,0x00095e00,0x00024680, +0x0001f440,0x00001200,0x00002840,0x00000340, +0xffffff80,0xfffff040,0x00003740,0xfffef600, +0x00014000,0xfff7fbc0,0xffff0680,0xffcbb880, +0x0045bf00,0x0014b140,0x00098580,0x0001f580, +0x0001ea80,0x00000900,0x00002680,0x000002c0, +0xffffff80,0xffffef00,0x000035c0,0xfffee3c0, +0x00011ac0,0xfff7b540,0xfffded80,0xffca1d80, +0x0044ef80,0x00130580,0x0009a1c0,0x0001a700, +0x0001dfc0,0x00000080,0x000024c0,0x00000280, +0xffffff40,0xffffedc0,0x00003400,0xfffed180, +0x0000f280,0xfff77340,0xfffcc700,0xffc88d80, +0x00440bc0,0x001161c0,0x0009b3c0,0x00015b00, +0x0001d380,0xfffff8c0,0x000022c0,0x00000240, +0xffffff40,0xffffec40,0x00003200,0xfffebf40, +0x0000c680,0xfff73680,0xfffb92c0,0xffc708c0, +0x00431500,0x000fc6c0,0x0009bb80,0x000111c0, +0x0001c640,0xfffff1c0,0x00002100,0x00000200, +0xffffff00,0xffffeac0,0x00002f40,0xfffead00, +0x00009740,0xfff6ff40,0xfffa5180,0xffc59080, +0x00420b40,0x000e3500,0x0009b9c0,0x0000cb80, +0x0001b7c0,0xffffeb40,0x00001f40,0x000001c0, +0xffffff00,0xffffe940,0x00002c40,0xfffe9b00, +0x00006480,0xfff6ce00,0xfff90380,0xffc425c0, +0x0040ef80,0x000cad00,0x0009af00,0x00008840, +0x0001a880,0xffffe580,0x00001d40,0x000001c0, +0xfffffec0,0xffffe7c0,0x000028c0,0xfffe8980, +0x00002e40,0xfff6a3c0,0xfff7a900,0xffc2c900, +0x003fc280,0x000b2fc0,0x00099b80,0x00004800, +0x00019880,0xffffe040,0x00001bc0,0x00000180, +0xfffffec0,0xffffe600,0x00002480,0xfffe7840, +0xfffff4c0,0xfff68040,0xfff64240,0xffc17b40, +0x003e84c0,0x0009bdc0,0x00097fc0,0x00000b40, +0x000187c0,0xffffdb80,0x00001a00,0x00000140, +0xfffffe80,0xffffe440,0x00001fc0,0xfffe6780, +0xffffb800,0xfff66480,0xfff4d040,0xffc03d80, +0x003d3700,0x00085700,0x00095c40,0xffffd1c0, +0x00017680,0xffffd740,0x00001840,0x00000140, +0xfffffe40,0xffffe2c0,0x00001a80,0xfffe5780, +0xffff77c0,0xfff65100,0xfff35300,0xffbf1080, +0x003bda40,0x0006fc80,0x00093200,0xffff9b80, +0x00016500,0xffffd3c0,0x000016c0,0x00000100, +0xfffffe40,0xffffe0c0,0x000014c0,0xfffe4840, +0xffff3480,0xfff64640,0xfff1cb00,0xffbdf4c0, +0x003a6f80,0x0005ae80,0x000900c0,0xffff68c0, +0x00015300,0xffffd0c0,0x00001540,0x00000100, +0xfffffe00,0xffffdf00,0x00000e40,0xfffe39c0, +0xfffeee40,0xfff64480,0xfff03940,0xffbceb00, +0x0038f740,0x00046d40,0x0008c980,0xffff3980, +0x000140c0,0xffffce00,0x000013c0,0x000000c0, +0xfffffdc0,0xffffdd40,0x00000740,0xfffe2c80, +0xfffea500,0xfff64c40,0xffee9e40,0xffbbf440, +0x00377280,0x00033900,0x00088cc0,0xffff0d80, +0x00012e80,0xffffcc00,0x00001240,0x000000c0, +0xfffffd80,0xffffdb40,0xffffff80,0xfffe2040, +0xfffe5900,0xfff65e40,0xffecfa80,0xffbb1080, +0x0035e280,0x00021280,0x00084ac0,0xfffee540, +0x00011c40,0xffffca40,0x00001100,0x00000080, +0xfffffd40,0xffffd980,0xfffff700,0xfffe1580, +0xfffe0a80,0xfff67a80,0xffeb4ec0,0xffba4100, +0x00344780,0x0000f980,0x00080440,0xfffec000, +0x00010a00,0xffffc8c0,0x00000fc0,0x00000080, +0xfffffcc0,0xffffd7c0,0xffffee00,0xfffe0bc0, +0xfffdb980,0xfff6a200,0xffe99bc0,0xffb985c0, +0x0032a340,0xffffee80,0x0007b980,0xfffe9e80, +0x0000f7c0,0xffffc800,0x00000e80,0x00000080, +0xfffffc80,0xffffd5c0,0xffffe440,0xfffe0400, +0xfffd6640,0xfff6d4c0,0xffe7e280,0xffb8df40, +0x0030f640,0xfffef180,0x00076b40,0xfffe8040, +0x0000e5c0,0xffffc740,0x00000d40,0x00000080, +0xfffffc00,0xffffd400,0xffffd9c0,0xfffdfdc0, +0xfffd1100,0xfff71340,0xffe62380,0xffb84e40, +0x002f4180,0xfffe02c0,0x000719c0,0xfffe6500, +0x0000d400,0xffffc700,0x00000c40,0x00000040, +0xfffffbc0,0xffffd240,0xffffcec0,0xfffdf940, +0xfffcba40,0xfff75e00,0xffe45fc0,0xffb7d300, +0x002d8640,0xfffd2240,0x0006c5c0,0xfffe4d40, +0x0000c2c0,0xffffc700,0x00000b40,0x00000040, +0xfffffb40,0xffffd080,0xffffc300,0xfffdf6c0, +0xfffc61c0,0xfff7b500,0xffe29800,0xffb76dc0, +0x002bc540,0xfffc5000,0x00066f40,0xfffe3880, +0x0000b1c0,0xffffc740,0x00000a40,0x00000040, +0xfffffac0,0xffffcf00,0xffffb680,0xfffdf640, +0xfffc0840,0xfff81900,0xffe0cd40,0xffb71e80, +0x0029ff80,0xfffb8bc0,0x00061740,0xfffe26c0, +0x0000a140,0xffffc7c0,0x00000980,0x00000040, +0xfffffa00,0xffffcd80,0xffffa940,0xfffdf800, +0xfffbadc0,0xfff88a00,0xffdf0040,0xffb6e600, +0x00283600,0xfffad600,0x0005bdc0,0xfffe1800, +0x00009140,0xffffc880,0x000008c0,0x00000040, +0xfffff980,0xffffcc00,0xffff9bc0,0xfffdfc40, +0xfffb5300,0xfff90880,0xffdd3200,0xffb6c400, +0x00266a00,0xfffa2e40,0x00056340,0xfffe0c00, +0x000081c0,0xffffc980,0x000007c0,0x00000040, +0x004013c2,0x0040b346,0x0041fa2d,0x0043f934, +0x0046cc1c,0x004a9d9d,0x004fae37,0x0056601f, +0x005f4cf7,0x006b6fcf,0x007c7d1e,0x0115b035, +0x013df91b,0x0207655e,0x03342c83,0x0a185230, +0x00404f46,0x0042e13c,0x0048919f,0x0052cb0e, +0x0064e240,0x0107c449,0x015c7926,0x050cf270, +0x004140fb,0x004cf8df,0x0073326c,0x02480d9d, +0x004545ea,0x01273d75,0x005a827a,0x007fffff, +0x006597fb,0x0050a28c,0x00400000,0x0032cbfd, +0x00285146,0x00200000,0x001965ff,0x001428a3, +0x00100000,0x000cb2ff,0x000a1451,0x00080000, +0x00065980,0x00050a29,0x00040000,0x00032cc0, +0x00028514,0x00020000,0x00019660,0x0001428a, +0x00010000,0x0000cb30,0x0000a145,0x00008000, +0x00006598,0x000050a3,0x00004000,0x000032cc, +0x00002851,0x00002000,0x00001966,0x00001429, +0x00001000,0x00000cb3,0x00000a14,0x00000800, +0x00000659,0x0000050a,0x00000400,0x0000032d, +0x00000285,0x00000200,0x00000196,0x00000143, +0x00000100,0x000000cb,0x000000a1,0x00000080, +0x00000066,0x00000051,0x00000040,0x00000033, +0x00000028,0x00000020,0x00000019,0x00000014, +0x00000010,0x0000000d,0x0000000a,0x00000008, +0x00000006,0x00000005,0x00000000,0x00555555, +0x00666666,0x00492492,0x0071c71c,0x00444444, +0x00421084,0x00410410,0x00408102,0x00404040, +0x00402010,0x00401004,0x00400801,0x00400400, +0x00400200,0x00400100,0x00400080,0x00400040, +0x00400000,0x00400000,0x00200000,0x00400000, +0x00100000,0x00080000,0x00040000,0x00020000, +0x00010000,0x00008000,0x00004000,0x00002000, +0x00001000,0x00000800,0x00000400,0x00000200, +0x00000100,0x0003588d,0x0002b15e,0x0002056d, +0x00015600,0x0000a329,0xffffeed9,0xffff3960, +0xfffe8423,0xfffdd11c,0xfffd2048,0xfffc7353, +0xfffbcb6f,0xfffb29a6,0xfffa8f15,0x000494ae, +0x0003f991,0x00032dd1,0xfffd2d8f,0x0001eb47, +0xfffe9968,0x00009af6,0x000011de,0xffff4335, +0x00018d69,0xfffdecd4,0x000302f8,0xfffca0d7, +0x0004683d,0xfffb67f8,0x0005b36d,0x00045963, +0xfffbd51e,0x00030062,0xfffd0dee,0x0001d046, +0xfffe8a0a,0x00009258,0x000012b1,0xffff4d9e, +0x00019ec3,0xfffe0a44,0x0003245a,0xfffcd082, +0x000498f0,0xfffba919,0x0005f304,0x00041bf4, +0xfffba72a,0x0002d19e,0xfffcf060,0x0001b407, +0xfffe7c08,0x0000894a,0x0000138d,0xffff58ac, +0x0001afaf,0xfffe28fe,0x000343bf,0xfffd026f, +0x0004c6f6,0xfffbed06,0x00062e61,0x0003dc0e, +0xfffb7bf1,0x0002a17f,0xfffcd522,0x000196a0, +0xfffe6e70,0x00007ff6,0x00001439,0xffff63f6, +0x0001beb3,0xfffe4882,0x0003616d,0xfffd361b, +0x0004f1cf,0xfffc332a,0x0006658f,0x00039943, +0xfffb52c0,0x00026ec7,0xfffcbb94,0x0001789f, +0xfffe6160,0x00007677,0x000014d4,0xffff6f74, +0x0001cc9b,0xfffe694f,0x00037cbf,0xfffd6b41, +0x000519c2,0xfffc7baf,0x00069971,0x00035486, +0xfffb2d0c,0x00023ad8,0xfffca3ee,0x00015989, +0xfffe55af,0x00006ca7,0x00001570,0xffff7b71, +0x0001d9cb,0xfffe8b46,0x0003959e,0xfffda1fe, +0x00053ee6,0xfffcc6b4,0x0006c950,0x00030e08, +0xfffb0a7a,0x0002061e,0xfffc8ec0,0x00013911, +0xfffe4b1d,0x00006278,0x000015e8,0xffff87b6, +0x0001e577,0xfffeadd6,0x0003acc2,0xfffdda34, +0x00056059,0xfffd136d,0x0006f4b5,0x0002c562, +0xfffaea7c,0x0001cfa6,0xfffc7b14,0x0001182b, +0xfffe4159,0x00005817,0x0000165c,0xffff9417, +0x0001f00f,0xfffed14c,0x0003c199,0xfffe13f6, +0x00057e83,0xfffd61cd,0x00071ba1,0x00027ab5, +0xfffacdc3,0x00019833,0xfffc6989,0x0000f6ca, +0xfffe38da,0x00004d9d,0x000016ef,0xffffa103, +0x0001f98f,0xfffef5c0,0x0003d3d1,0xfffe4f00, +0x0005998c,0xfffdb21e,0x00073e77,0x00022e75, +0xfffab482,0x00015fd1,0xfffc5b13,0x0000d45d, +0xfffe318f,0x000042ed,0x0000176b,0xffffae8f, +0x0002018f,0xffff1a91,0x0003e40c,0xfffe8af2, +0x0005b0ca,0xfffe03b8,0x00075d14,0x0001e141, +0xfffa9e9b,0x0001262a,0xfffc4e31,0x0000b1af, +0xfffe2b26,0x00003805,0x000017b1,0xffffbc21, +0x000208b8,0xffff3fb6,0x0003f1d7,0xfffec7af, +0x0005c4c5,0xfffe5654,0x0007768a,0x000192fe, +0xfffa8bb0,0x0000ec3f,0xfffc4365,0x00008ec9, +0xfffe25f0,0x00002d05,0x000017ec,0xffffc984, +0x00020ec6,0xffff658d,0x0003fcba,0xffff0500, +0x0005d576,0xfffeaa37,0x00078bc6,0x00014367, +0xfffa7bec,0x0000b1f4,0xfffc3b82,0x00006b06, +0xfffe2201,0x000021eb,0x00001823,0xffffd704, +0x0002132a,0xffff8be7,0x00040534,0xffff4315, +0x0005e22e,0xfffeff0a,0x00079ce3,0x0000f33f, +0xfffa6fc9,0x000076ca,0xfffc3558,0x00004762, +0xfffe1ef3,0x000016a1,0x0000183f,0xffffe4a6, +0x00021664,0xffffb27d,0x00040b7b,0xffff81e5, +0x0005eb4e,0xffff5475,0x0007a857,0x0000a2cb, +0xfffa671b,0x00003b64,0xfffc31e2,0x00002416, +0xfffe1ce1,0x00000b46,0x00001850,0xfffff24d, +0x00021855,0xffffd93a,0x00040f75,0xffffc0e6, +0x0005f0e3,0xffffaa3e,0x0007af45,0x0000519f, +0xfffa6218,0x0003f991,0x0003588d,0x0002b15e, +0x0002056d,0x00015600,0x0000a329,0xffffeed9, +0xffff3960,0xfffe8423,0xfffdd11c,0xfffd2048, +0xfffc7353,0xfffbcb6f,0xfffb29a6,0xfffa8f15, +0x000494ae,0x0003c6b0,0xfffc7e8b,0x00028ef6, +0xfffde181,0x000144eb,0xffff5500,0xffffefb9, +0x0000d01d,0xfffe9755,0x000249a4,0xfffd453c, +0x0003b80e,0xfffc01aa,0x000511d6,0xfffad527, +0xfffb334e,0x0003916c,0xfffc5778,0x00026a92, +0xfffdc9f5,0x00013314,0xffff4d99,0xfffff0b6, +0x0000d911,0xfffeab80,0x00026369,0xfffd6c0a, +0x0003e17f,0xfffc39d8,0x000549df,0xfffb1eb2, +0xfffafe6c,0x00035929,0xfffc3321,0x000244a6, +0xfffdb402,0x00012035,0xffff46ac,0xfffff192, +0x0000e16a,0xfffebfe0,0x00027b3d,0xfffd9433, +0x0004087b,0xfffc74b7,0x00057e8d,0xfffb6a81, +0xfffacc1c,0x00031fbe,0xfffc10df,0x00021e0c, +0xfffd9f6d,0x00010cb7,0xffff402e,0xfffff279, +0x0000e965,0xfffed574,0x00029159,0xfffdbdc4, +0x00042c4c,0xfffcb1e7,0x0005b02d,0xfffbb942, +0xfffa9d38,0x0002e44a,0xfffbf0fd,0x0001f5b4, +0xfffd8c38,0x0000f8b1,0xffff3a21,0xfffff391, +0x0000f0e6,0xfffeec44,0x0002a642,0xfffde90e, +0x00044e32,0xfffcf0fb,0x0005de46,0xfffc0b18, +0xfffa71d1,0x0002a659,0xfffbd3de,0x0001cb90, +0xfffd7a97,0x0000e403,0xffff3490,0xfffff49c, +0x0000f7a8,0xffff0340,0x0002b95f,0xfffe1573, +0x00046dbe,0xfffd3284,0x00060888,0xfffc5f51, +0xfffa4996,0x00026786,0xfffbb8df,0x0001a0e1, +0xfffd6a4e,0x0000ced2,0xffff2f75,0xfffff593, +0x0000fdbe,0xffff1a53,0x0002ca87,0xfffe42f5, +0x0004898a,0xfffd7563,0x00062f0b,0xfffcb5de, +0xfffa2508,0x00022713,0xfffba0bf,0x0001754a, +0xfffd5b5f,0x0000b92c,0xffff2acd,0xfffff6b0, +0x0001034f,0xffff3241,0x0002da5c,0xfffe71c6, +0x0004a341,0xfffdb946,0x000651e8,0xfffd0e37, +0xfffa0402,0x0001e4d4,0xfffb8b9c,0x00014898, +0xfffd4e7d,0x0000a304,0xffff26b7,0xfffff7e1, +0x00010846,0xffff4b34,0x0002e897,0xfffea13f, +0x0004ba63,0xfffdff2d,0x00067115,0xfffd6839, +0xfff9e680,0x0001a1fa,0xfffb789e,0x00011b2e, +0xfffd43a4,0x00008c6e,0xffff2341,0xfffff8fd, +0x00010c9c,0xffff6469,0x0002f48f,0xfffed1a4, +0x0004cd6a,0xfffe4608,0x00068c1b,0xfffdc409, +0xfff9cd15,0x00015dfe,0xfffb68a0,0x0000ecee, +0xfffd3a2e,0x0000757d,0xffff204b,0xfffffa1e, +0x00011054,0xffff7da1,0x0002fe9c,0xffff033e, +0x0004de57,0xfffe8dc6,0x0006a2d5,0xfffe213e, +0xfff9b77d,0x000118d3,0xfffb5bde,0x0000be25, +0xfffd3224,0x00005e52,0xffff1dc1,0xfffffb4b, +0x00011353,0xffff9740,0x00030748,0xffff351c, +0x0004ec95,0xfffed755,0x0006b5b4,0xfffe7fc6, +0xfff9a599,0x0000d334,0xfffb519f,0x00008f08, +0xfffd2bbf,0x00004704,0xffff1bc1,0xfffffc71, +0x00011598,0xffffb135,0x00030e43,0xffff6720, +0x0004f6f3,0xffff2119,0x0006c46e,0xfffedf38, +0xfff997c7,0x00008d13,0xfffb4a55,0x00005fa5, +0xfffd273b,0x00002f76,0xffff1a63,0xfffffda0, +0x00011744,0xffffcb67,0x000312ff,0xffff99cf, +0x0004ff0c,0xffff6a9c,0x0006cebd,0xffff3f0a, +0xfff98dbe,0x00004691,0xfffb4620,0x00003010, +0xfffd24fc,0x000017b5,0xffff199d,0xfffffed8, +0x0001185a,0xffffe5c6,0x0003157e,0xffffcce3, +0x000503ae,0xffffb515,0x0006d537,0xffff9f5a, +0xfff98767,0xfffb44b0,0xfffc3131,0xfffd2475, +0xfffe1c28,0xffff195d,0x00001859,0x000118bd, +0x000218df,0x0003163a,0x000410e0,0x000504a7, +0x0005f2b3,0x0006d796,0x0007b1fe,0xfff98537, +0xfffa609b,0xfffc7e8b,0x00028ef6,0xfffde181, +0x000144eb,0xffff5500,0xffffefb9,0x0000d01d, +0xfffe9755,0x000249a4,0xfffd453c,0x0003b80e, +0xfffc01aa,0x000511d6,0xfffad527,0xfffb334e, +0x0003c6b0,0xfffc5778,0x00026a92,0xfffdc9f5, +0x00013314,0xffff4d99,0xfffff0b6,0x0000d911, +0xfffeab80,0x00026369,0xfffd6c0a,0x0003e17f, +0xfffc39d8,0x000549df,0xfffb1eb2,0xfffafe6c, +0x0003916c,0xfffc3321,0x000244a6,0xfffdb402, +0x00012035,0xffff46ac,0xfffff192,0x0000e16a, +0xfffebfe0,0x00027b3d,0xfffd9433,0x0004087b, +0xfffc74b7,0x00057e8d,0xfffb6a81,0xfffacc1c, +0x00035929,0xfffc10df,0x00021e0c,0xfffd9f6d, +0x00010cb7,0xffff402e,0xfffff279,0x0000e965, +0xfffed574,0x00029159,0xfffdbdc4,0x00042c4c, +0xfffcb1e7,0x0005b02d,0xfffbb942,0xfffa9d38, +0x00031fbe,0xfffbf0fd,0x0001f5b4,0xfffd8c38, +0x0000f8b1,0xffff3a21,0xfffff391,0x0000f0e6, +0xfffeec44,0x0002a642,0xfffde90e,0x00044e32, +0xfffcf0fb,0x0005de46,0xfffc0b18,0xfffa71d1, +0x0002e44a,0xfffbd3de,0x0001cb90,0xfffd7a97, +0x0000e403,0xffff3490,0xfffff49c,0x0000f7a8, +0xffff0340,0x0002b95f,0xfffe1573,0x00046dbe, +0xfffd3284,0x00060888,0xfffc5f51,0xfffa4996, +0x0002a659,0xfffbb8df,0x0001a0e1,0xfffd6a4e, +0x0000ced2,0xffff2f75,0xfffff593,0x0000fdbe, +0xffff1a53,0x0002ca87,0xfffe42f5,0x0004898a, +0xfffd7563,0x00062f0b,0xfffcb5de,0xfffa2508, +0x00026786,0xfffba0bf,0x0001754a,0xfffd5b5f, +0x0000b92c,0xffff2acd,0xfffff6b0,0x0001034f, +0xffff3241,0x0002da5c,0xfffe71c6,0x0004a341, +0xfffdb946,0x000651e8,0xfffd0e37,0xfffa0402, +0x00022713,0xfffb8b9c,0x00014898,0xfffd4e7d, +0x0000a304,0xffff26b7,0xfffff7e1,0x00010846, +0xffff4b34,0x0002e897,0xfffea13f,0x0004ba63, +0xfffdff2d,0x00067115,0xfffd6839,0xfff9e680, +0x0001e4d4,0xfffb789e,0x00011b2e,0xfffd43a4, +0x00008c6e,0xffff2341,0xfffff8fd,0x00010c9c, +0xffff6469,0x0002f48f,0xfffed1a4,0x0004cd6a, +0xfffe4608,0x00068c1b,0xfffdc409,0xfff9cd15, +0x0001a1fa,0xfffb68a0,0x0000ecee,0xfffd3a2e, +0x0000757d,0xffff204b,0xfffffa1e,0x00011054, +0xffff7da1,0x0002fe9c,0xffff033e,0x0004de57, +0xfffe8dc6,0x0006a2d5,0xfffe213e,0xfff9b77d, +0x00015dfe,0xfffb5bde,0x0000be25,0xfffd3224, +0x00005e52,0xffff1dc1,0xfffffb4b,0x00011353, +0xffff9740,0x00030748,0xffff351c,0x0004ec95, +0xfffed755,0x0006b5b4,0xfffe7fc6,0xfff9a599, +0x000118d3,0xfffb519f,0x00008f08,0xfffd2bbf, +0x00004704,0xffff1bc1,0xfffffc71,0x00011598, +0xffffb135,0x00030e43,0xffff6720,0x0004f6f3, +0xffff2119,0x0006c46e,0xfffedf38,0xfff997c7, +0x0000d334,0xfffb4a55,0x00005fa5,0xfffd273b, +0x00002f76,0xffff1a63,0xfffffda0,0x00011744, +0xffffcb67,0x000312ff,0xffff99cf,0x0004ff0c, +0xffff6a9c,0x0006cebd,0xffff3f0a,0xfff98dbe, +0x00008d13,0xfffb4620,0x00003010,0xfffd24fc, +0x000017b5,0xffff199d,0xfffffed8,0x0001185a, +0xffffe5c6,0x0003157e,0xffffcce3,0x000503ae, +0xffffb515,0x0006d537,0xffff9f5a,0xfff98767, +0x00004691,0xfffa609b,0xfffb44b0,0xfffc3131, +0xfffd2475,0xfffe1c28,0xffff195d,0x00001859, +0x000118bd,0x000218df,0x0003163a,0x000410e0, +0x000504a7,0x0005f2b3,0x0006d796,0x0007b1fe, +0xfff98537,0xfffbd51e,0x00032dd1,0xfffd2d8f, +0x0001eb47,0xfffe9968,0x00009af6,0x000011de, +0xffff4335,0x00018d69,0xfffdecd4,0x000302f8, +0xfffca0d7,0x0004683d,0xfffb67f8,0x0005b36d, +0x00045963,0xfffba72a,0x00030062,0xfffd0dee, +0x0001d046,0xfffe8a0a,0x00009258,0x000012b1, +0xffff4d9e,0x00019ec3,0xfffe0a44,0x0003245a, +0xfffcd082,0x000498f0,0xfffba919,0x0005f304, +0x00041bf4,0xfffb7bf1,0x0002d19e,0xfffcf060, +0x0001b407,0xfffe7c08,0x0000894a,0x0000138d, +0xffff58ac,0x0001afaf,0xfffe28fe,0x000343bf, +0xfffd026f,0x0004c6f6,0xfffbed06,0x00062e61, +0x0003dc0e,0xfffb52c0,0x0002a17f,0xfffcd522, +0x000196a0,0xfffe6e70,0x00007ff6,0x00001439, +0xffff63f6,0x0001beb3,0xfffe4882,0x0003616d, +0xfffd361b,0x0004f1cf,0xfffc332a,0x0006658f, +0x00039943,0xfffb2d0c,0x00026ec7,0xfffcbb94, +0x0001789f,0xfffe6160,0x00007677,0x000014d4, +0xffff6f74,0x0001cc9b,0xfffe694f,0x00037cbf, +0xfffd6b41,0x000519c2,0xfffc7baf,0x00069971, +0x00035486,0xfffb0a7a,0x00023ad8,0xfffca3ee, +0x00015989,0xfffe55af,0x00006ca7,0x00001570, +0xffff7b71,0x0001d9cb,0xfffe8b46,0x0003959e, +0xfffda1fe,0x00053ee6,0xfffcc6b4,0x0006c950, +0x00030e08,0xfffaea7c,0x0002061e,0xfffc8ec0, +0x00013911,0xfffe4b1d,0x00006278,0x000015e8, +0xffff87b6,0x0001e577,0xfffeadd6,0x0003acc2, +0xfffdda34,0x00056059,0xfffd136d,0x0006f4b5, +0x0002c562,0xfffacdc3,0x0001cfa6,0xfffc7b14, +0x0001182b,0xfffe4159,0x00005817,0x0000165c, +0xffff9417,0x0001f00f,0xfffed14c,0x0003c199, +0xfffe13f6,0x00057e83,0xfffd61cd,0x00071ba1, +0x00027ab5,0xfffab482,0x00019833,0xfffc6989, +0x0000f6ca,0xfffe38da,0x00004d9d,0x000016ef, +0xffffa103,0x0001f98f,0xfffef5c0,0x0003d3d1, +0xfffe4f00,0x0005998c,0xfffdb21e,0x00073e77, +0x00022e75,0xfffa9e9b,0x00015fd1,0xfffc5b13, +0x0000d45d,0xfffe318f,0x000042ed,0x0000176b, +0xffffae8f,0x0002018f,0xffff1a91,0x0003e40c, +0xfffe8af2,0x0005b0ca,0xfffe03b8,0x00075d14, +0x0001e141,0xfffa8bb0,0x0001262a,0xfffc4e31, +0x0000b1af,0xfffe2b26,0x00003805,0x000017b1, +0xffffbc21,0x000208b8,0xffff3fb6,0x0003f1d7, +0xfffec7af,0x0005c4c5,0xfffe5654,0x0007768a, +0x000192fe,0xfffa7bec,0x0000ec3f,0xfffc4365, +0x00008ec9,0xfffe25f0,0x00002d05,0x000017ec, +0xffffc984,0x00020ec6,0xffff658d,0x0003fcba, +0xffff0500,0x0005d576,0xfffeaa37,0x00078bc6, +0x00014367,0xfffa6fc9,0x0000b1f4,0xfffc3b82, +0x00006b06,0xfffe2201,0x000021eb,0x00001823, +0xffffd704,0x0002132a,0xffff8be7,0x00040534, +0xffff4315,0x0005e22e,0xfffeff0a,0x00079ce3, +0x0000f33f,0xfffa671b,0x000076ca,0xfffc3558, +0x00004762,0xfffe1ef3,0x000016a1,0x0000183f, +0xffffe4a6,0x00021664,0xffffb27d,0x00040b7b, +0xffff81e5,0x0005eb4e,0xffff5475,0x0007a857, +0x0000a2cb,0xfffa6218,0x00003b64,0xfffc31e2, +0x00002416,0xfffe1ce1,0x00000b46,0x00001850, +0xfffff24d,0x00021855,0xffffd93a,0x00040f75, +0xffffc0e6,0x0005f0e3,0xffffaa3e,0x0007af45, +0x0000519f,0x00030000,0x000f0007,0x003f001f, +0x00ff007f,0x03ff01ff,0x0fff07ff,0x3fff1fff, +0xffff7fff,0x00030000,0x00070005,0x000f0009, +0x003f001f,0x00ff007f,0x03ff01ff,0x0fff07ff, +0xffff1fff,0x00030000,0x00070005,0x000f0009, +0xffff001f,0x00030000,0xffff0005,0x04030504, +0x08070605,0x0c0b0a09,0x100f0e0d,0x03070504, +0x0605040a,0x0a090807,0x100d0c0b,0x03070503, +0x1005040a,0x10070502,0x03030100,0x03030303, +0x03030303,0x03030303,0x03010100,0x03030301, +0x03030303,0x03030303,0x03010100,0x03030301, +0x03010100,0x04020000,0x08070605,0x0c0b0a09, +0x100f0e0d,0x02010000,0x06050403,0x0a090807, +0x100d0c0b,0x02010000,0x10050403,0x10010000, +0x00030000,0x00090005,0x001f000f,0x007f003f, +0x01ff00ff,0x07ff03ff,0x1fff0fff,0x7fff3fff, +0x00030000,0x00090005,0x001f000f,0x007f003f, +0x0a070504,0x07060504,0x0b0a0908,0x0f0e0d0c, +0x0a070503,0x07060504,0x01010100,0x03030303, +0x03030303,0x03030303,0x01010100,0x03030303, +0x03010000,0x07060504,0x0b0a0908,0x0f0e0d0c, +0x03010000,0x07060504,0x00555555,0x002aaaab, +0x00249249,0x00124925,0x00111111,0x00088889, +0x00084210,0x00421084,0x00041041,0x00020821, +0x00020408,0x00081020,0x00010101,0x00008081, +0x00008040,0x00100804,0x00004010,0x00020080, +0x00002004,0x00004008,0x00001001,0x00000801, +0x00000800,0x00200100,0x00000400,0x00080020, +0x00000200,0x00020004,0x00200000,0x00600040, +0x00a00080,0x00e000c0,0x01200100,0x01600140, +0x01a00180,0x000001c0,0x00300020,0x00400038, +0x00600050,0x00800070,0x00c000a0,0x010000e0, +0x01800140,0x00200000,0x00300028,0x00400038, +0x00600050,0x00800070,0x00c000a0,0x010000e0, +0x00000140,0x00900000,0x00fc00d8,0x01680120, +0x01f801b0,0x02d00240,0x03f00360,0x05a00480, +0x000006c0,0x00680000,0x00b6009c,0x010500d0, +0x016d0139,0x020a01a1,0x02db0272,0x04140343, +0x000004e5,0x006c0000,0x00bd00a2,0x010e00d8, +0x017a0144,0x006301b0,0x013b00cf,0x00c601a7, +0x0000019e,0x00600000,0x00a80090,0x00f000c0, +0x01500120,0x01e00180,0x02a00240,0x03c00300, +0x00000480,0x10000000,0x10101010,0x20101010, +0x20202020,0x20202020,0x28202020,0x28282828, +0x00002828,0x10100000,0x10101010,0x10101010, +0x00000000,0x00000000,0x00000000,0x00000000, +0xcbcecdc4,0xcfcac9c8,0xc3c6c5cc,0xc7c2c1c0, +0x1b1e1d14,0x1f1a1918,0x1316151c,0x17121110, +0x2b2e2d24,0x2f2a2928,0x2326252c,0x27222120, +0x3b3e3d34,0x3f3a3938,0x3336353c,0x37323130, +0x0b0e0d04,0x0f0a0908,0x0306050c,0x07020100, +0xdbdeddd4,0xdfdad9d8,0xd3d6d5dc,0xd7d2d1d0, +0xebeeede4,0xefeae9e8,0xe3e6e5ec,0xe7e2e1e0, +0xfbfefdf4,0xfffaf9f8,0xf3f6f5fc,0xf7f2f1f0, +0x4b4e4d44,0x4f4a4948,0x4346454c,0x47424140, +0x9b9e9d94,0x9f9a9998,0x9396959c,0x97929190, +0xabaeada4,0xafaaa9a8,0xa3a6a5ac,0xa7a2a1a0, +0xbbbebdb4,0xbfbab9b8,0xb3b6b5bc,0xb7b2b1b0, +0x8b8e8d84,0x8f8a8988,0x8386858c,0x87828180, +0x5b5e5d54,0x5f5a5958,0x5356555c,0x57525150, +0x6b6e6d64,0x6f6a6968,0x6366656c,0x67626160, +0x7b7e7d74,0x7f7a7978,0x7376757c,0x77727170, +0x341424c4,0x3e1e2ece,0x3d1d2dcd,0x3b1b2bcb, +0xb494a444,0xbe9eae4e,0xbd9dad4d,0xbb9bab4b, +0xf4d4e404,0xfedeee0e,0xfddded0d,0xfbdbeb0b, +0x74546484,0x7e5e6e8e,0x7d5d6d8d,0x7b5b6b8b, +0x3c1c2ccc,0x361626c6,0x351525c5,0x331323c3, +0xbc9cac4c,0xb696a646,0xb595a545,0xb393a343, +0xfcdcec0c,0xf6d6e606,0xf5d5e505,0xf3d3e303, +0x7c5c6c8c,0x76566686,0x75556585,0x73536383, +0x381828c8,0x3a1a2aca,0x391929c9,0x3f1f2fcf, +0xb898a848,0xba9aaa4a,0xb999a949,0xbf9faf4f, +0xf8d8e808,0xfadaea0a,0xf9d9e909,0xffdfef0f, +0x78586888,0x7a5a6a8a,0x79596989,0x7f5f6f8f, +0x301020c0,0x321222c2,0x311121c1,0x371727c7, +0xb090a040,0xb292a242,0xb191a141,0xb797a747, +0xf0d0e000,0xf2d2e202,0xf1d1e101,0xf7d7e707, +0x70506080,0x72526282,0x71516181,0x77576787, +0x05040100,0x15141110,0x25242120,0x35343130, +0x85848180,0x95949190,0xa5a4a1a0,0xb5b4b1b0, +0xc0408000,0xe060a020,0xd0509010,0xf070b030, +0xc8488808,0xe868a828,0xd8589818,0xf878b838, +0xc4448404,0xe464a424,0xd4549414,0xf474b434, +0xcc4c8c0c,0xec6cac2c,0xdc5c9c1c,0xfc7cbc3c, +0xc2428202,0xe262a222,0xd2529212,0xf272b232, +0xca4a8a0a,0xea6aaa2a,0xda5a9a1a,0xfa7aba3a, +0xc6468606,0xe666a626,0xd6569616,0xf676b636, +0xce4e8e0e,0xee6eae2e,0xde5e9e1e,0xfe7ebe3e, +0xc1418101,0xe161a121,0xd1519111,0xf171b131, +0xc9498909,0xe969a929,0xd9599919,0xf979b939, +0xc5458505,0xe565a525,0xd5559515,0xf575b535, +0xcd4d8d0d,0xed6dad2d,0xdd5d9d1d,0xfd7dbd3d, +0xc3438303,0xe363a323,0xd3539313,0xf373b333, +0xcb4b8b0b,0xeb6bab2b,0xdb5b9b1b,0xfb7bbb3b, +0xc7478707,0xe767a727,0xd7579717,0xf777b737, +0xcf4f8f0f,0xef6faf2f,0xdf5f9f1f,0xff7fbf3f, +0x1045a3e2,0x000000f4,0x263b7333,0x766b2363, +0x2b367e3e,0x7b662e6e,0x06db93d3,0x964b0343, +0x0bd69ede,0x9b460e4e,0x825f1757,0x12cf87c7, +0x8f521a5a,0x1fc28aca,0x00d199d9,0x90410949, +0x01d098d8,0x91400848,0x24357d3d,0x74652d6d, +0x25347c3c,0x75642c6c,0x04d59ddd,0x94450d4d, +0x05d49cdc,0x95440c4c,0x80511959,0x10c189c9, +0x81501858,0x11c088c8,0x02df97d7,0x924f0747, +0x0fd29ada,0x9f420a4a,0x865b1353,0x16cb83c3, +0x8b561e5e,0x1bc68ece,0xa6bbf3b3,0xf6eba3e3, +0xabb6febe,0xfbe6aeee,0x223f7737,0x726f2767, +0x2f327a3a,0x7f622a6a,0xa0b1f9b9,0xf0e1a9e9, +0xa1b0f8b8,0xf1e0a8e8,0x84551d5d,0x14c58dcd, +0x85541c5c,0x15c48ccc,0xa4b5fdbd,0xf4e5aded, +0xa5b4fcbc,0xf5e4acec,0x20317939,0x70612969, +0x21307838,0x71602868,0xa2bff7b7,0xf2efa7e7, +0xafb2faba,0xffe2aaea,0x00000000,0x00000000, + +}; + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/mpg_240.h linux.19pre5-ac1/drivers/media/video/ls220/mpg_240.h --- linux.19p5/drivers/media/video/ls220/mpg_240.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/ls220/mpg_240.h Thu Feb 21 21:27:18 2002 @@ -0,0 +1,1594 @@ +static u32 MPG240Ucode1f1800[] = { +0x820f001f,0x802f001f,0xb500000d,0x00000000, +0x00ffb81e,0x00000000,0x00000000,0x00000000, +0x00ffb81e,0x00000000,0x00000000,0x00000000, +0xb5000b5f,0x00000000,0x00000000,0x00000000, +0x80070800,0x001f6047,0x8013001f,0x90208000, +0x003fb174,0x803effe8,0x803effec,0x9020fa00, +0x803effd0,0x803effdc,0x803effd8,0x9020fe00, +0x803effd4,0x805bff7c,0x802500d4,0x94020080, +0xb0000000,0xb4200023,0x8013ffcf,0x9800cfff, +0x80730030,0x98631000,0x94420007,0xb0020002, +0xb4200005,0x8013ffc7,0x9800c7ff,0x80730038, +0x98631000,0xb5000006,0xb0020001,0xb4200004, +0x8013ffcf,0x9800cfff,0x80730030,0x98631000, +0x1421b800,0x1821b803,0x802600d4,0x8033001f, +0x98210000,0x802600a2,0x8033001f,0x98210300, +0x802600a3,0x80270225,0x80530001,0x98420100, +0x1821b802,0x80530200,0x98420000,0x804600a6, +0xb500001d,0x805bff7c,0x8013ffcf,0x9800cfff, +0x80730030,0x98631000,0x94420007,0xb0020002, +0xb4200005,0x8013ffc7,0x9800c7ff,0x80730038, +0x98631000,0xb5000006,0xb0020001,0xb4200004, +0x8013ffcf,0x9800cfff,0x80730030,0x98631000, +0x1421b800,0x1821b803,0x802600d4,0x8033001f, +0x98210000,0x802600a2,0x8033001f,0x98210300, +0x802600a3,0x80270c25,0x802600a1,0x80270002, +0x803eff84,0x80070000,0x801effc0,0x801effc4, +0x801effc8,0x801effcc,0x801eff88,0x80770000, +0x8057ffff,0x80170080,0x80070000,0xb6003f02, +0xb6002001,0x001fa020,0x8007ffff,0x801eff84, +0x80070001,0x001f25dc,0x001f20b1,0x80070000, +0x001f6046,0x001fb17c,0x001fb17d,0x80070000, +0x801e78d0,0x98004000,0x001f62ea,0x80070100, +0x801efff0,0x81df0004,0x00000000,0x00000000, +0x801bfff0,0x00000000,0x940000ff,0xb0000000, +0xb4200057,0x003f42ea,0x94010010,0xb0000000, +0xb400fff7,0x003f05dc,0xb0010001,0xb4200034, +0x803bffe8,0x801bffec,0x00000000,0x3001b800, +0xb4600001,0x90214000,0x0421b800,0xb0010800, +0xb460000d,0x80050086,0x005f902e,0xb0020000, +0xb4200002,0x001fb02e,0xb5000006,0x0420b802, +0xb0010930,0xb4a0ffe2,0x80070000,0x001fb02e, +0x83e40146,0xb500ffde,0x83e40111,0x80070000, +0x001fb02e,0x001f42ea,0x9400000f,0xb0000000, +0xb4000010,0x9400fff0,0x001f62ea,0x003f9174, +0x9421ffff,0x90210004,0xb001c000,0xb4800002, +0x8421c000,0x90218000,0x8013001f,0x1821b800, +0x003fb174,0x003f917c,0x90210004,0x003fb17c, +0x83e4012e,0x8013001f,0x83e71b0c,0x1bffb800, +0x003f9179,0x1821b800,0x00ffb801,0xb5000008, +0x80270000,0x003f25dc,0x8013001f,0x83e71b30, +0x1bffb800,0x003f917a,0x1821b800,0x00ffb801, +0x80070000,0x001f20b1,0x001f42ea,0x9420000f, +0xb0010000,0xb4200003,0x98000800,0x001f62ea, +0xb500ffaf,0x9400fff0,0x001f62ea,0x80270000, +0x8057ffff,0x80770000,0x80171800,0xb6000302, +0xb6002001,0x001fa021,0xb500ffa5,0xb500ffa4, +0x803bffc0,0x805bffc4,0x807bffc8,0x809bffcc, +0x5828b801,0x5cb8b802,0x1821b805,0x5848b802, +0x5cb8b803,0x1842b805,0x5868b803,0x5cb8b804, +0x1863b805,0x5888b804,0x1884b800,0x803effc0, +0x805effc4,0x807effc8,0x809effcc,0x003f42ea, +0xb0000086,0xb4400079,0xb0000084,0xb4000049, +0xb0000085,0xb4000063,0xb0000086,0xb400006c, +0xb0000081,0xb4000005,0xb0000082,0xb4000003, +0xb0000080,0xb4000001,0xb5000069,0x8013007f, +0x9800ffff,0x001fb02d,0x80070000,0x001fb17c, +0x8013001f,0x9040fa00,0x805effd0,0x805effdc, +0x805effd8,0x9040fe00,0x805effd4,0x9040c000, +0x805effe4,0x90008000,0x801effe0,0x001fb174, +0x801effe8,0x801effec,0x80078000,0x801e78d4, +0x80070000,0x001fb17c,0x001fb17d,0x001fb02e, +0x83e400ce,0x8013001f,0x98000000,0x800600a2, +0x8013001f,0x98000300,0x800600a3,0x805bff7c, +0x80070c25,0x94420080,0xb0020080,0xb420000d, +0x8013001f,0x98000000,0x800600a2,0x8013001f, +0x98000300,0x800600a3,0x80070225,0x80530001, +0x98420100,0x1800b802,0x80530200,0x98420000, +0x804600a6,0x800600a1,0x80050080,0x98000022, +0x80060080,0x80072000,0x001fb179,0x80074360, +0x001fb17a,0x80070001,0x001f25dc,0x98214000, +0xb5000029,0x8047ffff,0x805eff84,0x805bff88, +0x00000000,0xb0020001,0xb4200002,0x80470000, +0x805eff88,0x805bff7c,0x80070c25,0x94420080, +0xb0020080,0xb4200007,0x80070225,0x80530001, +0x98420100,0x1800b802,0x80530200,0x98420000, +0x804600a6,0x800600a1,0x80070001,0x800600a0, +0x9421efff,0x98210010,0xb500000f,0x80070000, +0x001fb17c,0x80070001,0x001f25dc,0x83e4008b, +0x80050081,0x80330008,0x98210000,0x1800b801, +0x80060081,0x003f42ea,0x9421ffef,0xb5000002, +0x98211000,0x9421ffef,0x83e40080,0x003f62ea, +0x80070100,0x801efff0,0xb500ff15,0xb000008b, +0xb400001c,0xb0000087,0xb400ffe8,0xb0000088, +0xb4000023,0xb000008a,0xb4000024,0xb000008c, +0xb4000019,0xb000008e,0xb4000014,0xb000008d, +0xb400001d,0xb0000089,0xb400001f,0xb00000a0, +0xb4000021,0xb00000a1,0xb4000022,0xb00000a2, +0xb400002b,0xb00000a3,0xb4000027,0xb00000a4, +0xb4000029,0xb00000a5,0xb4000029,0xb00000a6, +0xb4000029,0x803efff8,0xb500ffdd,0x80070000, +0x001fb17e,0xb500ffda,0x803bffb0,0x00000000, +0x003fb02d,0xb500ffd6,0x98210020,0xb500ffd2, +0x9421ffdf,0xb500ffd0,0xb500ffd1,0x80270341, +0x803efff8,0xb500ffce,0x803bff80,0x00000000, +0x003f62ef,0xb500ffca,0x003f917b,0x803efff8, +0xb500ffc7,0x80270000,0x8047fef0,0x003eb802, +0x90420004,0x003eb802,0x90420004,0x003eb802, +0x90420004,0x003eb802,0x83640d7c,0xb500ffbc, +0x83640d2a,0xb500ffba,0x83640ce9,0xb500ffb8, +0x83440c50,0xb500ffb6,0x83440c39,0xb500ffb4, +0x817bffe8,0x815b78d4,0x00000000,0x956bffff, +0x300bb80a,0xb4600001,0x916b4000,0x056bb80a, +0xb00b0080,0xb4a00026,0x80af001f,0x808f0000, +0x806f0000,0x81b300ff,0x8057ffff,0x5d67b80b, +0x5d42b80a,0xb62b001c,0xb00a3000,0xb4800001, +0x854a1000,0x80cf0400,0x015fb178,0x5942b80a, +0x01cfb80a,0x015f9178,0xb520ffff,0x80171000, +0xb600200a,0x01ff8000,0x5a18b80f,0x5a28b80f, +0x1631b80d,0x5e48b80f,0x9652ff00,0x5e78b80f, +0x1a73b810,0x1a73b811,0x1813a032,0x80cf0400, +0x015fb178,0x5942b80a,0x01afb80a,0x015f9178, +0xb520ffff,0x914a0020,0x5942b80a,0x815e78d4, +0x00000000,0x00000000,0x00ffb81f,0x80070000, +0x80470000,0x81171800,0xb6002003,0xb6003002, +0x001eb802,0x90420004,0xb6002003,0x011fa020, +0x011fa020,0x011fa020,0x00ffb81f,0x80070000, +0x80478000,0xb6002003,0xb6008002,0x001eb802, +0x90420004,0x00ffb81f,0x00000000,0x00000000, +0x015f42ea,0x944a4000,0xb0024000,0xb4200071, +0x954abfff,0x015f62ea,0x808f0000,0x80ef007c, +0x80171000,0x80971400,0x80270000,0xb6001003, +0xb6002002,0x001fa021,0x009fa021,0x80a76604, +0x80271400,0xb6001004,0x01efb801,0x01afb805, +0xb520ffff,0x90a50080,0x80a76e04,0x80271400, +0xb6001004,0x01efb801,0x01afb805,0xb520ffff, +0x90a50080,0x806f001f,0x80af001f,0x80276400, +0x5c22b801,0x806701e1,0x00cfb803,0x003fb178, +0x5822b801,0x01cfb801,0x003f9178,0x0047b86f, +0xb0020001,0xb4c0fffd,0x80275c00,0x5c22b801, +0x80670200,0xb600100a,0x00cfb803,0x003fb178, +0x5822b801,0x01cfb801,0x003f9178,0x0047b86f, +0xb0020001,0xb4c0fffd,0x90210020,0x90630020, +0x808f0000,0x806f001f,0x80af001f,0x8027647c, +0x5c22b801,0x8067017e,0xb600020a,0x00cfb803, +0x003fb178,0x5822b801,0x01cfb801,0x003f9178, +0x0047b86f,0xb0020001,0xb4c0fffd,0x90210020, +0x90630020,0x806f0010,0x80af0010,0x8027657c, +0x5c22b801,0x806701be,0x00cfb803,0x003fb178, +0x5822b801,0x01cfb801,0x003f9178,0x0047b86f, +0xb0020001,0xb4c0fffd,0x802765c0,0x5c22b801, +0x806701cf,0x00cfb803,0x003fb178,0x5822b801, +0x01cfb801,0x003f9178,0x0047b86f,0xb0020001, +0xb4c0fffd,0x80276000,0x005fb801,0x8033001f, +0x98218000,0x803effe0,0x90214000,0x803effe4, +0x8193001f,0x998c8000,0x019fb174,0x83270000, +0x003fb819,0x003f9174,0x5823b801,0x83338000, +0x1b39b801,0x003fb819,0x00000000,0x00000000, +0x81550000,0x0187b860,0x858c0040,0x81b380fc, +0x99ad0000,0x300cb80d,0xb4600003,0x81b30002, +0x99ad0000,0x118cb80d,0x003fb80c,0x00000000, +0x00000000,0x81550000,0x8257ffff,0x82d7ffff, +0x8357ffff,0x81672000,0x83440189,0xb00a0001, +0xb4000141,0x0187b860,0x858c0010,0x5988b80c, +0x5d8bb80c,0x958cffff,0xb00cc000,0xb4800002, +0x858cc000,0x918c8000,0x81b3001f,0x198cb80d, +0x801bffec,0x00000000,0x819effec,0x819e78d8, +0x019fb174,0x05acb800,0x300cb800,0xb4600001, +0x91ad4000,0x001f917c,0x1000b80d,0x001fb17c, +0x83440194,0xb00a0000,0xb4200127,0x015f0081, +0xb00a0002,0xb4200124,0x037f0082,0xb01b0000, +0xb400001e,0x0367b860,0x5b68b81b,0x5f68b81b, +0x017f4047,0x916b0010,0x5963b80b,0x83440160, +0x801bff84,0xb00a0001,0xb400000b,0xb00b00c0, +0xb460fffa,0x803f0000,0x80138000,0x1b7bb800, +0x003fb81b,0x00000000,0x00000000,0x80150000, +0x801bff84,0xb5000009,0x803f0000,0x80138000, +0x1b7bb800,0x003fb81b,0x00000000,0x00000000, +0x80150000,0x801bff84,0xb5000103,0x801bff84, +0x003f0084,0x3000b801,0x803eff84,0xb4000073, +0x801bff7c,0x00000000,0x94800080,0xb0040080, +0xb4200036,0x94800007,0x80730200,0xb0010002, +0xb420000e,0x80270265,0xb0040001,0xb4200003, +0x80130030,0x98000000,0xb5000006,0x80130030, +0x98000000,0xb0040000,0xb4000002,0x80130038, +0x98000000,0x98630060,0xb500001f,0xb0010000, +0xb420000e,0x80270225,0xb0040001,0xb4200003, +0x80130030,0x98001000,0xb5000006,0x80130030, +0x98001000,0xb0040000,0xb4000002,0x80130038, +0x98001000,0x98630000,0xb500000f,0xb0010001, +0xb420004a,0x80270225,0xb0040001,0xb4200003, +0x80130030,0x98002000,0xb5000006,0x80130030, +0x98000000,0xb0040000,0xb4000002,0x80130038, +0x98000000,0x98630040,0x806600a6,0x80530001, +0x98420100,0x1821b802,0xb500002d,0x94800007, +0xb0010002,0xb420000d,0x80270c65,0xb0040001, +0xb4200003,0x80130030,0x98000000,0xb5000006, +0x80130030,0x98000000,0xb0040000,0xb4000002, +0x80130038,0x98000000,0xb500001d,0xb0010000, +0xb420000d,0x80270c25,0xb0040001,0xb4200003, +0x80130030,0x98001000,0xb5000006,0x80130030, +0x98001000,0xb0040000,0xb4000002,0x80130038, +0x98001000,0xb500000e,0xb0010001,0xb4200017, +0x80270c25,0xb0040001,0xb4200003,0x80130030, +0x98002000,0xb5000006,0x80130030,0x98000000, +0xb0040000,0xb4000002,0x80130038,0x98000000, +0x806500d4,0x8053ffcf,0x9842cfff,0xb0040002, +0xb4200002,0x8053ffc7,0x9842c7ff,0x802600a1, +0x1463b802,0x1863b800,0x806600d4,0x807bff7c, +0x00000000,0x94630080,0xb0030080,0xb420000b, +0x807bff88,0x00000000,0xb0030001,0xb4000007, +0x802500a1,0x80670001,0x807eff88,0x80530001, +0x98420100,0x1821b802,0x802600a1,0x81070000, +0x011f62e2,0x011f62e3,0x011f0082,0xb0080000, +0xb4200004,0x81150010,0x00000000,0x00000000, +0x011f62de,0x011f0081,0xb0080001,0xb4200026, +0x81070020,0x011f25c1,0x81070180,0x011f62e1, +0x8344022a,0x8344024e,0x011f0082,0xb0080000, +0xb4200004,0x834401b1,0x8344019e,0xb00a0000, +0xb4200061,0x80c70000,0x00df25cb,0x83440261, +0x834405e7,0x02ff05b9,0x82a70000,0x82870000, +0x834403cf,0x92940001,0x3014b817,0xb480fffc, +0x8344067f,0x80270000,0x003f25dc,0x83440760, +0x003f05dc,0xb0010001,0xb4000003,0x802725d4, +0x003fb17a,0x00ffb81f,0x80d3001f,0x834725ac, +0x1b5ab806,0xb500002d,0xb0080002,0x81470004, +0xb4200045,0x81070008,0x011f25c1,0x81070480, +0x011f62e1,0x83440276,0x834402b0,0x011f0082, +0xb0080000,0xb4200004,0x8344019a,0x83440175, +0xb00a0000,0xb4200038,0x80c70000,0x00df25cb, +0x83440334,0x02df05cb,0x5ec2b816,0x834405ff, +0x02ff05b9,0x82a70000,0x82870000,0x834403a4, +0x92940001,0x3014b817,0xb480fffc,0x92b50001, +0xb0150003,0xb480fff8,0x83440651,0x80270000, +0x003f25dc,0x83440732,0x003f05dc,0xb0010001, +0xb4000003,0x8027268c,0x003fb17a,0x00ffb81f, +0x80d3001f,0x83472650,0x1b5ab806,0x80db78d8, +0x80fbffec,0x00000000,0x3006b807,0xb4200007, +0x00df05cb,0x90c60001,0x00df25cb,0xb006000c, +0xb4000002,0x035fb179,0x00ffb81f,0x80c70000, +0x00df25cb,0x80fb78dc,0x00000000,0x90e70001, +0xb00701b9,0xb4a00001,0x80e70001,0x80fe78dc, +0xb500feb0,0x802500a5,0x8153001f,0x3001b80a, +0xb420fffc,0x00ffb81f,0x001f42ea,0x1800b80a, +0x001f62ea,0x017f4047,0x5963b80b,0x0187b860, +0x118cb80b,0x81b380fe,0x99ad0000,0x300cb80d, +0xb4800003,0x81b30002,0x99ad0000,0x058cb80d, +0x003fb80c,0x00000000,0x00000000,0x81550000, +0x0187b860,0x5988b80c,0x5d8bb80c,0x958cffff, +0xb00cc000,0xb4800002,0x858cc000,0x918c8000, +0x81b3001f,0x198cb80d,0x801bffec,0x00000000, +0x819effec,0x019fb174,0x05acb800,0x300cb800, +0xb4600001,0x91ad4000,0x001f917c,0x1000b80d, +0x001fb17c,0x80171000,0x80971400,0x80270000, +0xb6001003,0xb6002002,0x001fa021,0x009fa021, +0x80171800,0xb6000602,0xb6002001,0x001fa021, +0x806f001f,0x80af001f,0x80a76604,0x80271400, +0xb6001004,0x01efb801,0x01afb805,0xb520ffff, +0x90a50080,0x80a76e04,0x80271400,0xb6001004, +0x01efb801,0x01afb805,0xb520ffff,0x90a50080, +0x81472000,0x015fb179,0x00ffb81f,0x00000000, +0x811be024,0x0107b860,0x95080007,0xb0080000, +0xb4000004,0xa5080008,0x00000000,0x0155b808, +0x00000000,0x8115000c,0x856b000c,0xb0080fff, +0xb400000b,0x81550004,0x856b0004,0x5904b808, +0x1908b80a,0x95080fff,0xb0080fff,0xb4000004, +0x81470001,0xb00b0020,0xb440fff6,0xb500000c, +0x81d50004,0x856b0004,0x00000000,0xb00e000f, +0xb400fffb,0x940b0007,0xb0000000,0xb420ffed, +0x001f42ea,0x9400fffe,0x81470000,0x001f62ea, +0x00ffb81a,0x950e0008,0x5d03b808,0x00000000, +0xb0080000,0xb40000c9,0x011f2080,0x950e0006, +0x5d01b808,0x81270004,0x0529b808,0x950e0001, +0x013f2081,0x011f2082,0x81150004,0x00000000, +0xb0080000,0xb40000bd,0xb008000f,0xb40000bb, +0x011f2083,0x81150002,0x00000000,0x81670004, +0xb0080002,0xb46000b5,0x011f2084,0x013f0081, +0xb0090002,0xb4200011,0x013f0083,0xb0080000, +0xb4200002,0x81077844,0xb5000005,0xb0080001, +0xb4200002,0x81077884,0xb5000001,0x81077824, +0x013f0083,0x5921b809,0x1129b808,0x0119b809, +0x00000000,0x00000000,0x011f6047,0x81150001, +0x00000000,0x011f2085,0x81150001,0x00000000, +0x011f2086,0x81350002,0x00000000,0x013f2087, +0x81150002,0x00000000,0x011f2088,0x81150001, +0x00000000,0x011f2089,0x81150001,0x00000000, +0x011f208a,0x81150002,0x00000000,0x011f208b, +0x81070001,0xb0090003,0xb4000001,0x81070002, +0x011f25b9,0x81070020,0x013f0081,0xb0090002, +0xb4200065,0x85290001,0xad29000f,0x00000000, +0x011f0083,0x1108b809,0x5901b808,0x910877c8, +0x0139b808,0x011f05b9,0x85080001,0x6928b809, +0x011f0084,0xb0090038,0xb4800007,0xb0080001, +0xb4000002,0xb0090050,0xb4400003,0x81270000, +0x8107001b,0xb5000010,0xb0080001,0xb4000005, +0xb0090060,0xb4800003,0x81270001,0x8107001e, +0xb5000009,0xb0080002,0xb4000005,0xb0090030, +0xb4400003,0x81270002,0x81070008,0xb5000002, +0x81270003,0x8107000c,0x011f25bb,0x013f25c0, +0xb0090002,0xb460001b,0x80477604,0x5c42b802, +0x814fffc0,0x80cf0037,0x005fb178,0x5842b802, +0x01cfb802,0x005f9178,0xb520ffff,0x90420020, +0x814fb580,0x80cf0057,0x005fb178,0x5842b802, +0x01cfb802,0x005f9178,0xb520ffff,0x804778a4, +0x5c42b802,0x814f39c0,0x80cf002f,0x005fb178, +0x5842b802,0x01cfb802,0x005f9178,0xb520ffff, +0xb5000021,0x804776e0,0x5c42b802,0x814fef40, +0x80cf0037,0x005fb178,0x5842b802,0x01cfb802, +0x005f9178,0xb520ffff,0x8297013c,0x8317018c, +0xb6000602,0x005f8034,0x031fa022,0x82970124, +0x83170160,0xb6000602,0x005f8034,0x031fa022, +0x8297010c,0x83170134,0xb6000602,0x005f8034, +0x031fa022,0x804778c4,0x5c42b802,0x814f1080, +0x80cf002f,0x005fb178,0x5842b802,0x01cfb802, +0x005f9178,0xb520ffff,0x013f0081,0xb0090001, +0xb420000e,0x808f0000,0x806f001b,0x80af001b, +0x80277758,0x5c22b801,0x80670037,0x00cfb803, +0x003fb178,0x5822b801,0x01cfb801,0x003f9178, +0x0047b86f,0xb0020001,0xb4c0fffd,0x011f25bb, +0x011f0087,0xb0080001,0xb4000002,0x011f05bb, +0xb5000003,0x011f0088,0x91080001,0x5902b808, +0x011f25ba,0x81470000,0x00ffb81a,0x81470008, +0x00ffb81a,0x81270000,0x81470000,0x300842de, +0xb400000b,0x013f42e2,0x91290001,0x013f62e2, +0x013f42e3,0x91290001,0x013f62e3,0x83640006, +0x00000000,0x00000000,0x013f42e2,0x81470002, +0x013f62e2,0x00ffb81a,0x00ffb81b,0x83640041, +0x80c70004,0x80270000,0xb600200d,0x00ff05b9, +0x5c42b801,0x300205ba,0xb4800001,0x80e70001, +0x80470000,0xb6270005,0x1062b801,0x914301b8, +0x00fff00a,0x83840050,0x90420080,0x90210004, +0x00ffb81a,0x8364002f,0x017f05bb,0x800700bc, +0x80270000,0xb00b0000,0xb4000015,0xb62b0014, +0x00ff05b9,0x5c42b801,0x300205ba,0xb4800001, +0x80e70001,0x80470000,0xb0070000,0xb400000b, +0xb627000a,0x1062b801,0x914301b8,0x00fff00a, +0x5c62b801,0x1063b800,0x00bff003,0x90650134, +0x00dff003,0x83840034,0x90420080,0x90210004, +0x019f05b9,0x80c70002,0x80270000,0xb00b0000, +0xb400000f,0xb62b000e,0x80470000,0xb00c0000, +0xb400000a,0xb62c0009,0x1062b801,0x914301b8, +0x00fff00a,0xb0070000,0xb4000003,0x906302b8, +0x00fff003,0x83840020,0x90420080,0x90210004, +0x00ffb81a,0x8107ffff,0x80c70004,0x00ff0083, +0x83840019,0x80c70002,0x00ff0084,0x83840016, +0x80c70001,0x00ff0085,0x83840013,0x80c70001, +0x00ff0086,0x83840010,0x80c70002,0x00ff0087, +0x8384000d,0x80c70002,0x00ff0088,0x8384000a, +0x80c70001,0x00ff0089,0x83840007,0x80c70001, +0x00ff008a,0x83840004,0x80c70002,0x00ff008b, +0x83840001,0x00ffb81b,0x80a70001,0x64a6b805, +0x5ca1b805,0xb0050000,0xb400000e,0x95288000, +0xb0090000,0xb4000001,0x81270001,0x5901b808, +0x1547b805,0xb00a0000,0xb4000001,0x81470001, +0x2129b80a,0xb0090000,0xb4000001,0xa1088005, +0xb500ffef,0x9508ffff,0x00ffb81c,0x015f05ba, +0x013f05b9,0x800700bc,0xb0090000,0xb400000f, +0xb00a0000,0xb400000d,0x80270000,0xb62a000b, +0x80470000,0xb6290008,0x80950004,0x5865b802, +0x1063b801,0x5862b803,0x906301b8,0x0217b803, +0x90420001,0x021fa004,0x90210001,0xa54a0020, +0xb4c0000e,0xb0090000,0xb400000c,0xb62a000b, +0x80950004,0x80470000,0xb6290007,0x5865b802, +0x1063b801,0x5862b803,0x906301b8,0x0217b803, +0x90420001,0x021fa004,0x90210001,0x00ffb81a, +0x013f05b9,0xb0090000,0xb4000019,0x80270000, +0xb6002017,0x80470000,0xb6290014,0x5865b802, +0x1063b801,0x5862b803,0x914301b8,0x009ff00a, +0xad420060,0x00000000,0x114ab801,0x5942b80a, +0x914a1c80,0x0217b80a,0xb0040000,0xb4000004, +0x80950006,0x00000000,0x021fa004,0xb5000002, +0x8087003f,0x021fa004,0x90420001,0x90210001, +0x00ffb81a,0x8257ffff,0x82d7ffff,0x011f05ba, +0x013f05b9,0x80270000,0xb0090000,0xb400002b, +0xb6280015,0x80470000,0xb6290012,0x5865b802, +0x1063b801,0x5862b803,0x914301b8,0xaca20060, +0x009ff00a,0x10a5b801,0x58a2b805,0x90a502b8, +0x0217b805,0x80670000,0xb0040000,0xb4000003, +0x90840001,0x0075b804,0x00000000,0x021fa003, +0x90420001,0x90210001,0xa5480020,0xb4000013, +0x5822b801,0xb62a0011,0x914101b8,0x90a102b8, +0x0217b805,0x009ff00a,0xb0040000,0x80670000, +0xb4000002,0x90840001,0x0075b804,0xb6290006, +0x021fa203,0x009f8210,0x009f8210,0x009f8210, +0x009f8210,0x009f8210,0x90210004,0x00ffb81a, +0x015f05ba,0x013f05b9,0x800700bc,0xb0090000, +0xb4000013,0xb00a0000,0xb4000011,0x80270000, +0xb62a000f,0x80470000,0xb629000c,0x1080b801, +0x007ff004,0x90830134,0x007ff004,0x0095b803, +0x5865b802,0x1063b801,0x5862b803,0x906301b8, +0x0217b803,0x90420001,0x021fa004,0x90210001, +0x011f05bb,0x254ab808,0xb4c0000d,0xb62a000c, +0x1080b801,0x007ff004,0x90830134,0x007ff004, +0x0095b803,0x5862b801,0x906301b8,0x0217b803, +0x90210001,0x021fa204,0x007f8210,0x021fa004, +0xa5480020,0xb4c0000e,0xb0090000,0xb400000c, +0x80870000,0xb62a000a,0x80470000,0xb6290007, +0x5865b802,0x1063b801,0x5862b803,0x906301b8, +0x0217b803,0x90420001,0x021fa004,0x90210001, +0x00000000,0x00000000,0x00ffb81a,0x011f05bb, +0x013f05b9,0xb0080000,0xb4000015,0xb0090000, +0xb4000013,0x00000000,0x80270000,0xb6280010, +0x80470000,0xb629000d,0x5865b802,0x1063b801, +0x5862b803,0x914301b8,0x009ff00a,0xb0040000, +0xb4000005,0x80950002,0x906302b8,0x0217b803, +0x00000000,0x021fa004,0x90420001,0x90210001, +0xa5480020,0xb00a0000,0xb4000010,0xb0090000, +0xb400000e,0x00000000,0x80870000,0xb62a000b, +0x80470000,0xb6290008,0x5865b802,0x1063b801, +0x5862b803,0x906302b8,0x0217b803,0x00000000, +0x021fa004,0x90420001,0x90210001,0xb0080000, +0xb400004c,0xb0090000,0xb400004a,0x00000000, +0x80270000,0xb6280047,0x80470000,0xb6290044, +0x5865b802,0x1063b801,0x5862b803,0x914301b8, +0x009ff00a,0xad420060,0x00000000,0x00000000, +0x00000000,0x114ab801,0x5942b80a,0x914a1c80, +0x0217b80a,0xb0040000,0xb400002e,0x906302b8, +0x009ff003,0xb0040000,0xb420000a,0x80950006, +0x00000000,0x021fa204,0x80950006,0x015f8210, +0x021fa204,0x80950006,0x015f8210,0x021fa004, +0xb5000026,0xb0040001,0xb4200009,0x80950006, +0x00000000,0x021fa204,0x015f8210,0x021fa204, +0x80950006,0x015f8210,0x021fa004,0xb500001b, +0xb0040003,0xb4200009,0x80950006,0x00000000, +0x021fa204,0x80950006,0x015f8210,0x021fa204, +0x015f8210,0x021fa004,0xb5000010,0xb0040002, +0xb420000e,0x80950006,0x00000000,0x021fa204, +0x015f8210,0x021fa204,0x015f8210,0x021fa004, +0xb5000006,0x8087003f,0x021fa204,0x015f8210, +0x021fa204,0x015f8210,0x021fa004,0x90420001, +0x90210001,0xa5480020,0xb4c00011,0xb0090000, +0xb400000f,0x8087003f,0x5862b801,0x90631afc, +0xb62a000b,0x90630004,0x0047b803,0xb6290008, +0x90420180,0x0217b802,0x00000000,0x021fa204, +0x003f8210,0x021fa204,0x003f8210,0x021fa004, +0x00ffb81a,0x8257ffff,0x82d7ffff,0x011f05bb, +0x013f05b9,0x80270000,0x00e7b809,0x300105ba, +0xb4800001,0x80e70001,0x800700bc,0x80470000, +0xb0070000,0xb400004c,0xb627004b,0x5865b802, +0x1063b801,0x5862b803,0x914301b8,0xaca20060, +0x009ff00a,0x10a5b801,0x58a2b805,0x90a502b8, +0x0217b805,0xb0040000,0xb400002b,0x1060b801, +0x00bff003,0x10a5b804,0x90650160,0x00dff003, +0xb0060003,0xb4200007,0x90650134,0x00dff003, +0xb6000303,0x0075b806,0x021fa203,0x007f8210, +0xb5000021,0x5861b805,0x906300dc,0x009fd803, +0x90650134,0x00dff003,0xaca20060,0x00000000, +0x00000000,0x00000000,0x0075b806,0x10a5b801, +0x58a2b805,0x90a502b8,0x0217b805,0x588fb804, +0xb600030c,0xb6001007,0x04a3b804,0xb4600002, +0x58a1b803,0xb5000002,0x58a1b805,0x90a50001, +0x0067b805,0x9465ffff,0x5d50b805,0x021fa20a, +0x015f8210,0xb5000004,0x81470000,0xb6000302, +0x021fa20a,0x009f8210,0x009f05b9,0xb0040002, +0xb420000c,0x300105ba,0xb480000a,0x58a2b801, +0x90a502b8,0x0217b805,0x90a50180,0x0297b805, +0xb6000304,0x00bf8210,0x009f8210,0x029fa205, +0x009f8214,0x90420001,0x90210001,0x3001b808, +0xb480ffa9,0xa5480020,0xb00a0000,0xb4000015, +0xb0090000,0xb4000013,0x58a2b801,0x90a502b8, +0xb62a0010,0x80470000,0xb629000d,0xaca20060, +0x00000000,0x00000000,0x00000000,0x80670000, +0x10a5b801,0x58a2b805,0x90a502b8,0x0217b805, +0xb6000302,0x021fa203,0x00bf8210,0x90420001, +0x90210001,0x00ffb81a,0x00000000,0x00000000, +0x80770000,0x8057ffff,0x80f70000,0x80d7ffff, +0x81770000,0x8157ffff,0x81f70000,0x81d7ffff, +0xac140060,0xac350020,0x00000000,0x00000000, +0x12c0b801,0x5ac2b816,0x92d61980,0x83a400a5, +0xad940400,0x009f9173,0x013f05ca,0x914c6604, +0x114ab804,0x001f97e0,0x001eb80a,0xb0090000, +0xb4000003,0x80a76e44,0x80c76644,0xb5000002, +0x80a76644,0x80c76e44,0x808f000f,0x806f0000, +0x80af000e,0x80cf07e1,0x11e5b80c,0x11efb804, +0x5de2b80f,0x01ffb178,0x59e2b80f,0x01afb80f, +0x01ff9178,0x0047b86f,0xb0020001,0xb4c0fffd, +0x80cf07f0,0x1206b80c,0x1210b804,0x5e02b810, +0x021fb178,0x5a02b810,0x01afb810,0x021f9178, +0x0047b86f,0xb0020001,0xb4c0fffd,0x916c6e04, +0x116bb804,0x001f97ff,0x001eb80b,0x808f0000, +0x806f001f,0x80af001f,0x90ac6604,0x5ca2b805, +0x80270400,0xb600080a,0x00cfb801,0x00bfb178, +0x58a2b805,0x01cfb805,0x00bf9178,0x0047b86f, +0xb0020001,0xb4c0fffd,0x90210020,0x90a50020, +0x90ac6e04,0x5ca2b805,0x80270500,0xb600080a, +0x00cfb801,0x00bfb178,0x58a2b805,0x01cfb805, +0x00bf9178,0x0047b86f,0xb0020001,0xb4c0fffd, +0x90210020,0x90a50020,0x81530020,0xac140060, +0xac350020,0x80170800,0x80d7003c,0x12c0b801, +0x5ac2b816,0x92d602b8,0x0117b816,0x90241000, +0x0097b801,0x80470000,0x4002b803,0xb6000804, +0x005f8020,0x480287e4,0x005f8020,0x500287e4, +0x00000000,0x00000000,0x00000000,0x1021b80a, +0x5c36b801,0x5801b800,0x18c0b801,0xb0090000, +0xb4000002,0x90641440,0xb5000001,0x90641040, +0xb6000f0d,0x0097b803,0x80470000,0x4002b803, +0xb6001002,0x005f8020,0x480287e4,0x0108a026, +0x90630040,0x00000000,0x1021b80a,0x5c36b801, +0x5801b800,0x18c0b801,0x90641400,0x0097b803, +0x80470000,0x4002b803,0x005f8020,0x005f87e4, +0xb6000802,0x005f8040,0x480287c4,0x005f87e0, +0x0108a026,0x00000000,0x1021b80a,0x5c36b801, +0x5801b800,0x18c0b801,0xb0090000,0xb4000002, +0x906417c0,0xb5000001,0x906413c0,0xb6000f0f, +0x0097b803,0x80470000,0x4002b803,0xb6000804, +0x005f8020,0x500287e4,0x005f8020,0x480287e4, +0x0108a026,0x84630040,0x00000000,0x1021b80a, +0x5c36b801,0x5801b800,0x18c0b801,0xb0140000, +0xb4200005,0x90840004,0x9484003f,0x009fb173, +0xa1290001,0x013f25ca,0x80d7ffff,0x0108a026, +0x00ffb81a,0x81330004,0x8093007f,0x9884ffff, +0x80b3ff80,0x0017b816,0x90360040,0x0097b801, +0x81530010,0xb6001004,0x400a8000,0x404a8004, +0x0008a020,0x0088a022,0x0017b816,0x9036007c, +0x0097b801,0x81171000,0xb6001004,0x40048020, +0x480487e4,0x00000000,0x0108a020,0x81470000, +0x81670001,0x81870008,0x81a70040,0x81c707c4, +0x81e70040,0xb6000432,0xb00a0001,0xb4e00004, +0x80c71000,0x80e71000,0x81171040,0xb5000003, +0x80c71040,0x80e71040,0x81171000,0x844d0004, +0x10e7b802,0xb62b001f,0x0017b806,0x0097b807, +0xb62c0004,0x40048020,0x480487e4,0x00000000, +0x0108a020,0x0017b806,0x0097b807,0x0197b80e, +0x00000000,0x001f8020,0x042087e4,0xb62c000f, +0x4041800c,0x001f8020,0x0048b802,0x5e38802c, +0x2e11b801,0x042087e4,0x1042b810,0x0462b804, +0xb4a00002,0x0047b804,0xb5000003,0x0462b805, +0xb4600001,0x0047b805,0x011fa022,0x10c6b80f, +0x10e7b80f,0x5961b80b,0x5d81b80c,0x5da1b80d, +0x5de1b80f,0x914a0001,0x954a0001,0x11ceb80f, +0x80171018,0x81171fcc,0x80470000,0x41448020, +0x494487c0,0x00000000,0x0188b80a,0x494487e0, +0x00000000,0x0148b80a,0x0502a10a,0x4145b80c, +0x494580e0,0x00000000,0x0108a5ea,0x41448080, +0x494487c0,0x00000000,0x0108a78a,0x49448020, +0x00000000,0x0108a2ea,0x41448020,0x49448720, +0x00000000,0x0188b80a,0x4145b80c,0x49458080, +0x494587a0,0x00000000,0x0108a68a,0x4145b80c, +0x49458080,0x494587a0,0x00000000,0x0108a08a, +0x4145b80c,0x49458020,0x49458040,0x00000000, +0x0188b80a,0x494587e0,0x00000000,0x0108a08a, +0x4144b80c,0x494587a0,0x00000000,0x0108a52a, +0x41448080,0x49448040,0x494486c0,0x00000000, +0x0108a04a,0x41448040,0x49448720,0x00000000, +0x0108a36a,0x04028020,0x011fa420,0x001f8040, +0x011fa100,0x001f8080,0x011fa080,0x001f8100, +0x011fa040,0x001f8660,0x011fa120,0x41458020, +0x49458000,0x00000000,0x0108a00a,0x0017b816, +0x9036007c,0x0097b801,0x81171000,0x81970784, +0x00000000,0x001f8020,0x042087e4,0xb600100f, +0x4041800c,0x001f8020,0x0048b802,0x5e38802c, +0x2e11b801,0x042087e4,0x1042b810,0x0462b804, +0xb4a00002,0x0047b804,0xb5000003,0x0462b805, +0xb4600001,0x0047b805,0x011fa022,0x81470000, +0x81670001,0x81870008,0x81a70040,0x81c707c4, +0x81e70040,0xb6000432,0xb00a0001,0xb4e00004, +0x80c71000,0x80e71000,0x81171040,0xb5000003, +0x80c71040,0x80e71040,0x81171000,0x844d0004, +0x10e7b802,0xb62b001f,0x0017b806,0x0097b807, +0xb62c0004,0x40048020,0x480487e4,0x00000000, +0x0108a020,0x0017b806,0x0097b807,0x0197b80e, +0x00000000,0x001f8020,0x042087e4,0xb62c000f, +0x4041800c,0x001f8020,0x0048b802,0x5e38802c, +0x2e11b801,0x042087e4,0x1042b810,0x0462b804, +0xb4a00002,0x0047b804,0xb5000003,0x0462b805, +0xb4600001,0x0047b805,0x011fa022,0x10c6b80f, +0x10e7b80f,0x5961b80b,0x5d81b80c,0x5da1b80d, +0x5de1b80f,0x914a0001,0x954a0001,0x11ceb80f, +0x80171034,0x81171f84,0x80470000,0x41448040, +0x49448640,0x00000000,0x0188b80a,0x49448100, +0x49448780,0x00000000,0x0108a08a,0x4144b80c, +0x49448040,0x49448080,0x494487c0,0x00000000, +0x0108a16a,0x4145b80c,0x49458700,0x00000000, +0x0188b80a,0x494581a0,0x494586e0,0x00000000, +0x0108a66a,0x4145b80c,0x49448040,0x494487e0, +0x00000000,0x0188b80a,0x011fa1ec,0x4145b80c, +0x49458100,0x49458780,0x00000000,0x0108a08a, +0x41458720,0x49458100,0x494586e0,0x49458160, +0x49458020,0x49458020,0x49458760,0x00000000, +0x0108a08a,0x414587a0,0x49458080,0x49458760, +0x494580c0,0x49458700,0x49458140,0x49458020, +0x49458760,0x00000000,0x0108a74a,0x414587a0, +0x49458080,0x49458760,0x494580e0,0x49458700, +0x49458120,0x49458020,0x49458760,0x00000000, +0x0108a08a,0x41458720,0x49458100,0x494586e0, +0x49458140,0x49458040,0x49458020,0x49458720, +0x00000000,0x0108a0ca,0x41458080,0x49458040, +0x49458020,0x49458620,0x00000000,0x0188b80a, +0x49458080,0x00000000,0x0108a7ca,0x4144b80c, +0x49458040,0x49458020,0x49458080,0x00000000, +0x0108a5ea,0x41448080,0x49448700,0x00000000, +0x0188b80a,0x49448780,0x00000000,0x0108a7ca, +0x4144b80c,0x49448140,0x00000000,0x0108a7ca, +0x49448040,0x00000000,0x0108a0ca,0x41448700, +0x00000000,0x0188b80a,0x49448000,0x00000000, +0x0108a04a,0x011fa00c,0x80171f80,0xb6002006, +0x40048000,0x48048000,0x48048000,0x48048000, +0x00000000,0x0008a020,0x00ffb81d,0x00000000, +0x80770000,0x8057ffff,0x015f05b9,0x017f05bb, +0x8293ffff,0x9a94ffff,0x81a70000,0xb62a003a, +0xaded0180,0xae0d0180,0xadcd0080,0x902f1980, +0x0017b801,0xb6002033,0x904e01b8,0x00000000, +0x013ff002,0xb0090000,0xb400001f,0x904f02b8, +0x80c70000,0x011fd802,0x6829b808,0x94210001, +0xb0010001,0xb4e00001,0x00c7b814,0x6429b806, +0x80470001,0x6449b802,0x84420001,0x1442b808, +0x84690001,0x5863b803,0x906300dc,0x1042b801, +0x003f9803,0x90420001,0x4082b801,0x90630004, +0x003f9803,0x00000000,0x5897b804,0x1804b805, +0x4082b801,0x00000000,0x00000000,0x00000000, +0x10a4b800,0xb5000001,0x80a70000,0x90501c80, +0x00000000,0x007ff002,0x5842b803,0x904205f8, +0x0097b802,0x00000000,0x40058004,0x48058004, +0x00000000,0x0008a020,0x91ce0004,0x91ef0004, +0x92100004,0x91ad0001,0x00ffb81a,0x80770000, +0x8057ffff,0x80d7ffff,0x015f05b9,0x017f05bb, +0x8293ff80,0x9a940000,0x82a70020,0x81a70000, +0x81e702b8,0x80171980,0xb62a004f,0xb600034d, +0xac0d0080,0xac4d0180,0xac960080,0x822700bc, +0x91c001b8,0x00000000,0x1042b804,0x92021c80, +0xb62b003a,0x013ff00e,0x00fff011,0xb0090000, +0xb4000027,0x10e7b809,0x5821b807,0x902100dc, +0x00000000,0x001fd801,0x82470000,0x80270001, +0x6452b801,0x3002b800,0xb4600002,0x92520001, +0xb500fffb,0x86520001,0x80c70000,0x011fd80f, +0x6832b808,0xb0010001,0xb4e00001,0x00c7b814, +0x84520017,0x0056b802,0x80270001,0x6432b801, +0x84210001,0x1408b801,0x6402b800,0x10c6b800, +0x9027018c,0x00000000,0x001ff001,0x5802b800, +0x9020073c,0x904006f8,0x007f9801,0x0097b802, +0x10c6b803,0x40868004,0x48868004,0xb5000003, +0x80c70000,0x40868004,0x00000000,0x0088b804, +0x003ff010,0x5822b801,0x902105f8,0x0097b801, +0x91ce0004,0x91ef0004,0x40448004,0x48448004, +0x92100004,0x0008a022,0x92310001,0x0435b80b, +0xb4000007,0x80870000,0xb6210005,0x001fa024, +0x91ce0004,0x91ef0004,0x92100004,0x92310001, +0x00000000,0x91ad0001,0x00ffb81a,0x00000000, +0x007f05b9,0x001f0081,0xb0000001,0xb4400029, +0x001f05d8,0xac400080,0x801702b8,0x80970438, +0x90421800,0x0117b802,0x8087ffff,0x80b3ffff, +0x80d3007f,0x98c6ff00,0x80f3ff80,0x81070080, +0xb6002018,0x10088020,0x0056b800,0x0442b806, +0xb4a00004,0xb0000000,0x0007b806,0xb4400001, +0x0007b807,0x0027b800,0x5c08b800,0x1400b804, +0xb0030001,0xb4000008,0x10288024,0x0056b801, +0x0442b806,0xb4a00004,0xb0010000,0x0027b806, +0xb4400001,0x0027b807,0x5828b801,0x1421b805, +0x1900a021,0x001f05d8,0x90000001,0x001f25d8, +0x00ffb81a,0x801702b8,0x80970438,0x81171800, +0x8087ffff,0x80b3ffff,0x80d3007f,0x98c6ff00, +0x80f3ff80,0x81070080,0xb6006018,0x10088020, +0x0056b800,0x0442b806,0xb4a00004,0xb0000000, +0x0007b806,0xb4400001,0x0007b807,0x0027b800, +0x5c08b800,0x1400b804,0xb0030001,0xb4000008, +0x10288024,0x0056b801,0x0442b806,0xb4a00004, +0xb0010000,0x0027b806,0xb4400001,0x0027b807, +0x5828b801,0x1421b805,0x1900a021,0x00ffb81a, +0x001f0081,0xb0000001,0xb4400006,0x001f05d8, +0xb0000003,0xb4000003,0x80270001,0x003f25dc, +0x00ffb81a,0x003f05d9,0x009f05cb,0xb0010000, +0xb400000e,0x015f42ed,0x81070000,0x8127017c, +0xb00a0000,0xb4000002,0x81070180,0x812702fc, +0x802500a5,0x9421ffff,0x3001b808,0xb4800011, +0x3001b809,0xb4a00079,0xb500000e,0x001f0081, +0xb0000001,0xb4400003,0xb0040002,0xb4200006, +0xb5000002,0xb0040000,0xb4200003,0x802702ff, +0x81470000,0xb5000003,0x80270001,0x003f25d9, +0x81470180,0xb0040000,0xb4200001,0x83840348, +0x80070000,0x001f25d8,0x009f902d,0x80af001f, +0x808f0000,0x806f0000,0x8007ffff,0x8033ffff, +0x80171800,0x807bff8c,0x94630003,0xb0030003, +0xb4000016,0xb0030002,0xb4000035,0xb0030001, +0xb4000024,0xb6006010,0x14618000,0x6068b803, +0x40c4b803,0x14608000,0x00c8b806,0x5870b803, +0x6068b803,0x4104b803,0x58c8b806,0x0108b808, +0x14c6b801,0x00000000,0x00000000,0x5d08b808, +0x1508b800,0x1806a028,0xb5000030,0xb6006010, +0x14618000,0x6068b803,0x40c4b803,0x14608000, +0x00c8b806,0x5870b803,0x6068b803,0x4104b803, +0x5cc8b806,0x0108b808,0x14c6b800,0x00000000, +0x00000000,0x5908b808,0x1508b801,0x1806a028, +0xb500001e,0xb600600d,0x14618000,0x6068b803, +0x40c4b803,0x00000000,0x00c8b806,0x00000000, +0x00000000,0x00000000,0x5d08b806,0x1508b800, +0x58c8b806,0x14c6b801,0x1806a028,0xb500000f, +0xb600600e,0x14608000,0x5868b803,0x6068b803, +0x40c4b803,0x00000000,0x00c8b806,0x00000000, +0x00000000,0x00000000,0x5d08b806,0x1508b800, +0x58c8b806,0x14c6b801,0x1806a028,0x80670600, +0x5d22b80a,0xb600030a,0x00cfb803,0x013fb178, +0x5922b809,0x01afb809,0x013f9178,0x0047b86f, +0xb0020001,0xb4c0fffd,0x90630020,0x91290020, +0x81270180,0xb00a0000,0xb4000001,0x81270000, +0x013f62ed,0x80270001,0x003f25dc,0x00ffb81a, +0x001f0081,0xb0000001,0xb4400006,0x001f05d8, +0xb0000003,0xb4000003,0x80270001,0x003f25dc, +0x00ffb81a,0x003f05d9,0x009f05cb,0xb0010000, +0xb400000e,0x015f42ed,0x81070000,0x8127017c, +0xb00a0000,0xb4000002,0x81070180,0x812702fc, +0x802500a5,0x9421ffff,0x3001b808,0xb4800011, +0x3001b809,0xb4a00079,0xb500000e,0x001f0081, +0xb0000001,0xb4400003,0xb0040002,0xb4200006, +0xb5000002,0xb0040000,0xb4200003,0x802702ff, +0x81470000,0xb5000003,0x80270001,0x003f25d9, +0x81470180,0xb0040000,0xb4200001,0x838402b4, +0x80070000,0x001f25d8,0x009f902d,0x80af001f, +0x808f0000,0x806f0000,0x8007ffff,0x8033ffff, +0x80171800,0x807bff8c,0x94630003,0xb0030003, +0xb4000016,0xb0030002,0xb4000035,0xb0030001, +0xb4000024,0xb6006010,0x14618000,0x6068b803, +0x40c4b803,0x14608000,0x00c8b806,0x5870b803, +0x6068b803,0x4104b803,0x58c8b806,0x0108b808, +0x14c6b801,0x00000000,0x00000000,0x5d08b808, +0x1508b800,0x1806a028,0xb5000030,0xb6006010, +0x14618000,0x6068b803,0x40c4b803,0x14608000, +0x00c8b806,0x5870b803,0x6068b803,0x4104b803, +0x5cc8b806,0x0108b808,0x14c6b800,0x00000000, +0x00000000,0x5908b808,0x1508b801,0x1806a028, +0xb500001e,0xb600600d,0x14618000,0x6068b803, +0x40c4b803,0x00000000,0x00c8b806,0x00000000, +0x00000000,0x00000000,0x5908b806,0x1508b801, +0x5cc8b806,0x14c6b800,0x1806a028,0xb500000f, +0xb600600e,0x14608000,0x5870b803,0x6068b803, +0x40c4b803,0x00000000,0x00c8b806,0x00000000, +0x00000000,0x00000000,0x5908b806,0x1508b801, +0x5cc8b806,0x14c6b800,0x1806a028,0x80670600, +0x5d22b80a,0xb600030a,0x00cfb803,0x013fb178, +0x5922b809,0x01afb809,0x013f9178,0x0047b86f, +0xb0020001,0xb4c0fffd,0x90630020,0x91290020, +0x81270180,0xb00a0000,0xb4000001,0x81270000, +0x013f62ed,0x80270001,0x003f25dc,0x00ffb81a, +0x029fb024,0x02bfb025,0x02dfb026,0x02ffb027, +0x031fb028,0x033fb029,0x033f4046,0x0287b86f, +0x029fb02a,0x8285009d,0x9a940008,0x8286009d, +0x8285009c,0x96b48000,0xb0158000,0xb40001b5, +0x96b40100,0xb0150100,0xb400020b,0x96b40400, +0xb0150400,0xb400020c,0x96b40001,0xb0150001, +0xb400000c,0x96b40008,0xb0150008,0xb40001ad, +0x96b44000,0xb0154000,0xb400020b,0x96b40002, +0xb0150002,0xb4000182,0x00000000,0x00000000, +0xb500021d,0x02bf917e,0x92b50001,0x02bfb17e, +0x82850082,0x96f40001,0xb0170000,0xb4000171, +0x5efdb814,0x96f70001,0xb0170001,0xb420000b, +0x83050069,0x9718003f,0x82e50064,0x12f7b818, +0x86f70109,0x82feff74,0x02e7b86f,0x9af74000, +0x01ffb817,0x96f7bfff,0x01ffb817,0x83050081, +0x82a5009a,0x96b50001,0xb0150001,0xb4200014, +0x82a70000,0x02bfb17e,0x96b41840,0xb0150800, +0xb420000c,0x96b40008,0x5aa9b815,0x96d46000, +0x5ec3b816,0x82f3000f,0x9af7c00f,0x1718b817, +0x1ab5b818,0x1ab5b816,0x9ab50340,0x82a60081, +0xb500014c,0x9b180180,0x83060081,0xb5000149, +0x82a5009a,0x96b50002,0xb0150002,0xb420001b, +0x82a70000,0x02bfb17e,0x96b41800,0xb0151800, +0xb4000013,0x96b40040,0xb0150040,0xb4200004, +0xa3180c00,0x9b180340,0x83060081,0xb5000139, +0x96b40008,0x5aa9b815,0x96d46000,0x5ec3b816, +0x82f3000f,0x9af7c00f,0x1718b817,0x1ab5b818, +0x1ab5b816,0x9ab50340,0x82a60081,0xb500012d, +0x9b180180,0x83060081,0xb500012a,0x82a500c1, +0x96b5000f,0xb015000b,0xb420000e,0x96b40020, +0xb0150020,0xb400000b,0x96b40200,0xb0150200, +0xb4000008,0x82c50086,0x82e50094,0x3016b817, +0xb4400004,0x06f7b816,0xb017ff00,0xb4400001, +0xb5000118,0x96b46000,0xb0156000,0xb4000011, +0x96b41820,0xb0150820,0xb4200004,0x9b391000, +0x82a5009a,0x96b5feff,0x82a6009a,0x96b40040, +0xb0150040,0xb4200001,0x9739efff,0x96b91000, +0xb0151000,0xb4200003,0x82a5009a,0x9ab50100, +0x82a6009a,0x96b40040,0xb0150040,0xb4200019, +0x96b41800,0xb0151800,0xb4200006,0x96b98000, +0xb0158000,0xb4200003,0x9b180180,0x83060081, +0xb50000f8,0x96d80c00,0x82b300ff,0x9ab5f3ff, +0x1718b815,0xb0160c00,0xb4000007,0x82e50098, +0x96f70400,0xb0170400,0xb4200002,0x82c70c00, +0xb5000001,0xa2d60c00,0x1b18b816,0x9b180340, +0xb50000c4,0x96b40220,0xb0150000,0xb4e00021, +0x82a5009d,0x82f3ffff,0x16b5b817,0x82f33800, +0x3015b817,0xb420001b,0x96f98000,0xb0178000, +0xb4000018,0x82a70000,0x02bfb17e,0x82c5009d, +0x96d6ffff,0x82b3c800,0x9ab58001,0x82e500c1, +0x96f7000f,0xb017000b,0xb4000002,0x82b38800, +0x9ab58001,0x1ab5b816,0x82c5009a,0x96d60020, +0xb0160020,0xb4200002,0x82b3c800,0x9ab58001, +0x82a6009d,0x02ff917e,0x00000000,0xb0170040, +0xb4800000,0x5eb5b814,0x96b500f0,0x96f46000, +0x5eedb817,0x1ab5b817,0xb0170003,0xb4000004, +0x96b500ef,0x96f70001,0x5ae4b817,0x1ab5b817, +0x96d41800,0xb0161800,0xb400000a,0x96f900ff, +0x96b500ff,0x9739ff00,0x1b39b815,0x02a7b817, +0x96b500f3,0x96d40008,0x5ec1b816,0x1ab5b816, +0xb500000c,0x96f98000,0xb0178000,0xb4200007, +0x5efeb814,0x96f70001,0xb0170001,0xb4000003, +0x9b180180,0x83060081,0xb50000a2,0x96b500f3, +0x9ab50008,0x9739fff3,0x96d40020,0xb0160020, +0xb4200019,0x82c7001f,0x82c600c9,0x9b398000, +0x82c70000,0x02dfb17e,0x96d40010,0x5ac8b816, +0x82f300ff,0x9af7cfff,0x1718b817,0x1b18b816, +0x9b180340,0x82c5009d,0x96d6ffff,0x82f33800, +0x9af78001,0x1af7b816,0x82c5009a,0x96d60020, +0xb0160020,0xb4200002,0x82f3c800,0x9af78001, +0x82e6009d,0xb500005f,0x97397fff,0x96b500ff, +0x5aaab815,0x82f300fc,0x9af703ff,0x1718b817, +0x1b18b815,0x9b180340,0x82c5009a,0x96d60010, +0xb0160010,0xb4200027,0x82c70000,0x02dfb17e, +0x82c50086,0x92d60e10,0x82c60086,0x82c50094, +0x5eefb818,0x96f70003,0xb0170003,0xb4200002, +0x82e70e10,0xb5000001,0x82e70e10,0x12d6b817, +0x82e50081,0x9af70020,0x82e60081,0x82c60094, +0xa2f70020,0x82e60081,0x82f30001,0x16f7b818, +0x5ef0b817,0xb0170001,0xb4000004,0x96f84000, +0x5ee4b817,0x9718f3ff,0x1b18b817,0x82f32800, +0x9af78000,0x82e6009d,0x83060081,0x83070001, +0x8306009f,0x8305009c,0xb0180001,0xb4e0fffb, +0xb50000f5,0x82c5009d,0x82f33800,0x9af78001, +0x3016b817,0xb420000f,0x82b3c800,0x9ab58001, +0x82e500c1,0x96f7000f,0xb017000b,0xb4000002, +0x82b38800,0x9ab58001,0x82c5009a,0x96d60020, +0xb0160020,0xb4200002,0x82b3c800,0x9ab58001, +0x82a6009d,0x82c5009a,0x96d60080,0xb0160080, +0xb4000013,0x02df917e,0x00000000,0xb0160010, +0xb480000f,0x82c500c1,0x96d6000f,0xb016000b, +0xb400000b,0x82c50087,0x96d60080,0x5ac7b816, +0x82c50098,0x96d60800,0x5ac3b816,0x96f84000, +0x3017b816,0xb4200002,0x033f4046,0x9b394000, +0x9739bfff,0x82e50061,0x96f70008,0xb0170008, +0xb4000005,0x5eefb818,0x96f70003,0xb0170003, +0xb4000001,0x9718ffff,0x96b41800,0xb0151800, +0xb4000008,0x5eb9b814,0x96b5000f,0x82c50099, +0x5ed0b816,0x96f6000f,0x5ab0b815,0x82a60099, +0xb5000002,0x5ef9b814,0x96f7000f,0x5aecb817, +0x82c5009a,0x96d60fff,0x1ad6b817,0x82c6009a, +0x96b46000,0xb0156000,0xb4200005,0x5ae2b817, +0x82d30ffc,0x9ad63fff,0x1718b816,0x1b18b817, +0x83060081,0x83070001,0x8306009f,0x8305009c, +0xb0180001,0xb4e0fffb,0x00000000,0xb500009e, +0x82850083,0x96b400ff,0xb015003c,0xb4200019, +0x96b92000,0xb0152000,0xb4000002,0x9b392000, +0xb5000014,0x9739d3ff,0x82870000,0x82860087, +0x82870008,0x82860083,0x829bff78,0x82a7001f, +0xb0140400,0xb4000001,0x82a70010,0x82a600c9, +0x829bff78,0x00000000,0x828600cb,0x8285009d, +0x82b3ffff,0x9ab5fffd,0x1694b815,0x8286009d, +0xb5000000,0x83070002,0x8306009f,0x00000000, +0xb500007d,0x83078000,0x8306009f,0x00000000, +0xb5000079,0x82850094,0x82a50086,0x06b5b814, +0x02b6b815,0xb0151700,0xb440004b,0x8285006c, +0x969400ff,0xb0140024,0xb4000019,0xb0140012, +0xb4000017,0x8285009a,0x5eedb814,0x96f70003, +0xb0170003,0xb4000009,0x82a50083,0x5ea8b815, +0x96b500ff,0xb0150020,0xb4400002,0x82c70bbc, +0xb5000001,0x82c70bb8,0xb5000008,0x82a50083, +0x5ea8b815,0x96b500ff,0xb0150020,0xb4400002, +0x82c71199,0xb5000001,0x82c71197,0xb5000016, +0x8285009a,0x5eedb814,0x96f70003,0xb0170003, +0xb4000009,0x82a50083,0x5ea8b815,0x96b500ff, +0xb0150020,0xb4400002,0x82c70e18,0xb5000001, +0x82c70e04,0xb5000008,0x82a50083,0x5ea8b815, +0x96b500ff,0xb0150020,0xb4400002,0x82c70e18, +0xb5000001,0x82c70e04,0x82e50086,0x12f7b816, +0x02bf917e,0xb0150020,0xb480000b,0x82a5009a, +0x96b56000,0xb0156000,0xb4000007,0x82a50098, +0x96d50a00,0xb0160a00,0xb4000002,0xb0160000, +0xb4200001,0x92f70704,0x82850081,0x9ab40020, +0x82a60081,0x82c50094,0x82e60094,0x82860081, +0x86b70704,0x82a6009b,0x83070008,0x8306009f, +0x00000000,0xb5000024,0x83070100,0x8306009f, +0x00000000,0xb5000020,0x83070000,0x83050081, +0x9b180180,0x83060081,0x83070400,0x8306009f, +0x00000000,0xb5000018,0x82870000,0x82850082, +0x5eb7b814,0x96b500fc,0x96d40006,0x5ec1b816, +0x1ab5b816,0x5aacb815,0x83050081,0x82d3001c, +0x9ad600ff,0x1718b816,0x1b18b815,0x9b180e00, +0x83060081,0x83074000,0x8306009f,0x8305009d, +0x82d3ffff,0x9ad6bfff,0x1718b816,0x8306009d, +0x00000000,0xb5000000,0x029f902a,0x01ffb814, +0x033f6046,0x029f9024,0x02bf9025,0x02df9026, +0x02ff9027,0x031f9028,0x033f9029,0x00ffb81e, +0x02ff917d,0x92f7092f,0x031f0084,0xb0180001, +0xb4200002,0x02ff917d,0x92f70870,0x02ffb17d, +0x02ff917c,0x82bbffdc,0x829bffd8,0x93150004, +0x3014b815,0xb4000017,0x02dbb818,0x029bb815, +0x3017b816,0xb4800013,0x5a81b814,0x029fb17d, +0x82def200,0x82fef204,0x82e50086,0x06f7b814, +0x02f6b817,0x82fef208,0x82860095,0x82870001, +0x829ef220,0x8293001f,0x9294fe00,0x92b50008, +0x3015b814,0xb4800002,0x82b3001f,0x92b5fa00, +0x82beffdc,0x82850086,0x83250094,0x06d4b819, +0x02d6b816,0xb016ffff,0xb4a00009,0x82c50081, +0x9ab60020,0x82a60081,0x82a50086,0x92b50e10, +0x82a60094,0x82c60081,0x86b50704,0x82a6009b, +0x00ffb81c,0x00000000,0x00000000,0x00000000, +0x001f9012,0x001fb200,0x001f004c,0x001f2804, +0x801bfef0,0x8058fef4,0x803bff68,0x8078ff6c, +0x2000b801,0x2042b803,0x001fb204,0x005f2814, +0x82e70001,0x83640048,0x029fb014,0x829efef0, +0x8286000f,0x02bf2054,0x82bcfef4,0x82a6000e, +0x00ffb81a,0x80e70001,0x801336e3,0x9800eb76, +0x001fb200,0x800700ab,0x001f2804,0x801bc3e8, +0x8058c3ec,0x83640024,0x82e70000,0x83640036, +0x029fb3c0,0x029fb200,0x02bf2f04,0x02bf2804, +0x801bc000,0x8058c004,0x8364001b,0x82e70000, +0x8364002d,0x001f93c0,0x3000b814,0xb420000a, +0x001f0f04,0x3000b815,0xb4200007,0x829efef0, +0x82bcfef4,0x029fb012,0x02bf204c,0x82870001, +0x829cfef5,0x00ffb81a,0xb0070000,0xb4000007, +0x80e70000,0x801399fa,0x9800c92e,0x001fb200, +0x800700af,0x001f2804,0xb500ffdc,0x82870000, +0x829cfef5,0x00ffb81a,0x80c700ff,0x803bff68, +0x8078ff6c,0x14a0b806,0x2063b805,0x007f2814, +0x2021b802,0x58c8b806,0x14a0b806,0x58b0b805, +0x2021b805,0x58c8b806,0x14a0b806,0x2021b805, +0x58c8b806,0x14a0b806,0x5cb0b805,0x2021b805, +0x003fb204,0x00ffb81b,0x82c70000,0x83070800, +0x83270005,0x8197080c,0x81d7ffff,0x83840126, +0x83840001,0x00ffb81b,0x808f0000,0x806f001f, +0x80af001f,0x80270240,0x81e77c08,0x5de2b80f, +0xb6000208,0x00cfb801,0x01ffb178,0x59e2b80f, +0x01cfb80f,0x01ff9178,0xb520ffff,0x91ef0020, +0x90210020,0x80270280,0x81e77b00,0x5de2b80f, +0xb6000208,0x00cfb801,0x01ffb178,0x59e2b80f, +0x01cfb80f,0x01ff9178,0xb520ffff,0x91ef0020, +0x90210020,0x8057ffff,0x80170830,0x80070810, +0x80270808,0xb6000509,0x005ff000,0x90420900, +0x007ff001,0x90630a00,0x009ff002,0x00bff003, +0x2004a025,0x90000001,0x90210001,0x80070814, +0x80d7ffff,0x8097085c,0x8017083c,0xb6000404, +0x005ff000,0x007f87e0,0x84000001,0x2082a7e3, +0x80970860,0x80170840,0x2082b803,0x007f8000, +0x2083a004,0x80170830,0x80970850,0x80270808, +0xb6000508,0x005f8024,0x90420900,0x007ff001, +0x90630a00,0x009ff002,0x00bff003,0x2004a025, +0x90210001,0x80170840,0x00000000,0x02bf87e0, +0x80970860,0x82870000,0xb6000404,0x005f87e4, +0x5a88b814,0x204287e0,0x1a94b802,0x00ffb81c, +0x001f0e49,0x001f2b09,0x001f0e41,0x001f2b08, +0x001f0e46,0x001f2b07,0x001f0e48,0x001f2b06, +0x001f0e42,0x001f2b05,0x001f0e47,0x001f2b04, +0x001f0e45,0x001f2b03,0x001f0e43,0x001f2b02, +0x001f0e40,0x001f2b01,0x001f0e44,0x001f2b00, +0x001f0f25,0xa020000c,0x94400001,0x94600002, +0x94810004,0x94a10008,0x94c00010,0x5943b802, +0x5861b803,0x5882b804,0x5ca2b805,0x5cc4b806, +0x194ab803,0x194ab804,0x194ab805,0x194ab806, +0x015f2b38,0x801b7c00,0x003f92c1,0x5c28b801, +0x005f92c2,0x5858b802,0x1821b802,0x2000b801, +0x001fb2c4,0x80187c04,0x003f0b09,0x2000b801, +0x001f2b14,0x82c70001,0x82e70001,0x83070b10, +0x8327001e,0x81970b35,0x8384009f,0x02df0b38, +0x82170e30,0x838400f1,0x819efef0,0x817cfef4, +0x819eff68,0x817cff6c,0x00ffb81b,0x820f001f, +0x8018fef8,0x8057ffff,0x001f2b09,0x8018fef6, +0x80d7ffff,0x001f2b08,0x8018fefa,0x8157ffff, +0x001f2b07,0x8018fefd,0x81d7ffff,0x001f2b06, +0x8018fefb,0x802f001f,0x001f2b05,0x8018fefe, +0x00000000,0x001f2b04,0x8018fef9,0x00000000, +0x001f2b03,0x8018feff,0x00000000,0x001f2b02, +0x8018fef7,0x00000000,0x001f2b01,0x8018fefc, +0x00000000,0x001f2b00,0x001f0f25,0xa0200011, +0x94410001,0x94600002,0x94800004,0x94a00008, +0x94c10010,0x5941b802,0x5861b803,0x5c82b804, +0x58a1b805,0x5cc1b806,0x194ab803,0x194ab804, +0x194ab805,0x194ab806,0x015f2b38,0x801b7c00, +0x003f92c1,0x5c28b801,0x005f92c2,0x5858b802, +0x1821b802,0x2000b801,0x001fb2c4,0x80187c04, +0x003f0b09,0x2000b801,0x001f2b14,0x82c70001, +0x82e70001,0x83070b10,0x8327001e,0x81970b35, +0x83840055,0x02df0b38,0x82170e20,0x838400a7, +0x819efef0,0x817cfef4,0x5ac8b80c,0x02ff0e44, +0x1ad6b817,0x02dfb391,0x5ed8b80c,0x5968b80b, +0x1ad6b80b,0x02df6724,0x00ffb81b,0x820f001f, +0x8018fefe,0x8057ffff,0x001f2b09,0x8018fefa, +0x80d7ffff,0x001f2b08,0x8018fefc,0x8157ffff, +0x001f2b07,0x8018feff,0x81d7ffff,0x001f2b06, +0x8018fef8,0x802f001f,0x001f2b05,0x8018fefb, +0x00000000,0x001f2b04,0x8018fefd,0x00000000, +0x001f2b03,0x8018fef6,0x00000000,0x001f2b02, +0x8018fef9,0x00000000,0x001f2b01,0x8018fef7, +0x00000000,0x001f2b00,0x801b7c00,0x003f92c1, +0x5c28b801,0x005f92c2,0x5858b802,0x1821b802, +0x2000b801,0x001fb2c4,0x80187c04,0x003f0b09, +0x2000b801,0x001f2b14,0x82c70001,0x82e70001, +0x83070b10,0x8327001e,0x81970b35,0x83840016, +0x83270000,0x831bfef0,0x82f8fef4,0x02c7b819, +0x82170e28,0x83840065,0x300cb818,0xb4200002, +0x300bb817,0xb4000006,0x93390001,0xb0190020, +0xb480fff6,0x83270000,0x833cfef5,0x00ffb81b, +0x019fb390,0x017f2e44,0x033f2f25,0x83270001, +0x833cfef5,0x00ffb81b,0x0007b818,0x90000003, +0x00000000,0x015ff000,0x90000001,0x5949b80a, +0x013ff000,0x194ab809,0x84000002,0x994a0100, +0x017ff000,0x958b00f8,0x5981b80c,0x956b0007, +0x198cb80b,0x84000002,0x998c0008,0x017ff000, +0x90000001,0x5971b80b,0x198cb80b,0x017ff000, +0x5969b80b,0x198cb80b,0x81a70000,0x94d90003, +0x82a70000,0xb6260019,0xb6000818,0x5df0b80a, +0x5e02b80a,0x21efb810,0x95ef0001,0x5941b80a, +0x194ab80f,0x21efb816,0x5e18b80c,0x5e35b80c, +0x5e54b80c,0x5e6cb80c,0x2210b811,0x2252b813, +0x2210b812,0x96100001,0x5981b80c,0x198cb810, +0x2210b817,0x10afb810,0x10a5b80d,0x5da1b805, +0x94a50001,0x5aa1b815,0x1ab5b805,0x019fa7f5, +0x5cc2b819,0xb626001c,0x82870000,0xb6000419, +0xb6000818,0x5df0b80a,0x5e02b80a,0x21efb810, +0x95ef0001,0x5941b80a,0x194ab80f,0x21efb816, +0x5e18b80c,0x5e35b80c,0x5e54b80c,0x5e6cb80c, +0x2210b811,0x2252b813,0x2210b812,0x96100001, +0x5981b80c,0x198cb810,0x2210b817,0x10afb810, +0x10a5b80d,0x5da1b805,0x94a50001,0x5a81b814, +0x1a94b805,0x019fa7f4,0x00ffb81c,0x8257ffff, +0x808f0000,0x806f001f,0x80af001f,0x80270300, +0x81e778e0,0x5de2b80f,0xb6000208,0x00cfb801, +0x01ffb178,0x59e2b80f,0x01cfb80f,0x01ff9178, +0xb520ffff,0x91ef0020,0x90210020,0x80270340, +0x81e779e0,0x5de2b80f,0xb6000208,0x00cfb801, +0x01ffb178,0x59e2b80f,0x01cfb80f,0x01ff9178, +0xb520ffff,0x91ef0020,0x90210020,0x80270280, +0x81e77b00,0x5de2b80f,0xb6000208,0x00cfb801, +0x01ffb178,0x59e2b80f,0x01cfb80f,0x01ff9178, +0xb520ffff,0x91ef0020,0x90210020,0x806f0007, +0x80af0007,0x80270380,0x81e77ae0,0x5de2b80f, +0x00cfb801,0x01ffb178,0x59e2b80f,0x01cfb80f, +0x01ff9178,0xb520ffff,0x91ef0020,0x90210020, +0x80170b60,0x001f0b00,0x001fa020,0x001f0b01, +0x001fa020,0x001f0b02,0x001fa020,0x001f0b03, +0x001fa020,0x001f0b04,0x001fa000,0x80970b50, +0x81170b70,0x82a70b35,0x83a40060,0x001f87e4, +0xb6000405,0x86b50001,0x83a4005c,0x001f8004, +0x003f87e8,0x2080a7e1,0x80970b70,0x80170b50, +0x81170b50,0x81970b40,0x82a70b30,0x001f800c, +0x003f8008,0x2100a001,0x83a40050,0x001f87e4, +0xb6000405,0x86b50001,0x83a4004c,0x001f8004, +0x003f87e8,0x2080a7e1,0x80970b50,0x80170b70, +0x81170b70,0x81970b60,0x82a70b2b,0x001f800c, +0x003f8008,0x2100a001,0x83a40040,0x83a4004e, +0xb6000407,0x86b50001,0x83a4003c,0x001f8004, +0x003f87e8,0x2080a001,0x83a40047,0x00000000, +0x80970b70,0x80170b50,0x81170b50,0x81970b40, +0x82a70b26,0x001f800c,0x003f8008,0x2100a001, +0x83a4002e,0x83a4003c,0xb6000407,0x86b50001, +0x83a4002a,0x001f8004,0x003f87e8,0x2080a001, +0x83a40035,0x00000000,0x80970b50,0x80170b70, +0x81170b70,0x81970b60,0x82a70b21,0x001f800c, +0x003f8008,0x2100a001,0x83a4001c,0x001f87e4, +0xb6000405,0x86b50001,0x83a40018,0x001f8004, +0x003f87e8,0x2080a7e1,0x80970b70,0x80170b50, +0x81170b50,0x81970b40,0x82a70b1c,0x001f800c, +0x003f8008,0x2100a001,0x83a4000c,0x017f87e4, +0x81870000,0xb6000406,0x86b50001,0x83a40007, +0x001f87e4,0x200087e8,0x5988b80c,0x198cb800, +0x021fa02c,0x021fa00b,0x00ffb81c,0x005ff015, +0x90420a00,0x003f87e0,0x001ff002,0x2060b801, +0x90630c00,0x90960e00,0x001ff003,0x003ff004, +0x20a0b801,0x90a50d00,0x00000000,0x001ff005, +0x009fa000,0x00ffb81d,0x001f8004,0x5c21b800, +0x5847b800,0x1821b802,0x942100ff,0x2080a7e1, +0x00ffb81d,0x00000000,0x00000000,0x00000000, + +}; + +static u32 MPG240Ucode1f5c00[] = { +0x00000000,0xfffff8c0,0x00003540,0xffff8d40, +0x0001fd40,0xfffaf7c0,0x00066b80,0xffdb63c0, +0x00494780,0x00249c40,0x00066b80,0x00050840, +0x0001fd40,0x000072c0,0x00003540,0x00000740, +0xffffffc0,0xfffff840,0x00003680,0xffff7e40, +0x0001f400,0xfffa9cc0,0x0005d1c0,0xffd99600, +0x00493c00,0x0022ce00,0x0006f780,0x0004ad00, +0x000203c0,0x00006440,0x00003400,0x00000680, +0xffffffc0,0xfffff740,0x00003780,0xffff6ec0, +0x0001e800,0xfffa4240,0x00052a00,0xffd7ca00, +0x00491a00,0x0020ffc0,0x00077600,0x00045240, +0x00020800,0x000056c0,0x00003280,0x00000600, +0xffffffc0,0xfffff680,0x00003840,0xffff5ec0, +0x0001d940,0xfff9e8c0,0x00047440,0xffd60080, +0x0048e180,0x001f32c0,0x0007e700,0x0003f7c0, +0x000209c0,0x00004980,0x00003100,0x00000540, +0xffffffc0,0xfffff5c0,0x000038c0,0xffff4e40, +0x0001c780,0xfff990c0,0x0003b000,0xffd43ac0, +0x00489240,0x001d6800,0x00084b00,0x00039e40, +0x00020940,0x00003d00,0x00002f80,0x000004c0, +0xffffffc0,0xfffff4c0,0x00003900,0xffff3d40, +0x0001b2c0,0xfff93a40,0x0002ddc0,0xffd279c0, +0x00482d00,0x001ba040,0x0008a200,0x000345c0, +0x000206c0,0x00003140,0x00002dc0,0x00000440, +0xffffffc0,0xfffff3c0,0x00003900,0xffff2c00, +0x00019b00,0xfff8e640,0x0001fd40,0xffd0be80, +0x0047b1c0,0x0019dc80,0x0008ecc0,0x0002ef00, +0x00020240,0x00002640,0x00002c00,0x00000400, +0xffffff80,0xfffff2c0,0x000038c0,0xffff1a40, +0x00017fc0,0xfff894c0,0x00010e80,0xffcf09c0, +0x004720c0,0x00181d80,0x00092b40,0x000299c0, +0x0001fc00,0x00001bc0,0x00002a40,0x00000380, +0xffffff80,0xfffff180,0x00003800,0xffff0840, +0x00016180,0xfff84680,0x00001180,0xffcd5cc0, +0x00467a40,0x00166440,0x00095e00,0x00024680, +0x0001f440,0x00001200,0x00002840,0x00000340, +0xffffff80,0xfffff040,0x00003740,0xfffef600, +0x00014000,0xfff7fbc0,0xffff0680,0xffcbb880, +0x0045bf00,0x0014b140,0x00098580,0x0001f580, +0x0001ea80,0x00000900,0x00002680,0x000002c0, +0xffffff80,0xffffef00,0x000035c0,0xfffee3c0, +0x00011ac0,0xfff7b540,0xfffded80,0xffca1d80, +0x0044ef80,0x00130580,0x0009a1c0,0x0001a700, +0x0001dfc0,0x00000080,0x000024c0,0x00000280, +0xffffff40,0xffffedc0,0x00003400,0xfffed180, +0x0000f280,0xfff77340,0xfffcc700,0xffc88d80, +0x00440bc0,0x001161c0,0x0009b3c0,0x00015b00, +0x0001d380,0xfffff8c0,0x000022c0,0x00000240, +0xffffff40,0xffffec40,0x00003200,0xfffebf40, +0x0000c680,0xfff73680,0xfffb92c0,0xffc708c0, +0x00431500,0x000fc6c0,0x0009bb80,0x000111c0, +0x0001c640,0xfffff1c0,0x00002100,0x00000200, +0xffffff00,0xffffeac0,0x00002f40,0xfffead00, +0x00009740,0xfff6ff40,0xfffa5180,0xffc59080, +0x00420b40,0x000e3500,0x0009b9c0,0x0000cb80, +0x0001b7c0,0xffffeb40,0x00001f40,0x000001c0, +0xffffff00,0xffffe940,0x00002c40,0xfffe9b00, +0x00006480,0xfff6ce00,0xfff90380,0xffc425c0, +0x0040ef80,0x000cad00,0x0009af00,0x00008840, +0x0001a880,0xffffe580,0x00001d40,0x000001c0, +0xfffffec0,0xffffe7c0,0x000028c0,0xfffe8980, +0x00002e40,0xfff6a3c0,0xfff7a900,0xffc2c900, +0x003fc280,0x000b2fc0,0x00099b80,0x00004800, +0x00019880,0xffffe040,0x00001bc0,0x00000180, +0xfffffec0,0xffffe600,0x00002480,0xfffe7840, +0xfffff4c0,0xfff68040,0xfff64240,0xffc17b40, +0x003e84c0,0x0009bdc0,0x00097fc0,0x00000b40, +0x000187c0,0xffffdb80,0x00001a00,0x00000140, +0xfffffe80,0xffffe440,0x00001fc0,0xfffe6780, +0xffffb800,0xfff66480,0xfff4d040,0xffc03d80, +0x003d3700,0x00085700,0x00095c40,0xffffd1c0, +0x00017680,0xffffd740,0x00001840,0x00000140, +0xfffffe40,0xffffe2c0,0x00001a80,0xfffe5780, +0xffff77c0,0xfff65100,0xfff35300,0xffbf1080, +0x003bda40,0x0006fc80,0x00093200,0xffff9b80, +0x00016500,0xffffd3c0,0x000016c0,0x00000100, +0xfffffe40,0xffffe0c0,0x000014c0,0xfffe4840, +0xffff3480,0xfff64640,0xfff1cb00,0xffbdf4c0, +0x003a6f80,0x0005ae80,0x000900c0,0xffff68c0, +0x00015300,0xffffd0c0,0x00001540,0x00000100, +0xfffffe00,0xffffdf00,0x00000e40,0xfffe39c0, +0xfffeee40,0xfff64480,0xfff03940,0xffbceb00, +0x0038f740,0x00046d40,0x0008c980,0xffff3980, +0x000140c0,0xffffce00,0x000013c0,0x000000c0, +0xfffffdc0,0xffffdd40,0x00000740,0xfffe2c80, +0xfffea500,0xfff64c40,0xffee9e40,0xffbbf440, +0x00377280,0x00033900,0x00088cc0,0xffff0d80, +0x00012e80,0xffffcc00,0x00001240,0x000000c0, +0xfffffd80,0xffffdb40,0xffffff80,0xfffe2040, +0xfffe5900,0xfff65e40,0xffecfa80,0xffbb1080, +0x0035e280,0x00021280,0x00084ac0,0xfffee540, +0x00011c40,0xffffca40,0x00001100,0x00000080, +0xfffffd40,0xffffd980,0xfffff700,0xfffe1580, +0xfffe0a80,0xfff67a80,0xffeb4ec0,0xffba4100, +0x00344780,0x0000f980,0x00080440,0xfffec000, +0x00010a00,0xffffc8c0,0x00000fc0,0x00000080, +0xfffffcc0,0xffffd7c0,0xffffee00,0xfffe0bc0, +0xfffdb980,0xfff6a200,0xffe99bc0,0xffb985c0, +0x0032a340,0xffffee80,0x0007b980,0xfffe9e80, +0x0000f7c0,0xffffc800,0x00000e80,0x00000080, +0xfffffc80,0xffffd5c0,0xffffe440,0xfffe0400, +0xfffd6640,0xfff6d4c0,0xffe7e280,0xffb8df40, +0x0030f640,0xfffef180,0x00076b40,0xfffe8040, +0x0000e5c0,0xffffc740,0x00000d40,0x00000080, +0xfffffc00,0xffffd400,0xffffd9c0,0xfffdfdc0, +0xfffd1100,0xfff71340,0xffe62380,0xffb84e40, +0x002f4180,0xfffe02c0,0x000719c0,0xfffe6500, +0x0000d400,0xffffc700,0x00000c40,0x00000040, +0xfffffbc0,0xffffd240,0xffffcec0,0xfffdf940, +0xfffcba40,0xfff75e00,0xffe45fc0,0xffb7d300, +0x002d8640,0xfffd2240,0x0006c5c0,0xfffe4d40, +0x0000c2c0,0xffffc700,0x00000b40,0x00000040, +0xfffffb40,0xffffd080,0xffffc300,0xfffdf6c0, +0xfffc61c0,0xfff7b500,0xffe29800,0xffb76dc0, +0x002bc540,0xfffc5000,0x00066f40,0xfffe3880, +0x0000b1c0,0xffffc740,0x00000a40,0x00000040, +0xfffffac0,0xffffcf00,0xffffb680,0xfffdf640, +0xfffc0840,0xfff81900,0xffe0cd40,0xffb71e80, +0x0029ff80,0xfffb8bc0,0x00061740,0xfffe26c0, +0x0000a140,0xffffc7c0,0x00000980,0x00000040, +0xfffffa00,0xffffcd80,0xffffa940,0xfffdf800, +0xfffbadc0,0xfff88a00,0xffdf0040,0xffb6e600, +0x00283600,0xfffad600,0x0005bdc0,0xfffe1800, +0x00009140,0xffffc880,0x000008c0,0x00000040, +0xfffff980,0xffffcc00,0xffff9bc0,0xfffdfc40, +0xfffb5300,0xfff90880,0xffdd3200,0xffb6c400, +0x00266a00,0xfffa2e40,0x00056340,0xfffe0c00, +0x000081c0,0xffffc980,0x000007c0,0x00000040, +0x004013c2,0x0040b346,0x0041fa2d,0x0043f934, +0x0046cc1c,0x004a9d9d,0x004fae37,0x0056601f, +0x005f4cf7,0x006b6fcf,0x007c7d1e,0x0115b035, +0x013df91b,0x0207655e,0x03342c83,0x0a185230, +0x00404f46,0x0042e13c,0x0048919f,0x0052cb0e, +0x0064e240,0x0107c449,0x015c7926,0x050cf270, +0x004140fb,0x004cf8df,0x0073326c,0x02480d9d, +0x004545ea,0x01273d75,0x005a827a,0x007fffff, +0x006597fb,0x0050a28c,0x00400000,0x0032cbfd, +0x00285146,0x00200000,0x001965ff,0x001428a3, +0x00100000,0x000cb2ff,0x000a1451,0x00080000, +0x00065980,0x00050a29,0x00040000,0x00032cc0, +0x00028514,0x00020000,0x00019660,0x0001428a, +0x00010000,0x0000cb30,0x0000a145,0x00008000, +0x00006598,0x000050a3,0x00004000,0x000032cc, +0x00002851,0x00002000,0x00001966,0x00001429, +0x00001000,0x00000cb3,0x00000a14,0x00000800, +0x00000659,0x0000050a,0x00000400,0x0000032d, +0x00000285,0x00000200,0x00000196,0x00000143, +0x00000100,0x000000cb,0x000000a1,0x00000080, +0x00000066,0x00000051,0x00000040,0x00000033, +0x00000028,0x00000020,0x00000019,0x00000014, +0x00000010,0x0000000d,0x0000000a,0x00000008, +0x00000006,0x00000005,0x00000000,0x00555555, +0x00666666,0x00492492,0x0071c71c,0x00444444, +0x00421084,0x00410410,0x00408102,0x00404040, +0x00402010,0x00401004,0x00400801,0x00400400, +0x00400200,0x00400100,0x00400080,0x00400040, +0x00400000,0x00400000,0x00200000,0x00400000, +0x00100000,0x00080000,0x00040000,0x00020000, +0x00010000,0x00008000,0x00004000,0x00002000, +0x00001000,0x00000800,0x00000400,0x00000200, +0x00000100,0x0003588d,0x0002b15e,0x0002056d, +0x00015600,0x0000a329,0xffffeed9,0xffff3960, +0xfffe8423,0xfffdd11c,0xfffd2048,0xfffc7353, +0xfffbcb6f,0xfffb29a6,0xfffa8f15,0x000494ae, +0x0003f991,0x00032dd1,0xfffd2d8f,0x0001eb47, +0xfffe9968,0x00009af6,0x000011de,0xffff4335, +0x00018d69,0xfffdecd4,0x000302f8,0xfffca0d7, +0x0004683d,0xfffb67f8,0x0005b36d,0x00045963, +0xfffbd51e,0x00030062,0xfffd0dee,0x0001d046, +0xfffe8a0a,0x00009258,0x000012b1,0xffff4d9e, +0x00019ec3,0xfffe0a44,0x0003245a,0xfffcd082, +0x000498f0,0xfffba919,0x0005f304,0x00041bf4, +0xfffba72a,0x0002d19e,0xfffcf060,0x0001b407, +0xfffe7c08,0x0000894a,0x0000138d,0xffff58ac, +0x0001afaf,0xfffe28fe,0x000343bf,0xfffd026f, +0x0004c6f6,0xfffbed06,0x00062e61,0x0003dc0e, +0xfffb7bf1,0x0002a17f,0xfffcd522,0x000196a0, +0xfffe6e70,0x00007ff6,0x00001439,0xffff63f6, +0x0001beb3,0xfffe4882,0x0003616d,0xfffd361b, +0x0004f1cf,0xfffc332a,0x0006658f,0x00039943, +0xfffb52c0,0x00026ec7,0xfffcbb94,0x0001789f, +0xfffe6160,0x00007677,0x000014d4,0xffff6f74, +0x0001cc9b,0xfffe694f,0x00037cbf,0xfffd6b41, +0x000519c2,0xfffc7baf,0x00069971,0x00035486, +0xfffb2d0c,0x00023ad8,0xfffca3ee,0x00015989, +0xfffe55af,0x00006ca7,0x00001570,0xffff7b71, +0x0001d9cb,0xfffe8b46,0x0003959e,0xfffda1fe, +0x00053ee6,0xfffcc6b4,0x0006c950,0x00030e08, +0xfffb0a7a,0x0002061e,0xfffc8ec0,0x00013911, +0xfffe4b1d,0x00006278,0x000015e8,0xffff87b6, +0x0001e577,0xfffeadd6,0x0003acc2,0xfffdda34, +0x00056059,0xfffd136d,0x0006f4b5,0x0002c562, +0xfffaea7c,0x0001cfa6,0xfffc7b14,0x0001182b, +0xfffe4159,0x00005817,0x0000165c,0xffff9417, +0x0001f00f,0xfffed14c,0x0003c199,0xfffe13f6, +0x00057e83,0xfffd61cd,0x00071ba1,0x00027ab5, +0xfffacdc3,0x00019833,0xfffc6989,0x0000f6ca, +0xfffe38da,0x00004d9d,0x000016ef,0xffffa103, +0x0001f98f,0xfffef5c0,0x0003d3d1,0xfffe4f00, +0x0005998c,0xfffdb21e,0x00073e77,0x00022e75, +0xfffab482,0x00015fd1,0xfffc5b13,0x0000d45d, +0xfffe318f,0x000042ed,0x0000176b,0xffffae8f, +0x0002018f,0xffff1a91,0x0003e40c,0xfffe8af2, +0x0005b0ca,0xfffe03b8,0x00075d14,0x0001e141, +0xfffa9e9b,0x0001262a,0xfffc4e31,0x0000b1af, +0xfffe2b26,0x00003805,0x000017b1,0xffffbc21, +0x000208b8,0xffff3fb6,0x0003f1d7,0xfffec7af, +0x0005c4c5,0xfffe5654,0x0007768a,0x000192fe, +0xfffa8bb0,0x0000ec3f,0xfffc4365,0x00008ec9, +0xfffe25f0,0x00002d05,0x000017ec,0xffffc984, +0x00020ec6,0xffff658d,0x0003fcba,0xffff0500, +0x0005d576,0xfffeaa37,0x00078bc6,0x00014367, +0xfffa7bec,0x0000b1f4,0xfffc3b82,0x00006b06, +0xfffe2201,0x000021eb,0x00001823,0xffffd704, +0x0002132a,0xffff8be7,0x00040534,0xffff4315, +0x0005e22e,0xfffeff0a,0x00079ce3,0x0000f33f, +0xfffa6fc9,0x000076ca,0xfffc3558,0x00004762, +0xfffe1ef3,0x000016a1,0x0000183f,0xffffe4a6, +0x00021664,0xffffb27d,0x00040b7b,0xffff81e5, +0x0005eb4e,0xffff5475,0x0007a857,0x0000a2cb, +0xfffa671b,0x00003b64,0xfffc31e2,0x00002416, +0xfffe1ce1,0x00000b46,0x00001850,0xfffff24d, +0x00021855,0xffffd93a,0x00040f75,0xffffc0e6, +0x0005f0e3,0xffffaa3e,0x0007af45,0x0000519f, +0xfffa6218,0x0003f991,0x0003588d,0x0002b15e, +0x0002056d,0x00015600,0x0000a329,0xffffeed9, +0xffff3960,0xfffe8423,0xfffdd11c,0xfffd2048, +0xfffc7353,0xfffbcb6f,0xfffb29a6,0xfffa8f15, +0x000494ae,0x0003c6b0,0xfffc7e8b,0x00028ef6, +0xfffde181,0x000144eb,0xffff5500,0xffffefb9, +0x0000d01d,0xfffe9755,0x000249a4,0xfffd453c, +0x0003b80e,0xfffc01aa,0x000511d6,0xfffad527, +0xfffb334e,0x0003916c,0xfffc5778,0x00026a92, +0xfffdc9f5,0x00013314,0xffff4d99,0xfffff0b6, +0x0000d911,0xfffeab80,0x00026369,0xfffd6c0a, +0x0003e17f,0xfffc39d8,0x000549df,0xfffb1eb2, +0xfffafe6c,0x00035929,0xfffc3321,0x000244a6, +0xfffdb402,0x00012035,0xffff46ac,0xfffff192, +0x0000e16a,0xfffebfe0,0x00027b3d,0xfffd9433, +0x0004087b,0xfffc74b7,0x00057e8d,0xfffb6a81, +0xfffacc1c,0x00031fbe,0xfffc10df,0x00021e0c, +0xfffd9f6d,0x00010cb7,0xffff402e,0xfffff279, +0x0000e965,0xfffed574,0x00029159,0xfffdbdc4, +0x00042c4c,0xfffcb1e7,0x0005b02d,0xfffbb942, +0xfffa9d38,0x0002e44a,0xfffbf0fd,0x0001f5b4, +0xfffd8c38,0x0000f8b1,0xffff3a21,0xfffff391, +0x0000f0e6,0xfffeec44,0x0002a642,0xfffde90e, +0x00044e32,0xfffcf0fb,0x0005de46,0xfffc0b18, +0xfffa71d1,0x0002a659,0xfffbd3de,0x0001cb90, +0xfffd7a97,0x0000e403,0xffff3490,0xfffff49c, +0x0000f7a8,0xffff0340,0x0002b95f,0xfffe1573, +0x00046dbe,0xfffd3284,0x00060888,0xfffc5f51, +0xfffa4996,0x00026786,0xfffbb8df,0x0001a0e1, +0xfffd6a4e,0x0000ced2,0xffff2f75,0xfffff593, +0x0000fdbe,0xffff1a53,0x0002ca87,0xfffe42f5, +0x0004898a,0xfffd7563,0x00062f0b,0xfffcb5de, +0xfffa2508,0x00022713,0xfffba0bf,0x0001754a, +0xfffd5b5f,0x0000b92c,0xffff2acd,0xfffff6b0, +0x0001034f,0xffff3241,0x0002da5c,0xfffe71c6, +0x0004a341,0xfffdb946,0x000651e8,0xfffd0e37, +0xfffa0402,0x0001e4d4,0xfffb8b9c,0x00014898, +0xfffd4e7d,0x0000a304,0xffff26b7,0xfffff7e1, +0x00010846,0xffff4b34,0x0002e897,0xfffea13f, +0x0004ba63,0xfffdff2d,0x00067115,0xfffd6839, +0xfff9e680,0x0001a1fa,0xfffb789e,0x00011b2e, +0xfffd43a4,0x00008c6e,0xffff2341,0xfffff8fd, +0x00010c9c,0xffff6469,0x0002f48f,0xfffed1a4, +0x0004cd6a,0xfffe4608,0x00068c1b,0xfffdc409, +0xfff9cd15,0x00015dfe,0xfffb68a0,0x0000ecee, +0xfffd3a2e,0x0000757d,0xffff204b,0xfffffa1e, +0x00011054,0xffff7da1,0x0002fe9c,0xffff033e, +0x0004de57,0xfffe8dc6,0x0006a2d5,0xfffe213e, +0xfff9b77d,0x000118d3,0xfffb5bde,0x0000be25, +0xfffd3224,0x00005e52,0xffff1dc1,0xfffffb4b, +0x00011353,0xffff9740,0x00030748,0xffff351c, +0x0004ec95,0xfffed755,0x0006b5b4,0xfffe7fc6, +0xfff9a599,0x0000d334,0xfffb519f,0x00008f08, +0xfffd2bbf,0x00004704,0xffff1bc1,0xfffffc71, +0x00011598,0xffffb135,0x00030e43,0xffff6720, +0x0004f6f3,0xffff2119,0x0006c46e,0xfffedf38, +0xfff997c7,0x00008d13,0xfffb4a55,0x00005fa5, +0xfffd273b,0x00002f76,0xffff1a63,0xfffffda0, +0x00011744,0xffffcb67,0x000312ff,0xffff99cf, +0x0004ff0c,0xffff6a9c,0x0006cebd,0xffff3f0a, +0xfff98dbe,0x00004691,0xfffb4620,0x00003010, +0xfffd24fc,0x000017b5,0xffff199d,0xfffffed8, +0x0001185a,0xffffe5c6,0x0003157e,0xffffcce3, +0x000503ae,0xffffb515,0x0006d537,0xffff9f5a, +0xfff98767,0xfffb44b0,0xfffc3131,0xfffd2475, +0xfffe1c28,0xffff195d,0x00001859,0x000118bd, +0x000218df,0x0003163a,0x000410e0,0x000504a7, +0x0005f2b3,0x0006d796,0x0007b1fe,0xfff98537, +0xfffa609b,0xfffc7e8b,0x00028ef6,0xfffde181, +0x000144eb,0xffff5500,0xffffefb9,0x0000d01d, +0xfffe9755,0x000249a4,0xfffd453c,0x0003b80e, +0xfffc01aa,0x000511d6,0xfffad527,0xfffb334e, +0x0003c6b0,0xfffc5778,0x00026a92,0xfffdc9f5, +0x00013314,0xffff4d99,0xfffff0b6,0x0000d911, +0xfffeab80,0x00026369,0xfffd6c0a,0x0003e17f, +0xfffc39d8,0x000549df,0xfffb1eb2,0xfffafe6c, +0x0003916c,0xfffc3321,0x000244a6,0xfffdb402, +0x00012035,0xffff46ac,0xfffff192,0x0000e16a, +0xfffebfe0,0x00027b3d,0xfffd9433,0x0004087b, +0xfffc74b7,0x00057e8d,0xfffb6a81,0xfffacc1c, +0x00035929,0xfffc10df,0x00021e0c,0xfffd9f6d, +0x00010cb7,0xffff402e,0xfffff279,0x0000e965, +0xfffed574,0x00029159,0xfffdbdc4,0x00042c4c, +0xfffcb1e7,0x0005b02d,0xfffbb942,0xfffa9d38, +0x00031fbe,0xfffbf0fd,0x0001f5b4,0xfffd8c38, +0x0000f8b1,0xffff3a21,0xfffff391,0x0000f0e6, +0xfffeec44,0x0002a642,0xfffde90e,0x00044e32, +0xfffcf0fb,0x0005de46,0xfffc0b18,0xfffa71d1, +0x0002e44a,0xfffbd3de,0x0001cb90,0xfffd7a97, +0x0000e403,0xffff3490,0xfffff49c,0x0000f7a8, +0xffff0340,0x0002b95f,0xfffe1573,0x00046dbe, +0xfffd3284,0x00060888,0xfffc5f51,0xfffa4996, +0x0002a659,0xfffbb8df,0x0001a0e1,0xfffd6a4e, +0x0000ced2,0xffff2f75,0xfffff593,0x0000fdbe, +0xffff1a53,0x0002ca87,0xfffe42f5,0x0004898a, +0xfffd7563,0x00062f0b,0xfffcb5de,0xfffa2508, +0x00026786,0xfffba0bf,0x0001754a,0xfffd5b5f, +0x0000b92c,0xffff2acd,0xfffff6b0,0x0001034f, +0xffff3241,0x0002da5c,0xfffe71c6,0x0004a341, +0xfffdb946,0x000651e8,0xfffd0e37,0xfffa0402, +0x00022713,0xfffb8b9c,0x00014898,0xfffd4e7d, +0x0000a304,0xffff26b7,0xfffff7e1,0x00010846, +0xffff4b34,0x0002e897,0xfffea13f,0x0004ba63, +0xfffdff2d,0x00067115,0xfffd6839,0xfff9e680, +0x0001e4d4,0xfffb789e,0x00011b2e,0xfffd43a4, +0x00008c6e,0xffff2341,0xfffff8fd,0x00010c9c, +0xffff6469,0x0002f48f,0xfffed1a4,0x0004cd6a, +0xfffe4608,0x00068c1b,0xfffdc409,0xfff9cd15, +0x0001a1fa,0xfffb68a0,0x0000ecee,0xfffd3a2e, +0x0000757d,0xffff204b,0xfffffa1e,0x00011054, +0xffff7da1,0x0002fe9c,0xffff033e,0x0004de57, +0xfffe8dc6,0x0006a2d5,0xfffe213e,0xfff9b77d, +0x00015dfe,0xfffb5bde,0x0000be25,0xfffd3224, +0x00005e52,0xffff1dc1,0xfffffb4b,0x00011353, +0xffff9740,0x00030748,0xffff351c,0x0004ec95, +0xfffed755,0x0006b5b4,0xfffe7fc6,0xfff9a599, +0x000118d3,0xfffb519f,0x00008f08,0xfffd2bbf, +0x00004704,0xffff1bc1,0xfffffc71,0x00011598, +0xffffb135,0x00030e43,0xffff6720,0x0004f6f3, +0xffff2119,0x0006c46e,0xfffedf38,0xfff997c7, +0x0000d334,0xfffb4a55,0x00005fa5,0xfffd273b, +0x00002f76,0xffff1a63,0xfffffda0,0x00011744, +0xffffcb67,0x000312ff,0xffff99cf,0x0004ff0c, +0xffff6a9c,0x0006cebd,0xffff3f0a,0xfff98dbe, +0x00008d13,0xfffb4620,0x00003010,0xfffd24fc, +0x000017b5,0xffff199d,0xfffffed8,0x0001185a, +0xffffe5c6,0x0003157e,0xffffcce3,0x000503ae, +0xffffb515,0x0006d537,0xffff9f5a,0xfff98767, +0x00004691,0xfffa609b,0xfffb44b0,0xfffc3131, +0xfffd2475,0xfffe1c28,0xffff195d,0x00001859, +0x000118bd,0x000218df,0x0003163a,0x000410e0, +0x000504a7,0x0005f2b3,0x0006d796,0x0007b1fe, +0xfff98537,0xfffbd51e,0x00032dd1,0xfffd2d8f, +0x0001eb47,0xfffe9968,0x00009af6,0x000011de, +0xffff4335,0x00018d69,0xfffdecd4,0x000302f8, +0xfffca0d7,0x0004683d,0xfffb67f8,0x0005b36d, +0x00045963,0xfffba72a,0x00030062,0xfffd0dee, +0x0001d046,0xfffe8a0a,0x00009258,0x000012b1, +0xffff4d9e,0x00019ec3,0xfffe0a44,0x0003245a, +0xfffcd082,0x000498f0,0xfffba919,0x0005f304, +0x00041bf4,0xfffb7bf1,0x0002d19e,0xfffcf060, +0x0001b407,0xfffe7c08,0x0000894a,0x0000138d, +0xffff58ac,0x0001afaf,0xfffe28fe,0x000343bf, +0xfffd026f,0x0004c6f6,0xfffbed06,0x00062e61, +0x0003dc0e,0xfffb52c0,0x0002a17f,0xfffcd522, +0x000196a0,0xfffe6e70,0x00007ff6,0x00001439, +0xffff63f6,0x0001beb3,0xfffe4882,0x0003616d, +0xfffd361b,0x0004f1cf,0xfffc332a,0x0006658f, +0x00039943,0xfffb2d0c,0x00026ec7,0xfffcbb94, +0x0001789f,0xfffe6160,0x00007677,0x000014d4, +0xffff6f74,0x0001cc9b,0xfffe694f,0x00037cbf, +0xfffd6b41,0x000519c2,0xfffc7baf,0x00069971, +0x00035486,0xfffb0a7a,0x00023ad8,0xfffca3ee, +0x00015989,0xfffe55af,0x00006ca7,0x00001570, +0xffff7b71,0x0001d9cb,0xfffe8b46,0x0003959e, +0xfffda1fe,0x00053ee6,0xfffcc6b4,0x0006c950, +0x00030e08,0xfffaea7c,0x0002061e,0xfffc8ec0, +0x00013911,0xfffe4b1d,0x00006278,0x000015e8, +0xffff87b6,0x0001e577,0xfffeadd6,0x0003acc2, +0xfffdda34,0x00056059,0xfffd136d,0x0006f4b5, +0x0002c562,0xfffacdc3,0x0001cfa6,0xfffc7b14, +0x0001182b,0xfffe4159,0x00005817,0x0000165c, +0xffff9417,0x0001f00f,0xfffed14c,0x0003c199, +0xfffe13f6,0x00057e83,0xfffd61cd,0x00071ba1, +0x00027ab5,0xfffab482,0x00019833,0xfffc6989, +0x0000f6ca,0xfffe38da,0x00004d9d,0x000016ef, +0xffffa103,0x0001f98f,0xfffef5c0,0x0003d3d1, +0xfffe4f00,0x0005998c,0xfffdb21e,0x00073e77, +0x00022e75,0xfffa9e9b,0x00015fd1,0xfffc5b13, +0x0000d45d,0xfffe318f,0x000042ed,0x0000176b, +0xffffae8f,0x0002018f,0xffff1a91,0x0003e40c, +0xfffe8af2,0x0005b0ca,0xfffe03b8,0x00075d14, +0x0001e141,0xfffa8bb0,0x0001262a,0xfffc4e31, +0x0000b1af,0xfffe2b26,0x00003805,0x000017b1, +0xffffbc21,0x000208b8,0xffff3fb6,0x0003f1d7, +0xfffec7af,0x0005c4c5,0xfffe5654,0x0007768a, +0x000192fe,0xfffa7bec,0x0000ec3f,0xfffc4365, +0x00008ec9,0xfffe25f0,0x00002d05,0x000017ec, +0xffffc984,0x00020ec6,0xffff658d,0x0003fcba, +0xffff0500,0x0005d576,0xfffeaa37,0x00078bc6, +0x00014367,0xfffa6fc9,0x0000b1f4,0xfffc3b82, +0x00006b06,0xfffe2201,0x000021eb,0x00001823, +0xffffd704,0x0002132a,0xffff8be7,0x00040534, +0xffff4315,0x0005e22e,0xfffeff0a,0x00079ce3, +0x0000f33f,0xfffa671b,0x000076ca,0xfffc3558, +0x00004762,0xfffe1ef3,0x000016a1,0x0000183f, +0xffffe4a6,0x00021664,0xffffb27d,0x00040b7b, +0xffff81e5,0x0005eb4e,0xffff5475,0x0007a857, +0x0000a2cb,0xfffa6218,0x00003b64,0xfffc31e2, +0x00002416,0xfffe1ce1,0x00000b46,0x00001850, +0xfffff24d,0x00021855,0xffffd93a,0x00040f75, +0xffffc0e6,0x0005f0e3,0xffffaa3e,0x0007af45, +0x0000519f,0x00030000,0x000f0007,0x003f001f, +0x00ff007f,0x03ff01ff,0x0fff07ff,0x3fff1fff, +0xffff7fff,0x00030000,0x00070005,0x000f0009, +0x003f001f,0x00ff007f,0x03ff01ff,0x0fff07ff, +0xffff1fff,0x00030000,0x00070005,0x000f0009, +0xffff001f,0x00030000,0xffff0005,0x04030504, +0x08070605,0x0c0b0a09,0x100f0e0d,0x03070504, +0x0605040a,0x0a090807,0x100d0c0b,0x03070503, +0x1005040a,0x10070502,0x03030100,0x03030303, +0x03030303,0x03030303,0x03010100,0x03030301, +0x03030303,0x03030303,0x03010100,0x03030301, +0x03010100,0x04020000,0x08070605,0x0c0b0a09, +0x100f0e0d,0x02010000,0x06050403,0x0a090807, +0x100d0c0b,0x02010000,0x10050403,0x10010000, +0x00030000,0x00090005,0x001f000f,0x007f003f, +0x01ff00ff,0x07ff03ff,0x1fff0fff,0x7fff3fff, +0x00030000,0x00090005,0x001f000f,0x007f003f, +0x0a070504,0x07060504,0x0b0a0908,0x0f0e0d0c, +0x0a070503,0x07060504,0x01010100,0x03030303, +0x03030303,0x03030303,0x01010100,0x03030303, +0x03010000,0x07060504,0x0b0a0908,0x0f0e0d0c, +0x03010000,0x07060504,0x00555555,0x002aaaab, +0x00249249,0x00124925,0x00111111,0x00088889, +0x00084210,0x00421084,0x00041041,0x00020821, +0x00020408,0x00081020,0x00010101,0x00008081, +0x00008040,0x00100804,0x00004010,0x00020080, +0x00002004,0x00004008,0x00001001,0x00000801, +0x00000800,0x00200100,0x00000400,0x00080020, +0x00000200,0x00020004,0x00200000,0x00600040, +0x00a00080,0x00e000c0,0x01200100,0x01600140, +0x01a00180,0x000001c0,0x00300020,0x00400038, +0x00600050,0x00800070,0x00c000a0,0x010000e0, +0x01800140,0x00200000,0x00300028,0x00400038, +0x00600050,0x00800070,0x00c000a0,0x010000e0, +0x00000140,0x00900000,0x00fc00d8,0x01680120, +0x01f801b0,0x02d00240,0x03f00360,0x05a00480, +0x000006c0,0x00680000,0x00b6009c,0x010500d0, +0x016d0139,0x020a01a1,0x02db0272,0x04140343, +0x000004e5,0x006c0000,0x00bd00a2,0x010e00d8, +0x017a0144,0x006301b0,0x013b00cf,0x00c601a7, +0x0000019e,0x00600000,0x00a80090,0x00f000c0, +0x01500120,0x01e00180,0x02a00240,0x03c00300, +0x00000480,0x10000000,0x10101010,0x20101010, +0x20202020,0x20202020,0x28202020,0x28282828, +0x00002828,0x10100000,0x10101010,0x10101010, +0x00000000,0x00000000,0x00000000,0x00000000, +0xcbcecdc4,0xcfcac9c8,0xc3c6c5cc,0xc7c2c1c0, +0x1b1e1d14,0x1f1a1918,0x1316151c,0x17121110, +0x2b2e2d24,0x2f2a2928,0x2326252c,0x27222120, +0x3b3e3d34,0x3f3a3938,0x3336353c,0x37323130, +0x0b0e0d04,0x0f0a0908,0x0306050c,0x07020100, +0xdbdeddd4,0xdfdad9d8,0xd3d6d5dc,0xd7d2d1d0, +0xebeeede4,0xefeae9e8,0xe3e6e5ec,0xe7e2e1e0, +0xfbfefdf4,0xfffaf9f8,0xf3f6f5fc,0xf7f2f1f0, +0x4b4e4d44,0x4f4a4948,0x4346454c,0x47424140, +0x9b9e9d94,0x9f9a9998,0x9396959c,0x97929190, +0xabaeada4,0xafaaa9a8,0xa3a6a5ac,0xa7a2a1a0, +0xbbbebdb4,0xbfbab9b8,0xb3b6b5bc,0xb7b2b1b0, +0x8b8e8d84,0x8f8a8988,0x8386858c,0x87828180, +0x5b5e5d54,0x5f5a5958,0x5356555c,0x57525150, +0x6b6e6d64,0x6f6a6968,0x6366656c,0x67626160, +0x7b7e7d74,0x7f7a7978,0x7376757c,0x77727170, +0x341424c4,0x3e1e2ece,0x3d1d2dcd,0x3b1b2bcb, +0xb494a444,0xbe9eae4e,0xbd9dad4d,0xbb9bab4b, +0xf4d4e404,0xfedeee0e,0xfddded0d,0xfbdbeb0b, +0x74546484,0x7e5e6e8e,0x7d5d6d8d,0x7b5b6b8b, +0x3c1c2ccc,0x361626c6,0x351525c5,0x331323c3, +0xbc9cac4c,0xb696a646,0xb595a545,0xb393a343, +0xfcdcec0c,0xf6d6e606,0xf5d5e505,0xf3d3e303, +0x7c5c6c8c,0x76566686,0x75556585,0x73536383, +0x381828c8,0x3a1a2aca,0x391929c9,0x3f1f2fcf, +0xb898a848,0xba9aaa4a,0xb999a949,0xbf9faf4f, +0xf8d8e808,0xfadaea0a,0xf9d9e909,0xffdfef0f, +0x78586888,0x7a5a6a8a,0x79596989,0x7f5f6f8f, +0x301020c0,0x321222c2,0x311121c1,0x371727c7, +0xb090a040,0xb292a242,0xb191a141,0xb797a747, +0xf0d0e000,0xf2d2e202,0xf1d1e101,0xf7d7e707, +0x70506080,0x72526282,0x71516181,0x77576787, +0x05040100,0x15141110,0x25242120,0x35343130, +0x85848180,0x95949190,0xa5a4a1a0,0xb5b4b1b0, +0xc0408000,0xe060a020,0xd0509010,0xf070b030, +0xc8488808,0xe868a828,0xd8589818,0xf878b838, +0xc4448404,0xe464a424,0xd4549414,0xf474b434, +0xcc4c8c0c,0xec6cac2c,0xdc5c9c1c,0xfc7cbc3c, +0xc2428202,0xe262a222,0xd2529212,0xf272b232, +0xca4a8a0a,0xea6aaa2a,0xda5a9a1a,0xfa7aba3a, +0xc6468606,0xe666a626,0xd6569616,0xf676b636, +0xce4e8e0e,0xee6eae2e,0xde5e9e1e,0xfe7ebe3e, +0xc1418101,0xe161a121,0xd1519111,0xf171b131, +0xc9498909,0xe969a929,0xd9599919,0xf979b939, +0xc5458505,0xe565a525,0xd5559515,0xf575b535, +0xcd4d8d0d,0xed6dad2d,0xdd5d9d1d,0xfd7dbd3d, +0xc3438303,0xe363a323,0xd3539313,0xf373b333, +0xcb4b8b0b,0xeb6bab2b,0xdb5b9b1b,0xfb7bbb3b, +0xc7478707,0xe767a727,0xd7579717,0xf777b737, +0xcf4f8f0f,0xef6faf2f,0xdf5f9f1f,0xff7fbf3f, +0x1045a3e2,0x000000f4,0x263b7333,0x766b2363, +0x2b367e3e,0x7b662e6e,0x06db93d3,0x964b0343, +0x0bd69ede,0x9b460e4e,0x825f1757,0x12cf87c7, +0x8f521a5a,0x1fc28aca,0x00d199d9,0x90410949, +0x01d098d8,0x91400848,0x24357d3d,0x74652d6d, +0x25347c3c,0x75642c6c,0x04d59ddd,0x94450d4d, +0x05d49cdc,0x95440c4c,0x80511959,0x10c189c9, +0x81501858,0x11c088c8,0x02df97d7,0x924f0747, +0x0fd29ada,0x9f420a4a,0x865b1353,0x16cb83c3, +0x8b561e5e,0x1bc68ece,0xa6bbf3b3,0xf6eba3e3, +0xabb6febe,0xfbe6aeee,0x223f7737,0x726f2767, +0x2f327a3a,0x7f622a6a,0xa0b1f9b9,0xf0e1a9e9, +0xa1b0f8b8,0xf1e0a8e8,0x84551d5d,0x14c58dcd, +0x85541c5c,0x15c48ccc,0xa4b5fdbd,0xf4e5aded, +0xa5b4fcbc,0xf5e4acec,0x20317939,0x70612969, +0x21307838,0x71602868,0xa2bff7b7,0xf2efa7e7, +0xafb2faba,0xffe2aaea,0x00000000,0x00000000, + +}; + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/mpgi2s.h linux.19pre5-ac1/drivers/media/video/ls220/mpgi2s.h --- linux.19p5/drivers/media/video/ls220/mpgi2s.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/ls220/mpgi2s.h Thu Feb 21 21:27:39 2002 @@ -0,0 +1,1611 @@ +static u32 MPGI2SUcode1f1800[] = { +0x820f001f,0x802f001f,0x81df0000,0xb500000c, +0x00ffb81e,0x00000000,0x00000000,0x00000000, +0x00ffb81e,0x00000000,0x00000000,0x00000000, +0xb5000c0f,0x00000000,0x00000000,0x00000000, +0x80070800,0x001f6047,0x8013001f,0x90208000, +0x003fb174,0x803effe8,0x803effec,0x9020fa00, +0x803effd0,0x803effdc,0x803effd8,0x9020fe00, +0x803effd4,0x805bff7c,0x802500d4,0x94020080, +0xb0000000,0xb4200023,0x8013ffcf,0x9800cfff, +0x80730030,0x98631000,0x94420007,0xb0020002, +0xb4200005,0x8013ffc7,0x9800c7ff,0x80730038, +0x98631000,0xb5000006,0xb0020001,0xb4200004, +0x8013ffcf,0x9800cfff,0x80730030,0x98631000, +0x1421b800,0x1821b803,0x802600d4,0x8033001f, +0x98210000,0x802600a2,0x8033001f,0x98210300, +0x802600a3,0x80270225,0x80530001,0x98420100, +0x1821b802,0x80530200,0x98420000,0x804600a6, +0xb500001d,0x805bff7c,0x8013ffcf,0x9800cfff, +0x80730030,0x98632000,0x94420007,0xb0020002, +0xb4200005,0x8013ffc7,0x9800c7ff,0x80730038, +0x98632800,0xb5000006,0xb0020001,0xb4200004, +0x8013ffcf,0x9800cfff,0x80730030,0x98632000, +0x1421b800,0x1821b803,0x802600d4,0x8033001f, +0x98210000,0x802600a2,0x8033001f,0x98210600, +0x802600a3,0x80270eff,0x802600a1,0x80270002, +0x803eff84,0x80070000,0x801effc0,0x801effc4, +0x801effc8,0x801effcc,0x801eff88,0x80770000, +0x8057ffff,0x80170080,0x80070000,0xb6003f02, +0xb6002001,0x001fa020,0x8007ffff,0x801eff84, +0x80070001,0x001f25dc,0x001f20b1,0x80070000, +0x001f6046,0x001fb17c,0x001fb17d,0x80070000, +0x801e78d0,0x98004000,0x001f62ea,0x80070100, +0x801efff0,0x81df0004,0x00000000,0x00000000, +0x801bfff0,0x00000000,0x940000ff,0xb0000000, +0xb420005b,0x003f42ea,0x94010010,0xb0000000, +0xb400fff7,0x003f05dc,0xb0010001,0xb4200034, +0x803bffe8,0x801bffec,0x00000000,0x3001b800, +0xb4600001,0x90214000,0x0421b800,0xb0010800, +0xb460000d,0x80050086,0x005f902e,0xb0020000, +0xb4200002,0x001fb02e,0xb5000006,0x0420b802, +0xb0010930,0xb4a0ffe2,0x80070000,0x001fb02e, +0x83e40162,0xb500ffde,0x83e40129,0x80070000, +0x001fb02e,0x001f42ea,0x9400000f,0xb0000000, +0xb4000010,0x9400fff0,0x001f62ea,0x003f9174, +0x9421ffff,0x90210004,0xb001c000,0xb4800002, +0x8421c000,0x90218000,0x8013001f,0x1821b800, +0x003fb174,0x003f917c,0x90210004,0x003fb17c, +0x83e4014a,0x8013001f,0x83e71b0c,0x1bffb800, +0x003f9179,0x1821b800,0x00ffb801,0xb5000008, +0x80270000,0x003f25dc,0x8013001f,0x83e71b30, +0x1bffb800,0x003f917a,0x1821b800,0x00ffb801, +0x80070000,0x001f20b1,0x001f42ea,0x9420000f, +0xb0010000,0xb4200003,0x98000800,0x001f62ea, +0xb500ffaf,0x9400fff0,0x001f62ea,0x80270000, +0x8057ffff,0x80770000,0x80171980,0x81df0000, +0x00000000,0x00000000,0xb6000602,0xb6002001, +0x001fa021,0x81df0004,0xb500ffa1,0xb500ffa0, +0x803bffc0,0x805bffc4,0x807bffc8,0x809bffcc, +0x5828b801,0x5cb8b802,0x1821b805,0x5848b802, +0x5cb8b803,0x1842b805,0x5868b803,0x5cb8b804, +0x1863b805,0x5888b804,0x1884b800,0x803effc0, +0x805effc4,0x807effc8,0x809effcc,0x003f42ea, +0xb0000086,0xb4400079,0xb0000084,0xb4000049, +0xb0000085,0xb4000063,0xb0000086,0xb400006c, +0xb0000081,0xb4000005,0xb0000082,0xb4000003, +0xb0000080,0xb4000001,0xb5000069,0x8013007f, +0x9800ffff,0x001fb02d,0x80070000,0x001fb17c, +0x8013001f,0x9040fa00,0x805effd0,0x805effdc, +0x805effd8,0x9040fe00,0x805effd4,0x9040c000, +0x805effe4,0x90008000,0x801effe0,0x001fb174, +0x801effe8,0x801effec,0x80078000,0x801e78d4, +0x80070000,0x001fb17c,0x001fb17d,0x001fb02e, +0x83e400e6,0x8013001f,0x98000000,0x800600a2, +0x8013001f,0x98000600,0x800600a3,0x805bff7c, +0x80070eff,0x94420080,0xb0020080,0xb420000d, +0x8013001f,0x98000000,0x800600a2,0x8013001f, +0x98000300,0x800600a3,0x80070225,0x80530001, +0x98420100,0x1800b802,0x80530200,0x98420000, +0x804600a6,0x800600a1,0x80050080,0x98000022, +0x80060080,0x80072080,0x001fb179,0x80074618, +0x001fb17a,0x80070001,0x001f25dc,0x98214000, +0xb5000029,0x8047ffff,0x805eff84,0x805bff88, +0x00000000,0xb0020001,0xb4200002,0x80470000, +0x805eff88,0x805bff7c,0x80070eff,0x94420080, +0xb0020080,0xb4200007,0x80070225,0x80530001, +0x98420100,0x1800b802,0x80530200,0x98420000, +0x804600a6,0x800600a1,0x80070001,0x800600a0, +0x9421efff,0x98210010,0xb500000f,0x80070000, +0x001fb17c,0x80070001,0x001f25dc,0x83e400a3, +0x80050081,0x80330008,0x98210000,0x1800b801, +0x80060081,0x003f42ea,0x9421ffef,0xb5000002, +0x98211000,0x9421ffef,0x83e40098,0x003f62ea, +0x80070100,0x801efff0,0xb500ff11,0xb000008b, +0xb400001c,0xb0000087,0xb400ffe8,0xb0000088, +0xb4000023,0xb000008a,0xb4000024,0xb000008c, +0xb4000019,0xb000008e,0xb4000014,0xb000008d, +0xb400001d,0xb0000089,0xb400001f,0xb00000a0, +0xb4000021,0xb00000a1,0xb4000022,0xb00000a2, +0xb400002f,0xb00000a3,0xb4000027,0xb00000a4, +0xb4000031,0xb00000a5,0xb4000035,0xb00000a6, +0xb4000039,0x803efff8,0xb500ffdd,0x80070000, +0x001fb17e,0xb500ffda,0x803bffb0,0x00000000, +0x003fb02d,0xb500ffd6,0x98210020,0xb500ffd2, +0x9421ffdf,0xb500ffd0,0xb500ffd1,0x80270351, +0x803efff8,0xb500ffce,0x803bff80,0x00000000, +0x003f62ef,0xb500ffca,0x003f917b,0x803efff8, +0xb500ffc7,0x80270000,0x8047fef0,0x003eb802, +0x90420004,0x003eb802,0x90420004,0x003eb802, +0x90420004,0x003eb802,0x81df0000,0x00000000, +0x00000000,0x83640db9,0x81df0004,0xb500ffb8, +0x81df0000,0x00000000,0x00000000,0x83640d63, +0x81df0004,0xb500ffb2,0x81df0000,0x00000000, +0x00000000,0x83640d1e,0x81df0004,0xb500ffac, +0x81df0000,0x00000000,0x00000000,0x83440c81, +0x81df0004,0xb500ffa6,0x81df0000,0x00000000, +0x00000000,0x83440c66,0x81df0004,0xb500ffa0, +0x817bffe8,0x815b78d4,0x00000000,0x956bffff, +0x300bb80a,0xb4600001,0x916b4000,0x056bb80a, +0xb00b0080,0xb4a0002a,0x80af001f,0x808f0000, +0x806f0000,0x81b300ff,0x8057ffff,0x5d67b80b, +0x5d42b80a,0x81df0000,0x00000000,0x00000000, +0xb62b001c,0xb00a3000,0xb4800001,0x854a1000, +0x80cf0400,0x015fb178,0x5942b80a,0x01cfb80a, +0x015f9178,0xb520ffff,0x80171000,0xb600200a, +0x01ff8000,0x5a18b80f,0x5a28b80f,0x1631b80d, +0x5e48b80f,0x9652ff00,0x5e78b80f,0x1a73b810, +0x1a73b811,0x1813a032,0x80cf0400,0x015fb178, +0x5942b80a,0x01afb80a,0x015f9178,0xb520ffff, +0x914a0020,0x81df0004,0x5942b80a,0x815e78d4, +0x00000000,0x00000000,0x00ffb81f,0x81df0000, +0x80070000,0x80470000,0x81171800,0xb6002003, +0xb6003002,0x001eb802,0x90420004,0xb6002003, +0x011fa020,0x011fa020,0x011fa020,0x81df0004, +0x00ffb81f,0x80070000,0x80478000,0x81df0000, +0x00000000,0x00000000,0xb6002003,0xb6008002, +0x001eb802,0x90420004,0x81df0004,0x00ffb81f, +0x015f42ea,0x944a4000,0xb0024000,0xb4200081, +0x954abfff,0x015f62ea,0x808f0000,0x80ef007c, +0x80171000,0x80971400,0x80270000,0xb6001003, +0xb6002002,0x001fa021,0x009fa021,0x80a76604, +0x80271400,0x81df0000,0x00000000,0x00000000, +0xb6001004,0x01efb801,0x01afb805,0xb520ffff, +0x90a50080,0x81df0004,0x80a76e04,0x80271400, +0x81df0000,0x00000000,0x00000000,0xb6001004, +0x01efb801,0x01afb805,0xb520ffff,0x90a50080, +0x81df0004,0x806f001f,0x80af001f,0x80276400, +0x5c22b801,0x806701e1,0x00cfb803,0x003fb178, +0x5822b801,0x01cfb801,0x003f9178,0x0047b86f, +0xb0020001,0xb4c0fffd,0x80275c00,0x5c22b801, +0x80670200,0x81df0000,0x00000000,0x00000000, +0xb600100a,0x00cfb803,0x003fb178,0x5822b801, +0x01cfb801,0x003f9178,0x0047b86f,0xb0020001, +0xb4c0fffd,0x90210020,0x90630020,0x81df0004, +0x808f0000,0x806f001f,0x80af001f,0x8027647c, +0x5c22b801,0x8067017e,0x81df0000,0x00000000, +0x00000000,0xb600020a,0x00cfb803,0x003fb178, +0x5822b801,0x01cfb801,0x003f9178,0x0047b86f, +0xb0020001,0xb4c0fffd,0x90210020,0x90630020, +0x81df0004,0x806f0010,0x80af0010,0x8027657c, +0x5c22b801,0x806701be,0x00cfb803,0x003fb178, +0x5822b801,0x01cfb801,0x003f9178,0x0047b86f, +0xb0020001,0xb4c0fffd,0x802765c0,0x5c22b801, +0x806701cf,0x00cfb803,0x003fb178,0x5822b801, +0x01cfb801,0x003f9178,0x0047b86f,0xb0020001, +0xb4c0fffd,0x80276000,0x005fb801,0x8033001f, +0x98218000,0x803effe0,0x90214000,0x803effe4, +0x8193001f,0x998c8000,0x019fb174,0x83270000, +0x003fb819,0x003f9174,0x5823b801,0x83338000, +0x1b39b801,0x003fb819,0x00000000,0x00000000, +0x81550000,0x0187b860,0x858c0040,0x81b380fc, +0x99ad0000,0x300cb80d,0xb4600003,0x81b30002, +0x99ad0000,0x118cb80d,0x003fb80c,0x00000000, +0x00000000,0x81550000,0x8257ffff,0x82d7ffff, +0x8357ffff,0x81672000,0x83440191,0xb00a0001, +0xb4000141,0x0187b860,0x858c0010,0x5988b80c, +0x5d8bb80c,0x958cffff,0xb00cc000,0xb4800002, +0x858cc000,0x918c8000,0x81b3001f,0x198cb80d, +0x801bffec,0x00000000,0x819effec,0x819e78d8, +0x019fb174,0x05acb800,0x300cb800,0xb4600001, +0x91ad4000,0x001f917c,0x1000b80d,0x001fb17c, +0x8344019c,0xb00a0000,0xb4200127,0x015f0081, +0xb00a0002,0xb4200124,0x037f0082,0xb01b0000, +0xb400001e,0x0367b860,0x5b68b81b,0x5f68b81b, +0x017f4047,0x916b0010,0x5963b80b,0x83440168, +0x801bff84,0xb00a0001,0xb400000b,0xb00b00c0, +0xb460fffa,0x803f0000,0x80138000,0x1b7bb800, +0x003fb81b,0x00000000,0x00000000,0x80150000, +0x801bff84,0xb5000009,0x803f0000,0x80138000, +0x1b7bb800,0x003fb81b,0x00000000,0x00000000, +0x80150000,0x801bff84,0xb5000103,0x801bff84, +0x003f0084,0x3000b801,0x803eff84,0xb4000073, +0x801bff7c,0x00000000,0x94800080,0xb0040080, +0xb4200036,0x94800007,0x80730200,0xb0010002, +0xb420000e,0x80270265,0xb0040001,0xb4200003, +0x80130030,0x98000000,0xb5000006,0x80130030, +0x98000000,0xb0040000,0xb4000002,0x80130038, +0x98000000,0x98630060,0xb500001f,0xb0010000, +0xb420000e,0x80270225,0xb0040001,0xb4200003, +0x80130030,0x98001000,0xb5000006,0x80130030, +0x98001000,0xb0040000,0xb4000002,0x80130038, +0x98001000,0x98630000,0xb500000f,0xb0010001, +0xb420004a,0x80270225,0xb0040001,0xb4200003, +0x80130030,0x98002000,0xb5000006,0x80130030, +0x98000000,0xb0040000,0xb4000002,0x80130038, +0x98000000,0x98630040,0x806600a6,0x80530001, +0x98420100,0x1821b802,0xb500002d,0x94800007, +0xb0010002,0xb420000d,0x80270eff,0xb0040001, +0xb4200003,0x80130030,0x98002000,0xb5000006, +0x80130030,0x98000000,0xb0040000,0xb4000002, +0x80130038,0x98000000,0xb500001d,0xb0010000, +0xb420000d,0x80270eff,0xb0040001,0xb4200003, +0x80130030,0x98002000,0xb5000006,0x80130030, +0x98002000,0xb0040000,0xb4000002,0x80130038, +0x98002800,0xb500000e,0xb0010001,0xb4200017, +0x80270eff,0xb0040001,0xb4200003,0x80130030, +0x98002000,0xb5000006,0x80130030,0x98002000, +0xb0040000,0xb4000002,0x80130038,0x98002800, +0x806500d4,0x8053ffcf,0x9842cfff,0xb0040002, +0xb4200002,0x8053ffc7,0x9842c7ff,0x802600a1, +0x1463b802,0x1863b800,0x806600d4,0x807bff7c, +0x00000000,0x94630080,0xb0030080,0xb420000b, +0x807bff88,0x00000000,0xb0030001,0xb4000007, +0x802500a1,0x80670001,0x807eff88,0x80530001, +0x98420100,0x1821b802,0x802600a1,0x81070000, +0x011f62e2,0x011f62e3,0x011f0082,0xb0080000, +0xb4200004,0x81150010,0x00000000,0x00000000, +0x011f62de,0x011f0081,0xb0080001,0xb4200026, +0x81070020,0x011f25c1,0x81070180,0x011f62e1, +0x8344023e,0x8344026a,0x011f0082,0xb0080000, +0xb4200004,0x834401bd,0x834401aa,0xb00a0000, +0xb4200061,0x80c70000,0x00df25cb,0x83440281, +0x8344064f,0x02ff05b9,0x82a70000,0x82870000, +0x83440407,0x92940001,0x3014b817,0xb480fffc, +0x834406ef,0x80270000,0x003f25dc,0x834407de, +0x003f05dc,0xb0010001,0xb4000003,0x80272694, +0x003fb17a,0x00ffb81f,0x80d3001f,0x8347266c, +0x1b5ab806,0xb500002d,0xb0080002,0x81470004, +0xb4200045,0x81070008,0x011f25c1,0x81070480, +0x011f62e1,0x8344029e,0x834402dc,0x011f0082, +0xb0080000,0xb4200004,0x834401aa,0x83440181, +0xb00a0000,0xb4200038,0x80c70000,0x00df25cb, +0x83440368,0x02df05cb,0x5ec2b816,0x8344066b, +0x02ff05b9,0x82a70000,0x82870000,0x834403dc, +0x92940001,0x3014b817,0xb480fffc,0x92b50001, +0xb0150003,0xb480fff8,0x834406c1,0x80270000, +0x003f25dc,0x834407b0,0x003f05dc,0xb0010001, +0xb4000003,0x8027274c,0x003fb17a,0x00ffb81f, +0x80d3001f,0x83472710,0x1b5ab806,0x80db78d8, +0x80fbffec,0x00000000,0x3006b807,0xb4200007, +0x00df05cb,0x90c60001,0x00df25cb,0xb006000c, +0xb4000002,0x035fb179,0x00ffb81f,0x80c70000, +0x00df25cb,0x80fb78dc,0x00000000,0x90e70001, +0xb00701b9,0xb4a00001,0x80e70001,0x80fe78dc, +0xb500feb0,0x802500a5,0x8153001f,0x3001b80a, +0xb420fffc,0x00ffb81f,0x001f42ea,0x1800b80a, +0x001f62ea,0x017f4047,0x5963b80b,0x0187b860, +0x118cb80b,0x81b380fe,0x99ad0000,0x300cb80d, +0xb4800003,0x81b30002,0x99ad0000,0x058cb80d, +0x003fb80c,0x00000000,0x00000000,0x81550000, +0x0187b860,0x5988b80c,0x5d8bb80c,0x958cffff, +0xb00cc000,0xb4800002,0x858cc000,0x918c8000, +0x81b3001f,0x198cb80d,0x801bffec,0x00000000, +0x819effec,0x019fb174,0x05acb800,0x300cb800, +0xb4600001,0x91ad4000,0x001f917c,0x1000b80d, +0x001fb17c,0x80171000,0x80971400,0x80270000, +0xb6001003,0xb6002002,0x001fa021,0x009fa021, +0x80171800,0xb6000602,0xb6002001,0x001fa021, +0x806f001f,0x80af001f,0x80a76604,0x80271400, +0x81df0000,0x00000000,0x00000000,0xb6001004, +0x01efb801,0x01afb805,0xb520ffff,0x90a50080, +0x81df0004,0x80a76e04,0x80271400,0x81df0000, +0x00000000,0x00000000,0xb6001004,0x01efb801, +0x01afb805,0xb520ffff,0x90a50080,0x81df0004, +0x81472080,0x015fb179,0x00ffb81f,0x00000000, +0x811be024,0x0107b860,0x95080007,0xb0080000, +0xb4000004,0xa5080008,0x00000000,0x0155b808, +0x00000000,0x8115000c,0x856b000c,0xb0080fff, +0xb400000b,0x81550004,0x856b0004,0x5904b808, +0x1908b80a,0x95080fff,0xb0080fff,0xb4000004, +0x81470001,0xb00b0020,0xb440fff6,0xb500000c, +0x81d50004,0x856b0004,0x00000000,0xb00e000f, +0xb400fffb,0x940b0007,0xb0000000,0xb420ffed, +0x001f42ea,0x9400fffe,0x81470000,0x001f62ea, +0x00ffb81a,0x950e0008,0x5d03b808,0x00000000, +0xb0080000,0xb40000cd,0x011f2080,0x950e0006, +0x5d01b808,0x81270004,0x0529b808,0x950e0001, +0x013f2081,0x011f2082,0x81150004,0x00000000, +0xb0080000,0xb40000c1,0xb008000f,0xb40000bf, +0x011f2083,0x81150002,0x00000000,0x81670004, +0xb0080002,0xb46000b9,0x011f2084,0x013f0081, +0xb0090002,0xb4200011,0x013f0083,0xb0080000, +0xb4200002,0x81077844,0xb5000005,0xb0080001, +0xb4200002,0x81077884,0xb5000001,0x81077824, +0x013f0083,0x5921b809,0x1129b808,0x0119b809, +0x00000000,0x00000000,0x011f6047,0x81150001, +0x00000000,0x011f2085,0x81150001,0x00000000, +0x011f2086,0x81350002,0x00000000,0x013f2087, +0x81150002,0x00000000,0x011f2088,0x81150001, +0x00000000,0x011f2089,0x81150001,0x00000000, +0x011f208a,0x81150002,0x00000000,0x011f208b, +0x81070001,0xb0090003,0xb4000001,0x81070002, +0x011f25b9,0x81070020,0x013f0081,0xb0090002, +0xb4200069,0x85290001,0xad29000f,0x00000000, +0x011f0083,0x1108b809,0x5901b808,0x910877c8, +0x0139b808,0x011f05b9,0x85080001,0x6928b809, +0x011f0084,0xb0090038,0xb4800007,0xb0080001, +0xb4000002,0xb0090050,0xb4400003,0x81270000, +0x8107001b,0xb5000010,0xb0080001,0xb4000005, +0xb0090060,0xb4800003,0x81270001,0x8107001e, +0xb5000009,0xb0080002,0xb4000005,0xb0090030, +0xb4400003,0x81270002,0x81070008,0xb5000002, +0x81270003,0x8107000c,0x011f25bb,0x013f25c0, +0xb0090002,0xb460001b,0x80477604,0x5c42b802, +0x814fffc0,0x80cf0037,0x005fb178,0x5842b802, +0x01cfb802,0x005f9178,0xb520ffff,0x90420020, +0x814fb580,0x80cf0057,0x005fb178,0x5842b802, +0x01cfb802,0x005f9178,0xb520ffff,0x804778a4, +0x5c42b802,0x814f39c0,0x80cf002f,0x005fb178, +0x5842b802,0x01cfb802,0x005f9178,0xb520ffff, +0xb5000025,0x804776e0,0x5c42b802,0x814fef40, +0x80cf0037,0x005fb178,0x5842b802,0x01cfb802, +0x005f9178,0xb520ffff,0x8297013c,0x8317018c, +0x81df0000,0x00000000,0x00000000,0xb6000602, +0x005f8034,0x031fa022,0x82970124,0x83170160, +0xb6000602,0x005f8034,0x031fa022,0x8297010c, +0x83170134,0xb6000602,0x005f8034,0x031fa022, +0x81df0004,0x804778c4,0x5c42b802,0x814f1080, +0x80cf002f,0x005fb178,0x5842b802,0x01cfb802, +0x005f9178,0xb520ffff,0x013f0081,0xb0090001, +0xb420000e,0x808f0000,0x806f001b,0x80af001b, +0x80277758,0x5c22b801,0x80670037,0x00cfb803, +0x003fb178,0x5822b801,0x01cfb801,0x003f9178, +0x0047b86f,0xb0020001,0xb4c0fffd,0x011f25bb, +0x011f0087,0xb0080001,0xb4000002,0x011f05bb, +0xb5000003,0x011f0088,0x91080001,0x5902b808, +0x011f25ba,0x81470000,0x00ffb81a,0x81470008, +0x00ffb81a,0x81270000,0x81470000,0x300842de, +0xb400000b,0x013f42e2,0x91290001,0x013f62e2, +0x013f42e3,0x91290001,0x013f62e3,0x83640006, +0x00000000,0x00000000,0x013f42e2,0x81470002, +0x013f62e2,0x00ffb81a,0x00ffb81b,0x83640049, +0x80c70004,0x80270000,0x81df0000,0x00000000, +0x00000000,0xb600200d,0x00ff05b9,0x5c42b801, +0x300205ba,0xb4800001,0x80e70001,0x80470000, +0xb6270005,0x1062b801,0x914301b8,0x00fff00a, +0x83840055,0x90420080,0x90210004,0x81df0004, +0x00ffb81a,0x83640033,0x017f05bb,0x800700bc, +0x80270000,0x81df0000,0xb00b0000,0xb4000015, +0xb62b0014,0x00ff05b9,0x5c42b801,0x300205ba, +0xb4800001,0x80e70001,0x80470000,0xb0070000, +0xb400000b,0xb627000a,0x1062b801,0x914301b8, +0x00fff00a,0x5c62b801,0x1063b800,0x00bff003, +0x90650134,0x00dff003,0x83840037,0x90420080, +0x90210004,0x81df0004,0x019f05b9,0x80c70002, +0x80270000,0x81df0000,0xb00b0000,0xb400000f, +0xb62b000e,0x80470000,0xb00c0000,0xb400000a, +0xb62c0009,0x1062b801,0x914301b8,0x00fff00a, +0xb0070000,0xb4000003,0x906302b8,0x00fff003, +0x83840021,0x90420080,0x90210004,0x81df0004, +0x00ffb81a,0x8107ffff,0x80c70004,0x00ff0083, +0x83840019,0x80c70002,0x00ff0084,0x83840016, +0x80c70001,0x00ff0085,0x83840013,0x80c70001, +0x00ff0086,0x83840010,0x80c70002,0x00ff0087, +0x8384000d,0x80c70002,0x00ff0088,0x8384000a, +0x80c70001,0x00ff0089,0x83840007,0x80c70001, +0x00ff008a,0x83840004,0x80c70002,0x00ff008b, +0x83840001,0x00ffb81b,0x80a70001,0x64a6b805, +0x5ca1b805,0xb0050000,0xb400000e,0x95288000, +0xb0090000,0xb4000001,0x81270001,0x5901b808, +0x1547b805,0xb00a0000,0xb4000001,0x81470001, +0x2129b80a,0xb0090000,0xb4000001,0xa1088005, +0xb500ffef,0x9508ffff,0x00ffb81c,0x015f05ba, +0x013f05b9,0x800700bc,0xb0090000,0xb4000012, +0xb00a0000,0xb4000010,0x80270000,0x81df0000, +0x00000000,0x00000000,0xb62a000b,0x80470000, +0xb6290008,0x80950004,0x5865b802,0x1063b801, +0x5862b803,0x906301b8,0x0217b803,0x90420001, +0x021fa004,0x90210001,0x81df0004,0xa54a0020, +0xb4c00011,0xb0090000,0xb400000f,0x81df0000, +0x00000000,0x00000000,0xb62a000b,0x80950004, +0x80470000,0xb6290007,0x5865b802,0x1063b801, +0x5862b803,0x906301b8,0x0217b803,0x90420001, +0x021fa004,0x90210001,0x81df0004,0x00ffb81a, +0x013f05b9,0xb0090000,0xb400001c,0x80270000, +0x81df0000,0x00000000,0x00000000,0xb6002017, +0x80470000,0xb6290014,0x5865b802,0x1063b801, +0x5862b803,0x914301b8,0x009ff00a,0xad420060, +0x00000000,0x114ab801,0x5942b80a,0x914a1c80, +0x0217b80a,0xb0040000,0xb4000004,0x80950006, +0x00000000,0x021fa004,0xb5000002,0x8087003f, +0x021fa004,0x90420001,0x90210001,0x81df0004, +0x00ffb81a,0x8257ffff,0x82d7ffff,0x011f05ba, +0x013f05b9,0x80270000,0xb0090000,0xb4000033, +0x81df0000,0x00000000,0x00000000,0xb6280015, +0x80470000,0xb6290012,0x5865b802,0x1063b801, +0x5862b803,0x914301b8,0xaca20060,0x009ff00a, +0x10a5b801,0x58a2b805,0x90a502b8,0x0217b805, +0x80670000,0xb0040000,0xb4000003,0x90840001, +0x0075b804,0x00000000,0x021fa003,0x90420001, +0x90210001,0x81df0004,0xa5480020,0xb4000017, +0x5822b801,0x81df0000,0x00000000,0x00000000, +0xb62a0011,0x914101b8,0x90a102b8,0x0217b805, +0x009ff00a,0xb0040000,0x80670000,0xb4000002, +0x90840001,0x0075b804,0xb6290006,0x021fa203, +0x009f8210,0x009f8210,0x009f8210,0x009f8210, +0x009f8210,0x90210004,0x81df0004,0x00ffb81a, +0x015f05ba,0x013f05b9,0x800700bc,0xb0090000, +0xb4000016,0xb00a0000,0xb4000014,0x80270000, +0x81df0000,0x00000000,0x00000000,0xb62a000f, +0x80470000,0xb629000c,0x1080b801,0x007ff004, +0x90830134,0x007ff004,0x0095b803,0x5865b802, +0x1063b801,0x5862b803,0x906301b8,0x0217b803, +0x90420001,0x021fa004,0x90210001,0x011f05bb, +0x254ab808,0xb4c0000d,0xb62a000c,0x1080b801, +0x007ff004,0x90830134,0x007ff004,0x0095b803, +0x5862b801,0x906301b8,0x0217b803,0x90210001, +0x021fa204,0x007f8210,0x021fa004,0xa5480020, +0xb4c0000e,0xb0090000,0xb400000c,0x80870000, +0xb62a000a,0x80470000,0xb6290007,0x5865b802, +0x1063b801,0x5862b803,0x906301b8,0x0217b803, +0x90420001,0x021fa004,0x90210001,0x81df0004, +0x00000000,0x00000000,0x00ffb81a,0x011f05bb, +0x013f05b9,0xb0080000,0xb4000016,0xb0090000, +0xb4000014,0x81df0000,0x00000000,0x80270000, +0xb6280010,0x80470000,0xb629000d,0x5865b802, +0x1063b801,0x5862b803,0x914301b8,0x009ff00a, +0xb0040000,0xb4000005,0x80950002,0x906302b8, +0x0217b803,0x00000000,0x021fa004,0x90420001, +0x90210001,0x81df0004,0xa5480020,0xb00a0000, +0xb4000011,0xb0090000,0xb400000f,0x81df0000, +0x00000000,0x80870000,0xb62a000b,0x80470000, +0xb6290008,0x5865b802,0x1063b801,0x5862b803, +0x906302b8,0x0217b803,0x00000000,0x021fa004, +0x90420001,0x90210001,0x81df0004,0xb0080000, +0xb400004d,0xb0090000,0xb400004b,0x81df0000, +0x00000000,0x80270000,0xb6280047,0x80470000, +0xb6290044,0x5865b802,0x1063b801,0x5862b803, +0x914301b8,0x009ff00a,0xad420060,0x00000000, +0x00000000,0x00000000,0x114ab801,0x5942b80a, +0x914a1c80,0x0217b80a,0xb0040000,0xb400002e, +0x906302b8,0x009ff003,0xb0040000,0xb420000a, +0x80950006,0x00000000,0x021fa204,0x80950006, +0x015f8210,0x021fa204,0x80950006,0x015f8210, +0x021fa004,0xb5000026,0xb0040001,0xb4200009, +0x80950006,0x00000000,0x021fa204,0x015f8210, +0x021fa204,0x80950006,0x015f8210,0x021fa004, +0xb500001b,0xb0040003,0xb4200009,0x80950006, +0x00000000,0x021fa204,0x80950006,0x015f8210, +0x021fa204,0x015f8210,0x021fa004,0xb5000010, +0xb0040002,0xb420000e,0x80950006,0x00000000, +0x021fa204,0x015f8210,0x021fa204,0x015f8210, +0x021fa004,0xb5000006,0x8087003f,0x021fa204, +0x015f8210,0x021fa204,0x015f8210,0x021fa004, +0x90420001,0x90210001,0x81df0004,0xa5480020, +0xb4c00012,0xb0090000,0xb4000010,0x8087003f, +0x81df0000,0x5862b801,0x90631afc,0xb62a000b, +0x90630004,0x0047b803,0xb6290008,0x90420180, +0x0217b802,0x00000000,0x021fa204,0x003f8210, +0x021fa204,0x003f8210,0x021fa004,0x81df0004, +0x00ffb81a,0x8257ffff,0x82d7ffff,0x011f05bb, +0x013f05b9,0x80270000,0x00e7b809,0x300105ba, +0xb4800001,0x80e70001,0x800700bc,0x80470000, +0x81df0000,0xb0070000,0xb400004c,0xb627004b, +0x5865b802,0x1063b801,0x5862b803,0x914301b8, +0xaca20060,0x009ff00a,0x10a5b801,0x58a2b805, +0x90a502b8,0x0217b805,0xb0040000,0xb400002b, +0x1060b801,0x00bff003,0x10a5b804,0x90650160, +0x00dff003,0xb0060003,0xb4200007,0x90650134, +0x00dff003,0xb6000303,0x0075b806,0x021fa203, +0x007f8210,0xb5000021,0x5861b805,0x906300dc, +0x009fd803,0x90650134,0x00dff003,0xaca20060, +0x00000000,0x00000000,0x00000000,0x0075b806, +0x10a5b801,0x58a2b805,0x90a502b8,0x0217b805, +0x588fb804,0xb600030c,0xb6001007,0x04a3b804, +0xb4600002,0x58a1b803,0xb5000002,0x58a1b805, +0x90a50001,0x0067b805,0x9465ffff,0x5d50b805, +0x021fa20a,0x015f8210,0xb5000004,0x81470000, +0xb6000302,0x021fa20a,0x009f8210,0x009f05b9, +0xb0040002,0xb420000c,0x300105ba,0xb480000a, +0x58a2b801,0x90a502b8,0x0217b805,0x90a50180, +0x0297b805,0xb6000304,0x00bf8210,0x009f8210, +0x029fa205,0x009f8214,0x90420001,0x81df0004, +0x90210001,0x3001b808,0xb480ffa7,0xa5480020, +0xb00a0000,0xb4000019,0xb0090000,0xb4000017, +0x58a2b801,0x90a502b8,0x81df0000,0x00000000, +0x00000000,0xb62a0010,0x80470000,0xb629000d, +0xaca20060,0x00000000,0x00000000,0x00000000, +0x80670000,0x10a5b801,0x58a2b805,0x90a502b8, +0x0217b805,0xb6000302,0x021fa203,0x00bf8210, +0x90420001,0x90210001,0x81df0004,0x00ffb81a, +0x80770000,0x8057ffff,0x80f70000,0x80d7ffff, +0x81770000,0x8157ffff,0x81f70000,0x81d7ffff, +0xac140060,0xac350020,0x00000000,0x00000000, +0x12c0b801,0x5ac2b816,0x92d61980,0x83a400bd, +0xad940400,0x009f9173,0x013f05ca,0x914c6604, +0x114ab804,0x001f97e0,0x001eb80a,0xb0090000, +0xb4000003,0x80a76e44,0x80c76644,0xb5000002, +0x80a76644,0x80c76e44,0x808f000f,0x806f0000, +0x80af000e,0x80cf07e1,0x11e5b80c,0x11efb804, +0x5de2b80f,0x01ffb178,0x59e2b80f,0x01afb80f, +0x01ff9178,0x0047b86f,0xb0020001,0xb4c0fffd, +0x80cf07f0,0x1206b80c,0x1210b804,0x5e02b810, +0x021fb178,0x5a02b810,0x01afb810,0x021f9178, +0x0047b86f,0xb0020001,0xb4c0fffd,0x916c6e04, +0x116bb804,0x001f97ff,0x001eb80b,0x808f0000, +0x806f001f,0x80af001f,0x90ac6604,0x5ca2b805, +0x80270400,0x81df0000,0x00000000,0x00000000, +0xb600080a,0x00cfb801,0x00bfb178,0x58a2b805, +0x01cfb805,0x00bf9178,0x0047b86f,0xb0020001, +0xb4c0fffd,0x90210020,0x90a50020,0x81df0004, +0x90ac6e04,0x5ca2b805,0x80270500,0x81df0000, +0x00000000,0x00000000,0xb600080a,0x00cfb801, +0x00bfb178,0x58a2b805,0x01cfb805,0x00bf9178, +0x0047b86f,0xb0020001,0xb4c0fffd,0x90210020, +0x90a50020,0x81df0004,0x81530020,0xac140060, +0xac350020,0x80170800,0x80d7003c,0x12c0b801, +0x5ac2b816,0x92d602b8,0x0117b816,0x90241000, +0x0097b801,0x80470000,0x4002b803,0x81df0000, +0x00000000,0x00000000,0xb6000804,0x005f8020, +0x480287e4,0x005f8020,0x500287e4,0x81df0004, +0x00000000,0x00000000,0x00000000,0x1021b80a, +0x5c36b801,0x5801b800,0x18c0b801,0xb0090000, +0xb4000002,0x90641440,0xb5000001,0x90641040, +0x81df0000,0x00000000,0x00000000,0xb6000f0d, +0x0097b803,0x80470000,0x4002b803,0xb6001002, +0x005f8020,0x480287e4,0x0108a026,0x90630040, +0x00000000,0x1021b80a,0x5c36b801,0x5801b800, +0x18c0b801,0x81df0004,0x90641400,0x0097b803, +0x80470000,0x4002b803,0x005f8020,0x005f87e4, +0x81df0000,0x00000000,0x00000000,0xb6000802, +0x005f8040,0x480287c4,0x81df0004,0x005f87e0, +0x0108a026,0x00000000,0x1021b80a,0x5c36b801, +0x5801b800,0x18c0b801,0xb0090000,0xb4000002, +0x906417c0,0xb5000001,0x906413c0,0x81df0000, +0x00000000,0x00000000,0xb6000f0f,0x0097b803, +0x80470000,0x4002b803,0xb6000804,0x005f8020, +0x500287e4,0x005f8020,0x480287e4,0x0108a026, +0x84630040,0x00000000,0x1021b80a,0x5c36b801, +0x5801b800,0x18c0b801,0x81df0004,0xb0140000, +0xb4200005,0x90840004,0x9484003f,0x009fb173, +0xa1290001,0x013f25ca,0x80d7ffff,0x0108a026, +0x00ffb81a,0x81330004,0x8093007f,0x9884ffff, +0x80b3ff80,0x0017b816,0x90360040,0x0097b801, +0x81530010,0x81df0000,0x00000000,0x00000000, +0xb6001004,0x400a8000,0x404a8004,0x0008a020, +0x0088a022,0x81df0004,0x0017b816,0x9036007c, +0x0097b801,0x81171000,0x81df0000,0x00000000, +0x00000000,0xb6001004,0x40048020,0x480487e4, +0x00000000,0x0108a020,0x81df0004,0x81470000, +0x81670001,0x81870008,0x81a70040,0x81c707c4, +0x81e70040,0x81df0000,0x00000000,0x00000000, +0xb6000432,0xb00a0001,0xb4e00004,0x80c71000, +0x80e71000,0x81171040,0xb5000003,0x80c71040, +0x80e71040,0x81171000,0x844d0004,0x10e7b802, +0xb62b001f,0x0017b806,0x0097b807,0xb62c0004, +0x40048020,0x480487e4,0x00000000,0x0108a020, +0x0017b806,0x0097b807,0x0197b80e,0x00000000, +0x001f8020,0x042087e4,0xb62c000f,0x4041800c, +0x001f8020,0x0048b802,0x5e38802c,0x2e11b801, +0x042087e4,0x1042b810,0x0462b804,0xb4a00002, +0x0047b804,0xb5000003,0x0462b805,0xb4600001, +0x0047b805,0x011fa022,0x10c6b80f,0x10e7b80f, +0x5961b80b,0x5d81b80c,0x5da1b80d,0x5de1b80f, +0x914a0001,0x954a0001,0x11ceb80f,0x81df0004, +0x80171018,0x81171fcc,0x80470000,0x41448020, +0x494487c0,0x00000000,0x0188b80a,0x494487e0, +0x00000000,0x0148b80a,0x0502a10a,0x4145b80c, +0x494580e0,0x00000000,0x0108a5ea,0x41448080, +0x494487c0,0x00000000,0x0108a78a,0x49448020, +0x00000000,0x0108a2ea,0x41448020,0x49448720, +0x00000000,0x0188b80a,0x4145b80c,0x49458080, +0x494587a0,0x00000000,0x0108a68a,0x4145b80c, +0x49458080,0x494587a0,0x00000000,0x0108a08a, +0x4145b80c,0x49458020,0x49458040,0x00000000, +0x0188b80a,0x494587e0,0x00000000,0x0108a08a, +0x4144b80c,0x494587a0,0x00000000,0x0108a52a, +0x41448080,0x49448040,0x494486c0,0x00000000, +0x0108a04a,0x41448040,0x49448720,0x00000000, +0x0108a36a,0x04028020,0x011fa420,0x001f8040, +0x011fa100,0x001f8080,0x011fa080,0x001f8100, +0x011fa040,0x001f8660,0x011fa120,0x41458020, +0x49458000,0x00000000,0x0108a00a,0x0017b816, +0x9036007c,0x0097b801,0x81171000,0x81970784, +0x00000000,0x001f8020,0x042087e4,0x81df0000, +0x00000000,0x00000000,0xb600100f,0x4041800c, +0x001f8020,0x0048b802,0x5e38802c,0x2e11b801, +0x042087e4,0x1042b810,0x0462b804,0xb4a00002, +0x0047b804,0xb5000003,0x0462b805,0xb4600001, +0x0047b805,0x011fa022,0x81df0004,0x81470000, +0x81670001,0x81870008,0x81a70040,0x81c707c4, +0x81e70040,0x81df0000,0x00000000,0x00000000, +0xb6000432,0xb00a0001,0xb4e00004,0x80c71000, +0x80e71000,0x81171040,0xb5000003,0x80c71040, +0x80e71040,0x81171000,0x844d0004,0x10e7b802, +0xb62b001f,0x0017b806,0x0097b807,0xb62c0004, +0x40048020,0x480487e4,0x00000000,0x0108a020, +0x0017b806,0x0097b807,0x0197b80e,0x00000000, +0x001f8020,0x042087e4,0xb62c000f,0x4041800c, +0x001f8020,0x0048b802,0x5e38802c,0x2e11b801, +0x042087e4,0x1042b810,0x0462b804,0xb4a00002, +0x0047b804,0xb5000003,0x0462b805,0xb4600001, +0x0047b805,0x011fa022,0x10c6b80f,0x10e7b80f, +0x5961b80b,0x5d81b80c,0x5da1b80d,0x5de1b80f, +0x914a0001,0x954a0001,0x11ceb80f,0x81df0004, +0x80171034,0x81171f84,0x80470000,0x41448040, +0x49448640,0x00000000,0x0188b80a,0x49448100, +0x49448780,0x00000000,0x0108a08a,0x4144b80c, +0x49448040,0x49448080,0x494487c0,0x00000000, +0x0108a16a,0x4145b80c,0x49458700,0x00000000, +0x0188b80a,0x494581a0,0x494586e0,0x00000000, +0x0108a66a,0x4145b80c,0x49448040,0x494487e0, +0x00000000,0x0188b80a,0x011fa1ec,0x4145b80c, +0x49458100,0x49458780,0x00000000,0x0108a08a, +0x41458720,0x49458100,0x494586e0,0x49458160, +0x49458020,0x49458020,0x49458760,0x00000000, +0x0108a08a,0x414587a0,0x49458080,0x49458760, +0x494580c0,0x49458700,0x49458140,0x49458020, +0x49458760,0x00000000,0x0108a74a,0x414587a0, +0x49458080,0x49458760,0x494580e0,0x49458700, +0x49458120,0x49458020,0x49458760,0x00000000, +0x0108a08a,0x41458720,0x49458100,0x494586e0, +0x49458140,0x49458040,0x49458020,0x49458720, +0x00000000,0x0108a0ca,0x41458080,0x49458040, +0x49458020,0x49458620,0x00000000,0x0188b80a, +0x49458080,0x00000000,0x0108a7ca,0x4144b80c, +0x49458040,0x49458020,0x49458080,0x00000000, +0x0108a5ea,0x41448080,0x49448700,0x00000000, +0x0188b80a,0x49448780,0x00000000,0x0108a7ca, +0x4144b80c,0x49448140,0x00000000,0x0108a7ca, +0x49448040,0x00000000,0x0108a0ca,0x41448700, +0x00000000,0x0188b80a,0x49448000,0x00000000, +0x0108a04a,0x011fa00c,0x80171f80,0x81df0000, +0x00000000,0x00000000,0xb6002006,0x40048000, +0x48048000,0x48048000,0x48048000,0x00000000, +0x0008a020,0x81df0004,0x00ffb81d,0x00000000, +0x80770000,0x8057ffff,0x015f05b9,0x017f05bb, +0x8293ffff,0x9a94ffff,0x81a70000,0x81df0000, +0x00000000,0x00000000,0xb62a003a,0xaded0180, +0xae0d0180,0xadcd0080,0x902f1980,0x0017b801, +0xb6002033,0x904e01b8,0x00000000,0x013ff002, +0xb0090000,0xb400001f,0x904f02b8,0x80c70000, +0x011fd802,0x6829b808,0x94210001,0xb0010001, +0xb4e00001,0x00c7b814,0x6429b806,0x80470001, +0x6449b802,0x84420001,0x1442b808,0x84690001, +0x5863b803,0x906300dc,0x1042b801,0x003f9803, +0x90420001,0x4082b801,0x90630004,0x003f9803, +0x00000000,0x5897b804,0x1804b805,0x4082b801, +0x00000000,0x00000000,0x00000000,0x10a4b800, +0xb5000001,0x80a70000,0x90501c80,0x00000000, +0x007ff002,0x5842b803,0x904205f8,0x0097b802, +0x00000000,0x40058004,0x48058004,0x00000000, +0x0008a020,0x91ce0004,0x91ef0004,0x92100004, +0x91ad0001,0x81df0004,0x00ffb81a,0x80770000, +0x8057ffff,0x80d7ffff,0x015f05b9,0x017f05bb, +0x8293ff80,0x9a940000,0x82a70020,0x81a70000, +0x81e702b8,0x80171980,0x81df0000,0x00000000, +0x00000000,0xb62a004f,0xb600034d,0xac0d0080, +0xac4d0180,0xac960080,0x822700bc,0x91c001b8, +0x00000000,0x1042b804,0x92021c80,0xb62b003a, +0x013ff00e,0x00fff011,0xb0090000,0xb4000027, +0x10e7b809,0x5821b807,0x902100dc,0x00000000, +0x001fd801,0x82470000,0x80270001,0x6452b801, +0x3002b800,0xb4600002,0x92520001,0xb500fffb, +0x86520001,0x80c70000,0x011fd80f,0x6832b808, +0xb0010001,0xb4e00001,0x00c7b814,0x84520017, +0x0056b802,0x80270001,0x6432b801,0x84210001, +0x1408b801,0x6402b800,0x10c6b800,0x9027018c, +0x00000000,0x001ff001,0x5802b800,0x9020073c, +0x904006f8,0x007f9801,0x0097b802,0x10c6b803, +0x40868004,0x48868004,0xb5000003,0x80c70000, +0x40868004,0x00000000,0x0088b804,0x003ff010, +0x5822b801,0x902105f8,0x0097b801,0x91ce0004, +0x91ef0004,0x40448004,0x48448004,0x92100004, +0x0008a022,0x92310001,0x0435b80b,0xb4000007, +0x80870000,0xb6210005,0x001fa024,0x91ce0004, +0x91ef0004,0x92100004,0x92310001,0x00000000, +0x91ad0001,0x81df0004,0x00ffb81a,0x00000000, +0x007f05b9,0x001f0081,0xb0000001,0xb440002d, +0x001f05d8,0xac400080,0x801702b8,0x80970438, +0x90421800,0x0117b802,0x8087ffff,0x80b3ffff, +0x80d3007f,0x98c6ff00,0x80f3ff80,0x81070080, +0x81df0000,0x00000000,0x00000000,0xb6002018, +0x10088020,0x0056b800,0x0442b806,0xb4a00004, +0xb0000000,0x0007b806,0xb4400001,0x0007b807, +0x0027b800,0x5c08b800,0x1400b804,0xb0030001, +0xb4000008,0x10288024,0x0056b801,0x0442b806, +0xb4a00004,0xb0010000,0x0027b806,0xb4400001, +0x0027b807,0x5828b801,0x1421b805,0x1900a021, +0x81df0004,0x001f05d8,0x90000001,0x001f25d8, +0x00ffb81a,0x801702b8,0x80970438,0x81171800, +0x8087ffff,0x80b3ffff,0x80d3007f,0x98c6ff00, +0x80f3ff80,0x81070080,0x81df0000,0x00000000, +0x00000000,0xb6006018,0x10088020,0x0056b800, +0x0442b806,0xb4a00004,0xb0000000,0x0007b806, +0xb4400001,0x0007b807,0x0027b800,0x5c08b800, +0x1400b804,0xb0030001,0xb4000008,0x10288024, +0x0056b801,0x0442b806,0xb4a00004,0xb0010000, +0x0027b806,0xb4400001,0x0027b807,0x5828b801, +0x1421b805,0x1900a021,0x81df0004,0x00ffb81a, +0x001f0081,0xb0000001,0xb4400006,0x001f05d8, +0xb0000003,0xb4000003,0x80270001,0x003f25dc, +0x00ffb81a,0x003f05d9,0x009f05cb,0xb0010000, +0xb400000e,0x015f42ed,0x81070000,0x8127017c, +0xb00a0000,0xb4000002,0x81070180,0x812702fc, +0x802500a5,0x9421ffff,0x3001b808,0xb4800011, +0x3001b809,0xb4a0007f,0xb500000e,0x001f0081, +0xb0000001,0xb4400003,0xb0040002,0xb4200006, +0xb5000002,0xb0040000,0xb4200003,0x802702ff, +0x81470000,0xb5000003,0x80270001,0x003f25d9, +0x81470180,0xb0040000,0xb4200001,0x838402e6, +0x80070000,0x001f25d8,0x009f902d,0x80af001f, +0x808f0000,0x806f0000,0x8007ffff,0x8033ffff, +0x80171800,0x81df0000,0x807bff8c,0x94630003, +0xb0030003,0xb4000016,0xb0030002,0xb4000035, +0xb0030001,0xb4000024,0xb6006010,0x14618000, +0x6068b803,0x40c4b803,0x14608000,0x00c8b806, +0x5870b803,0x6068b803,0x4104b803,0x58c8b806, +0x0108b808,0x14c6b801,0x00000000,0x00000000, +0x5d08b808,0x1508b800,0x1806a028,0xb5000030, +0xb6006010,0x14618000,0x6068b803,0x40c4b803, +0x14608000,0x00c8b806,0x5870b803,0x6068b803, +0x4104b803,0x5cc8b806,0x0108b808,0x14c6b800, +0x00000000,0x00000000,0x5908b808,0x1508b801, +0x1806a028,0xb500001e,0xb600600d,0x14618000, +0x6068b803,0x40c4b803,0x00000000,0x00c8b806, +0x00000000,0x00000000,0x00000000,0x5d08b806, +0x1508b800,0x58c8b806,0x14c6b801,0x1806a028, +0xb500000f,0xb600600e,0x14608000,0x5868b803, +0x6068b803,0x40c4b803,0x00000000,0x00c8b806, +0x00000000,0x00000000,0x00000000,0x5d08b806, +0x1508b800,0x58c8b806,0x14c6b801,0x1806a028, +0x81df0004,0x80670600,0x5d22b80a,0x81df0000, +0x00000000,0x00000000,0xb600030a,0x00cfb803, +0x013fb178,0x5922b809,0x01afb809,0x013f9178, +0x0047b86f,0xb0020001,0xb4c0fffd,0x90630020, +0x91290020,0x81df0004,0x81270180,0xb00a0000, +0xb4000001,0x81270000,0x013f62ed,0x80270001, +0x003f25dc,0x00ffb81a,0x801bff7c,0x00000000, +0x94000080,0xb0000080,0xb400ff61,0x001f0081, +0xb0000001,0xb4400006,0x001f05d8,0xb0000003, +0xb4000003,0x80270001,0x003f25dc,0x00ffb81a, +0x003f05d9,0x009f05cb,0xb0010000,0xb400000e, +0x015f42ed,0x81070000,0x812702fc,0xb00a0000, +0xb4000002,0x81070300,0x812705fc,0x802500a5, +0x9421ffff,0x3001b808,0xb4800011,0x3001b809, +0xb4a00073,0xb500000e,0x001f0081,0xb0000001, +0xb4400003,0xb0040002,0xb4200006,0xb5000002, +0xb0040000,0xb4200003,0x802705ff,0x81470000, +0xb5000003,0x80270001,0x003f25d9,0x81470300, +0xb0040000,0xb4200001,0x83840247,0x80070000, +0x001f25d8,0x009f902d,0x80af001f,0x808f0000, +0x806f0000,0x8007ffff,0x8033ffff,0x80171800, +0x807bff8c,0x80971980,0x81df0000,0x94630003, +0xb0030003,0xb4000013,0xb0030002,0xb400002c, +0xb0030001,0xb400001e,0xb600600d,0x58708000, +0x6068b803,0x40c4b803,0x14618020,0x00c8b806, +0x6068b803,0x4104b803,0x00000000,0x0108b808, +0x5887a026,0x00000000,0x00000000,0x5887a028, +0xb5000026,0xb600600d,0x14618000,0x6068b803, +0x40c4b803,0x58708020,0x00c8b806,0x6068b803, +0x4104b803,0x00000000,0x0108b808,0x5887a026, +0x00000000,0x00000000,0x5887a028,0xb5000017, +0xb600600a,0x14618000,0x6068b803,0x40c4b803, +0x00000000,0x00c8b806,0x00000000,0x00000000, +0x00000000,0x5887a026,0x5887a026,0xb500000b, +0xb600600a,0x58708000,0x6068b803,0x40c4b803, +0x00000000,0x00c8b806,0x00000000,0x00000000, +0x00000000,0x5887a026,0x5887a026,0x81df0004, +0x80670660,0x5d22b80a,0x81df0000,0x00000000, +0x00000000,0xb600060a,0x00cfb803,0x013fb178, +0x5922b809,0x01afb809,0x013f9178,0x0047b86f, +0xb0020001,0xb4c0fffd,0x90630020,0x91290020, +0x81df0004,0x81270300,0xb00a0000,0xb4000001, +0x81270000,0x013f62ed,0x80270001,0x003f25dc, +0x00ffb81a,0x00000000,0x00000000,0x00000000, +0x029fb024,0x02bfb025,0x02dfb026,0x02ffb027, +0x031fb028,0x033fb029,0x033f4046,0x0287b86f, +0x029fb02a,0x8285009c,0x96b48000,0xb0158000, +0xb400018e,0x96b40100,0xb0150100,0xb40001a4, +0x96b40400,0xb0150400,0xb40001a5,0x96b40001, +0xb0150001,0xb400000c,0x96b40008,0xb0150008, +0xb4000197,0x96b44000,0xb0154000,0xb40001a4, +0x96b40002,0xb0150002,0xb400015b,0x00000000, +0x00000000,0xb50001b6,0x02bf917e,0x92b50001, +0x02bfb17e,0x82850082,0x5efdb814,0x96f70001, +0xb0170001,0xb420000b,0x83050069,0x9718003f, +0x82e50064,0x12f7b818,0x86f70109,0x82feff74, +0x02e7b86f,0x9af74000,0x01ffb817,0x96f7bfff, +0x01ffb817,0x83050081,0x82a5009a,0x96b50001, +0xb0150001,0xb4200014,0x82a70000,0x02bfb17e, +0x96b41840,0xb0150800,0xb420000c,0x96b40008, +0x5aa9b815,0x96d46000,0x5ec3b816,0x82f3000f, +0x9af7c00f,0x1718b817,0x1ab5b818,0x1ab5b816, +0x9ab50340,0x82a60081,0xb500012b,0x9b180180, +0x83060081,0xb5000128,0x82a5009a,0x96b50002, +0xb0150002,0xb420001b,0x82a70000,0x02bfb17e, +0x96b41800,0xb0151800,0xb4000013,0x96b40040, +0xb0150040,0xb4200004,0xa3180c00,0x9b180340, +0x83060081,0xb5000118,0x96b40008,0x5aa9b815, +0x96d46000,0x5ec3b816,0x82f3000f,0x9af7c00f, +0x1718b817,0x1ab5b818,0x1ab5b816,0x9ab50340, +0x82a60081,0xb500010c,0x9b180180,0x83060081, +0xb5000109,0x82a500c1,0x96b5000f,0xb015000b, +0xb420000e,0x96b40020,0xb0150020,0xb400000b, +0x96b40200,0xb0150200,0xb4000008,0x82c50086, +0x82e50094,0x3016b817,0xb4400004,0x06f7b816, +0xb017ff00,0xb4400001,0xb50000f7,0x96b46000, +0xb0156000,0xb4000011,0x96b41820,0xb0150820, +0xb4200004,0x9b391000,0x82a5009a,0x96b5feff, +0x82a6009a,0x96b40040,0xb0150040,0xb4200001, +0x9739efff,0x96b91000,0xb0151000,0xb4200003, +0x82a5009a,0x9ab50100,0x82a6009a,0x96b40040, +0xb0150040,0xb4200019,0x96b41800,0xb0151800, +0xb4200006,0x96b98000,0xb0158000,0xb4200003, +0x9b180180,0x83060081,0xb50000d7,0x96d80c00, +0x82b300ff,0x9ab5f3ff,0x1718b815,0xb0160c00, +0xb4000007,0x82e50098,0x96f70400,0xb0170400, +0xb4200002,0x82c70c00,0xb5000001,0xa2d60c00, +0x1b18b816,0x9b180340,0xb50000bd,0x96b40220, +0xb0150000,0xb4e00021,0x82a5009d,0x82f3ffff, +0x16b5b817,0x82f3000e,0x3015b817,0xb420001b, +0x96f98000,0xb0178000,0xb4000018,0x82a70000, +0x02bfb17e,0x82c5009d,0x96d6ffff,0x82b30032, +0x9ab58001,0x82e500c1,0x96f7000f,0xb017000b, +0xb4000002,0x82b30022,0x9ab58001,0x1ab5b816, +0x82c5009a,0x96d60020,0xb0160020,0xb4200002, +0x82b30032,0x9ab58001,0x82a6009d,0x02ff917e, +0x00000000,0xb0170040,0xb4800000,0x5eb5b814, +0x96b500f0,0x96f46000,0x5eedb817,0x1ab5b817, +0xb0170003,0xb4000004,0x96b500ef,0x96f70001, +0x5ae4b817,0x1ab5b817,0x96d41800,0xb0161800, +0xb400000a,0x96f900ff,0x96b500ff,0x9739ff00, +0x1b39b815,0x02a7b817,0x96b500f3,0x96d40008, +0x5ec1b816,0x1ab5b816,0xb500000c,0x96f98000, +0xb0178000,0xb4200007,0x5efeb814,0x96f70001, +0xb0170001,0xb4000003,0x9b180180,0x83060081, +0xb5000081,0x96b500f3,0x9ab50008,0x9739fff3, +0x96d40020,0xb0160020,0xb4200017,0x9b398000, +0x82c70000,0x02dfb17e,0x96d40010,0x5ac8b816, +0x82f300ff,0x9af7cfff,0x1718b817,0x1b18b816, +0x9b180340,0x82c5009d,0x96d6ffff,0x82f3000e, +0x9af78001,0x1af7b816,0x82c5009a,0x96d60020, +0xb0160020,0xb4200002,0x82f30032,0x9af78001, +0x82e6009d,0xb500005a,0x97397fff,0x96b500ff, +0x5aaab815,0x82f300fc,0x9af703ff,0x1718b817, +0x1b18b815,0x9b180340,0x82c5009a,0x96d60010, +0xb0160010,0xb4200024,0x82c70000,0x02dfb17e, +0x82c50086,0x92d60e10,0x82c60086,0x82c50094, +0x5eefb818,0x96f70003,0xb0170003,0xb4200002, +0x82e70e10,0xb5000001,0x82e70e10,0x12d6b817, +0x82e50081,0x9af70020,0x82e60081,0x82c60094, +0xa2f70020,0x82e60081,0x82f30001,0x16f7b818, +0x5ef0b817,0xb0170001,0xb4000004,0x96f84000, +0x5ee4b817,0x9718f3ff,0x1b18b817,0x82f3000a, +0x9af78000,0x82e6009d,0x83060081,0x83070001, +0x8306009f,0xb5000096,0x82c5009d,0x82f3000e, +0x9af78001,0x3016b817,0xb420000f,0x82b30032, +0x9ab58001,0x82e500c1,0x96f7000f,0xb017000b, +0xb4000002,0x82b30022,0x9ab58001,0x82c5009a, +0x96d60020,0xb0160020,0xb4200002,0x82b30032, +0x9ab58001,0x82a6009d,0x82c5009a,0x96d60080, +0xb0160080,0xb4000011,0x02df917e,0x00000000, +0xb0160010,0xb480000d,0x82c500c1,0x96d6000f, +0xb016000b,0xb4000009,0x82c50087,0x96d60080, +0x5ac7b816,0x96f84000,0x3017b816,0xb4200003, +0x033f4046,0x9b394000,0xb500000b,0x9739bfff, +0x82e50061,0x96f70008,0xb0170008,0xb4000005, +0x5eefb818,0x96f70003,0xb0170003,0xb4000001, +0x9718ffff,0x83060081,0x83070001,0x8306009f, +0x00000000,0xb500005e,0x82850083,0x96b400ff, +0xb015003c,0xb4200019,0x96b92000,0xb0152000, +0xb4000002,0x9b392000,0xb5000014,0x9739d3ff, +0x82870000,0x82860087,0x82870008,0x82860083, +0x829bff78,0x82a7001f,0xb0140400,0xb4000001, +0x82a70010,0x82a600c9,0x829bff78,0x00000000, +0x828600cb,0x8285009d,0x82b3ffff,0x9ab5fffd, +0x1694b815,0x8286009d,0xb5000000,0x83070002, +0x8306009f,0x00000000,0xb500003d,0x96b90800, +0xb0150800,0xb4200009,0x9739f7ff,0x82a703fd, +0x82a600cb,0x82a7003c,0x82a60083,0x8285009d, +0x9a940002,0x8286009d,0xb5000004,0x82850087, +0x5a82b814,0xa2940200,0x82860087,0xb5000000, +0x83078000,0x8306009f,0x00000000,0xb5000028, +0x83070008,0x8306009f,0x00000000,0xb5000024, +0x83070100,0x8306009f,0x00000000,0xb5000020, +0x83070000,0x83050081,0x9b180180,0x83060081, +0x83070400,0x8306009f,0x00000000,0xb5000018, +0x82870000,0x82850082,0x5eb7b814,0x96b500fc, +0x96d40006,0x5ec1b816,0x1ab5b816,0x5aacb815, +0x83050081,0x82d3001c,0x9ad600ff,0x1718b816, +0x1b18b815,0x9b180e00,0x83060081,0x83074000, +0x8306009f,0x8305009d,0x82d300ff,0x9ad6bfff, +0x1718b816,0x8306009d,0x00000000,0xb5000000, +0x029f902a,0x01ffb814,0x033f6046,0x029f9024, +0x02bf9025,0x02df9026,0x02ff9027,0x031f9028, +0x033f9029,0x00ffb81e,0x02ff917d,0x92f7092f, +0x031f0084,0xb0180001,0xb4200002,0x02ff917d, +0x92f70870,0x02ffb17d,0x02ff917c,0x82bbffdc, +0x829bffd8,0x93150004,0x3014b815,0xb4000017, +0x02dbb818,0x029bb815,0x3017b816,0xb4800013, +0x5a81b814,0x029fb17d,0x82def200,0x82fef204, +0x82e50086,0x06f7b814,0x02f6b817,0x82fef208, +0x82860095,0x82870001,0x829ef220,0x8293001f, +0x9294fe00,0x92b50008,0x3015b814,0xb4800002, +0x82b3001f,0x92b5fa00,0x82beffdc,0x82850086, +0x83250094,0x06d4b819,0x02d6b816,0xb016ffff, +0xb4a00009,0x82c50081,0x9ab60020,0x82a60081, +0x82a50086,0x92b50e10,0x82a60094,0x82c60081, +0x86b50704,0x82a6009b,0x00ffb81c,0x00000000, +0x001f9012,0x001fb200,0x001f004c,0x001f2804, +0x801bfef0,0x8058fef4,0x803bff68,0x8078ff6c, +0x2000b801,0x2042b803,0x001fb204,0x005f2814, +0x82e70001,0x83640048,0x029fb014,0x829efef0, +0x8286000f,0x02bf2054,0x82bcfef4,0x82a6000e, +0x00ffb81a,0x80e70001,0x801336e3,0x9800eb76, +0x001fb200,0x800700ab,0x001f2804,0x801bc3e8, +0x8058c3ec,0x83640024,0x82e70000,0x83640036, +0x029fb3c0,0x029fb200,0x02bf2f04,0x02bf2804, +0x801bc000,0x8058c004,0x8364001b,0x82e70000, +0x8364002d,0x001f93c0,0x3000b814,0xb420000a, +0x001f0f04,0x3000b815,0xb4200007,0x829efef0, +0x82bcfef4,0x029fb012,0x02bf204c,0x82870001, +0x829cfef5,0x00ffb81a,0xb0070000,0xb4000007, +0x80e70000,0x801399fa,0x9800c92e,0x001fb200, +0x800700af,0x001f2804,0xb500ffdc,0x82870000, +0x829cfef5,0x00ffb81a,0x80c700ff,0x803bff68, +0x8078ff6c,0x14a0b806,0x2063b805,0x007f2814, +0x2021b802,0x58c8b806,0x14a0b806,0x58b0b805, +0x2021b805,0x58c8b806,0x14a0b806,0x2021b805, +0x58c8b806,0x14a0b806,0x5cb0b805,0x2021b805, +0x003fb204,0x00ffb81b,0x82c70000,0x83070800, +0x83270005,0x8197080c,0x81d7ffff,0x83840126, +0x83840001,0x00ffb81b,0x808f0000,0x806f001f, +0x80af001f,0x80270240,0x81e77c08,0x5de2b80f, +0xb6000208,0x00cfb801,0x01ffb178,0x59e2b80f, +0x01cfb80f,0x01ff9178,0xb520ffff,0x91ef0020, +0x90210020,0x80270280,0x81e77b00,0x5de2b80f, +0xb6000208,0x00cfb801,0x01ffb178,0x59e2b80f, +0x01cfb80f,0x01ff9178,0xb520ffff,0x91ef0020, +0x90210020,0x8057ffff,0x80170830,0x80070810, +0x80270808,0xb6000509,0x005ff000,0x90420900, +0x007ff001,0x90630a00,0x009ff002,0x00bff003, +0x2004a025,0x90000001,0x90210001,0x80070814, +0x80d7ffff,0x8097085c,0x8017083c,0xb6000404, +0x005ff000,0x007f87e0,0x84000001,0x2082a7e3, +0x80970860,0x80170840,0x2082b803,0x007f8000, +0x2083a004,0x80170830,0x80970850,0x80270808, +0xb6000508,0x005f8024,0x90420900,0x007ff001, +0x90630a00,0x009ff002,0x00bff003,0x2004a025, +0x90210001,0x80170840,0x00000000,0x02bf87e0, +0x80970860,0x82870000,0xb6000404,0x005f87e4, +0x5a88b814,0x204287e0,0x1a94b802,0x00ffb81c, +0x001f0e49,0x001f2b09,0x001f0e41,0x001f2b08, +0x001f0e46,0x001f2b07,0x001f0e48,0x001f2b06, +0x001f0e42,0x001f2b05,0x001f0e47,0x001f2b04, +0x001f0e45,0x001f2b03,0x001f0e43,0x001f2b02, +0x001f0e40,0x001f2b01,0x001f0e44,0x001f2b00, +0x001f0f25,0xa020000c,0x94400001,0x94600002, +0x94810004,0x94a10008,0x94c00010,0x5943b802, +0x5861b803,0x5882b804,0x5ca2b805,0x5cc4b806, +0x194ab803,0x194ab804,0x194ab805,0x194ab806, +0x015f2b38,0x801b7c00,0x003f92c1,0x5c28b801, +0x005f92c2,0x5858b802,0x1821b802,0x2000b801, +0x001fb2c4,0x80187c04,0x003f0b09,0x2000b801, +0x001f2b14,0x82c70001,0x82e70001,0x83070b10, +0x8327001e,0x81970b35,0x8384009f,0x02df0b38, +0x82170e30,0x838400f1,0x819efef0,0x817cfef4, +0x819eff68,0x817cff6c,0x00ffb81b,0x820f001f, +0x8018fef8,0x8057ffff,0x001f2b09,0x8018fef6, +0x80d7ffff,0x001f2b08,0x8018fefa,0x8157ffff, +0x001f2b07,0x8018fefd,0x81d7ffff,0x001f2b06, +0x8018fefb,0x802f001f,0x001f2b05,0x8018fefe, +0x00000000,0x001f2b04,0x8018fef9,0x00000000, +0x001f2b03,0x8018feff,0x00000000,0x001f2b02, +0x8018fef7,0x00000000,0x001f2b01,0x8018fefc, +0x00000000,0x001f2b00,0x001f0f25,0xa0200011, +0x94410001,0x94600002,0x94800004,0x94a00008, +0x94c10010,0x5941b802,0x5861b803,0x5c82b804, +0x58a1b805,0x5cc1b806,0x194ab803,0x194ab804, +0x194ab805,0x194ab806,0x015f2b38,0x801b7c00, +0x003f92c1,0x5c28b801,0x005f92c2,0x5858b802, +0x1821b802,0x2000b801,0x001fb2c4,0x80187c04, +0x003f0b09,0x2000b801,0x001f2b14,0x82c70001, +0x82e70001,0x83070b10,0x8327001e,0x81970b35, +0x83840055,0x02df0b38,0x82170e20,0x838400a7, +0x819efef0,0x817cfef4,0x5ac8b80c,0x02ff0e44, +0x1ad6b817,0x02dfb391,0x5ed8b80c,0x5968b80b, +0x1ad6b80b,0x02df6724,0x00ffb81b,0x820f001f, +0x8018fefe,0x8057ffff,0x001f2b09,0x8018fefa, +0x80d7ffff,0x001f2b08,0x8018fefc,0x8157ffff, +0x001f2b07,0x8018feff,0x81d7ffff,0x001f2b06, +0x8018fef8,0x802f001f,0x001f2b05,0x8018fefb, +0x00000000,0x001f2b04,0x8018fefd,0x00000000, +0x001f2b03,0x8018fef6,0x00000000,0x001f2b02, +0x8018fef9,0x00000000,0x001f2b01,0x8018fef7, +0x00000000,0x001f2b00,0x801b7c00,0x003f92c1, +0x5c28b801,0x005f92c2,0x5858b802,0x1821b802, +0x2000b801,0x001fb2c4,0x80187c04,0x003f0b09, +0x2000b801,0x001f2b14,0x82c70001,0x82e70001, +0x83070b10,0x8327001e,0x81970b35,0x83840016, +0x83270000,0x831bfef0,0x82f8fef4,0x02c7b819, +0x82170e28,0x83840065,0x300cb818,0xb4200002, +0x300bb817,0xb4000006,0x93390001,0xb0190020, +0xb480fff6,0x83270000,0x833cfef5,0x00ffb81b, +0x019fb390,0x017f2e44,0x033f2f25,0x83270001, +0x833cfef5,0x00ffb81b,0x0007b818,0x90000003, +0x00000000,0x015ff000,0x90000001,0x5949b80a, +0x013ff000,0x194ab809,0x84000002,0x994a0100, +0x017ff000,0x958b00f8,0x5981b80c,0x956b0007, +0x198cb80b,0x84000002,0x998c0008,0x017ff000, +0x90000001,0x5971b80b,0x198cb80b,0x017ff000, +0x5969b80b,0x198cb80b,0x81a70000,0x94d90003, +0x82a70000,0xb6260019,0xb6000818,0x5df0b80a, +0x5e02b80a,0x21efb810,0x95ef0001,0x5941b80a, +0x194ab80f,0x21efb816,0x5e18b80c,0x5e35b80c, +0x5e54b80c,0x5e6cb80c,0x2210b811,0x2252b813, +0x2210b812,0x96100001,0x5981b80c,0x198cb810, +0x2210b817,0x10afb810,0x10a5b80d,0x5da1b805, +0x94a50001,0x5aa1b815,0x1ab5b805,0x019fa7f5, +0x5cc2b819,0xb626001c,0x82870000,0xb6000419, +0xb6000818,0x5df0b80a,0x5e02b80a,0x21efb810, +0x95ef0001,0x5941b80a,0x194ab80f,0x21efb816, +0x5e18b80c,0x5e35b80c,0x5e54b80c,0x5e6cb80c, +0x2210b811,0x2252b813,0x2210b812,0x96100001, +0x5981b80c,0x198cb810,0x2210b817,0x10afb810, +0x10a5b80d,0x5da1b805,0x94a50001,0x5a81b814, +0x1a94b805,0x019fa7f4,0x00ffb81c,0x8257ffff, +0x808f0000,0x806f001f,0x80af001f,0x80270300, +0x81e778e0,0x5de2b80f,0xb6000208,0x00cfb801, +0x01ffb178,0x59e2b80f,0x01cfb80f,0x01ff9178, +0xb520ffff,0x91ef0020,0x90210020,0x80270340, +0x81e779e0,0x5de2b80f,0xb6000208,0x00cfb801, +0x01ffb178,0x59e2b80f,0x01cfb80f,0x01ff9178, +0xb520ffff,0x91ef0020,0x90210020,0x80270280, +0x81e77b00,0x5de2b80f,0xb6000208,0x00cfb801, +0x01ffb178,0x59e2b80f,0x01cfb80f,0x01ff9178, +0xb520ffff,0x91ef0020,0x90210020,0x806f0007, +0x80af0007,0x80270380,0x81e77ae0,0x5de2b80f, +0x00cfb801,0x01ffb178,0x59e2b80f,0x01cfb80f, +0x01ff9178,0xb520ffff,0x91ef0020,0x90210020, +0x80170b60,0x001f0b00,0x001fa020,0x001f0b01, +0x001fa020,0x001f0b02,0x001fa020,0x001f0b03, +0x001fa020,0x001f0b04,0x001fa000,0x80970b50, +0x81170b70,0x82a70b35,0x83a40060,0x001f87e4, +0xb6000405,0x86b50001,0x83a4005c,0x001f8004, +0x003f87e8,0x2080a7e1,0x80970b70,0x80170b50, +0x81170b50,0x81970b40,0x82a70b30,0x001f800c, +0x003f8008,0x2100a001,0x83a40050,0x001f87e4, +0xb6000405,0x86b50001,0x83a4004c,0x001f8004, +0x003f87e8,0x2080a7e1,0x80970b50,0x80170b70, +0x81170b70,0x81970b60,0x82a70b2b,0x001f800c, +0x003f8008,0x2100a001,0x83a40040,0x83a4004e, +0xb6000407,0x86b50001,0x83a4003c,0x001f8004, +0x003f87e8,0x2080a001,0x83a40047,0x00000000, +0x80970b70,0x80170b50,0x81170b50,0x81970b40, +0x82a70b26,0x001f800c,0x003f8008,0x2100a001, +0x83a4002e,0x83a4003c,0xb6000407,0x86b50001, +0x83a4002a,0x001f8004,0x003f87e8,0x2080a001, +0x83a40035,0x00000000,0x80970b50,0x80170b70, +0x81170b70,0x81970b60,0x82a70b21,0x001f800c, +0x003f8008,0x2100a001,0x83a4001c,0x001f87e4, +0xb6000405,0x86b50001,0x83a40018,0x001f8004, +0x003f87e8,0x2080a7e1,0x80970b70,0x80170b50, +0x81170b50,0x81970b40,0x82a70b1c,0x001f800c, +0x003f8008,0x2100a001,0x83a4000c,0x017f87e4, +0x81870000,0xb6000406,0x86b50001,0x83a40007, +0x001f87e4,0x200087e8,0x5988b80c,0x198cb800, +0x021fa02c,0x021fa00b,0x00ffb81c,0x005ff015, +0x90420a00,0x003f87e0,0x001ff002,0x2060b801, +0x90630c00,0x90960e00,0x001ff003,0x003ff004, +0x20a0b801,0x90a50d00,0x00000000,0x001ff005, +0x009fa000,0x00ffb81d,0x001f8004,0x5c21b800, +0x5847b800,0x1821b802,0x942100ff,0x2080a7e1, +0x00ffb81d,0x00000000,0x00000000,0x00000000, + +}; + +static u32 MPGI2SUcode1f5c00[] = { +0x00000000,0xfffff8c0,0x00003540,0xffff8d40, +0x0001fd40,0xfffaf7c0,0x00066b80,0xffdb63c0, +0x00494780,0x00249c40,0x00066b80,0x00050840, +0x0001fd40,0x000072c0,0x00003540,0x00000740, +0xffffffc0,0xfffff840,0x00003680,0xffff7e40, +0x0001f400,0xfffa9cc0,0x0005d1c0,0xffd99600, +0x00493c00,0x0022ce00,0x0006f780,0x0004ad00, +0x000203c0,0x00006440,0x00003400,0x00000680, +0xffffffc0,0xfffff740,0x00003780,0xffff6ec0, +0x0001e800,0xfffa4240,0x00052a00,0xffd7ca00, +0x00491a00,0x0020ffc0,0x00077600,0x00045240, +0x00020800,0x000056c0,0x00003280,0x00000600, +0xffffffc0,0xfffff680,0x00003840,0xffff5ec0, +0x0001d940,0xfff9e8c0,0x00047440,0xffd60080, +0x0048e180,0x001f32c0,0x0007e700,0x0003f7c0, +0x000209c0,0x00004980,0x00003100,0x00000540, +0xffffffc0,0xfffff5c0,0x000038c0,0xffff4e40, +0x0001c780,0xfff990c0,0x0003b000,0xffd43ac0, +0x00489240,0x001d6800,0x00084b00,0x00039e40, +0x00020940,0x00003d00,0x00002f80,0x000004c0, +0xffffffc0,0xfffff4c0,0x00003900,0xffff3d40, +0x0001b2c0,0xfff93a40,0x0002ddc0,0xffd279c0, +0x00482d00,0x001ba040,0x0008a200,0x000345c0, +0x000206c0,0x00003140,0x00002dc0,0x00000440, +0xffffffc0,0xfffff3c0,0x00003900,0xffff2c00, +0x00019b00,0xfff8e640,0x0001fd40,0xffd0be80, +0x0047b1c0,0x0019dc80,0x0008ecc0,0x0002ef00, +0x00020240,0x00002640,0x00002c00,0x00000400, +0xffffff80,0xfffff2c0,0x000038c0,0xffff1a40, +0x00017fc0,0xfff894c0,0x00010e80,0xffcf09c0, +0x004720c0,0x00181d80,0x00092b40,0x000299c0, +0x0001fc00,0x00001bc0,0x00002a40,0x00000380, +0xffffff80,0xfffff180,0x00003800,0xffff0840, +0x00016180,0xfff84680,0x00001180,0xffcd5cc0, +0x00467a40,0x00166440,0x00095e00,0x00024680, +0x0001f440,0x00001200,0x00002840,0x00000340, +0xffffff80,0xfffff040,0x00003740,0xfffef600, +0x00014000,0xfff7fbc0,0xffff0680,0xffcbb880, +0x0045bf00,0x0014b140,0x00098580,0x0001f580, +0x0001ea80,0x00000900,0x00002680,0x000002c0, +0xffffff80,0xffffef00,0x000035c0,0xfffee3c0, +0x00011ac0,0xfff7b540,0xfffded80,0xffca1d80, +0x0044ef80,0x00130580,0x0009a1c0,0x0001a700, +0x0001dfc0,0x00000080,0x000024c0,0x00000280, +0xffffff40,0xffffedc0,0x00003400,0xfffed180, +0x0000f280,0xfff77340,0xfffcc700,0xffc88d80, +0x00440bc0,0x001161c0,0x0009b3c0,0x00015b00, +0x0001d380,0xfffff8c0,0x000022c0,0x00000240, +0xffffff40,0xffffec40,0x00003200,0xfffebf40, +0x0000c680,0xfff73680,0xfffb92c0,0xffc708c0, +0x00431500,0x000fc6c0,0x0009bb80,0x000111c0, +0x0001c640,0xfffff1c0,0x00002100,0x00000200, +0xffffff00,0xffffeac0,0x00002f40,0xfffead00, +0x00009740,0xfff6ff40,0xfffa5180,0xffc59080, +0x00420b40,0x000e3500,0x0009b9c0,0x0000cb80, +0x0001b7c0,0xffffeb40,0x00001f40,0x000001c0, +0xffffff00,0xffffe940,0x00002c40,0xfffe9b00, +0x00006480,0xfff6ce00,0xfff90380,0xffc425c0, +0x0040ef80,0x000cad00,0x0009af00,0x00008840, +0x0001a880,0xffffe580,0x00001d40,0x000001c0, +0xfffffec0,0xffffe7c0,0x000028c0,0xfffe8980, +0x00002e40,0xfff6a3c0,0xfff7a900,0xffc2c900, +0x003fc280,0x000b2fc0,0x00099b80,0x00004800, +0x00019880,0xffffe040,0x00001bc0,0x00000180, +0xfffffec0,0xffffe600,0x00002480,0xfffe7840, +0xfffff4c0,0xfff68040,0xfff64240,0xffc17b40, +0x003e84c0,0x0009bdc0,0x00097fc0,0x00000b40, +0x000187c0,0xffffdb80,0x00001a00,0x00000140, +0xfffffe80,0xffffe440,0x00001fc0,0xfffe6780, +0xffffb800,0xfff66480,0xfff4d040,0xffc03d80, +0x003d3700,0x00085700,0x00095c40,0xffffd1c0, +0x00017680,0xffffd740,0x00001840,0x00000140, +0xfffffe40,0xffffe2c0,0x00001a80,0xfffe5780, +0xffff77c0,0xfff65100,0xfff35300,0xffbf1080, +0x003bda40,0x0006fc80,0x00093200,0xffff9b80, +0x00016500,0xffffd3c0,0x000016c0,0x00000100, +0xfffffe40,0xffffe0c0,0x000014c0,0xfffe4840, +0xffff3480,0xfff64640,0xfff1cb00,0xffbdf4c0, +0x003a6f80,0x0005ae80,0x000900c0,0xffff68c0, +0x00015300,0xffffd0c0,0x00001540,0x00000100, +0xfffffe00,0xffffdf00,0x00000e40,0xfffe39c0, +0xfffeee40,0xfff64480,0xfff03940,0xffbceb00, +0x0038f740,0x00046d40,0x0008c980,0xffff3980, +0x000140c0,0xffffce00,0x000013c0,0x000000c0, +0xfffffdc0,0xffffdd40,0x00000740,0xfffe2c80, +0xfffea500,0xfff64c40,0xffee9e40,0xffbbf440, +0x00377280,0x00033900,0x00088cc0,0xffff0d80, +0x00012e80,0xffffcc00,0x00001240,0x000000c0, +0xfffffd80,0xffffdb40,0xffffff80,0xfffe2040, +0xfffe5900,0xfff65e40,0xffecfa80,0xffbb1080, +0x0035e280,0x00021280,0x00084ac0,0xfffee540, +0x00011c40,0xffffca40,0x00001100,0x00000080, +0xfffffd40,0xffffd980,0xfffff700,0xfffe1580, +0xfffe0a80,0xfff67a80,0xffeb4ec0,0xffba4100, +0x00344780,0x0000f980,0x00080440,0xfffec000, +0x00010a00,0xffffc8c0,0x00000fc0,0x00000080, +0xfffffcc0,0xffffd7c0,0xffffee00,0xfffe0bc0, +0xfffdb980,0xfff6a200,0xffe99bc0,0xffb985c0, +0x0032a340,0xffffee80,0x0007b980,0xfffe9e80, +0x0000f7c0,0xffffc800,0x00000e80,0x00000080, +0xfffffc80,0xffffd5c0,0xffffe440,0xfffe0400, +0xfffd6640,0xfff6d4c0,0xffe7e280,0xffb8df40, +0x0030f640,0xfffef180,0x00076b40,0xfffe8040, +0x0000e5c0,0xffffc740,0x00000d40,0x00000080, +0xfffffc00,0xffffd400,0xffffd9c0,0xfffdfdc0, +0xfffd1100,0xfff71340,0xffe62380,0xffb84e40, +0x002f4180,0xfffe02c0,0x000719c0,0xfffe6500, +0x0000d400,0xffffc700,0x00000c40,0x00000040, +0xfffffbc0,0xffffd240,0xffffcec0,0xfffdf940, +0xfffcba40,0xfff75e00,0xffe45fc0,0xffb7d300, +0x002d8640,0xfffd2240,0x0006c5c0,0xfffe4d40, +0x0000c2c0,0xffffc700,0x00000b40,0x00000040, +0xfffffb40,0xffffd080,0xffffc300,0xfffdf6c0, +0xfffc61c0,0xfff7b500,0xffe29800,0xffb76dc0, +0x002bc540,0xfffc5000,0x00066f40,0xfffe3880, +0x0000b1c0,0xffffc740,0x00000a40,0x00000040, +0xfffffac0,0xffffcf00,0xffffb680,0xfffdf640, +0xfffc0840,0xfff81900,0xffe0cd40,0xffb71e80, +0x0029ff80,0xfffb8bc0,0x00061740,0xfffe26c0, +0x0000a140,0xffffc7c0,0x00000980,0x00000040, +0xfffffa00,0xffffcd80,0xffffa940,0xfffdf800, +0xfffbadc0,0xfff88a00,0xffdf0040,0xffb6e600, +0x00283600,0xfffad600,0x0005bdc0,0xfffe1800, +0x00009140,0xffffc880,0x000008c0,0x00000040, +0xfffff980,0xffffcc00,0xffff9bc0,0xfffdfc40, +0xfffb5300,0xfff90880,0xffdd3200,0xffb6c400, +0x00266a00,0xfffa2e40,0x00056340,0xfffe0c00, +0x000081c0,0xffffc980,0x000007c0,0x00000040, +0x004013c2,0x0040b346,0x0041fa2d,0x0043f934, +0x0046cc1c,0x004a9d9d,0x004fae37,0x0056601f, +0x005f4cf7,0x006b6fcf,0x007c7d1e,0x0115b035, +0x013df91b,0x0207655e,0x03342c83,0x0a185230, +0x00404f46,0x0042e13c,0x0048919f,0x0052cb0e, +0x0064e240,0x0107c449,0x015c7926,0x050cf270, +0x004140fb,0x004cf8df,0x0073326c,0x02480d9d, +0x004545ea,0x01273d75,0x005a827a,0x007fffff, +0x006597fb,0x0050a28c,0x00400000,0x0032cbfd, +0x00285146,0x00200000,0x001965ff,0x001428a3, +0x00100000,0x000cb2ff,0x000a1451,0x00080000, +0x00065980,0x00050a29,0x00040000,0x00032cc0, +0x00028514,0x00020000,0x00019660,0x0001428a, +0x00010000,0x0000cb30,0x0000a145,0x00008000, +0x00006598,0x000050a3,0x00004000,0x000032cc, +0x00002851,0x00002000,0x00001966,0x00001429, +0x00001000,0x00000cb3,0x00000a14,0x00000800, +0x00000659,0x0000050a,0x00000400,0x0000032d, +0x00000285,0x00000200,0x00000196,0x00000143, +0x00000100,0x000000cb,0x000000a1,0x00000080, +0x00000066,0x00000051,0x00000040,0x00000033, +0x00000028,0x00000020,0x00000019,0x00000014, +0x00000010,0x0000000d,0x0000000a,0x00000008, +0x00000006,0x00000005,0x00000000,0x00555555, +0x00666666,0x00492492,0x0071c71c,0x00444444, +0x00421084,0x00410410,0x00408102,0x00404040, +0x00402010,0x00401004,0x00400801,0x00400400, +0x00400200,0x00400100,0x00400080,0x00400040, +0x00400000,0x00400000,0x00200000,0x00400000, +0x00100000,0x00080000,0x00040000,0x00020000, +0x00010000,0x00008000,0x00004000,0x00002000, +0x00001000,0x00000800,0x00000400,0x00000200, +0x00000100,0x0003588d,0x0002b15e,0x0002056d, +0x00015600,0x0000a329,0xffffeed9,0xffff3960, +0xfffe8423,0xfffdd11c,0xfffd2048,0xfffc7353, +0xfffbcb6f,0xfffb29a6,0xfffa8f15,0x000494ae, +0x0003f991,0x00032dd1,0xfffd2d8f,0x0001eb47, +0xfffe9968,0x00009af6,0x000011de,0xffff4335, +0x00018d69,0xfffdecd4,0x000302f8,0xfffca0d7, +0x0004683d,0xfffb67f8,0x0005b36d,0x00045963, +0xfffbd51e,0x00030062,0xfffd0dee,0x0001d046, +0xfffe8a0a,0x00009258,0x000012b1,0xffff4d9e, +0x00019ec3,0xfffe0a44,0x0003245a,0xfffcd082, +0x000498f0,0xfffba919,0x0005f304,0x00041bf4, +0xfffba72a,0x0002d19e,0xfffcf060,0x0001b407, +0xfffe7c08,0x0000894a,0x0000138d,0xffff58ac, +0x0001afaf,0xfffe28fe,0x000343bf,0xfffd026f, +0x0004c6f6,0xfffbed06,0x00062e61,0x0003dc0e, +0xfffb7bf1,0x0002a17f,0xfffcd522,0x000196a0, +0xfffe6e70,0x00007ff6,0x00001439,0xffff63f6, +0x0001beb3,0xfffe4882,0x0003616d,0xfffd361b, +0x0004f1cf,0xfffc332a,0x0006658f,0x00039943, +0xfffb52c0,0x00026ec7,0xfffcbb94,0x0001789f, +0xfffe6160,0x00007677,0x000014d4,0xffff6f74, +0x0001cc9b,0xfffe694f,0x00037cbf,0xfffd6b41, +0x000519c2,0xfffc7baf,0x00069971,0x00035486, +0xfffb2d0c,0x00023ad8,0xfffca3ee,0x00015989, +0xfffe55af,0x00006ca7,0x00001570,0xffff7b71, +0x0001d9cb,0xfffe8b46,0x0003959e,0xfffda1fe, +0x00053ee6,0xfffcc6b4,0x0006c950,0x00030e08, +0xfffb0a7a,0x0002061e,0xfffc8ec0,0x00013911, +0xfffe4b1d,0x00006278,0x000015e8,0xffff87b6, +0x0001e577,0xfffeadd6,0x0003acc2,0xfffdda34, +0x00056059,0xfffd136d,0x0006f4b5,0x0002c562, +0xfffaea7c,0x0001cfa6,0xfffc7b14,0x0001182b, +0xfffe4159,0x00005817,0x0000165c,0xffff9417, +0x0001f00f,0xfffed14c,0x0003c199,0xfffe13f6, +0x00057e83,0xfffd61cd,0x00071ba1,0x00027ab5, +0xfffacdc3,0x00019833,0xfffc6989,0x0000f6ca, +0xfffe38da,0x00004d9d,0x000016ef,0xffffa103, +0x0001f98f,0xfffef5c0,0x0003d3d1,0xfffe4f00, +0x0005998c,0xfffdb21e,0x00073e77,0x00022e75, +0xfffab482,0x00015fd1,0xfffc5b13,0x0000d45d, +0xfffe318f,0x000042ed,0x0000176b,0xffffae8f, +0x0002018f,0xffff1a91,0x0003e40c,0xfffe8af2, +0x0005b0ca,0xfffe03b8,0x00075d14,0x0001e141, +0xfffa9e9b,0x0001262a,0xfffc4e31,0x0000b1af, +0xfffe2b26,0x00003805,0x000017b1,0xffffbc21, +0x000208b8,0xffff3fb6,0x0003f1d7,0xfffec7af, +0x0005c4c5,0xfffe5654,0x0007768a,0x000192fe, +0xfffa8bb0,0x0000ec3f,0xfffc4365,0x00008ec9, +0xfffe25f0,0x00002d05,0x000017ec,0xffffc984, +0x00020ec6,0xffff658d,0x0003fcba,0xffff0500, +0x0005d576,0xfffeaa37,0x00078bc6,0x00014367, +0xfffa7bec,0x0000b1f4,0xfffc3b82,0x00006b06, +0xfffe2201,0x000021eb,0x00001823,0xffffd704, +0x0002132a,0xffff8be7,0x00040534,0xffff4315, +0x0005e22e,0xfffeff0a,0x00079ce3,0x0000f33f, +0xfffa6fc9,0x000076ca,0xfffc3558,0x00004762, +0xfffe1ef3,0x000016a1,0x0000183f,0xffffe4a6, +0x00021664,0xffffb27d,0x00040b7b,0xffff81e5, +0x0005eb4e,0xffff5475,0x0007a857,0x0000a2cb, +0xfffa671b,0x00003b64,0xfffc31e2,0x00002416, +0xfffe1ce1,0x00000b46,0x00001850,0xfffff24d, +0x00021855,0xffffd93a,0x00040f75,0xffffc0e6, +0x0005f0e3,0xffffaa3e,0x0007af45,0x0000519f, +0xfffa6218,0x0003f991,0x0003588d,0x0002b15e, +0x0002056d,0x00015600,0x0000a329,0xffffeed9, +0xffff3960,0xfffe8423,0xfffdd11c,0xfffd2048, +0xfffc7353,0xfffbcb6f,0xfffb29a6,0xfffa8f15, +0x000494ae,0x0003c6b0,0xfffc7e8b,0x00028ef6, +0xfffde181,0x000144eb,0xffff5500,0xffffefb9, +0x0000d01d,0xfffe9755,0x000249a4,0xfffd453c, +0x0003b80e,0xfffc01aa,0x000511d6,0xfffad527, +0xfffb334e,0x0003916c,0xfffc5778,0x00026a92, +0xfffdc9f5,0x00013314,0xffff4d99,0xfffff0b6, +0x0000d911,0xfffeab80,0x00026369,0xfffd6c0a, +0x0003e17f,0xfffc39d8,0x000549df,0xfffb1eb2, +0xfffafe6c,0x00035929,0xfffc3321,0x000244a6, +0xfffdb402,0x00012035,0xffff46ac,0xfffff192, +0x0000e16a,0xfffebfe0,0x00027b3d,0xfffd9433, +0x0004087b,0xfffc74b7,0x00057e8d,0xfffb6a81, +0xfffacc1c,0x00031fbe,0xfffc10df,0x00021e0c, +0xfffd9f6d,0x00010cb7,0xffff402e,0xfffff279, +0x0000e965,0xfffed574,0x00029159,0xfffdbdc4, +0x00042c4c,0xfffcb1e7,0x0005b02d,0xfffbb942, +0xfffa9d38,0x0002e44a,0xfffbf0fd,0x0001f5b4, +0xfffd8c38,0x0000f8b1,0xffff3a21,0xfffff391, +0x0000f0e6,0xfffeec44,0x0002a642,0xfffde90e, +0x00044e32,0xfffcf0fb,0x0005de46,0xfffc0b18, +0xfffa71d1,0x0002a659,0xfffbd3de,0x0001cb90, +0xfffd7a97,0x0000e403,0xffff3490,0xfffff49c, +0x0000f7a8,0xffff0340,0x0002b95f,0xfffe1573, +0x00046dbe,0xfffd3284,0x00060888,0xfffc5f51, +0xfffa4996,0x00026786,0xfffbb8df,0x0001a0e1, +0xfffd6a4e,0x0000ced2,0xffff2f75,0xfffff593, +0x0000fdbe,0xffff1a53,0x0002ca87,0xfffe42f5, +0x0004898a,0xfffd7563,0x00062f0b,0xfffcb5de, +0xfffa2508,0x00022713,0xfffba0bf,0x0001754a, +0xfffd5b5f,0x0000b92c,0xffff2acd,0xfffff6b0, +0x0001034f,0xffff3241,0x0002da5c,0xfffe71c6, +0x0004a341,0xfffdb946,0x000651e8,0xfffd0e37, +0xfffa0402,0x0001e4d4,0xfffb8b9c,0x00014898, +0xfffd4e7d,0x0000a304,0xffff26b7,0xfffff7e1, +0x00010846,0xffff4b34,0x0002e897,0xfffea13f, +0x0004ba63,0xfffdff2d,0x00067115,0xfffd6839, +0xfff9e680,0x0001a1fa,0xfffb789e,0x00011b2e, +0xfffd43a4,0x00008c6e,0xffff2341,0xfffff8fd, +0x00010c9c,0xffff6469,0x0002f48f,0xfffed1a4, +0x0004cd6a,0xfffe4608,0x00068c1b,0xfffdc409, +0xfff9cd15,0x00015dfe,0xfffb68a0,0x0000ecee, +0xfffd3a2e,0x0000757d,0xffff204b,0xfffffa1e, +0x00011054,0xffff7da1,0x0002fe9c,0xffff033e, +0x0004de57,0xfffe8dc6,0x0006a2d5,0xfffe213e, +0xfff9b77d,0x000118d3,0xfffb5bde,0x0000be25, +0xfffd3224,0x00005e52,0xffff1dc1,0xfffffb4b, +0x00011353,0xffff9740,0x00030748,0xffff351c, +0x0004ec95,0xfffed755,0x0006b5b4,0xfffe7fc6, +0xfff9a599,0x0000d334,0xfffb519f,0x00008f08, +0xfffd2bbf,0x00004704,0xffff1bc1,0xfffffc71, +0x00011598,0xffffb135,0x00030e43,0xffff6720, +0x0004f6f3,0xffff2119,0x0006c46e,0xfffedf38, +0xfff997c7,0x00008d13,0xfffb4a55,0x00005fa5, +0xfffd273b,0x00002f76,0xffff1a63,0xfffffda0, +0x00011744,0xffffcb67,0x000312ff,0xffff99cf, +0x0004ff0c,0xffff6a9c,0x0006cebd,0xffff3f0a, +0xfff98dbe,0x00004691,0xfffb4620,0x00003010, +0xfffd24fc,0x000017b5,0xffff199d,0xfffffed8, +0x0001185a,0xffffe5c6,0x0003157e,0xffffcce3, +0x000503ae,0xffffb515,0x0006d537,0xffff9f5a, +0xfff98767,0xfffb44b0,0xfffc3131,0xfffd2475, +0xfffe1c28,0xffff195d,0x00001859,0x000118bd, +0x000218df,0x0003163a,0x000410e0,0x000504a7, +0x0005f2b3,0x0006d796,0x0007b1fe,0xfff98537, +0xfffa609b,0xfffc7e8b,0x00028ef6,0xfffde181, +0x000144eb,0xffff5500,0xffffefb9,0x0000d01d, +0xfffe9755,0x000249a4,0xfffd453c,0x0003b80e, +0xfffc01aa,0x000511d6,0xfffad527,0xfffb334e, +0x0003c6b0,0xfffc5778,0x00026a92,0xfffdc9f5, +0x00013314,0xffff4d99,0xfffff0b6,0x0000d911, +0xfffeab80,0x00026369,0xfffd6c0a,0x0003e17f, +0xfffc39d8,0x000549df,0xfffb1eb2,0xfffafe6c, +0x0003916c,0xfffc3321,0x000244a6,0xfffdb402, +0x00012035,0xffff46ac,0xfffff192,0x0000e16a, +0xfffebfe0,0x00027b3d,0xfffd9433,0x0004087b, +0xfffc74b7,0x00057e8d,0xfffb6a81,0xfffacc1c, +0x00035929,0xfffc10df,0x00021e0c,0xfffd9f6d, +0x00010cb7,0xffff402e,0xfffff279,0x0000e965, +0xfffed574,0x00029159,0xfffdbdc4,0x00042c4c, +0xfffcb1e7,0x0005b02d,0xfffbb942,0xfffa9d38, +0x00031fbe,0xfffbf0fd,0x0001f5b4,0xfffd8c38, +0x0000f8b1,0xffff3a21,0xfffff391,0x0000f0e6, +0xfffeec44,0x0002a642,0xfffde90e,0x00044e32, +0xfffcf0fb,0x0005de46,0xfffc0b18,0xfffa71d1, +0x0002e44a,0xfffbd3de,0x0001cb90,0xfffd7a97, +0x0000e403,0xffff3490,0xfffff49c,0x0000f7a8, +0xffff0340,0x0002b95f,0xfffe1573,0x00046dbe, +0xfffd3284,0x00060888,0xfffc5f51,0xfffa4996, +0x0002a659,0xfffbb8df,0x0001a0e1,0xfffd6a4e, +0x0000ced2,0xffff2f75,0xfffff593,0x0000fdbe, +0xffff1a53,0x0002ca87,0xfffe42f5,0x0004898a, +0xfffd7563,0x00062f0b,0xfffcb5de,0xfffa2508, +0x00026786,0xfffba0bf,0x0001754a,0xfffd5b5f, +0x0000b92c,0xffff2acd,0xfffff6b0,0x0001034f, +0xffff3241,0x0002da5c,0xfffe71c6,0x0004a341, +0xfffdb946,0x000651e8,0xfffd0e37,0xfffa0402, +0x00022713,0xfffb8b9c,0x00014898,0xfffd4e7d, +0x0000a304,0xffff26b7,0xfffff7e1,0x00010846, +0xffff4b34,0x0002e897,0xfffea13f,0x0004ba63, +0xfffdff2d,0x00067115,0xfffd6839,0xfff9e680, +0x0001e4d4,0xfffb789e,0x00011b2e,0xfffd43a4, +0x00008c6e,0xffff2341,0xfffff8fd,0x00010c9c, +0xffff6469,0x0002f48f,0xfffed1a4,0x0004cd6a, +0xfffe4608,0x00068c1b,0xfffdc409,0xfff9cd15, +0x0001a1fa,0xfffb68a0,0x0000ecee,0xfffd3a2e, +0x0000757d,0xffff204b,0xfffffa1e,0x00011054, +0xffff7da1,0x0002fe9c,0xffff033e,0x0004de57, +0xfffe8dc6,0x0006a2d5,0xfffe213e,0xfff9b77d, +0x00015dfe,0xfffb5bde,0x0000be25,0xfffd3224, +0x00005e52,0xffff1dc1,0xfffffb4b,0x00011353, +0xffff9740,0x00030748,0xffff351c,0x0004ec95, +0xfffed755,0x0006b5b4,0xfffe7fc6,0xfff9a599, +0x000118d3,0xfffb519f,0x00008f08,0xfffd2bbf, +0x00004704,0xffff1bc1,0xfffffc71,0x00011598, +0xffffb135,0x00030e43,0xffff6720,0x0004f6f3, +0xffff2119,0x0006c46e,0xfffedf38,0xfff997c7, +0x0000d334,0xfffb4a55,0x00005fa5,0xfffd273b, +0x00002f76,0xffff1a63,0xfffffda0,0x00011744, +0xffffcb67,0x000312ff,0xffff99cf,0x0004ff0c, +0xffff6a9c,0x0006cebd,0xffff3f0a,0xfff98dbe, +0x00008d13,0xfffb4620,0x00003010,0xfffd24fc, +0x000017b5,0xffff199d,0xfffffed8,0x0001185a, +0xffffe5c6,0x0003157e,0xffffcce3,0x000503ae, +0xffffb515,0x0006d537,0xffff9f5a,0xfff98767, +0x00004691,0xfffa609b,0xfffb44b0,0xfffc3131, +0xfffd2475,0xfffe1c28,0xffff195d,0x00001859, +0x000118bd,0x000218df,0x0003163a,0x000410e0, +0x000504a7,0x0005f2b3,0x0006d796,0x0007b1fe, +0xfff98537,0xfffbd51e,0x00032dd1,0xfffd2d8f, +0x0001eb47,0xfffe9968,0x00009af6,0x000011de, +0xffff4335,0x00018d69,0xfffdecd4,0x000302f8, +0xfffca0d7,0x0004683d,0xfffb67f8,0x0005b36d, +0x00045963,0xfffba72a,0x00030062,0xfffd0dee, +0x0001d046,0xfffe8a0a,0x00009258,0x000012b1, +0xffff4d9e,0x00019ec3,0xfffe0a44,0x0003245a, +0xfffcd082,0x000498f0,0xfffba919,0x0005f304, +0x00041bf4,0xfffb7bf1,0x0002d19e,0xfffcf060, +0x0001b407,0xfffe7c08,0x0000894a,0x0000138d, +0xffff58ac,0x0001afaf,0xfffe28fe,0x000343bf, +0xfffd026f,0x0004c6f6,0xfffbed06,0x00062e61, +0x0003dc0e,0xfffb52c0,0x0002a17f,0xfffcd522, +0x000196a0,0xfffe6e70,0x00007ff6,0x00001439, +0xffff63f6,0x0001beb3,0xfffe4882,0x0003616d, +0xfffd361b,0x0004f1cf,0xfffc332a,0x0006658f, +0x00039943,0xfffb2d0c,0x00026ec7,0xfffcbb94, +0x0001789f,0xfffe6160,0x00007677,0x000014d4, +0xffff6f74,0x0001cc9b,0xfffe694f,0x00037cbf, +0xfffd6b41,0x000519c2,0xfffc7baf,0x00069971, +0x00035486,0xfffb0a7a,0x00023ad8,0xfffca3ee, +0x00015989,0xfffe55af,0x00006ca7,0x00001570, +0xffff7b71,0x0001d9cb,0xfffe8b46,0x0003959e, +0xfffda1fe,0x00053ee6,0xfffcc6b4,0x0006c950, +0x00030e08,0xfffaea7c,0x0002061e,0xfffc8ec0, +0x00013911,0xfffe4b1d,0x00006278,0x000015e8, +0xffff87b6,0x0001e577,0xfffeadd6,0x0003acc2, +0xfffdda34,0x00056059,0xfffd136d,0x0006f4b5, +0x0002c562,0xfffacdc3,0x0001cfa6,0xfffc7b14, +0x0001182b,0xfffe4159,0x00005817,0x0000165c, +0xffff9417,0x0001f00f,0xfffed14c,0x0003c199, +0xfffe13f6,0x00057e83,0xfffd61cd,0x00071ba1, +0x00027ab5,0xfffab482,0x00019833,0xfffc6989, +0x0000f6ca,0xfffe38da,0x00004d9d,0x000016ef, +0xffffa103,0x0001f98f,0xfffef5c0,0x0003d3d1, +0xfffe4f00,0x0005998c,0xfffdb21e,0x00073e77, +0x00022e75,0xfffa9e9b,0x00015fd1,0xfffc5b13, +0x0000d45d,0xfffe318f,0x000042ed,0x0000176b, +0xffffae8f,0x0002018f,0xffff1a91,0x0003e40c, +0xfffe8af2,0x0005b0ca,0xfffe03b8,0x00075d14, +0x0001e141,0xfffa8bb0,0x0001262a,0xfffc4e31, +0x0000b1af,0xfffe2b26,0x00003805,0x000017b1, +0xffffbc21,0x000208b8,0xffff3fb6,0x0003f1d7, +0xfffec7af,0x0005c4c5,0xfffe5654,0x0007768a, +0x000192fe,0xfffa7bec,0x0000ec3f,0xfffc4365, +0x00008ec9,0xfffe25f0,0x00002d05,0x000017ec, +0xffffc984,0x00020ec6,0xffff658d,0x0003fcba, +0xffff0500,0x0005d576,0xfffeaa37,0x00078bc6, +0x00014367,0xfffa6fc9,0x0000b1f4,0xfffc3b82, +0x00006b06,0xfffe2201,0x000021eb,0x00001823, +0xffffd704,0x0002132a,0xffff8be7,0x00040534, +0xffff4315,0x0005e22e,0xfffeff0a,0x00079ce3, +0x0000f33f,0xfffa671b,0x000076ca,0xfffc3558, +0x00004762,0xfffe1ef3,0x000016a1,0x0000183f, +0xffffe4a6,0x00021664,0xffffb27d,0x00040b7b, +0xffff81e5,0x0005eb4e,0xffff5475,0x0007a857, +0x0000a2cb,0xfffa6218,0x00003b64,0xfffc31e2, +0x00002416,0xfffe1ce1,0x00000b46,0x00001850, +0xfffff24d,0x00021855,0xffffd93a,0x00040f75, +0xffffc0e6,0x0005f0e3,0xffffaa3e,0x0007af45, +0x0000519f,0x00030000,0x000f0007,0x003f001f, +0x00ff007f,0x03ff01ff,0x0fff07ff,0x3fff1fff, +0xffff7fff,0x00030000,0x00070005,0x000f0009, +0x003f001f,0x00ff007f,0x03ff01ff,0x0fff07ff, +0xffff1fff,0x00030000,0x00070005,0x000f0009, +0xffff001f,0x00030000,0xffff0005,0x04030504, +0x08070605,0x0c0b0a09,0x100f0e0d,0x03070504, +0x0605040a,0x0a090807,0x100d0c0b,0x03070503, +0x1005040a,0x10070502,0x03030100,0x03030303, +0x03030303,0x03030303,0x03010100,0x03030301, +0x03030303,0x03030303,0x03010100,0x03030301, +0x03010100,0x04020000,0x08070605,0x0c0b0a09, +0x100f0e0d,0x02010000,0x06050403,0x0a090807, +0x100d0c0b,0x02010000,0x10050403,0x10010000, +0x00030000,0x00090005,0x001f000f,0x007f003f, +0x01ff00ff,0x07ff03ff,0x1fff0fff,0x7fff3fff, +0x00030000,0x00090005,0x001f000f,0x007f003f, +0x0a070504,0x07060504,0x0b0a0908,0x0f0e0d0c, +0x0a070503,0x07060504,0x01010100,0x03030303, +0x03030303,0x03030303,0x01010100,0x03030303, +0x03010000,0x07060504,0x0b0a0908,0x0f0e0d0c, +0x03010000,0x07060504,0x00555555,0x002aaaab, +0x00249249,0x00124925,0x00111111,0x00088889, +0x00084210,0x00421084,0x00041041,0x00020821, +0x00020408,0x00081020,0x00010101,0x00008081, +0x00008040,0x00100804,0x00004010,0x00020080, +0x00002004,0x00004008,0x00001001,0x00000801, +0x00000800,0x00200100,0x00000400,0x00080020, +0x00000200,0x00020004,0x00200000,0x00600040, +0x00a00080,0x00e000c0,0x01200100,0x01600140, +0x01a00180,0x000001c0,0x00300020,0x00400038, +0x00600050,0x00800070,0x00c000a0,0x010000e0, +0x01800140,0x00200000,0x00300028,0x00400038, +0x00600050,0x00800070,0x00c000a0,0x010000e0, +0x00000140,0x00900000,0x00fc00d8,0x01680120, +0x01f801b0,0x02d00240,0x03f00360,0x05a00480, +0x000006c0,0x00680000,0x00b6009c,0x010500d0, +0x016d0139,0x020a01a1,0x02db0272,0x04140343, +0x000004e5,0x006c0000,0x00bd00a2,0x010e00d8, +0x017a0144,0x006301b0,0x013b00cf,0x00c601a7, +0x0000019e,0x00600000,0x00a80090,0x00f000c0, +0x01500120,0x01e00180,0x02a00240,0x03c00300, +0x00000480,0x10000000,0x10101010,0x20101010, +0x20202020,0x20202020,0x28202020,0x28282828, +0x00002828,0x10100000,0x10101010,0x10101010, +0x00000000,0x00000000,0x00000000,0x00000000, +0xcbcecdc4,0xcfcac9c8,0xc3c6c5cc,0xc7c2c1c0, +0x1b1e1d14,0x1f1a1918,0x1316151c,0x17121110, +0x2b2e2d24,0x2f2a2928,0x2326252c,0x27222120, +0x3b3e3d34,0x3f3a3938,0x3336353c,0x37323130, +0x0b0e0d04,0x0f0a0908,0x0306050c,0x07020100, +0xdbdeddd4,0xdfdad9d8,0xd3d6d5dc,0xd7d2d1d0, +0xebeeede4,0xefeae9e8,0xe3e6e5ec,0xe7e2e1e0, +0xfbfefdf4,0xfffaf9f8,0xf3f6f5fc,0xf7f2f1f0, +0x4b4e4d44,0x4f4a4948,0x4346454c,0x47424140, +0x9b9e9d94,0x9f9a9998,0x9396959c,0x97929190, +0xabaeada4,0xafaaa9a8,0xa3a6a5ac,0xa7a2a1a0, +0xbbbebdb4,0xbfbab9b8,0xb3b6b5bc,0xb7b2b1b0, +0x8b8e8d84,0x8f8a8988,0x8386858c,0x87828180, +0x5b5e5d54,0x5f5a5958,0x5356555c,0x57525150, +0x6b6e6d64,0x6f6a6968,0x6366656c,0x67626160, +0x7b7e7d74,0x7f7a7978,0x7376757c,0x77727170, +0x341424c4,0x3e1e2ece,0x3d1d2dcd,0x3b1b2bcb, +0xb494a444,0xbe9eae4e,0xbd9dad4d,0xbb9bab4b, +0xf4d4e404,0xfedeee0e,0xfddded0d,0xfbdbeb0b, +0x74546484,0x7e5e6e8e,0x7d5d6d8d,0x7b5b6b8b, +0x3c1c2ccc,0x361626c6,0x351525c5,0x331323c3, +0xbc9cac4c,0xb696a646,0xb595a545,0xb393a343, +0xfcdcec0c,0xf6d6e606,0xf5d5e505,0xf3d3e303, +0x7c5c6c8c,0x76566686,0x75556585,0x73536383, +0x381828c8,0x3a1a2aca,0x391929c9,0x3f1f2fcf, +0xb898a848,0xba9aaa4a,0xb999a949,0xbf9faf4f, +0xf8d8e808,0xfadaea0a,0xf9d9e909,0xffdfef0f, +0x78586888,0x7a5a6a8a,0x79596989,0x7f5f6f8f, +0x301020c0,0x321222c2,0x311121c1,0x371727c7, +0xb090a040,0xb292a242,0xb191a141,0xb797a747, +0xf0d0e000,0xf2d2e202,0xf1d1e101,0xf7d7e707, +0x70506080,0x72526282,0x71516181,0x77576787, +0x05040100,0x15141110,0x25242120,0x35343130, +0x85848180,0x95949190,0xa5a4a1a0,0xb5b4b1b0, +0xc0408000,0xe060a020,0xd0509010,0xf070b030, +0xc8488808,0xe868a828,0xd8589818,0xf878b838, +0xc4448404,0xe464a424,0xd4549414,0xf474b434, +0xcc4c8c0c,0xec6cac2c,0xdc5c9c1c,0xfc7cbc3c, +0xc2428202,0xe262a222,0xd2529212,0xf272b232, +0xca4a8a0a,0xea6aaa2a,0xda5a9a1a,0xfa7aba3a, +0xc6468606,0xe666a626,0xd6569616,0xf676b636, +0xce4e8e0e,0xee6eae2e,0xde5e9e1e,0xfe7ebe3e, +0xc1418101,0xe161a121,0xd1519111,0xf171b131, +0xc9498909,0xe969a929,0xd9599919,0xf979b939, +0xc5458505,0xe565a525,0xd5559515,0xf575b535, +0xcd4d8d0d,0xed6dad2d,0xdd5d9d1d,0xfd7dbd3d, +0xc3438303,0xe363a323,0xd3539313,0xf373b333, +0xcb4b8b0b,0xeb6bab2b,0xdb5b9b1b,0xfb7bbb3b, +0xc7478707,0xe767a727,0xd7579717,0xf777b737, +0xcf4f8f0f,0xef6faf2f,0xdf5f9f1f,0xff7fbf3f, +0x1045a3e2,0x000000f4,0x263b7333,0x766b2363, +0x2b367e3e,0x7b662e6e,0x06db93d3,0x964b0343, +0x0bd69ede,0x9b460e4e,0x825f1757,0x12cf87c7, +0x8f521a5a,0x1fc28aca,0x00d199d9,0x90410949, +0x01d098d8,0x91400848,0x24357d3d,0x74652d6d, +0x25347c3c,0x75642c6c,0x04d59ddd,0x94450d4d, +0x05d49cdc,0x95440c4c,0x80511959,0x10c189c9, +0x81501858,0x11c088c8,0x02df97d7,0x924f0747, +0x0fd29ada,0x9f420a4a,0x865b1353,0x16cb83c3, +0x8b561e5e,0x1bc68ece,0xa6bbf3b3,0xf6eba3e3, +0xabb6febe,0xfbe6aeee,0x223f7737,0x726f2767, +0x2f327a3a,0x7f622a6a,0xa0b1f9b9,0xf0e1a9e9, +0xa1b0f8b8,0xf1e0a8e8,0x84551d5d,0x14c58dcd, +0x85541c5c,0x15c48ccc,0xa4b5fdbd,0xf4e5aded, +0xa5b4fcbc,0xf5e4acec,0x20317939,0x70612969, +0x21307838,0x71602868,0xa2bff7b7,0xf2efa7e7, +0xafb2faba,0xffe2aaea,0x00000000,0x00000000, + +}; + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/mpgi2s_240.h linux.19pre5-ac1/drivers/media/video/ls220/mpgi2s_240.h --- linux.19p5/drivers/media/video/ls220/mpgi2s_240.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/ls220/mpgi2s_240.h Thu Feb 21 21:27:50 2002 @@ -0,0 +1,1593 @@ +static u32 MPGI2S240Ucode1f1800[] = { +0x820f001f,0x802f001f,0xb500000d,0x00000000, +0x00ffb81e,0x00000000,0x00000000,0x00000000, +0x00ffb81e,0x00000000,0x00000000,0x00000000, +0xb5000b5b,0x00000000,0x00000000,0x00000000, +0x80070800,0x001f6047,0x8013001f,0x90208000, +0x003fb174,0x803effe8,0x803effec,0x9020fa00, +0x803effd0,0x803effdc,0x803effd8,0x9020fe00, +0x803effd4,0x805bff7c,0x802500d4,0x94020080, +0xb0000000,0xb4200023,0x8013ffcf,0x9800cfff, +0x80730030,0x98631000,0x94420007,0xb0020002, +0xb4200005,0x8013ffc7,0x9800c7ff,0x80730038, +0x98631000,0xb5000006,0xb0020001,0xb4200004, +0x8013ffcf,0x9800cfff,0x80730030,0x98631000, +0x1421b800,0x1821b803,0x802600d4,0x8033001f, +0x98210000,0x802600a2,0x8033001f,0x98210300, +0x802600a3,0x80270225,0x80530001,0x98420100, +0x1821b802,0x80530200,0x98420000,0x804600a6, +0xb500001d,0x805bff7c,0x8013ffcf,0x9800cfff, +0x80730030,0x98632000,0x94420007,0xb0020002, +0xb4200005,0x8013ffc7,0x9800c7ff,0x80730038, +0x98632800,0xb5000006,0xb0020001,0xb4200004, +0x8013ffcf,0x9800cfff,0x80730030,0x98632000, +0x1421b800,0x1821b803,0x802600d4,0x8033001f, +0x98210000,0x802600a2,0x8033001f,0x98210600, +0x802600a3,0x80270eff,0x802600a1,0x80270002, +0x803eff84,0x80070000,0x801effc0,0x801effc4, +0x801effc8,0x801effcc,0x801eff88,0x80770000, +0x8057ffff,0x80170080,0x80070000,0xb6003f02, +0xb6002001,0x001fa020,0x8007ffff,0x801eff84, +0x80070001,0x001f25dc,0x001f20b1,0x80070000, +0x001f6046,0x001fb17c,0x001fb17d,0x80070000, +0x801e78d0,0x98004000,0x001f62ea,0x80070100, +0x801efff0,0x81df0004,0x00000000,0x00000000, +0x801bfff0,0x00000000,0x940000ff,0xb0000000, +0xb4200057,0x003f42ea,0x94010010,0xb0000000, +0xb400fff7,0x003f05dc,0xb0010001,0xb4200034, +0x803bffe8,0x801bffec,0x00000000,0x3001b800, +0xb4600001,0x90214000,0x0421b800,0xb0010800, +0xb460000d,0x80050086,0x005f902e,0xb0020000, +0xb4200002,0x001fb02e,0xb5000006,0x0420b802, +0xb0010930,0xb4a0ffe2,0x80070000,0x001fb02e, +0x83e40146,0xb500ffde,0x83e40111,0x80070000, +0x001fb02e,0x001f42ea,0x9400000f,0xb0000000, +0xb4000010,0x9400fff0,0x001f62ea,0x003f9174, +0x9421ffff,0x90210004,0xb001c000,0xb4800002, +0x8421c000,0x90218000,0x8013001f,0x1821b800, +0x003fb174,0x003f917c,0x90210004,0x003fb17c, +0x83e4012e,0x8013001f,0x83e71b0c,0x1bffb800, +0x003f9179,0x1821b800,0x00ffb801,0xb5000008, +0x80270000,0x003f25dc,0x8013001f,0x83e71b30, +0x1bffb800,0x003f917a,0x1821b800,0x00ffb801, +0x80070000,0x001f20b1,0x001f42ea,0x9420000f, +0xb0010000,0xb4200003,0x98000800,0x001f62ea, +0xb500ffaf,0x9400fff0,0x001f62ea,0x80270000, +0x8057ffff,0x80770000,0x80171980,0xb6000602, +0xb6002001,0x001fa021,0xb500ffa5,0xb500ffa4, +0x803bffc0,0x805bffc4,0x807bffc8,0x809bffcc, +0x5828b801,0x5cb8b802,0x1821b805,0x5848b802, +0x5cb8b803,0x1842b805,0x5868b803,0x5cb8b804, +0x1863b805,0x5888b804,0x1884b800,0x803effc0, +0x805effc4,0x807effc8,0x809effcc,0x003f42ea, +0xb0000086,0xb4400079,0xb0000084,0xb4000049, +0xb0000085,0xb4000063,0xb0000086,0xb400006c, +0xb0000081,0xb4000005,0xb0000082,0xb4000003, +0xb0000080,0xb4000001,0xb5000069,0x8013007f, +0x9800ffff,0x001fb02d,0x80070000,0x001fb17c, +0x8013001f,0x9040fa00,0x805effd0,0x805effdc, +0x805effd8,0x9040fe00,0x805effd4,0x9040c000, +0x805effe4,0x90008000,0x801effe0,0x001fb174, +0x801effe8,0x801effec,0x80078000,0x801e78d4, +0x80070000,0x001fb17c,0x001fb17d,0x001fb02e, +0x83e400ce,0x8013001f,0x98000000,0x800600a2, +0x8013001f,0x98000600,0x800600a3,0x805bff7c, +0x80070eff,0x94420080,0xb0020080,0xb420000d, +0x8013001f,0x98000000,0x800600a2,0x8013001f, +0x98000300,0x800600a3,0x80070225,0x80530001, +0x98420100,0x1800b802,0x80530200,0x98420000, +0x804600a6,0x800600a1,0x80050080,0x98000022, +0x80060080,0x80072000,0x001fb179,0x80074360, +0x001fb17a,0x80070001,0x001f25dc,0x98214000, +0xb5000029,0x8047ffff,0x805eff84,0x805bff88, +0x00000000,0xb0020001,0xb4200002,0x80470000, +0x805eff88,0x805bff7c,0x80070eff,0x94420080, +0xb0020080,0xb4200007,0x80070225,0x80530001, +0x98420100,0x1800b802,0x80530200,0x98420000, +0x804600a6,0x800600a1,0x80070001,0x800600a0, +0x9421efff,0x98210010,0xb500000f,0x80070000, +0x001fb17c,0x80070001,0x001f25dc,0x83e4008b, +0x80050081,0x80330008,0x98210000,0x1800b801, +0x80060081,0x003f42ea,0x9421ffef,0xb5000002, +0x98211000,0x9421ffef,0x83e40080,0x003f62ea, +0x80070100,0x801efff0,0xb500ff15,0xb000008b, +0xb400001c,0xb0000087,0xb400ffe8,0xb0000088, +0xb4000023,0xb000008a,0xb4000024,0xb000008c, +0xb4000019,0xb000008e,0xb4000014,0xb000008d, +0xb400001d,0xb0000089,0xb400001f,0xb00000a0, +0xb4000021,0xb00000a1,0xb4000022,0xb00000a2, +0xb400002b,0xb00000a3,0xb4000027,0xb00000a4, +0xb4000029,0xb00000a5,0xb4000029,0xb00000a6, +0xb4000029,0x803efff8,0xb500ffdd,0x80070000, +0x001fb17e,0xb500ffda,0x803bffb0,0x00000000, +0x003fb02d,0xb500ffd6,0x98210020,0xb500ffd2, +0x9421ffdf,0xb500ffd0,0xb500ffd1,0x80270351, +0x803efff8,0xb500ffce,0x803bff80,0x00000000, +0x003f62ef,0xb500ffca,0x003f917b,0x803efff8, +0xb500ffc7,0x80270000,0x8047fef0,0x003eb802, +0x90420004,0x003eb802,0x90420004,0x003eb802, +0x90420004,0x003eb802,0x83640d78,0xb500ffbc, +0x83640d26,0xb500ffba,0x83640ce5,0xb500ffb8, +0x83440c4c,0xb500ffb6,0x83440c35,0xb500ffb4, +0x817bffe8,0x815b78d4,0x00000000,0x956bffff, +0x300bb80a,0xb4600001,0x916b4000,0x056bb80a, +0xb00b0080,0xb4a00026,0x80af001f,0x808f0000, +0x806f0000,0x81b300ff,0x8057ffff,0x5d67b80b, +0x5d42b80a,0xb62b001c,0xb00a3000,0xb4800001, +0x854a1000,0x80cf0400,0x015fb178,0x5942b80a, +0x01cfb80a,0x015f9178,0xb520ffff,0x80171000, +0xb600200a,0x01ff8000,0x5a18b80f,0x5a28b80f, +0x1631b80d,0x5e48b80f,0x9652ff00,0x5e78b80f, +0x1a73b810,0x1a73b811,0x1813a032,0x80cf0400, +0x015fb178,0x5942b80a,0x01afb80a,0x015f9178, +0xb520ffff,0x914a0020,0x5942b80a,0x815e78d4, +0x00000000,0x00000000,0x00ffb81f,0x80070000, +0x80470000,0x81171800,0xb6002003,0xb6003002, +0x001eb802,0x90420004,0xb6002003,0x011fa020, +0x011fa020,0x011fa020,0x00ffb81f,0x80070000, +0x80478000,0xb6002003,0xb6008002,0x001eb802, +0x90420004,0x00ffb81f,0x00000000,0x00000000, +0x015f42ea,0x944a4000,0xb0024000,0xb4200071, +0x954abfff,0x015f62ea,0x808f0000,0x80ef007c, +0x80171000,0x80971400,0x80270000,0xb6001003, +0xb6002002,0x001fa021,0x009fa021,0x80a76604, +0x80271400,0xb6001004,0x01efb801,0x01afb805, +0xb520ffff,0x90a50080,0x80a76e04,0x80271400, +0xb6001004,0x01efb801,0x01afb805,0xb520ffff, +0x90a50080,0x806f001f,0x80af001f,0x80276400, +0x5c22b801,0x806701e1,0x00cfb803,0x003fb178, +0x5822b801,0x01cfb801,0x003f9178,0x0047b86f, +0xb0020001,0xb4c0fffd,0x80275c00,0x5c22b801, +0x80670200,0xb600100a,0x00cfb803,0x003fb178, +0x5822b801,0x01cfb801,0x003f9178,0x0047b86f, +0xb0020001,0xb4c0fffd,0x90210020,0x90630020, +0x808f0000,0x806f001f,0x80af001f,0x8027647c, +0x5c22b801,0x8067017e,0xb600020a,0x00cfb803, +0x003fb178,0x5822b801,0x01cfb801,0x003f9178, +0x0047b86f,0xb0020001,0xb4c0fffd,0x90210020, +0x90630020,0x806f0010,0x80af0010,0x8027657c, +0x5c22b801,0x806701be,0x00cfb803,0x003fb178, +0x5822b801,0x01cfb801,0x003f9178,0x0047b86f, +0xb0020001,0xb4c0fffd,0x802765c0,0x5c22b801, +0x806701cf,0x00cfb803,0x003fb178,0x5822b801, +0x01cfb801,0x003f9178,0x0047b86f,0xb0020001, +0xb4c0fffd,0x80276000,0x005fb801,0x8033001f, +0x98218000,0x803effe0,0x90214000,0x803effe4, +0x8193001f,0x998c8000,0x019fb174,0x83270000, +0x003fb819,0x003f9174,0x5823b801,0x83338000, +0x1b39b801,0x003fb819,0x00000000,0x00000000, +0x81550000,0x0187b860,0x858c0040,0x81b380fc, +0x99ad0000,0x300cb80d,0xb4600003,0x81b30002, +0x99ad0000,0x118cb80d,0x003fb80c,0x00000000, +0x00000000,0x81550000,0x8257ffff,0x82d7ffff, +0x8357ffff,0x81672000,0x83440189,0xb00a0001, +0xb4000141,0x0187b860,0x858c0010,0x5988b80c, +0x5d8bb80c,0x958cffff,0xb00cc000,0xb4800002, +0x858cc000,0x918c8000,0x81b3001f,0x198cb80d, +0x801bffec,0x00000000,0x819effec,0x819e78d8, +0x019fb174,0x05acb800,0x300cb800,0xb4600001, +0x91ad4000,0x001f917c,0x1000b80d,0x001fb17c, +0x83440194,0xb00a0000,0xb4200127,0x015f0081, +0xb00a0002,0xb4200124,0x037f0082,0xb01b0000, +0xb400001e,0x0367b860,0x5b68b81b,0x5f68b81b, +0x017f4047,0x916b0010,0x5963b80b,0x83440160, +0x801bff84,0xb00a0001,0xb400000b,0xb00b00c0, +0xb460fffa,0x803f0000,0x80138000,0x1b7bb800, +0x003fb81b,0x00000000,0x00000000,0x80150000, +0x801bff84,0xb5000009,0x803f0000,0x80138000, +0x1b7bb800,0x003fb81b,0x00000000,0x00000000, +0x80150000,0x801bff84,0xb5000103,0x801bff84, +0x003f0084,0x3000b801,0x803eff84,0xb4000073, +0x801bff7c,0x00000000,0x94800080,0xb0040080, +0xb4200036,0x94800007,0x80730200,0xb0010002, +0xb420000e,0x80270265,0xb0040001,0xb4200003, +0x80130030,0x98000000,0xb5000006,0x80130030, +0x98000000,0xb0040000,0xb4000002,0x80130038, +0x98000000,0x98630060,0xb500001f,0xb0010000, +0xb420000e,0x80270225,0xb0040001,0xb4200003, +0x80130030,0x98001000,0xb5000006,0x80130030, +0x98001000,0xb0040000,0xb4000002,0x80130038, +0x98001000,0x98630000,0xb500000f,0xb0010001, +0xb420004a,0x80270225,0xb0040001,0xb4200003, +0x80130030,0x98002000,0xb5000006,0x80130030, +0x98000000,0xb0040000,0xb4000002,0x80130038, +0x98000000,0x98630040,0x806600a6,0x80530001, +0x98420100,0x1821b802,0xb500002d,0x94800007, +0xb0010002,0xb420000d,0x80270eff,0xb0040001, +0xb4200003,0x80130030,0x98002000,0xb5000006, +0x80130030,0x98000000,0xb0040000,0xb4000002, +0x80130038,0x98000000,0xb500001d,0xb0010000, +0xb420000d,0x80270eff,0xb0040001,0xb4200003, +0x80130030,0x98002000,0xb5000006,0x80130030, +0x98002000,0xb0040000,0xb4000002,0x80130038, +0x98002800,0xb500000e,0xb0010001,0xb4200017, +0x80270eff,0xb0040001,0xb4200003,0x80130030, +0x98002000,0xb5000006,0x80130030,0x98002000, +0xb0040000,0xb4000002,0x80130038,0x98002800, +0x806500d4,0x8053ffcf,0x9842cfff,0xb0040002, +0xb4200002,0x8053ffc7,0x9842c7ff,0x802600a1, +0x1463b802,0x1863b800,0x806600d4,0x807bff7c, +0x00000000,0x94630080,0xb0030080,0xb420000b, +0x807bff88,0x00000000,0xb0030001,0xb4000007, +0x802500a1,0x80670001,0x807eff88,0x80530001, +0x98420100,0x1821b802,0x802600a1,0x81070000, +0x011f62e2,0x011f62e3,0x011f0082,0xb0080000, +0xb4200004,0x81150010,0x00000000,0x00000000, +0x011f62de,0x011f0081,0xb0080001,0xb4200026, +0x81070020,0x011f25c1,0x81070180,0x011f62e1, +0x8344022a,0x8344024e,0x011f0082,0xb0080000, +0xb4200004,0x834401b1,0x8344019e,0xb00a0000, +0xb4200061,0x80c70000,0x00df25cb,0x83440261, +0x834405e7,0x02ff05b9,0x82a70000,0x82870000, +0x834403cf,0x92940001,0x3014b817,0xb480fffc, +0x8344067f,0x80270000,0x003f25dc,0x83440760, +0x003f05dc,0xb0010001,0xb4000003,0x802725d4, +0x003fb17a,0x00ffb81f,0x80d3001f,0x834725ac, +0x1b5ab806,0xb500002d,0xb0080002,0x81470004, +0xb4200045,0x81070008,0x011f25c1,0x81070480, +0x011f62e1,0x83440276,0x834402b0,0x011f0082, +0xb0080000,0xb4200004,0x8344019a,0x83440175, +0xb00a0000,0xb4200038,0x80c70000,0x00df25cb, +0x83440334,0x02df05cb,0x5ec2b816,0x834405ff, +0x02ff05b9,0x82a70000,0x82870000,0x834403a4, +0x92940001,0x3014b817,0xb480fffc,0x92b50001, +0xb0150003,0xb480fff8,0x83440651,0x80270000, +0x003f25dc,0x83440732,0x003f05dc,0xb0010001, +0xb4000003,0x8027268c,0x003fb17a,0x00ffb81f, +0x80d3001f,0x83472650,0x1b5ab806,0x80db78d8, +0x80fbffec,0x00000000,0x3006b807,0xb4200007, +0x00df05cb,0x90c60001,0x00df25cb,0xb006000c, +0xb4000002,0x035fb179,0x00ffb81f,0x80c70000, +0x00df25cb,0x80fb78dc,0x00000000,0x90e70001, +0xb00701b9,0xb4a00001,0x80e70001,0x80fe78dc, +0xb500feb0,0x802500a5,0x8153001f,0x3001b80a, +0xb420fffc,0x00ffb81f,0x001f42ea,0x1800b80a, +0x001f62ea,0x017f4047,0x5963b80b,0x0187b860, +0x118cb80b,0x81b380fe,0x99ad0000,0x300cb80d, +0xb4800003,0x81b30002,0x99ad0000,0x058cb80d, +0x003fb80c,0x00000000,0x00000000,0x81550000, +0x0187b860,0x5988b80c,0x5d8bb80c,0x958cffff, +0xb00cc000,0xb4800002,0x858cc000,0x918c8000, +0x81b3001f,0x198cb80d,0x801bffec,0x00000000, +0x819effec,0x019fb174,0x05acb800,0x300cb800, +0xb4600001,0x91ad4000,0x001f917c,0x1000b80d, +0x001fb17c,0x80171000,0x80971400,0x80270000, +0xb6001003,0xb6002002,0x001fa021,0x009fa021, +0x80171800,0xb6000602,0xb6002001,0x001fa021, +0x806f001f,0x80af001f,0x80a76604,0x80271400, +0xb6001004,0x01efb801,0x01afb805,0xb520ffff, +0x90a50080,0x80a76e04,0x80271400,0xb6001004, +0x01efb801,0x01afb805,0xb520ffff,0x90a50080, +0x81472000,0x015fb179,0x00ffb81f,0x00000000, +0x811be024,0x0107b860,0x95080007,0xb0080000, +0xb4000004,0xa5080008,0x00000000,0x0155b808, +0x00000000,0x8115000c,0x856b000c,0xb0080fff, +0xb400000b,0x81550004,0x856b0004,0x5904b808, +0x1908b80a,0x95080fff,0xb0080fff,0xb4000004, +0x81470001,0xb00b0020,0xb440fff6,0xb500000c, +0x81d50004,0x856b0004,0x00000000,0xb00e000f, +0xb400fffb,0x940b0007,0xb0000000,0xb420ffed, +0x001f42ea,0x9400fffe,0x81470000,0x001f62ea, +0x00ffb81a,0x950e0008,0x5d03b808,0x00000000, +0xb0080000,0xb40000c9,0x011f2080,0x950e0006, +0x5d01b808,0x81270004,0x0529b808,0x950e0001, +0x013f2081,0x011f2082,0x81150004,0x00000000, +0xb0080000,0xb40000bd,0xb008000f,0xb40000bb, +0x011f2083,0x81150002,0x00000000,0x81670004, +0xb0080002,0xb46000b5,0x011f2084,0x013f0081, +0xb0090002,0xb4200011,0x013f0083,0xb0080000, +0xb4200002,0x81077844,0xb5000005,0xb0080001, +0xb4200002,0x81077884,0xb5000001,0x81077824, +0x013f0083,0x5921b809,0x1129b808,0x0119b809, +0x00000000,0x00000000,0x011f6047,0x81150001, +0x00000000,0x011f2085,0x81150001,0x00000000, +0x011f2086,0x81350002,0x00000000,0x013f2087, +0x81150002,0x00000000,0x011f2088,0x81150001, +0x00000000,0x011f2089,0x81150001,0x00000000, +0x011f208a,0x81150002,0x00000000,0x011f208b, +0x81070001,0xb0090003,0xb4000001,0x81070002, +0x011f25b9,0x81070020,0x013f0081,0xb0090002, +0xb4200065,0x85290001,0xad29000f,0x00000000, +0x011f0083,0x1108b809,0x5901b808,0x910877c8, +0x0139b808,0x011f05b9,0x85080001,0x6928b809, +0x011f0084,0xb0090038,0xb4800007,0xb0080001, +0xb4000002,0xb0090050,0xb4400003,0x81270000, +0x8107001b,0xb5000010,0xb0080001,0xb4000005, +0xb0090060,0xb4800003,0x81270001,0x8107001e, +0xb5000009,0xb0080002,0xb4000005,0xb0090030, +0xb4400003,0x81270002,0x81070008,0xb5000002, +0x81270003,0x8107000c,0x011f25bb,0x013f25c0, +0xb0090002,0xb460001b,0x80477604,0x5c42b802, +0x814fffc0,0x80cf0037,0x005fb178,0x5842b802, +0x01cfb802,0x005f9178,0xb520ffff,0x90420020, +0x814fb580,0x80cf0057,0x005fb178,0x5842b802, +0x01cfb802,0x005f9178,0xb520ffff,0x804778a4, +0x5c42b802,0x814f39c0,0x80cf002f,0x005fb178, +0x5842b802,0x01cfb802,0x005f9178,0xb520ffff, +0xb5000021,0x804776e0,0x5c42b802,0x814fef40, +0x80cf0037,0x005fb178,0x5842b802,0x01cfb802, +0x005f9178,0xb520ffff,0x8297013c,0x8317018c, +0xb6000602,0x005f8034,0x031fa022,0x82970124, +0x83170160,0xb6000602,0x005f8034,0x031fa022, +0x8297010c,0x83170134,0xb6000602,0x005f8034, +0x031fa022,0x804778c4,0x5c42b802,0x814f1080, +0x80cf002f,0x005fb178,0x5842b802,0x01cfb802, +0x005f9178,0xb520ffff,0x013f0081,0xb0090001, +0xb420000e,0x808f0000,0x806f001b,0x80af001b, +0x80277758,0x5c22b801,0x80670037,0x00cfb803, +0x003fb178,0x5822b801,0x01cfb801,0x003f9178, +0x0047b86f,0xb0020001,0xb4c0fffd,0x011f25bb, +0x011f0087,0xb0080001,0xb4000002,0x011f05bb, +0xb5000003,0x011f0088,0x91080001,0x5902b808, +0x011f25ba,0x81470000,0x00ffb81a,0x81470008, +0x00ffb81a,0x81270000,0x81470000,0x300842de, +0xb400000b,0x013f42e2,0x91290001,0x013f62e2, +0x013f42e3,0x91290001,0x013f62e3,0x83640006, +0x00000000,0x00000000,0x013f42e2,0x81470002, +0x013f62e2,0x00ffb81a,0x00ffb81b,0x83640041, +0x80c70004,0x80270000,0xb600200d,0x00ff05b9, +0x5c42b801,0x300205ba,0xb4800001,0x80e70001, +0x80470000,0xb6270005,0x1062b801,0x914301b8, +0x00fff00a,0x83840050,0x90420080,0x90210004, +0x00ffb81a,0x8364002f,0x017f05bb,0x800700bc, +0x80270000,0xb00b0000,0xb4000015,0xb62b0014, +0x00ff05b9,0x5c42b801,0x300205ba,0xb4800001, +0x80e70001,0x80470000,0xb0070000,0xb400000b, +0xb627000a,0x1062b801,0x914301b8,0x00fff00a, +0x5c62b801,0x1063b800,0x00bff003,0x90650134, +0x00dff003,0x83840034,0x90420080,0x90210004, +0x019f05b9,0x80c70002,0x80270000,0xb00b0000, +0xb400000f,0xb62b000e,0x80470000,0xb00c0000, +0xb400000a,0xb62c0009,0x1062b801,0x914301b8, +0x00fff00a,0xb0070000,0xb4000003,0x906302b8, +0x00fff003,0x83840020,0x90420080,0x90210004, +0x00ffb81a,0x8107ffff,0x80c70004,0x00ff0083, +0x83840019,0x80c70002,0x00ff0084,0x83840016, +0x80c70001,0x00ff0085,0x83840013,0x80c70001, +0x00ff0086,0x83840010,0x80c70002,0x00ff0087, +0x8384000d,0x80c70002,0x00ff0088,0x8384000a, +0x80c70001,0x00ff0089,0x83840007,0x80c70001, +0x00ff008a,0x83840004,0x80c70002,0x00ff008b, +0x83840001,0x00ffb81b,0x80a70001,0x64a6b805, +0x5ca1b805,0xb0050000,0xb400000e,0x95288000, +0xb0090000,0xb4000001,0x81270001,0x5901b808, +0x1547b805,0xb00a0000,0xb4000001,0x81470001, +0x2129b80a,0xb0090000,0xb4000001,0xa1088005, +0xb500ffef,0x9508ffff,0x00ffb81c,0x015f05ba, +0x013f05b9,0x800700bc,0xb0090000,0xb400000f, +0xb00a0000,0xb400000d,0x80270000,0xb62a000b, +0x80470000,0xb6290008,0x80950004,0x5865b802, +0x1063b801,0x5862b803,0x906301b8,0x0217b803, +0x90420001,0x021fa004,0x90210001,0xa54a0020, +0xb4c0000e,0xb0090000,0xb400000c,0xb62a000b, +0x80950004,0x80470000,0xb6290007,0x5865b802, +0x1063b801,0x5862b803,0x906301b8,0x0217b803, +0x90420001,0x021fa004,0x90210001,0x00ffb81a, +0x013f05b9,0xb0090000,0xb4000019,0x80270000, +0xb6002017,0x80470000,0xb6290014,0x5865b802, +0x1063b801,0x5862b803,0x914301b8,0x009ff00a, +0xad420060,0x00000000,0x114ab801,0x5942b80a, +0x914a1c80,0x0217b80a,0xb0040000,0xb4000004, +0x80950006,0x00000000,0x021fa004,0xb5000002, +0x8087003f,0x021fa004,0x90420001,0x90210001, +0x00ffb81a,0x8257ffff,0x82d7ffff,0x011f05ba, +0x013f05b9,0x80270000,0xb0090000,0xb400002b, +0xb6280015,0x80470000,0xb6290012,0x5865b802, +0x1063b801,0x5862b803,0x914301b8,0xaca20060, +0x009ff00a,0x10a5b801,0x58a2b805,0x90a502b8, +0x0217b805,0x80670000,0xb0040000,0xb4000003, +0x90840001,0x0075b804,0x00000000,0x021fa003, +0x90420001,0x90210001,0xa5480020,0xb4000013, +0x5822b801,0xb62a0011,0x914101b8,0x90a102b8, +0x0217b805,0x009ff00a,0xb0040000,0x80670000, +0xb4000002,0x90840001,0x0075b804,0xb6290006, +0x021fa203,0x009f8210,0x009f8210,0x009f8210, +0x009f8210,0x009f8210,0x90210004,0x00ffb81a, +0x015f05ba,0x013f05b9,0x800700bc,0xb0090000, +0xb4000013,0xb00a0000,0xb4000011,0x80270000, +0xb62a000f,0x80470000,0xb629000c,0x1080b801, +0x007ff004,0x90830134,0x007ff004,0x0095b803, +0x5865b802,0x1063b801,0x5862b803,0x906301b8, +0x0217b803,0x90420001,0x021fa004,0x90210001, +0x011f05bb,0x254ab808,0xb4c0000d,0xb62a000c, +0x1080b801,0x007ff004,0x90830134,0x007ff004, +0x0095b803,0x5862b801,0x906301b8,0x0217b803, +0x90210001,0x021fa204,0x007f8210,0x021fa004, +0xa5480020,0xb4c0000e,0xb0090000,0xb400000c, +0x80870000,0xb62a000a,0x80470000,0xb6290007, +0x5865b802,0x1063b801,0x5862b803,0x906301b8, +0x0217b803,0x90420001,0x021fa004,0x90210001, +0x00000000,0x00000000,0x00ffb81a,0x011f05bb, +0x013f05b9,0xb0080000,0xb4000015,0xb0090000, +0xb4000013,0x00000000,0x80270000,0xb6280010, +0x80470000,0xb629000d,0x5865b802,0x1063b801, +0x5862b803,0x914301b8,0x009ff00a,0xb0040000, +0xb4000005,0x80950002,0x906302b8,0x0217b803, +0x00000000,0x021fa004,0x90420001,0x90210001, +0xa5480020,0xb00a0000,0xb4000010,0xb0090000, +0xb400000e,0x00000000,0x80870000,0xb62a000b, +0x80470000,0xb6290008,0x5865b802,0x1063b801, +0x5862b803,0x906302b8,0x0217b803,0x00000000, +0x021fa004,0x90420001,0x90210001,0xb0080000, +0xb400004c,0xb0090000,0xb400004a,0x00000000, +0x80270000,0xb6280047,0x80470000,0xb6290044, +0x5865b802,0x1063b801,0x5862b803,0x914301b8, +0x009ff00a,0xad420060,0x00000000,0x00000000, +0x00000000,0x114ab801,0x5942b80a,0x914a1c80, +0x0217b80a,0xb0040000,0xb400002e,0x906302b8, +0x009ff003,0xb0040000,0xb420000a,0x80950006, +0x00000000,0x021fa204,0x80950006,0x015f8210, +0x021fa204,0x80950006,0x015f8210,0x021fa004, +0xb5000026,0xb0040001,0xb4200009,0x80950006, +0x00000000,0x021fa204,0x015f8210,0x021fa204, +0x80950006,0x015f8210,0x021fa004,0xb500001b, +0xb0040003,0xb4200009,0x80950006,0x00000000, +0x021fa204,0x80950006,0x015f8210,0x021fa204, +0x015f8210,0x021fa004,0xb5000010,0xb0040002, +0xb420000e,0x80950006,0x00000000,0x021fa204, +0x015f8210,0x021fa204,0x015f8210,0x021fa004, +0xb5000006,0x8087003f,0x021fa204,0x015f8210, +0x021fa204,0x015f8210,0x021fa004,0x90420001, +0x90210001,0xa5480020,0xb4c00011,0xb0090000, +0xb400000f,0x8087003f,0x5862b801,0x90631afc, +0xb62a000b,0x90630004,0x0047b803,0xb6290008, +0x90420180,0x0217b802,0x00000000,0x021fa204, +0x003f8210,0x021fa204,0x003f8210,0x021fa004, +0x00ffb81a,0x8257ffff,0x82d7ffff,0x011f05bb, +0x013f05b9,0x80270000,0x00e7b809,0x300105ba, +0xb4800001,0x80e70001,0x800700bc,0x80470000, +0xb0070000,0xb400004c,0xb627004b,0x5865b802, +0x1063b801,0x5862b803,0x914301b8,0xaca20060, +0x009ff00a,0x10a5b801,0x58a2b805,0x90a502b8, +0x0217b805,0xb0040000,0xb400002b,0x1060b801, +0x00bff003,0x10a5b804,0x90650160,0x00dff003, +0xb0060003,0xb4200007,0x90650134,0x00dff003, +0xb6000303,0x0075b806,0x021fa203,0x007f8210, +0xb5000021,0x5861b805,0x906300dc,0x009fd803, +0x90650134,0x00dff003,0xaca20060,0x00000000, +0x00000000,0x00000000,0x0075b806,0x10a5b801, +0x58a2b805,0x90a502b8,0x0217b805,0x588fb804, +0xb600030c,0xb6001007,0x04a3b804,0xb4600002, +0x58a1b803,0xb5000002,0x58a1b805,0x90a50001, +0x0067b805,0x9465ffff,0x5d50b805,0x021fa20a, +0x015f8210,0xb5000004,0x81470000,0xb6000302, +0x021fa20a,0x009f8210,0x009f05b9,0xb0040002, +0xb420000c,0x300105ba,0xb480000a,0x58a2b801, +0x90a502b8,0x0217b805,0x90a50180,0x0297b805, +0xb6000304,0x00bf8210,0x009f8210,0x029fa205, +0x009f8214,0x90420001,0x90210001,0x3001b808, +0xb480ffa9,0xa5480020,0xb00a0000,0xb4000015, +0xb0090000,0xb4000013,0x58a2b801,0x90a502b8, +0xb62a0010,0x80470000,0xb629000d,0xaca20060, +0x00000000,0x00000000,0x00000000,0x80670000, +0x10a5b801,0x58a2b805,0x90a502b8,0x0217b805, +0xb6000302,0x021fa203,0x00bf8210,0x90420001, +0x90210001,0x00ffb81a,0x00000000,0x00000000, +0x80770000,0x8057ffff,0x80f70000,0x80d7ffff, +0x81770000,0x8157ffff,0x81f70000,0x81d7ffff, +0xac140060,0xac350020,0x00000000,0x00000000, +0x12c0b801,0x5ac2b816,0x92d61980,0x83a400a5, +0xad940400,0x009f9173,0x013f05ca,0x914c6604, +0x114ab804,0x001f97e0,0x001eb80a,0xb0090000, +0xb4000003,0x80a76e44,0x80c76644,0xb5000002, +0x80a76644,0x80c76e44,0x808f000f,0x806f0000, +0x80af000e,0x80cf07e1,0x11e5b80c,0x11efb804, +0x5de2b80f,0x01ffb178,0x59e2b80f,0x01afb80f, +0x01ff9178,0x0047b86f,0xb0020001,0xb4c0fffd, +0x80cf07f0,0x1206b80c,0x1210b804,0x5e02b810, +0x021fb178,0x5a02b810,0x01afb810,0x021f9178, +0x0047b86f,0xb0020001,0xb4c0fffd,0x916c6e04, +0x116bb804,0x001f97ff,0x001eb80b,0x808f0000, +0x806f001f,0x80af001f,0x90ac6604,0x5ca2b805, +0x80270400,0xb600080a,0x00cfb801,0x00bfb178, +0x58a2b805,0x01cfb805,0x00bf9178,0x0047b86f, +0xb0020001,0xb4c0fffd,0x90210020,0x90a50020, +0x90ac6e04,0x5ca2b805,0x80270500,0xb600080a, +0x00cfb801,0x00bfb178,0x58a2b805,0x01cfb805, +0x00bf9178,0x0047b86f,0xb0020001,0xb4c0fffd, +0x90210020,0x90a50020,0x81530020,0xac140060, +0xac350020,0x80170800,0x80d7003c,0x12c0b801, +0x5ac2b816,0x92d602b8,0x0117b816,0x90241000, +0x0097b801,0x80470000,0x4002b803,0xb6000804, +0x005f8020,0x480287e4,0x005f8020,0x500287e4, +0x00000000,0x00000000,0x00000000,0x1021b80a, +0x5c36b801,0x5801b800,0x18c0b801,0xb0090000, +0xb4000002,0x90641440,0xb5000001,0x90641040, +0xb6000f0d,0x0097b803,0x80470000,0x4002b803, +0xb6001002,0x005f8020,0x480287e4,0x0108a026, +0x90630040,0x00000000,0x1021b80a,0x5c36b801, +0x5801b800,0x18c0b801,0x90641400,0x0097b803, +0x80470000,0x4002b803,0x005f8020,0x005f87e4, +0xb6000802,0x005f8040,0x480287c4,0x005f87e0, +0x0108a026,0x00000000,0x1021b80a,0x5c36b801, +0x5801b800,0x18c0b801,0xb0090000,0xb4000002, +0x906417c0,0xb5000001,0x906413c0,0xb6000f0f, +0x0097b803,0x80470000,0x4002b803,0xb6000804, +0x005f8020,0x500287e4,0x005f8020,0x480287e4, +0x0108a026,0x84630040,0x00000000,0x1021b80a, +0x5c36b801,0x5801b800,0x18c0b801,0xb0140000, +0xb4200005,0x90840004,0x9484003f,0x009fb173, +0xa1290001,0x013f25ca,0x80d7ffff,0x0108a026, +0x00ffb81a,0x81330004,0x8093007f,0x9884ffff, +0x80b3ff80,0x0017b816,0x90360040,0x0097b801, +0x81530010,0xb6001004,0x400a8000,0x404a8004, +0x0008a020,0x0088a022,0x0017b816,0x9036007c, +0x0097b801,0x81171000,0xb6001004,0x40048020, +0x480487e4,0x00000000,0x0108a020,0x81470000, +0x81670001,0x81870008,0x81a70040,0x81c707c4, +0x81e70040,0xb6000432,0xb00a0001,0xb4e00004, +0x80c71000,0x80e71000,0x81171040,0xb5000003, +0x80c71040,0x80e71040,0x81171000,0x844d0004, +0x10e7b802,0xb62b001f,0x0017b806,0x0097b807, +0xb62c0004,0x40048020,0x480487e4,0x00000000, +0x0108a020,0x0017b806,0x0097b807,0x0197b80e, +0x00000000,0x001f8020,0x042087e4,0xb62c000f, +0x4041800c,0x001f8020,0x0048b802,0x5e38802c, +0x2e11b801,0x042087e4,0x1042b810,0x0462b804, +0xb4a00002,0x0047b804,0xb5000003,0x0462b805, +0xb4600001,0x0047b805,0x011fa022,0x10c6b80f, +0x10e7b80f,0x5961b80b,0x5d81b80c,0x5da1b80d, +0x5de1b80f,0x914a0001,0x954a0001,0x11ceb80f, +0x80171018,0x81171fcc,0x80470000,0x41448020, +0x494487c0,0x00000000,0x0188b80a,0x494487e0, +0x00000000,0x0148b80a,0x0502a10a,0x4145b80c, +0x494580e0,0x00000000,0x0108a5ea,0x41448080, +0x494487c0,0x00000000,0x0108a78a,0x49448020, +0x00000000,0x0108a2ea,0x41448020,0x49448720, +0x00000000,0x0188b80a,0x4145b80c,0x49458080, +0x494587a0,0x00000000,0x0108a68a,0x4145b80c, +0x49458080,0x494587a0,0x00000000,0x0108a08a, +0x4145b80c,0x49458020,0x49458040,0x00000000, +0x0188b80a,0x494587e0,0x00000000,0x0108a08a, +0x4144b80c,0x494587a0,0x00000000,0x0108a52a, +0x41448080,0x49448040,0x494486c0,0x00000000, +0x0108a04a,0x41448040,0x49448720,0x00000000, +0x0108a36a,0x04028020,0x011fa420,0x001f8040, +0x011fa100,0x001f8080,0x011fa080,0x001f8100, +0x011fa040,0x001f8660,0x011fa120,0x41458020, +0x49458000,0x00000000,0x0108a00a,0x0017b816, +0x9036007c,0x0097b801,0x81171000,0x81970784, +0x00000000,0x001f8020,0x042087e4,0xb600100f, +0x4041800c,0x001f8020,0x0048b802,0x5e38802c, +0x2e11b801,0x042087e4,0x1042b810,0x0462b804, +0xb4a00002,0x0047b804,0xb5000003,0x0462b805, +0xb4600001,0x0047b805,0x011fa022,0x81470000, +0x81670001,0x81870008,0x81a70040,0x81c707c4, +0x81e70040,0xb6000432,0xb00a0001,0xb4e00004, +0x80c71000,0x80e71000,0x81171040,0xb5000003, +0x80c71040,0x80e71040,0x81171000,0x844d0004, +0x10e7b802,0xb62b001f,0x0017b806,0x0097b807, +0xb62c0004,0x40048020,0x480487e4,0x00000000, +0x0108a020,0x0017b806,0x0097b807,0x0197b80e, +0x00000000,0x001f8020,0x042087e4,0xb62c000f, +0x4041800c,0x001f8020,0x0048b802,0x5e38802c, +0x2e11b801,0x042087e4,0x1042b810,0x0462b804, +0xb4a00002,0x0047b804,0xb5000003,0x0462b805, +0xb4600001,0x0047b805,0x011fa022,0x10c6b80f, +0x10e7b80f,0x5961b80b,0x5d81b80c,0x5da1b80d, +0x5de1b80f,0x914a0001,0x954a0001,0x11ceb80f, +0x80171034,0x81171f84,0x80470000,0x41448040, +0x49448640,0x00000000,0x0188b80a,0x49448100, +0x49448780,0x00000000,0x0108a08a,0x4144b80c, +0x49448040,0x49448080,0x494487c0,0x00000000, +0x0108a16a,0x4145b80c,0x49458700,0x00000000, +0x0188b80a,0x494581a0,0x494586e0,0x00000000, +0x0108a66a,0x4145b80c,0x49448040,0x494487e0, +0x00000000,0x0188b80a,0x011fa1ec,0x4145b80c, +0x49458100,0x49458780,0x00000000,0x0108a08a, +0x41458720,0x49458100,0x494586e0,0x49458160, +0x49458020,0x49458020,0x49458760,0x00000000, +0x0108a08a,0x414587a0,0x49458080,0x49458760, +0x494580c0,0x49458700,0x49458140,0x49458020, +0x49458760,0x00000000,0x0108a74a,0x414587a0, +0x49458080,0x49458760,0x494580e0,0x49458700, +0x49458120,0x49458020,0x49458760,0x00000000, +0x0108a08a,0x41458720,0x49458100,0x494586e0, +0x49458140,0x49458040,0x49458020,0x49458720, +0x00000000,0x0108a0ca,0x41458080,0x49458040, +0x49458020,0x49458620,0x00000000,0x0188b80a, +0x49458080,0x00000000,0x0108a7ca,0x4144b80c, +0x49458040,0x49458020,0x49458080,0x00000000, +0x0108a5ea,0x41448080,0x49448700,0x00000000, +0x0188b80a,0x49448780,0x00000000,0x0108a7ca, +0x4144b80c,0x49448140,0x00000000,0x0108a7ca, +0x49448040,0x00000000,0x0108a0ca,0x41448700, +0x00000000,0x0188b80a,0x49448000,0x00000000, +0x0108a04a,0x011fa00c,0x80171f80,0xb6002006, +0x40048000,0x48048000,0x48048000,0x48048000, +0x00000000,0x0008a020,0x00ffb81d,0x00000000, +0x80770000,0x8057ffff,0x015f05b9,0x017f05bb, +0x8293ffff,0x9a94ffff,0x81a70000,0xb62a003a, +0xaded0180,0xae0d0180,0xadcd0080,0x902f1980, +0x0017b801,0xb6002033,0x904e01b8,0x00000000, +0x013ff002,0xb0090000,0xb400001f,0x904f02b8, +0x80c70000,0x011fd802,0x6829b808,0x94210001, +0xb0010001,0xb4e00001,0x00c7b814,0x6429b806, +0x80470001,0x6449b802,0x84420001,0x1442b808, +0x84690001,0x5863b803,0x906300dc,0x1042b801, +0x003f9803,0x90420001,0x4082b801,0x90630004, +0x003f9803,0x00000000,0x5897b804,0x1804b805, +0x4082b801,0x00000000,0x00000000,0x00000000, +0x10a4b800,0xb5000001,0x80a70000,0x90501c80, +0x00000000,0x007ff002,0x5842b803,0x904205f8, +0x0097b802,0x00000000,0x40058004,0x48058004, +0x00000000,0x0008a020,0x91ce0004,0x91ef0004, +0x92100004,0x91ad0001,0x00ffb81a,0x80770000, +0x8057ffff,0x80d7ffff,0x015f05b9,0x017f05bb, +0x8293ff80,0x9a940000,0x82a70020,0x81a70000, +0x81e702b8,0x80171980,0xb62a004f,0xb600034d, +0xac0d0080,0xac4d0180,0xac960080,0x822700bc, +0x91c001b8,0x00000000,0x1042b804,0x92021c80, +0xb62b003a,0x013ff00e,0x00fff011,0xb0090000, +0xb4000027,0x10e7b809,0x5821b807,0x902100dc, +0x00000000,0x001fd801,0x82470000,0x80270001, +0x6452b801,0x3002b800,0xb4600002,0x92520001, +0xb500fffb,0x86520001,0x80c70000,0x011fd80f, +0x6832b808,0xb0010001,0xb4e00001,0x00c7b814, +0x84520017,0x0056b802,0x80270001,0x6432b801, +0x84210001,0x1408b801,0x6402b800,0x10c6b800, +0x9027018c,0x00000000,0x001ff001,0x5802b800, +0x9020073c,0x904006f8,0x007f9801,0x0097b802, +0x10c6b803,0x40868004,0x48868004,0xb5000003, +0x80c70000,0x40868004,0x00000000,0x0088b804, +0x003ff010,0x5822b801,0x902105f8,0x0097b801, +0x91ce0004,0x91ef0004,0x40448004,0x48448004, +0x92100004,0x0008a022,0x92310001,0x0435b80b, +0xb4000007,0x80870000,0xb6210005,0x001fa024, +0x91ce0004,0x91ef0004,0x92100004,0x92310001, +0x00000000,0x91ad0001,0x00ffb81a,0x00000000, +0x007f05b9,0x001f0081,0xb0000001,0xb4400029, +0x001f05d8,0xac400080,0x801702b8,0x80970438, +0x90421800,0x0117b802,0x8087ffff,0x80b3ffff, +0x80d3007f,0x98c6ff00,0x80f3ff80,0x81070080, +0xb6002018,0x10088020,0x0056b800,0x0442b806, +0xb4a00004,0xb0000000,0x0007b806,0xb4400001, +0x0007b807,0x0027b800,0x5c08b800,0x1400b804, +0xb0030001,0xb4000008,0x10288024,0x0056b801, +0x0442b806,0xb4a00004,0xb0010000,0x0027b806, +0xb4400001,0x0027b807,0x5828b801,0x1421b805, +0x1900a021,0x001f05d8,0x90000001,0x001f25d8, +0x00ffb81a,0x801702b8,0x80970438,0x81171800, +0x8087ffff,0x80b3ffff,0x80d3007f,0x98c6ff00, +0x80f3ff80,0x81070080,0xb6006018,0x10088020, +0x0056b800,0x0442b806,0xb4a00004,0xb0000000, +0x0007b806,0xb4400001,0x0007b807,0x0027b800, +0x5c08b800,0x1400b804,0xb0030001,0xb4000008, +0x10288024,0x0056b801,0x0442b806,0xb4a00004, +0xb0010000,0x0027b806,0xb4400001,0x0027b807, +0x5828b801,0x1421b805,0x1900a021,0x00ffb81a, +0x001f0081,0xb0000001,0xb4400006,0x001f05d8, +0xb0000003,0xb4000003,0x80270001,0x003f25dc, +0x00ffb81a,0x003f05d9,0x009f05cb,0xb0010000, +0xb400000e,0x015f42ed,0x81070000,0x8127017c, +0xb00a0000,0xb4000002,0x81070180,0x812702fc, +0x802500a5,0x9421ffff,0x3001b808,0xb4800011, +0x3001b809,0xb4a00079,0xb500000e,0x001f0081, +0xb0000001,0xb4400003,0xb0040002,0xb4200006, +0xb5000002,0xb0040000,0xb4200003,0x802702ff, +0x81470000,0xb5000003,0x80270001,0x003f25d9, +0x81470180,0xb0040000,0xb4200001,0x83840344, +0x80070000,0x001f25d8,0x009f902d,0x80af001f, +0x808f0000,0x806f0000,0x8007ffff,0x8033ffff, +0x80171800,0x807bff8c,0x94630003,0xb0030003, +0xb4000016,0xb0030002,0xb4000035,0xb0030001, +0xb4000024,0xb6006010,0x14618000,0x6068b803, +0x40c4b803,0x14608000,0x00c8b806,0x5870b803, +0x6068b803,0x4104b803,0x58c8b806,0x0108b808, +0x14c6b801,0x00000000,0x00000000,0x5d08b808, +0x1508b800,0x1806a028,0xb5000030,0xb6006010, +0x14618000,0x6068b803,0x40c4b803,0x14608000, +0x00c8b806,0x5870b803,0x6068b803,0x4104b803, +0x5cc8b806,0x0108b808,0x14c6b800,0x00000000, +0x00000000,0x5908b808,0x1508b801,0x1806a028, +0xb500001e,0xb600600d,0x14618000,0x6068b803, +0x40c4b803,0x00000000,0x00c8b806,0x00000000, +0x00000000,0x00000000,0x5d08b806,0x1508b800, +0x58c8b806,0x14c6b801,0x1806a028,0xb500000f, +0xb600600e,0x14608000,0x5868b803,0x6068b803, +0x40c4b803,0x00000000,0x00c8b806,0x00000000, +0x00000000,0x00000000,0x5d08b806,0x1508b800, +0x58c8b806,0x14c6b801,0x1806a028,0x80670600, +0x5d22b80a,0xb600030a,0x00cfb803,0x013fb178, +0x5922b809,0x01afb809,0x013f9178,0x0047b86f, +0xb0020001,0xb4c0fffd,0x90630020,0x91290020, +0x81270180,0xb00a0000,0xb4000001,0x81270000, +0x013f62ed,0x80270001,0x003f25dc,0x00ffb81a, +0x801bff7c,0x00000000,0x94000080,0xb0000080, +0xb400ff67,0x001f0081,0xb0000001,0xb4400006, +0x001f05d8,0xb0000003,0xb4000003,0x80270001, +0x003f25dc,0x00ffb81a,0x003f05d9,0x009f05cb, +0xb0010000,0xb400000e,0x015f42ed,0x81070000, +0x812702fc,0xb00a0000,0xb4000002,0x81070300, +0x812705fc,0x802500a5,0x9421ffff,0x3001b808, +0xb4800011,0x3001b809,0xb4a0006d,0xb500000e, +0x001f0081,0xb0000001,0xb4400003,0xb0040002, +0xb4200006,0xb5000002,0xb0040000,0xb4200003, +0x802705ff,0x81470000,0xb5000003,0x80270001, +0x003f25d9,0x81470300,0xb0040000,0xb4200001, +0x838402ab,0x80070000,0x001f25d8,0x009f902d, +0x80af001f,0x808f0000,0x806f0000,0x8007ffff, +0x8033ffff,0x80171800,0x807bff8c,0x80971980, +0x94630003,0xb0030003,0xb4000013,0xb0030002, +0xb400002c,0xb0030001,0xb400001e,0xb600600d, +0x58708000,0x6068b803,0x40c4b803,0x14618020, +0x00c8b806,0x6068b803,0x4104b803,0x00000000, +0x0108b808,0x5887a026,0x00000000,0x00000000, +0x5887a028,0xb5000026,0xb600600d,0x14618000, +0x6068b803,0x40c4b803,0x58708020,0x00c8b806, +0x6068b803,0x4104b803,0x00000000,0x0108b808, +0x5887a026,0x00000000,0x00000000,0x5887a028, +0xb5000017,0xb600600a,0x14618000,0x6068b803, +0x40c4b803,0x00000000,0x00c8b806,0x00000000, +0x00000000,0x00000000,0x5887a026,0x5887a026, +0xb500000b,0xb600600a,0x58708000,0x6068b803, +0x40c4b803,0x00000000,0x00c8b806,0x00000000, +0x00000000,0x00000000,0x5887a026,0x5887a026, +0x80670660,0x5d22b80a,0xb600060a,0x00cfb803, +0x013fb178,0x5922b809,0x01afb809,0x013f9178, +0x0047b86f,0xb0020001,0xb4c0fffd,0x90630020, +0x91290020,0x81270300,0xb00a0000,0xb4000001, +0x81270000,0x013f62ed,0x80270001,0x003f25dc, +0x00ffb81a,0x00000000,0x00000000,0x00000000, +0x029fb024,0x02bfb025,0x02dfb026,0x02ffb027, +0x031fb028,0x033fb029,0x033f4046,0x0287b86f, +0x029fb02a,0x8285009d,0x9a940008,0x8286009d, +0x8285009c,0x96b48000,0xb0158000,0xb40001b5, +0x96b40100,0xb0150100,0xb400020b,0x96b40400, +0xb0150400,0xb400020c,0x96b40001,0xb0150001, +0xb400000c,0x96b40008,0xb0150008,0xb40001ad, +0x96b44000,0xb0154000,0xb400020b,0x96b40002, +0xb0150002,0xb4000182,0x00000000,0x00000000, +0xb500021d,0x02bf917e,0x92b50001,0x02bfb17e, +0x82850082,0x96f40001,0xb0170000,0xb4000171, +0x5efdb814,0x96f70001,0xb0170001,0xb420000b, +0x83050069,0x9718003f,0x82e50064,0x12f7b818, +0x86f70109,0x82feff74,0x02e7b86f,0x9af74000, +0x01ffb817,0x96f7bfff,0x01ffb817,0x83050081, +0x82a5009a,0x96b50001,0xb0150001,0xb4200014, +0x82a70000,0x02bfb17e,0x96b41840,0xb0150800, +0xb420000c,0x96b40008,0x5aa9b815,0x96d46000, +0x5ec3b816,0x82f3000f,0x9af7c00f,0x1718b817, +0x1ab5b818,0x1ab5b816,0x9ab50340,0x82a60081, +0xb500014c,0x9b180180,0x83060081,0xb5000149, +0x82a5009a,0x96b50002,0xb0150002,0xb420001b, +0x82a70000,0x02bfb17e,0x96b41800,0xb0151800, +0xb4000013,0x96b40040,0xb0150040,0xb4200004, +0xa3180c00,0x9b180340,0x83060081,0xb5000139, +0x96b40008,0x5aa9b815,0x96d46000,0x5ec3b816, +0x82f3000f,0x9af7c00f,0x1718b817,0x1ab5b818, +0x1ab5b816,0x9ab50340,0x82a60081,0xb500012d, +0x9b180180,0x83060081,0xb500012a,0x82a500c1, +0x96b5000f,0xb015000b,0xb420000e,0x96b40020, +0xb0150020,0xb400000b,0x96b40200,0xb0150200, +0xb4000008,0x82c50086,0x82e50094,0x3016b817, +0xb4400004,0x06f7b816,0xb017ff00,0xb4400001, +0xb5000118,0x96b46000,0xb0156000,0xb4000011, +0x96b41820,0xb0150820,0xb4200004,0x9b391000, +0x82a5009a,0x96b5feff,0x82a6009a,0x96b40040, +0xb0150040,0xb4200001,0x9739efff,0x96b91000, +0xb0151000,0xb4200003,0x82a5009a,0x9ab50100, +0x82a6009a,0x96b40040,0xb0150040,0xb4200019, +0x96b41800,0xb0151800,0xb4200006,0x96b98000, +0xb0158000,0xb4200003,0x9b180180,0x83060081, +0xb50000f8,0x96d80c00,0x82b300ff,0x9ab5f3ff, +0x1718b815,0xb0160c00,0xb4000007,0x82e50098, +0x96f70400,0xb0170400,0xb4200002,0x82c70c00, +0xb5000001,0xa2d60c00,0x1b18b816,0x9b180340, +0xb50000c4,0x96b40220,0xb0150000,0xb4e00021, +0x82a5009d,0x82f3ffff,0x16b5b817,0x82f33800, +0x3015b817,0xb420001b,0x96f98000,0xb0178000, +0xb4000018,0x82a70000,0x02bfb17e,0x82c5009d, +0x96d6ffff,0x82b3c800,0x9ab58001,0x82e500c1, +0x96f7000f,0xb017000b,0xb4000002,0x82b38800, +0x9ab58001,0x1ab5b816,0x82c5009a,0x96d60020, +0xb0160020,0xb4200002,0x82b3c800,0x9ab58001, +0x82a6009d,0x02ff917e,0x00000000,0xb0170040, +0xb4800000,0x5eb5b814,0x96b500f0,0x96f46000, +0x5eedb817,0x1ab5b817,0xb0170003,0xb4000004, +0x96b500ef,0x96f70001,0x5ae4b817,0x1ab5b817, +0x96d41800,0xb0161800,0xb400000a,0x96f900ff, +0x96b500ff,0x9739ff00,0x1b39b815,0x02a7b817, +0x96b500f3,0x96d40008,0x5ec1b816,0x1ab5b816, +0xb500000c,0x96f98000,0xb0178000,0xb4200007, +0x5efeb814,0x96f70001,0xb0170001,0xb4000003, +0x9b180180,0x83060081,0xb50000a2,0x96b500f3, +0x9ab50008,0x9739fff3,0x96d40020,0xb0160020, +0xb4200019,0x82c7001f,0x82c600c9,0x9b398000, +0x82c70000,0x02dfb17e,0x96d40010,0x5ac8b816, +0x82f300ff,0x9af7cfff,0x1718b817,0x1b18b816, +0x9b180340,0x82c5009d,0x96d6ffff,0x82f33800, +0x9af78001,0x1af7b816,0x82c5009a,0x96d60020, +0xb0160020,0xb4200002,0x82f3c800,0x9af78001, +0x82e6009d,0xb500005f,0x97397fff,0x96b500ff, +0x5aaab815,0x82f300fc,0x9af703ff,0x1718b817, +0x1b18b815,0x9b180340,0x82c5009a,0x96d60010, +0xb0160010,0xb4200027,0x82c70000,0x02dfb17e, +0x82c50086,0x92d60e10,0x82c60086,0x82c50094, +0x5eefb818,0x96f70003,0xb0170003,0xb4200002, +0x82e70e10,0xb5000001,0x82e70e10,0x12d6b817, +0x82e50081,0x9af70020,0x82e60081,0x82c60094, +0xa2f70020,0x82e60081,0x82f30001,0x16f7b818, +0x5ef0b817,0xb0170001,0xb4000004,0x96f84000, +0x5ee4b817,0x9718f3ff,0x1b18b817,0x82f32800, +0x9af78000,0x82e6009d,0x83060081,0x83070001, +0x8306009f,0x8305009c,0xb0180001,0xb4e0fffb, +0xb50000f5,0x82c5009d,0x82f33800,0x9af78001, +0x3016b817,0xb420000f,0x82b3c800,0x9ab58001, +0x82e500c1,0x96f7000f,0xb017000b,0xb4000002, +0x82b38800,0x9ab58001,0x82c5009a,0x96d60020, +0xb0160020,0xb4200002,0x82b3c800,0x9ab58001, +0x82a6009d,0x82c5009a,0x96d60080,0xb0160080, +0xb4000013,0x02df917e,0x00000000,0xb0160010, +0xb480000f,0x82c500c1,0x96d6000f,0xb016000b, +0xb400000b,0x82c50087,0x96d60080,0x5ac7b816, +0x82c50098,0x96d60800,0x5ac3b816,0x96f84000, +0x3017b816,0xb4200002,0x033f4046,0x9b394000, +0x9739bfff,0x82e50061,0x96f70008,0xb0170008, +0xb4000005,0x5eefb818,0x96f70003,0xb0170003, +0xb4000001,0x9718ffff,0x96b41800,0xb0151800, +0xb4000008,0x5eb9b814,0x96b5000f,0x82c50099, +0x5ed0b816,0x96f6000f,0x5ab0b815,0x82a60099, +0xb5000002,0x5ef9b814,0x96f7000f,0x5aecb817, +0x82c5009a,0x96d60fff,0x1ad6b817,0x82c6009a, +0x96b46000,0xb0156000,0xb4200005,0x5ae2b817, +0x82d30ffc,0x9ad63fff,0x1718b816,0x1b18b817, +0x83060081,0x83070001,0x8306009f,0x8305009c, +0xb0180001,0xb4e0fffb,0x00000000,0xb500009e, +0x82850083,0x96b400ff,0xb015003c,0xb4200019, +0x96b92000,0xb0152000,0xb4000002,0x9b392000, +0xb5000014,0x9739d3ff,0x82870000,0x82860087, +0x82870008,0x82860083,0x829bff78,0x82a7001f, +0xb0140400,0xb4000001,0x82a70010,0x82a600c9, +0x829bff78,0x00000000,0x828600cb,0x8285009d, +0x82b3ffff,0x9ab5fffd,0x1694b815,0x8286009d, +0xb5000000,0x83070002,0x8306009f,0x00000000, +0xb500007d,0x83078000,0x8306009f,0x00000000, +0xb5000079,0x82850094,0x82a50086,0x06b5b814, +0x02b6b815,0xb0151700,0xb440004b,0x8285006c, +0x969400ff,0xb0140024,0xb4000019,0xb0140012, +0xb4000017,0x8285009a,0x5eedb814,0x96f70003, +0xb0170003,0xb4000009,0x82a50083,0x5ea8b815, +0x96b500ff,0xb0150020,0xb4400002,0x82c70bbc, +0xb5000001,0x82c70bb8,0xb5000008,0x82a50083, +0x5ea8b815,0x96b500ff,0xb0150020,0xb4400002, +0x82c71199,0xb5000001,0x82c71197,0xb5000016, +0x8285009a,0x5eedb814,0x96f70003,0xb0170003, +0xb4000009,0x82a50083,0x5ea8b815,0x96b500ff, +0xb0150020,0xb4400002,0x82c70e18,0xb5000001, +0x82c70e04,0xb5000008,0x82a50083,0x5ea8b815, +0x96b500ff,0xb0150020,0xb4400002,0x82c70e18, +0xb5000001,0x82c70e04,0x82e50086,0x12f7b816, +0x02bf917e,0xb0150020,0xb480000b,0x82a5009a, +0x96b56000,0xb0156000,0xb4000007,0x82a50098, +0x96d50a00,0xb0160a00,0xb4000002,0xb0160000, +0xb4200001,0x92f70704,0x82850081,0x9ab40020, +0x82a60081,0x82c50094,0x82e60094,0x82860081, +0x86b70704,0x82a6009b,0x83070008,0x8306009f, +0x00000000,0xb5000024,0x83070100,0x8306009f, +0x00000000,0xb5000020,0x83070000,0x83050081, +0x9b180180,0x83060081,0x83070400,0x8306009f, +0x00000000,0xb5000018,0x82870000,0x82850082, +0x5eb7b814,0x96b500fc,0x96d40006,0x5ec1b816, +0x1ab5b816,0x5aacb815,0x83050081,0x82d3001c, +0x9ad600ff,0x1718b816,0x1b18b815,0x9b180e00, +0x83060081,0x83074000,0x8306009f,0x8305009d, +0x82d3ffff,0x9ad6bfff,0x1718b816,0x8306009d, +0x00000000,0xb5000000,0x029f902a,0x01ffb814, +0x033f6046,0x029f9024,0x02bf9025,0x02df9026, +0x02ff9027,0x031f9028,0x033f9029,0x00ffb81e, +0x02ff917d,0x92f7092f,0x031f0084,0xb0180001, +0xb4200002,0x02ff917d,0x92f70870,0x02ffb17d, +0x02ff917c,0x82bbffdc,0x829bffd8,0x93150004, +0x3014b815,0xb4000017,0x02dbb818,0x029bb815, +0x3017b816,0xb4800013,0x5a81b814,0x029fb17d, +0x82def200,0x82fef204,0x82e50086,0x06f7b814, +0x02f6b817,0x82fef208,0x82860095,0x82870001, +0x829ef220,0x8293001f,0x9294fe00,0x92b50008, +0x3015b814,0xb4800002,0x82b3001f,0x92b5fa00, +0x82beffdc,0x82850086,0x83250094,0x06d4b819, +0x02d6b816,0xb016ffff,0xb4a00009,0x82c50081, +0x9ab60020,0x82a60081,0x82a50086,0x92b50e10, +0x82a60094,0x82c60081,0x86b50704,0x82a6009b, +0x00ffb81c,0x00000000,0x00000000,0x00000000, +0x001f9012,0x001fb200,0x001f004c,0x001f2804, +0x801bfef0,0x8058fef4,0x803bff68,0x8078ff6c, +0x2000b801,0x2042b803,0x001fb204,0x005f2814, +0x82e70001,0x83640048,0x029fb014,0x829efef0, +0x8286000f,0x02bf2054,0x82bcfef4,0x82a6000e, +0x00ffb81a,0x80e70001,0x801336e3,0x9800eb76, +0x001fb200,0x800700ab,0x001f2804,0x801bc3e8, +0x8058c3ec,0x83640024,0x82e70000,0x83640036, +0x029fb3c0,0x029fb200,0x02bf2f04,0x02bf2804, +0x801bc000,0x8058c004,0x8364001b,0x82e70000, +0x8364002d,0x001f93c0,0x3000b814,0xb420000a, +0x001f0f04,0x3000b815,0xb4200007,0x829efef0, +0x82bcfef4,0x029fb012,0x02bf204c,0x82870001, +0x829cfef5,0x00ffb81a,0xb0070000,0xb4000007, +0x80e70000,0x801399fa,0x9800c92e,0x001fb200, +0x800700af,0x001f2804,0xb500ffdc,0x82870000, +0x829cfef5,0x00ffb81a,0x80c700ff,0x803bff68, +0x8078ff6c,0x14a0b806,0x2063b805,0x007f2814, +0x2021b802,0x58c8b806,0x14a0b806,0x58b0b805, +0x2021b805,0x58c8b806,0x14a0b806,0x2021b805, +0x58c8b806,0x14a0b806,0x5cb0b805,0x2021b805, +0x003fb204,0x00ffb81b,0x82c70000,0x83070800, +0x83270005,0x8197080c,0x81d7ffff,0x83840126, +0x83840001,0x00ffb81b,0x808f0000,0x806f001f, +0x80af001f,0x80270240,0x81e77c08,0x5de2b80f, +0xb6000208,0x00cfb801,0x01ffb178,0x59e2b80f, +0x01cfb80f,0x01ff9178,0xb520ffff,0x91ef0020, +0x90210020,0x80270280,0x81e77b00,0x5de2b80f, +0xb6000208,0x00cfb801,0x01ffb178,0x59e2b80f, +0x01cfb80f,0x01ff9178,0xb520ffff,0x91ef0020, +0x90210020,0x8057ffff,0x80170830,0x80070810, +0x80270808,0xb6000509,0x005ff000,0x90420900, +0x007ff001,0x90630a00,0x009ff002,0x00bff003, +0x2004a025,0x90000001,0x90210001,0x80070814, +0x80d7ffff,0x8097085c,0x8017083c,0xb6000404, +0x005ff000,0x007f87e0,0x84000001,0x2082a7e3, +0x80970860,0x80170840,0x2082b803,0x007f8000, +0x2083a004,0x80170830,0x80970850,0x80270808, +0xb6000508,0x005f8024,0x90420900,0x007ff001, +0x90630a00,0x009ff002,0x00bff003,0x2004a025, +0x90210001,0x80170840,0x00000000,0x02bf87e0, +0x80970860,0x82870000,0xb6000404,0x005f87e4, +0x5a88b814,0x204287e0,0x1a94b802,0x00ffb81c, +0x001f0e49,0x001f2b09,0x001f0e41,0x001f2b08, +0x001f0e46,0x001f2b07,0x001f0e48,0x001f2b06, +0x001f0e42,0x001f2b05,0x001f0e47,0x001f2b04, +0x001f0e45,0x001f2b03,0x001f0e43,0x001f2b02, +0x001f0e40,0x001f2b01,0x001f0e44,0x001f2b00, +0x001f0f25,0xa020000c,0x94400001,0x94600002, +0x94810004,0x94a10008,0x94c00010,0x5943b802, +0x5861b803,0x5882b804,0x5ca2b805,0x5cc4b806, +0x194ab803,0x194ab804,0x194ab805,0x194ab806, +0x015f2b38,0x801b7c00,0x003f92c1,0x5c28b801, +0x005f92c2,0x5858b802,0x1821b802,0x2000b801, +0x001fb2c4,0x80187c04,0x003f0b09,0x2000b801, +0x001f2b14,0x82c70001,0x82e70001,0x83070b10, +0x8327001e,0x81970b35,0x8384009f,0x02df0b38, +0x82170e30,0x838400f1,0x819efef0,0x817cfef4, +0x819eff68,0x817cff6c,0x00ffb81b,0x820f001f, +0x8018fef8,0x8057ffff,0x001f2b09,0x8018fef6, +0x80d7ffff,0x001f2b08,0x8018fefa,0x8157ffff, +0x001f2b07,0x8018fefd,0x81d7ffff,0x001f2b06, +0x8018fefb,0x802f001f,0x001f2b05,0x8018fefe, +0x00000000,0x001f2b04,0x8018fef9,0x00000000, +0x001f2b03,0x8018feff,0x00000000,0x001f2b02, +0x8018fef7,0x00000000,0x001f2b01,0x8018fefc, +0x00000000,0x001f2b00,0x001f0f25,0xa0200011, +0x94410001,0x94600002,0x94800004,0x94a00008, +0x94c10010,0x5941b802,0x5861b803,0x5c82b804, +0x58a1b805,0x5cc1b806,0x194ab803,0x194ab804, +0x194ab805,0x194ab806,0x015f2b38,0x801b7c00, +0x003f92c1,0x5c28b801,0x005f92c2,0x5858b802, +0x1821b802,0x2000b801,0x001fb2c4,0x80187c04, +0x003f0b09,0x2000b801,0x001f2b14,0x82c70001, +0x82e70001,0x83070b10,0x8327001e,0x81970b35, +0x83840055,0x02df0b38,0x82170e20,0x838400a7, +0x819efef0,0x817cfef4,0x5ac8b80c,0x02ff0e44, +0x1ad6b817,0x02dfb391,0x5ed8b80c,0x5968b80b, +0x1ad6b80b,0x02df6724,0x00ffb81b,0x820f001f, +0x8018fefe,0x8057ffff,0x001f2b09,0x8018fefa, +0x80d7ffff,0x001f2b08,0x8018fefc,0x8157ffff, +0x001f2b07,0x8018feff,0x81d7ffff,0x001f2b06, +0x8018fef8,0x802f001f,0x001f2b05,0x8018fefb, +0x00000000,0x001f2b04,0x8018fefd,0x00000000, +0x001f2b03,0x8018fef6,0x00000000,0x001f2b02, +0x8018fef9,0x00000000,0x001f2b01,0x8018fef7, +0x00000000,0x001f2b00,0x801b7c00,0x003f92c1, +0x5c28b801,0x005f92c2,0x5858b802,0x1821b802, +0x2000b801,0x001fb2c4,0x80187c04,0x003f0b09, +0x2000b801,0x001f2b14,0x82c70001,0x82e70001, +0x83070b10,0x8327001e,0x81970b35,0x83840016, +0x83270000,0x831bfef0,0x82f8fef4,0x02c7b819, +0x82170e28,0x83840065,0x300cb818,0xb4200002, +0x300bb817,0xb4000006,0x93390001,0xb0190020, +0xb480fff6,0x83270000,0x833cfef5,0x00ffb81b, +0x019fb390,0x017f2e44,0x033f2f25,0x83270001, +0x833cfef5,0x00ffb81b,0x0007b818,0x90000003, +0x00000000,0x015ff000,0x90000001,0x5949b80a, +0x013ff000,0x194ab809,0x84000002,0x994a0100, +0x017ff000,0x958b00f8,0x5981b80c,0x956b0007, +0x198cb80b,0x84000002,0x998c0008,0x017ff000, +0x90000001,0x5971b80b,0x198cb80b,0x017ff000, +0x5969b80b,0x198cb80b,0x81a70000,0x94d90003, +0x82a70000,0xb6260019,0xb6000818,0x5df0b80a, +0x5e02b80a,0x21efb810,0x95ef0001,0x5941b80a, +0x194ab80f,0x21efb816,0x5e18b80c,0x5e35b80c, +0x5e54b80c,0x5e6cb80c,0x2210b811,0x2252b813, +0x2210b812,0x96100001,0x5981b80c,0x198cb810, +0x2210b817,0x10afb810,0x10a5b80d,0x5da1b805, +0x94a50001,0x5aa1b815,0x1ab5b805,0x019fa7f5, +0x5cc2b819,0xb626001c,0x82870000,0xb6000419, +0xb6000818,0x5df0b80a,0x5e02b80a,0x21efb810, +0x95ef0001,0x5941b80a,0x194ab80f,0x21efb816, +0x5e18b80c,0x5e35b80c,0x5e54b80c,0x5e6cb80c, +0x2210b811,0x2252b813,0x2210b812,0x96100001, +0x5981b80c,0x198cb810,0x2210b817,0x10afb810, +0x10a5b80d,0x5da1b805,0x94a50001,0x5a81b814, +0x1a94b805,0x019fa7f4,0x00ffb81c,0x8257ffff, +0x808f0000,0x806f001f,0x80af001f,0x80270300, +0x81e778e0,0x5de2b80f,0xb6000208,0x00cfb801, +0x01ffb178,0x59e2b80f,0x01cfb80f,0x01ff9178, +0xb520ffff,0x91ef0020,0x90210020,0x80270340, +0x81e779e0,0x5de2b80f,0xb6000208,0x00cfb801, +0x01ffb178,0x59e2b80f,0x01cfb80f,0x01ff9178, +0xb520ffff,0x91ef0020,0x90210020,0x80270280, +0x81e77b00,0x5de2b80f,0xb6000208,0x00cfb801, +0x01ffb178,0x59e2b80f,0x01cfb80f,0x01ff9178, +0xb520ffff,0x91ef0020,0x90210020,0x806f0007, +0x80af0007,0x80270380,0x81e77ae0,0x5de2b80f, +0x00cfb801,0x01ffb178,0x59e2b80f,0x01cfb80f, +0x01ff9178,0xb520ffff,0x91ef0020,0x90210020, +0x80170b60,0x001f0b00,0x001fa020,0x001f0b01, +0x001fa020,0x001f0b02,0x001fa020,0x001f0b03, +0x001fa020,0x001f0b04,0x001fa000,0x80970b50, +0x81170b70,0x82a70b35,0x83a40060,0x001f87e4, +0xb6000405,0x86b50001,0x83a4005c,0x001f8004, +0x003f87e8,0x2080a7e1,0x80970b70,0x80170b50, +0x81170b50,0x81970b40,0x82a70b30,0x001f800c, +0x003f8008,0x2100a001,0x83a40050,0x001f87e4, +0xb6000405,0x86b50001,0x83a4004c,0x001f8004, +0x003f87e8,0x2080a7e1,0x80970b50,0x80170b70, +0x81170b70,0x81970b60,0x82a70b2b,0x001f800c, +0x003f8008,0x2100a001,0x83a40040,0x83a4004e, +0xb6000407,0x86b50001,0x83a4003c,0x001f8004, +0x003f87e8,0x2080a001,0x83a40047,0x00000000, +0x80970b70,0x80170b50,0x81170b50,0x81970b40, +0x82a70b26,0x001f800c,0x003f8008,0x2100a001, +0x83a4002e,0x83a4003c,0xb6000407,0x86b50001, +0x83a4002a,0x001f8004,0x003f87e8,0x2080a001, +0x83a40035,0x00000000,0x80970b50,0x80170b70, +0x81170b70,0x81970b60,0x82a70b21,0x001f800c, +0x003f8008,0x2100a001,0x83a4001c,0x001f87e4, +0xb6000405,0x86b50001,0x83a40018,0x001f8004, +0x003f87e8,0x2080a7e1,0x80970b70,0x80170b50, +0x81170b50,0x81970b40,0x82a70b1c,0x001f800c, +0x003f8008,0x2100a001,0x83a4000c,0x017f87e4, +0x81870000,0xb6000406,0x86b50001,0x83a40007, +0x001f87e4,0x200087e8,0x5988b80c,0x198cb800, +0x021fa02c,0x021fa00b,0x00ffb81c,0x005ff015, +0x90420a00,0x003f87e0,0x001ff002,0x2060b801, +0x90630c00,0x90960e00,0x001ff003,0x003ff004, +0x20a0b801,0x90a50d00,0x00000000,0x001ff005, +0x009fa000,0x00ffb81d,0x001f8004,0x5c21b800, +0x5847b800,0x1821b802,0x942100ff,0x2080a7e1, +0x00ffb81d,0x00000000,0x00000000,0x00000000, + +}; + +static u32 MPGI2S240Ucode1f5c00[] = { +0x00000000,0xfffff8c0,0x00003540,0xffff8d40, +0x0001fd40,0xfffaf7c0,0x00066b80,0xffdb63c0, +0x00494780,0x00249c40,0x00066b80,0x00050840, +0x0001fd40,0x000072c0,0x00003540,0x00000740, +0xffffffc0,0xfffff840,0x00003680,0xffff7e40, +0x0001f400,0xfffa9cc0,0x0005d1c0,0xffd99600, +0x00493c00,0x0022ce00,0x0006f780,0x0004ad00, +0x000203c0,0x00006440,0x00003400,0x00000680, +0xffffffc0,0xfffff740,0x00003780,0xffff6ec0, +0x0001e800,0xfffa4240,0x00052a00,0xffd7ca00, +0x00491a00,0x0020ffc0,0x00077600,0x00045240, +0x00020800,0x000056c0,0x00003280,0x00000600, +0xffffffc0,0xfffff680,0x00003840,0xffff5ec0, +0x0001d940,0xfff9e8c0,0x00047440,0xffd60080, +0x0048e180,0x001f32c0,0x0007e700,0x0003f7c0, +0x000209c0,0x00004980,0x00003100,0x00000540, +0xffffffc0,0xfffff5c0,0x000038c0,0xffff4e40, +0x0001c780,0xfff990c0,0x0003b000,0xffd43ac0, +0x00489240,0x001d6800,0x00084b00,0x00039e40, +0x00020940,0x00003d00,0x00002f80,0x000004c0, +0xffffffc0,0xfffff4c0,0x00003900,0xffff3d40, +0x0001b2c0,0xfff93a40,0x0002ddc0,0xffd279c0, +0x00482d00,0x001ba040,0x0008a200,0x000345c0, +0x000206c0,0x00003140,0x00002dc0,0x00000440, +0xffffffc0,0xfffff3c0,0x00003900,0xffff2c00, +0x00019b00,0xfff8e640,0x0001fd40,0xffd0be80, +0x0047b1c0,0x0019dc80,0x0008ecc0,0x0002ef00, +0x00020240,0x00002640,0x00002c00,0x00000400, +0xffffff80,0xfffff2c0,0x000038c0,0xffff1a40, +0x00017fc0,0xfff894c0,0x00010e80,0xffcf09c0, +0x004720c0,0x00181d80,0x00092b40,0x000299c0, +0x0001fc00,0x00001bc0,0x00002a40,0x00000380, +0xffffff80,0xfffff180,0x00003800,0xffff0840, +0x00016180,0xfff84680,0x00001180,0xffcd5cc0, +0x00467a40,0x00166440,0x00095e00,0x00024680, +0x0001f440,0x00001200,0x00002840,0x00000340, +0xffffff80,0xfffff040,0x00003740,0xfffef600, +0x00014000,0xfff7fbc0,0xffff0680,0xffcbb880, +0x0045bf00,0x0014b140,0x00098580,0x0001f580, +0x0001ea80,0x00000900,0x00002680,0x000002c0, +0xffffff80,0xffffef00,0x000035c0,0xfffee3c0, +0x00011ac0,0xfff7b540,0xfffded80,0xffca1d80, +0x0044ef80,0x00130580,0x0009a1c0,0x0001a700, +0x0001dfc0,0x00000080,0x000024c0,0x00000280, +0xffffff40,0xffffedc0,0x00003400,0xfffed180, +0x0000f280,0xfff77340,0xfffcc700,0xffc88d80, +0x00440bc0,0x001161c0,0x0009b3c0,0x00015b00, +0x0001d380,0xfffff8c0,0x000022c0,0x00000240, +0xffffff40,0xffffec40,0x00003200,0xfffebf40, +0x0000c680,0xfff73680,0xfffb92c0,0xffc708c0, +0x00431500,0x000fc6c0,0x0009bb80,0x000111c0, +0x0001c640,0xfffff1c0,0x00002100,0x00000200, +0xffffff00,0xffffeac0,0x00002f40,0xfffead00, +0x00009740,0xfff6ff40,0xfffa5180,0xffc59080, +0x00420b40,0x000e3500,0x0009b9c0,0x0000cb80, +0x0001b7c0,0xffffeb40,0x00001f40,0x000001c0, +0xffffff00,0xffffe940,0x00002c40,0xfffe9b00, +0x00006480,0xfff6ce00,0xfff90380,0xffc425c0, +0x0040ef80,0x000cad00,0x0009af00,0x00008840, +0x0001a880,0xffffe580,0x00001d40,0x000001c0, +0xfffffec0,0xffffe7c0,0x000028c0,0xfffe8980, +0x00002e40,0xfff6a3c0,0xfff7a900,0xffc2c900, +0x003fc280,0x000b2fc0,0x00099b80,0x00004800, +0x00019880,0xffffe040,0x00001bc0,0x00000180, +0xfffffec0,0xffffe600,0x00002480,0xfffe7840, +0xfffff4c0,0xfff68040,0xfff64240,0xffc17b40, +0x003e84c0,0x0009bdc0,0x00097fc0,0x00000b40, +0x000187c0,0xffffdb80,0x00001a00,0x00000140, +0xfffffe80,0xffffe440,0x00001fc0,0xfffe6780, +0xffffb800,0xfff66480,0xfff4d040,0xffc03d80, +0x003d3700,0x00085700,0x00095c40,0xffffd1c0, +0x00017680,0xffffd740,0x00001840,0x00000140, +0xfffffe40,0xffffe2c0,0x00001a80,0xfffe5780, +0xffff77c0,0xfff65100,0xfff35300,0xffbf1080, +0x003bda40,0x0006fc80,0x00093200,0xffff9b80, +0x00016500,0xffffd3c0,0x000016c0,0x00000100, +0xfffffe40,0xffffe0c0,0x000014c0,0xfffe4840, +0xffff3480,0xfff64640,0xfff1cb00,0xffbdf4c0, +0x003a6f80,0x0005ae80,0x000900c0,0xffff68c0, +0x00015300,0xffffd0c0,0x00001540,0x00000100, +0xfffffe00,0xffffdf00,0x00000e40,0xfffe39c0, +0xfffeee40,0xfff64480,0xfff03940,0xffbceb00, +0x0038f740,0x00046d40,0x0008c980,0xffff3980, +0x000140c0,0xffffce00,0x000013c0,0x000000c0, +0xfffffdc0,0xffffdd40,0x00000740,0xfffe2c80, +0xfffea500,0xfff64c40,0xffee9e40,0xffbbf440, +0x00377280,0x00033900,0x00088cc0,0xffff0d80, +0x00012e80,0xffffcc00,0x00001240,0x000000c0, +0xfffffd80,0xffffdb40,0xffffff80,0xfffe2040, +0xfffe5900,0xfff65e40,0xffecfa80,0xffbb1080, +0x0035e280,0x00021280,0x00084ac0,0xfffee540, +0x00011c40,0xffffca40,0x00001100,0x00000080, +0xfffffd40,0xffffd980,0xfffff700,0xfffe1580, +0xfffe0a80,0xfff67a80,0xffeb4ec0,0xffba4100, +0x00344780,0x0000f980,0x00080440,0xfffec000, +0x00010a00,0xffffc8c0,0x00000fc0,0x00000080, +0xfffffcc0,0xffffd7c0,0xffffee00,0xfffe0bc0, +0xfffdb980,0xfff6a200,0xffe99bc0,0xffb985c0, +0x0032a340,0xffffee80,0x0007b980,0xfffe9e80, +0x0000f7c0,0xffffc800,0x00000e80,0x00000080, +0xfffffc80,0xffffd5c0,0xffffe440,0xfffe0400, +0xfffd6640,0xfff6d4c0,0xffe7e280,0xffb8df40, +0x0030f640,0xfffef180,0x00076b40,0xfffe8040, +0x0000e5c0,0xffffc740,0x00000d40,0x00000080, +0xfffffc00,0xffffd400,0xffffd9c0,0xfffdfdc0, +0xfffd1100,0xfff71340,0xffe62380,0xffb84e40, +0x002f4180,0xfffe02c0,0x000719c0,0xfffe6500, +0x0000d400,0xffffc700,0x00000c40,0x00000040, +0xfffffbc0,0xffffd240,0xffffcec0,0xfffdf940, +0xfffcba40,0xfff75e00,0xffe45fc0,0xffb7d300, +0x002d8640,0xfffd2240,0x0006c5c0,0xfffe4d40, +0x0000c2c0,0xffffc700,0x00000b40,0x00000040, +0xfffffb40,0xffffd080,0xffffc300,0xfffdf6c0, +0xfffc61c0,0xfff7b500,0xffe29800,0xffb76dc0, +0x002bc540,0xfffc5000,0x00066f40,0xfffe3880, +0x0000b1c0,0xffffc740,0x00000a40,0x00000040, +0xfffffac0,0xffffcf00,0xffffb680,0xfffdf640, +0xfffc0840,0xfff81900,0xffe0cd40,0xffb71e80, +0x0029ff80,0xfffb8bc0,0x00061740,0xfffe26c0, +0x0000a140,0xffffc7c0,0x00000980,0x00000040, +0xfffffa00,0xffffcd80,0xffffa940,0xfffdf800, +0xfffbadc0,0xfff88a00,0xffdf0040,0xffb6e600, +0x00283600,0xfffad600,0x0005bdc0,0xfffe1800, +0x00009140,0xffffc880,0x000008c0,0x00000040, +0xfffff980,0xffffcc00,0xffff9bc0,0xfffdfc40, +0xfffb5300,0xfff90880,0xffdd3200,0xffb6c400, +0x00266a00,0xfffa2e40,0x00056340,0xfffe0c00, +0x000081c0,0xffffc980,0x000007c0,0x00000040, +0x004013c2,0x0040b346,0x0041fa2d,0x0043f934, +0x0046cc1c,0x004a9d9d,0x004fae37,0x0056601f, +0x005f4cf7,0x006b6fcf,0x007c7d1e,0x0115b035, +0x013df91b,0x0207655e,0x03342c83,0x0a185230, +0x00404f46,0x0042e13c,0x0048919f,0x0052cb0e, +0x0064e240,0x0107c449,0x015c7926,0x050cf270, +0x004140fb,0x004cf8df,0x0073326c,0x02480d9d, +0x004545ea,0x01273d75,0x005a827a,0x007fffff, +0x006597fb,0x0050a28c,0x00400000,0x0032cbfd, +0x00285146,0x00200000,0x001965ff,0x001428a3, +0x00100000,0x000cb2ff,0x000a1451,0x00080000, +0x00065980,0x00050a29,0x00040000,0x00032cc0, +0x00028514,0x00020000,0x00019660,0x0001428a, +0x00010000,0x0000cb30,0x0000a145,0x00008000, +0x00006598,0x000050a3,0x00004000,0x000032cc, +0x00002851,0x00002000,0x00001966,0x00001429, +0x00001000,0x00000cb3,0x00000a14,0x00000800, +0x00000659,0x0000050a,0x00000400,0x0000032d, +0x00000285,0x00000200,0x00000196,0x00000143, +0x00000100,0x000000cb,0x000000a1,0x00000080, +0x00000066,0x00000051,0x00000040,0x00000033, +0x00000028,0x00000020,0x00000019,0x00000014, +0x00000010,0x0000000d,0x0000000a,0x00000008, +0x00000006,0x00000005,0x00000000,0x00555555, +0x00666666,0x00492492,0x0071c71c,0x00444444, +0x00421084,0x00410410,0x00408102,0x00404040, +0x00402010,0x00401004,0x00400801,0x00400400, +0x00400200,0x00400100,0x00400080,0x00400040, +0x00400000,0x00400000,0x00200000,0x00400000, +0x00100000,0x00080000,0x00040000,0x00020000, +0x00010000,0x00008000,0x00004000,0x00002000, +0x00001000,0x00000800,0x00000400,0x00000200, +0x00000100,0x0003588d,0x0002b15e,0x0002056d, +0x00015600,0x0000a329,0xffffeed9,0xffff3960, +0xfffe8423,0xfffdd11c,0xfffd2048,0xfffc7353, +0xfffbcb6f,0xfffb29a6,0xfffa8f15,0x000494ae, +0x0003f991,0x00032dd1,0xfffd2d8f,0x0001eb47, +0xfffe9968,0x00009af6,0x000011de,0xffff4335, +0x00018d69,0xfffdecd4,0x000302f8,0xfffca0d7, +0x0004683d,0xfffb67f8,0x0005b36d,0x00045963, +0xfffbd51e,0x00030062,0xfffd0dee,0x0001d046, +0xfffe8a0a,0x00009258,0x000012b1,0xffff4d9e, +0x00019ec3,0xfffe0a44,0x0003245a,0xfffcd082, +0x000498f0,0xfffba919,0x0005f304,0x00041bf4, +0xfffba72a,0x0002d19e,0xfffcf060,0x0001b407, +0xfffe7c08,0x0000894a,0x0000138d,0xffff58ac, +0x0001afaf,0xfffe28fe,0x000343bf,0xfffd026f, +0x0004c6f6,0xfffbed06,0x00062e61,0x0003dc0e, +0xfffb7bf1,0x0002a17f,0xfffcd522,0x000196a0, +0xfffe6e70,0x00007ff6,0x00001439,0xffff63f6, +0x0001beb3,0xfffe4882,0x0003616d,0xfffd361b, +0x0004f1cf,0xfffc332a,0x0006658f,0x00039943, +0xfffb52c0,0x00026ec7,0xfffcbb94,0x0001789f, +0xfffe6160,0x00007677,0x000014d4,0xffff6f74, +0x0001cc9b,0xfffe694f,0x00037cbf,0xfffd6b41, +0x000519c2,0xfffc7baf,0x00069971,0x00035486, +0xfffb2d0c,0x00023ad8,0xfffca3ee,0x00015989, +0xfffe55af,0x00006ca7,0x00001570,0xffff7b71, +0x0001d9cb,0xfffe8b46,0x0003959e,0xfffda1fe, +0x00053ee6,0xfffcc6b4,0x0006c950,0x00030e08, +0xfffb0a7a,0x0002061e,0xfffc8ec0,0x00013911, +0xfffe4b1d,0x00006278,0x000015e8,0xffff87b6, +0x0001e577,0xfffeadd6,0x0003acc2,0xfffdda34, +0x00056059,0xfffd136d,0x0006f4b5,0x0002c562, +0xfffaea7c,0x0001cfa6,0xfffc7b14,0x0001182b, +0xfffe4159,0x00005817,0x0000165c,0xffff9417, +0x0001f00f,0xfffed14c,0x0003c199,0xfffe13f6, +0x00057e83,0xfffd61cd,0x00071ba1,0x00027ab5, +0xfffacdc3,0x00019833,0xfffc6989,0x0000f6ca, +0xfffe38da,0x00004d9d,0x000016ef,0xffffa103, +0x0001f98f,0xfffef5c0,0x0003d3d1,0xfffe4f00, +0x0005998c,0xfffdb21e,0x00073e77,0x00022e75, +0xfffab482,0x00015fd1,0xfffc5b13,0x0000d45d, +0xfffe318f,0x000042ed,0x0000176b,0xffffae8f, +0x0002018f,0xffff1a91,0x0003e40c,0xfffe8af2, +0x0005b0ca,0xfffe03b8,0x00075d14,0x0001e141, +0xfffa9e9b,0x0001262a,0xfffc4e31,0x0000b1af, +0xfffe2b26,0x00003805,0x000017b1,0xffffbc21, +0x000208b8,0xffff3fb6,0x0003f1d7,0xfffec7af, +0x0005c4c5,0xfffe5654,0x0007768a,0x000192fe, +0xfffa8bb0,0x0000ec3f,0xfffc4365,0x00008ec9, +0xfffe25f0,0x00002d05,0x000017ec,0xffffc984, +0x00020ec6,0xffff658d,0x0003fcba,0xffff0500, +0x0005d576,0xfffeaa37,0x00078bc6,0x00014367, +0xfffa7bec,0x0000b1f4,0xfffc3b82,0x00006b06, +0xfffe2201,0x000021eb,0x00001823,0xffffd704, +0x0002132a,0xffff8be7,0x00040534,0xffff4315, +0x0005e22e,0xfffeff0a,0x00079ce3,0x0000f33f, +0xfffa6fc9,0x000076ca,0xfffc3558,0x00004762, +0xfffe1ef3,0x000016a1,0x0000183f,0xffffe4a6, +0x00021664,0xffffb27d,0x00040b7b,0xffff81e5, +0x0005eb4e,0xffff5475,0x0007a857,0x0000a2cb, +0xfffa671b,0x00003b64,0xfffc31e2,0x00002416, +0xfffe1ce1,0x00000b46,0x00001850,0xfffff24d, +0x00021855,0xffffd93a,0x00040f75,0xffffc0e6, +0x0005f0e3,0xffffaa3e,0x0007af45,0x0000519f, +0xfffa6218,0x0003f991,0x0003588d,0x0002b15e, +0x0002056d,0x00015600,0x0000a329,0xffffeed9, +0xffff3960,0xfffe8423,0xfffdd11c,0xfffd2048, +0xfffc7353,0xfffbcb6f,0xfffb29a6,0xfffa8f15, +0x000494ae,0x0003c6b0,0xfffc7e8b,0x00028ef6, +0xfffde181,0x000144eb,0xffff5500,0xffffefb9, +0x0000d01d,0xfffe9755,0x000249a4,0xfffd453c, +0x0003b80e,0xfffc01aa,0x000511d6,0xfffad527, +0xfffb334e,0x0003916c,0xfffc5778,0x00026a92, +0xfffdc9f5,0x00013314,0xffff4d99,0xfffff0b6, +0x0000d911,0xfffeab80,0x00026369,0xfffd6c0a, +0x0003e17f,0xfffc39d8,0x000549df,0xfffb1eb2, +0xfffafe6c,0x00035929,0xfffc3321,0x000244a6, +0xfffdb402,0x00012035,0xffff46ac,0xfffff192, +0x0000e16a,0xfffebfe0,0x00027b3d,0xfffd9433, +0x0004087b,0xfffc74b7,0x00057e8d,0xfffb6a81, +0xfffacc1c,0x00031fbe,0xfffc10df,0x00021e0c, +0xfffd9f6d,0x00010cb7,0xffff402e,0xfffff279, +0x0000e965,0xfffed574,0x00029159,0xfffdbdc4, +0x00042c4c,0xfffcb1e7,0x0005b02d,0xfffbb942, +0xfffa9d38,0x0002e44a,0xfffbf0fd,0x0001f5b4, +0xfffd8c38,0x0000f8b1,0xffff3a21,0xfffff391, +0x0000f0e6,0xfffeec44,0x0002a642,0xfffde90e, +0x00044e32,0xfffcf0fb,0x0005de46,0xfffc0b18, +0xfffa71d1,0x0002a659,0xfffbd3de,0x0001cb90, +0xfffd7a97,0x0000e403,0xffff3490,0xfffff49c, +0x0000f7a8,0xffff0340,0x0002b95f,0xfffe1573, +0x00046dbe,0xfffd3284,0x00060888,0xfffc5f51, +0xfffa4996,0x00026786,0xfffbb8df,0x0001a0e1, +0xfffd6a4e,0x0000ced2,0xffff2f75,0xfffff593, +0x0000fdbe,0xffff1a53,0x0002ca87,0xfffe42f5, +0x0004898a,0xfffd7563,0x00062f0b,0xfffcb5de, +0xfffa2508,0x00022713,0xfffba0bf,0x0001754a, +0xfffd5b5f,0x0000b92c,0xffff2acd,0xfffff6b0, +0x0001034f,0xffff3241,0x0002da5c,0xfffe71c6, +0x0004a341,0xfffdb946,0x000651e8,0xfffd0e37, +0xfffa0402,0x0001e4d4,0xfffb8b9c,0x00014898, +0xfffd4e7d,0x0000a304,0xffff26b7,0xfffff7e1, +0x00010846,0xffff4b34,0x0002e897,0xfffea13f, +0x0004ba63,0xfffdff2d,0x00067115,0xfffd6839, +0xfff9e680,0x0001a1fa,0xfffb789e,0x00011b2e, +0xfffd43a4,0x00008c6e,0xffff2341,0xfffff8fd, +0x00010c9c,0xffff6469,0x0002f48f,0xfffed1a4, +0x0004cd6a,0xfffe4608,0x00068c1b,0xfffdc409, +0xfff9cd15,0x00015dfe,0xfffb68a0,0x0000ecee, +0xfffd3a2e,0x0000757d,0xffff204b,0xfffffa1e, +0x00011054,0xffff7da1,0x0002fe9c,0xffff033e, +0x0004de57,0xfffe8dc6,0x0006a2d5,0xfffe213e, +0xfff9b77d,0x000118d3,0xfffb5bde,0x0000be25, +0xfffd3224,0x00005e52,0xffff1dc1,0xfffffb4b, +0x00011353,0xffff9740,0x00030748,0xffff351c, +0x0004ec95,0xfffed755,0x0006b5b4,0xfffe7fc6, +0xfff9a599,0x0000d334,0xfffb519f,0x00008f08, +0xfffd2bbf,0x00004704,0xffff1bc1,0xfffffc71, +0x00011598,0xffffb135,0x00030e43,0xffff6720, +0x0004f6f3,0xffff2119,0x0006c46e,0xfffedf38, +0xfff997c7,0x00008d13,0xfffb4a55,0x00005fa5, +0xfffd273b,0x00002f76,0xffff1a63,0xfffffda0, +0x00011744,0xffffcb67,0x000312ff,0xffff99cf, +0x0004ff0c,0xffff6a9c,0x0006cebd,0xffff3f0a, +0xfff98dbe,0x00004691,0xfffb4620,0x00003010, +0xfffd24fc,0x000017b5,0xffff199d,0xfffffed8, +0x0001185a,0xffffe5c6,0x0003157e,0xffffcce3, +0x000503ae,0xffffb515,0x0006d537,0xffff9f5a, +0xfff98767,0xfffb44b0,0xfffc3131,0xfffd2475, +0xfffe1c28,0xffff195d,0x00001859,0x000118bd, +0x000218df,0x0003163a,0x000410e0,0x000504a7, +0x0005f2b3,0x0006d796,0x0007b1fe,0xfff98537, +0xfffa609b,0xfffc7e8b,0x00028ef6,0xfffde181, +0x000144eb,0xffff5500,0xffffefb9,0x0000d01d, +0xfffe9755,0x000249a4,0xfffd453c,0x0003b80e, +0xfffc01aa,0x000511d6,0xfffad527,0xfffb334e, +0x0003c6b0,0xfffc5778,0x00026a92,0xfffdc9f5, +0x00013314,0xffff4d99,0xfffff0b6,0x0000d911, +0xfffeab80,0x00026369,0xfffd6c0a,0x0003e17f, +0xfffc39d8,0x000549df,0xfffb1eb2,0xfffafe6c, +0x0003916c,0xfffc3321,0x000244a6,0xfffdb402, +0x00012035,0xffff46ac,0xfffff192,0x0000e16a, +0xfffebfe0,0x00027b3d,0xfffd9433,0x0004087b, +0xfffc74b7,0x00057e8d,0xfffb6a81,0xfffacc1c, +0x00035929,0xfffc10df,0x00021e0c,0xfffd9f6d, +0x00010cb7,0xffff402e,0xfffff279,0x0000e965, +0xfffed574,0x00029159,0xfffdbdc4,0x00042c4c, +0xfffcb1e7,0x0005b02d,0xfffbb942,0xfffa9d38, +0x00031fbe,0xfffbf0fd,0x0001f5b4,0xfffd8c38, +0x0000f8b1,0xffff3a21,0xfffff391,0x0000f0e6, +0xfffeec44,0x0002a642,0xfffde90e,0x00044e32, +0xfffcf0fb,0x0005de46,0xfffc0b18,0xfffa71d1, +0x0002e44a,0xfffbd3de,0x0001cb90,0xfffd7a97, +0x0000e403,0xffff3490,0xfffff49c,0x0000f7a8, +0xffff0340,0x0002b95f,0xfffe1573,0x00046dbe, +0xfffd3284,0x00060888,0xfffc5f51,0xfffa4996, +0x0002a659,0xfffbb8df,0x0001a0e1,0xfffd6a4e, +0x0000ced2,0xffff2f75,0xfffff593,0x0000fdbe, +0xffff1a53,0x0002ca87,0xfffe42f5,0x0004898a, +0xfffd7563,0x00062f0b,0xfffcb5de,0xfffa2508, +0x00026786,0xfffba0bf,0x0001754a,0xfffd5b5f, +0x0000b92c,0xffff2acd,0xfffff6b0,0x0001034f, +0xffff3241,0x0002da5c,0xfffe71c6,0x0004a341, +0xfffdb946,0x000651e8,0xfffd0e37,0xfffa0402, +0x00022713,0xfffb8b9c,0x00014898,0xfffd4e7d, +0x0000a304,0xffff26b7,0xfffff7e1,0x00010846, +0xffff4b34,0x0002e897,0xfffea13f,0x0004ba63, +0xfffdff2d,0x00067115,0xfffd6839,0xfff9e680, +0x0001e4d4,0xfffb789e,0x00011b2e,0xfffd43a4, +0x00008c6e,0xffff2341,0xfffff8fd,0x00010c9c, +0xffff6469,0x0002f48f,0xfffed1a4,0x0004cd6a, +0xfffe4608,0x00068c1b,0xfffdc409,0xfff9cd15, +0x0001a1fa,0xfffb68a0,0x0000ecee,0xfffd3a2e, +0x0000757d,0xffff204b,0xfffffa1e,0x00011054, +0xffff7da1,0x0002fe9c,0xffff033e,0x0004de57, +0xfffe8dc6,0x0006a2d5,0xfffe213e,0xfff9b77d, +0x00015dfe,0xfffb5bde,0x0000be25,0xfffd3224, +0x00005e52,0xffff1dc1,0xfffffb4b,0x00011353, +0xffff9740,0x00030748,0xffff351c,0x0004ec95, +0xfffed755,0x0006b5b4,0xfffe7fc6,0xfff9a599, +0x000118d3,0xfffb519f,0x00008f08,0xfffd2bbf, +0x00004704,0xffff1bc1,0xfffffc71,0x00011598, +0xffffb135,0x00030e43,0xffff6720,0x0004f6f3, +0xffff2119,0x0006c46e,0xfffedf38,0xfff997c7, +0x0000d334,0xfffb4a55,0x00005fa5,0xfffd273b, +0x00002f76,0xffff1a63,0xfffffda0,0x00011744, +0xffffcb67,0x000312ff,0xffff99cf,0x0004ff0c, +0xffff6a9c,0x0006cebd,0xffff3f0a,0xfff98dbe, +0x00008d13,0xfffb4620,0x00003010,0xfffd24fc, +0x000017b5,0xffff199d,0xfffffed8,0x0001185a, +0xffffe5c6,0x0003157e,0xffffcce3,0x000503ae, +0xffffb515,0x0006d537,0xffff9f5a,0xfff98767, +0x00004691,0xfffa609b,0xfffb44b0,0xfffc3131, +0xfffd2475,0xfffe1c28,0xffff195d,0x00001859, +0x000118bd,0x000218df,0x0003163a,0x000410e0, +0x000504a7,0x0005f2b3,0x0006d796,0x0007b1fe, +0xfff98537,0xfffbd51e,0x00032dd1,0xfffd2d8f, +0x0001eb47,0xfffe9968,0x00009af6,0x000011de, +0xffff4335,0x00018d69,0xfffdecd4,0x000302f8, +0xfffca0d7,0x0004683d,0xfffb67f8,0x0005b36d, +0x00045963,0xfffba72a,0x00030062,0xfffd0dee, +0x0001d046,0xfffe8a0a,0x00009258,0x000012b1, +0xffff4d9e,0x00019ec3,0xfffe0a44,0x0003245a, +0xfffcd082,0x000498f0,0xfffba919,0x0005f304, +0x00041bf4,0xfffb7bf1,0x0002d19e,0xfffcf060, +0x0001b407,0xfffe7c08,0x0000894a,0x0000138d, +0xffff58ac,0x0001afaf,0xfffe28fe,0x000343bf, +0xfffd026f,0x0004c6f6,0xfffbed06,0x00062e61, +0x0003dc0e,0xfffb52c0,0x0002a17f,0xfffcd522, +0x000196a0,0xfffe6e70,0x00007ff6,0x00001439, +0xffff63f6,0x0001beb3,0xfffe4882,0x0003616d, +0xfffd361b,0x0004f1cf,0xfffc332a,0x0006658f, +0x00039943,0xfffb2d0c,0x00026ec7,0xfffcbb94, +0x0001789f,0xfffe6160,0x00007677,0x000014d4, +0xffff6f74,0x0001cc9b,0xfffe694f,0x00037cbf, +0xfffd6b41,0x000519c2,0xfffc7baf,0x00069971, +0x00035486,0xfffb0a7a,0x00023ad8,0xfffca3ee, +0x00015989,0xfffe55af,0x00006ca7,0x00001570, +0xffff7b71,0x0001d9cb,0xfffe8b46,0x0003959e, +0xfffda1fe,0x00053ee6,0xfffcc6b4,0x0006c950, +0x00030e08,0xfffaea7c,0x0002061e,0xfffc8ec0, +0x00013911,0xfffe4b1d,0x00006278,0x000015e8, +0xffff87b6,0x0001e577,0xfffeadd6,0x0003acc2, +0xfffdda34,0x00056059,0xfffd136d,0x0006f4b5, +0x0002c562,0xfffacdc3,0x0001cfa6,0xfffc7b14, +0x0001182b,0xfffe4159,0x00005817,0x0000165c, +0xffff9417,0x0001f00f,0xfffed14c,0x0003c199, +0xfffe13f6,0x00057e83,0xfffd61cd,0x00071ba1, +0x00027ab5,0xfffab482,0x00019833,0xfffc6989, +0x0000f6ca,0xfffe38da,0x00004d9d,0x000016ef, +0xffffa103,0x0001f98f,0xfffef5c0,0x0003d3d1, +0xfffe4f00,0x0005998c,0xfffdb21e,0x00073e77, +0x00022e75,0xfffa9e9b,0x00015fd1,0xfffc5b13, +0x0000d45d,0xfffe318f,0x000042ed,0x0000176b, +0xffffae8f,0x0002018f,0xffff1a91,0x0003e40c, +0xfffe8af2,0x0005b0ca,0xfffe03b8,0x00075d14, +0x0001e141,0xfffa8bb0,0x0001262a,0xfffc4e31, +0x0000b1af,0xfffe2b26,0x00003805,0x000017b1, +0xffffbc21,0x000208b8,0xffff3fb6,0x0003f1d7, +0xfffec7af,0x0005c4c5,0xfffe5654,0x0007768a, +0x000192fe,0xfffa7bec,0x0000ec3f,0xfffc4365, +0x00008ec9,0xfffe25f0,0x00002d05,0x000017ec, +0xffffc984,0x00020ec6,0xffff658d,0x0003fcba, +0xffff0500,0x0005d576,0xfffeaa37,0x00078bc6, +0x00014367,0xfffa6fc9,0x0000b1f4,0xfffc3b82, +0x00006b06,0xfffe2201,0x000021eb,0x00001823, +0xffffd704,0x0002132a,0xffff8be7,0x00040534, +0xffff4315,0x0005e22e,0xfffeff0a,0x00079ce3, +0x0000f33f,0xfffa671b,0x000076ca,0xfffc3558, +0x00004762,0xfffe1ef3,0x000016a1,0x0000183f, +0xffffe4a6,0x00021664,0xffffb27d,0x00040b7b, +0xffff81e5,0x0005eb4e,0xffff5475,0x0007a857, +0x0000a2cb,0xfffa6218,0x00003b64,0xfffc31e2, +0x00002416,0xfffe1ce1,0x00000b46,0x00001850, +0xfffff24d,0x00021855,0xffffd93a,0x00040f75, +0xffffc0e6,0x0005f0e3,0xffffaa3e,0x0007af45, +0x0000519f,0x00030000,0x000f0007,0x003f001f, +0x00ff007f,0x03ff01ff,0x0fff07ff,0x3fff1fff, +0xffff7fff,0x00030000,0x00070005,0x000f0009, +0x003f001f,0x00ff007f,0x03ff01ff,0x0fff07ff, +0xffff1fff,0x00030000,0x00070005,0x000f0009, +0xffff001f,0x00030000,0xffff0005,0x04030504, +0x08070605,0x0c0b0a09,0x100f0e0d,0x03070504, +0x0605040a,0x0a090807,0x100d0c0b,0x03070503, +0x1005040a,0x10070502,0x03030100,0x03030303, +0x03030303,0x03030303,0x03010100,0x03030301, +0x03030303,0x03030303,0x03010100,0x03030301, +0x03010100,0x04020000,0x08070605,0x0c0b0a09, +0x100f0e0d,0x02010000,0x06050403,0x0a090807, +0x100d0c0b,0x02010000,0x10050403,0x10010000, +0x00030000,0x00090005,0x001f000f,0x007f003f, +0x01ff00ff,0x07ff03ff,0x1fff0fff,0x7fff3fff, +0x00030000,0x00090005,0x001f000f,0x007f003f, +0x0a070504,0x07060504,0x0b0a0908,0x0f0e0d0c, +0x0a070503,0x07060504,0x01010100,0x03030303, +0x03030303,0x03030303,0x01010100,0x03030303, +0x03010000,0x07060504,0x0b0a0908,0x0f0e0d0c, +0x03010000,0x07060504,0x00555555,0x002aaaab, +0x00249249,0x00124925,0x00111111,0x00088889, +0x00084210,0x00421084,0x00041041,0x00020821, +0x00020408,0x00081020,0x00010101,0x00008081, +0x00008040,0x00100804,0x00004010,0x00020080, +0x00002004,0x00004008,0x00001001,0x00000801, +0x00000800,0x00200100,0x00000400,0x00080020, +0x00000200,0x00020004,0x00200000,0x00600040, +0x00a00080,0x00e000c0,0x01200100,0x01600140, +0x01a00180,0x000001c0,0x00300020,0x00400038, +0x00600050,0x00800070,0x00c000a0,0x010000e0, +0x01800140,0x00200000,0x00300028,0x00400038, +0x00600050,0x00800070,0x00c000a0,0x010000e0, +0x00000140,0x00900000,0x00fc00d8,0x01680120, +0x01f801b0,0x02d00240,0x03f00360,0x05a00480, +0x000006c0,0x00680000,0x00b6009c,0x010500d0, +0x016d0139,0x020a01a1,0x02db0272,0x04140343, +0x000004e5,0x006c0000,0x00bd00a2,0x010e00d8, +0x017a0144,0x006301b0,0x013b00cf,0x00c601a7, +0x0000019e,0x00600000,0x00a80090,0x00f000c0, +0x01500120,0x01e00180,0x02a00240,0x03c00300, +0x00000480,0x10000000,0x10101010,0x20101010, +0x20202020,0x20202020,0x28202020,0x28282828, +0x00002828,0x10100000,0x10101010,0x10101010, +0x00000000,0x00000000,0x00000000,0x00000000, +0xcbcecdc4,0xcfcac9c8,0xc3c6c5cc,0xc7c2c1c0, +0x1b1e1d14,0x1f1a1918,0x1316151c,0x17121110, +0x2b2e2d24,0x2f2a2928,0x2326252c,0x27222120, +0x3b3e3d34,0x3f3a3938,0x3336353c,0x37323130, +0x0b0e0d04,0x0f0a0908,0x0306050c,0x07020100, +0xdbdeddd4,0xdfdad9d8,0xd3d6d5dc,0xd7d2d1d0, +0xebeeede4,0xefeae9e8,0xe3e6e5ec,0xe7e2e1e0, +0xfbfefdf4,0xfffaf9f8,0xf3f6f5fc,0xf7f2f1f0, +0x4b4e4d44,0x4f4a4948,0x4346454c,0x47424140, +0x9b9e9d94,0x9f9a9998,0x9396959c,0x97929190, +0xabaeada4,0xafaaa9a8,0xa3a6a5ac,0xa7a2a1a0, +0xbbbebdb4,0xbfbab9b8,0xb3b6b5bc,0xb7b2b1b0, +0x8b8e8d84,0x8f8a8988,0x8386858c,0x87828180, +0x5b5e5d54,0x5f5a5958,0x5356555c,0x57525150, +0x6b6e6d64,0x6f6a6968,0x6366656c,0x67626160, +0x7b7e7d74,0x7f7a7978,0x7376757c,0x77727170, +0x341424c4,0x3e1e2ece,0x3d1d2dcd,0x3b1b2bcb, +0xb494a444,0xbe9eae4e,0xbd9dad4d,0xbb9bab4b, +0xf4d4e404,0xfedeee0e,0xfddded0d,0xfbdbeb0b, +0x74546484,0x7e5e6e8e,0x7d5d6d8d,0x7b5b6b8b, +0x3c1c2ccc,0x361626c6,0x351525c5,0x331323c3, +0xbc9cac4c,0xb696a646,0xb595a545,0xb393a343, +0xfcdcec0c,0xf6d6e606,0xf5d5e505,0xf3d3e303, +0x7c5c6c8c,0x76566686,0x75556585,0x73536383, +0x381828c8,0x3a1a2aca,0x391929c9,0x3f1f2fcf, +0xb898a848,0xba9aaa4a,0xb999a949,0xbf9faf4f, +0xf8d8e808,0xfadaea0a,0xf9d9e909,0xffdfef0f, +0x78586888,0x7a5a6a8a,0x79596989,0x7f5f6f8f, +0x301020c0,0x321222c2,0x311121c1,0x371727c7, +0xb090a040,0xb292a242,0xb191a141,0xb797a747, +0xf0d0e000,0xf2d2e202,0xf1d1e101,0xf7d7e707, +0x70506080,0x72526282,0x71516181,0x77576787, +0x05040100,0x15141110,0x25242120,0x35343130, +0x85848180,0x95949190,0xa5a4a1a0,0xb5b4b1b0, +0xc0408000,0xe060a020,0xd0509010,0xf070b030, +0xc8488808,0xe868a828,0xd8589818,0xf878b838, +0xc4448404,0xe464a424,0xd4549414,0xf474b434, +0xcc4c8c0c,0xec6cac2c,0xdc5c9c1c,0xfc7cbc3c, +0xc2428202,0xe262a222,0xd2529212,0xf272b232, +0xca4a8a0a,0xea6aaa2a,0xda5a9a1a,0xfa7aba3a, +0xc6468606,0xe666a626,0xd6569616,0xf676b636, +0xce4e8e0e,0xee6eae2e,0xde5e9e1e,0xfe7ebe3e, +0xc1418101,0xe161a121,0xd1519111,0xf171b131, +0xc9498909,0xe969a929,0xd9599919,0xf979b939, +0xc5458505,0xe565a525,0xd5559515,0xf575b535, +0xcd4d8d0d,0xed6dad2d,0xdd5d9d1d,0xfd7dbd3d, +0xc3438303,0xe363a323,0xd3539313,0xf373b333, +0xcb4b8b0b,0xeb6bab2b,0xdb5b9b1b,0xfb7bbb3b, +0xc7478707,0xe767a727,0xd7579717,0xf777b737, +0xcf4f8f0f,0xef6faf2f,0xdf5f9f1f,0xff7fbf3f, +0x1045a3e2,0x000000f4,0x263b7333,0x766b2363, +0x2b367e3e,0x7b662e6e,0x06db93d3,0x964b0343, +0x0bd69ede,0x9b460e4e,0x825f1757,0x12cf87c7, +0x8f521a5a,0x1fc28aca,0x00d199d9,0x90410949, +0x01d098d8,0x91400848,0x24357d3d,0x74652d6d, +0x25347c3c,0x75642c6c,0x04d59ddd,0x94450d4d, +0x05d49cdc,0x95440c4c,0x80511959,0x10c189c9, +0x81501858,0x11c088c8,0x02df97d7,0x924f0747, +0x0fd29ada,0x9f420a4a,0x865b1353,0x16cb83c3, +0x8b561e5e,0x1bc68ece,0xa6bbf3b3,0xf6eba3e3, +0xabb6febe,0xfbe6aeee,0x223f7737,0x726f2767, +0x2f327a3a,0x7f622a6a,0xa0b1f9b9,0xf0e1a9e9, +0xa1b0f8b8,0xf1e0a8e8,0x84551d5d,0x14c58dcd, +0x85541c5c,0x15c48ccc,0xa4b5fdbd,0xf4e5aded, +0xa5b4fcbc,0xf5e4acec,0x20317939,0x70612969, +0x21307838,0x71602868,0xa2bff7b7,0xf2efa7e7, +0xafb2faba,0xffe2aaea,0x00000000,0x00000000, + +}; + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/pcm.h linux.19pre5-ac1/drivers/media/video/ls220/pcm.h --- linux.19p5/drivers/media/video/ls220/pcm.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/ls220/pcm.h Thu Feb 21 21:24:50 2002 @@ -0,0 +1,792 @@ +static u32 PCMUcode1f1800[] = { + 0xb500000f, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xb50001fb, 0x00000000, 0x00000000, 0x00000000, + 0x820f001f, 0x802f001f, 0x029f9014, 0x829efef0, + 0x8286000f, 0x02bf0054, 0x82bcfef4, 0x82a6000e, + 0x80074000, 0x001f6193, 0x8013001f, 0x9020c000, + 0x003fb006, 0x803effe8, 0x803effec, 0x9020fa00, + 0x803effd0, 0x803effdc, 0x803effd8, 0x9020fe00, + 0x803effd4, 0x90400000, 0x804600a2, 0x90421800, + 0x804600a3, 0x80132000, 0x98000040, 0x800600a6, + 0x80050080, 0x98000002, 0x80060080, 0x80070001, + 0x001f2013, 0x80070000, 0x001f23f9, 0x801e4b0c, + 0x001f210c, 0x80070001, 0x001f2324, 0x80070800, + 0x001f600f, 0x001fb0cb, 0x001fb010, 0x801efff0, + 0x98004000, 0x001f600e, 0x83e4011b, 0x80070000, + 0x801e4b14, 0x800500a0, 0xb0000001, 0xb4000009, + 0x80070001, 0x800600a0, 0x80050080, 0x98000020, + 0x80060080, 0x9400ffdf, 0x80060080, 0x80070000, + 0x800600a0, 0x80074000, 0x801e4b04, 0x81df0004, + 0x801bfff0, 0x00000000, 0x940000ff, 0xb0000000, + 0xb4200033, 0x003f400e, 0x94010010, 0xb0000000, + 0xb400fff7, 0x003f0013, 0xb0010001, 0xb420001f, + 0x803bffe8, 0x801bffec, 0x805b4b04, 0x00000000, + 0x3001b800, 0xb4600001, 0x9021a000, 0x0421b800, + 0x3001b802, 0xb460000d, 0x80050086, 0x005f9044, + 0x0420b802, 0xb00101e0, 0xb4a0ffe5, 0x001fb010, + 0x001f010c, 0xb0000001, 0xb400ffe1, 0x80070001, + 0x001f210c, 0x83e400e8, 0xb500ffdd, 0x8007001f, + 0x94000003, 0x5810b800, 0x83e719ec, 0x1bffb800, + 0x003f9008, 0x1821b800, 0x00ffb801, 0x80270000, + 0x003f2013, 0x8007001f, 0x94000003, 0x5810b800, + 0x83671a14, 0x1b7bb800, 0x003f9009, 0x1821b800, + 0x00ffb801, 0x80070000, 0x001f210c, 0xb500ffc8, + 0x003f400e, 0xb0000086, 0xb4400051, 0xb0000084, + 0xb400003b, 0xb0000085, 0xb4000041, 0xb0000086, + 0xb4000043, 0xb0000083, 0xb4000000, 0x815bff7c, + 0x00000000, 0x940a0080, 0x5c07b800, 0xb0000001, + 0xb400006f, 0x81674b18, 0x940a0007, 0x5803b800, + 0x116bb800, 0x005bb80b, 0x916b0004, 0x001bb80b, + 0x806500d4, 0x1463b800, 0x1863b802, 0x806600d4, + 0x80073c21, 0x801e4b00, 0x800600a1, 0x80074000, + 0x801e4b04, 0x8013001f, 0x98405000, 0x805effe0, + 0x005fb006, 0x805effe8, 0x805effec, 0x9042a000, + 0x805effe4, 0x9040fa00, 0x805effd0, 0x805effdc, + 0x805effd8, 0x9040fe00, 0x805effd4, 0x8013007f, + 0x9800ffff, 0x001fb040, 0x80070001, 0x001f2013, + 0x80070000, 0x001f2324, 0x001fb0cb, 0x001fb010, + 0x001fb041, 0x001fb042, 0x80073310, 0x001fb008, + 0x80071e40, 0x001fb009, 0x98214000, 0xb5000010, + 0x94011000, 0xb0001000, 0xb4200001, 0x9421efff, + 0x98210010, 0xb500000a, 0x80070000, 0x001fb0cb, + 0x83e40099, 0x003f400e, 0x9421ffef, 0xb5000004, + 0x83e40095, 0x003f400e, 0x98211000, 0x9421ffef, + 0x003f600e, 0x80070100, 0x801efff0, 0xb500ff74, + 0xb000008b, 0xb4000018, 0xb0000087, 0xb400ffee, + 0xb0000088, 0xb4000016, 0xb000008a, 0xb4000016, + 0xb000008c, 0xb4000017, 0xb0000089, 0xb4000019, + 0xb00000a0, 0xb400001b, 0xb00000a1, 0xb4000047, + 0xb00000a2, 0xb4000054, 0xb00000a3, 0xb400004c, + 0xb00000a4, 0xb4000056, 0xb00000a5, 0xb400005a, + 0xb00000a6, 0xb400005e, 0x803efff8, 0xb500ffe1, + 0x9421ffdf, 0xb500ffde, 0x80270100, 0x803efff8, + 0xb500ffdc, 0x803bffb0, 0x00000000, 0x003fb040, + 0xb500ffd8, 0x803bff80, 0x00000000, 0x003f6001, + 0xb500ffd4, 0x003f90ba, 0x803efff8, 0xb500ffd1, + 0x81674b18, 0x940a0007, 0x5803b800, 0x116bb800, + 0x005bb80b, 0x916b0004, 0x001bb80b, 0x806500d4, + 0x1463b800, 0x1863b802, 0x806600d4, 0x80130001, + 0x98003d21, 0x800600a1, 0x801e4b00, 0x80074000, + 0x801e4b04, 0x8013001f, 0x98405000, 0x805effe0, + 0x005fb006, 0x805effe8, 0x805effec, 0x9042a000, + 0x805effe4, 0x9040fa00, 0x805effd0, 0x805effdc, + 0x805effd8, 0x9040fe00, 0x805effd4, 0x80070001, + 0x001f2013, 0x80070000, 0x001f2324, 0x001fb0cb, + 0x001fb010, 0x80073b00, 0x001fb008, 0x800742f0, + 0x001fb009, 0x98214000, 0xb500ffa5, 0x80270000, + 0x8047fef0, 0x003eb802, 0x90420004, 0x003eb802, + 0x90420004, 0x003eb802, 0x90420004, 0x003eb802, + 0x81df0000, 0x00000000, 0x00000000, 0x8364042b, + 0x81df0004, 0xb500ff97, 0x81df0000, 0x00000000, + 0x00000000, 0x836403d5, 0x81df0004, 0xb500ff91, + 0x81df0000, 0x00000000, 0x00000000, 0x83640390, + 0x81df0004, 0xb500ff8b, 0x81df0000, 0x00000000, + 0x00000000, 0x834402f3, 0x81df0004, 0xb500ff85, + 0x81df0000, 0x00000000, 0x00000000, 0x834402d8, + 0x81df0004, 0xb500ff7f, 0x80070000, 0x80470000, + 0x81df0000, 0x00000000, 0x00000000, 0xb6002003, + 0xb6003002, 0x001eb802, 0x90420004, 0x80171000, + 0x8057ffff, 0xb6002002, 0xb6001801, 0x001fa020, + 0x81df0004, 0x00ffb81f, 0x83a70000, 0x8057ffff, + 0x80770000, 0x8073007d, 0x98636d4a, 0x0207b803, + 0x81df0000, 0x00000000, 0x00000000, 0x80171000, + 0xb6000007, 0x003fc020, 0x005fc7e0, 0x40c1b810, + 0x4102b810, 0x001fe026, 0x001fe0a8, 0x4210b803, + 0x81df0004, 0x80270000, 0x003f2013, 0x8007001f, + 0x94000003, 0x5810b800, 0x83671e1c, 0x1b7bb800, + 0x003f9009, 0x1821b800, 0x00ffb801, 0x003f0013, + 0xb0010001, 0xb420fff3, 0x93bd0001, 0xb01d0004, + 0xb480ffe3, 0x00ffb81f, 0x00000000, 0x00000000, + 0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000, + 0xb4000011, 0x815b4b0c, 0x81070000, 0x81270bf4, + 0xb00a0000, 0xb4000002, 0x81070c00, 0x812717f4, + 0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc, + 0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809, + 0xb4a00060, 0xb5000008, 0xb0040000, 0xb4200003, + 0x802717ff, 0x81470000, 0xb5000003, 0x80270001, + 0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200006, + 0x039f4193, 0x5b81b81c, 0x003f90cb, 0x1021b81c, + 0x003fb0cb, 0x8384024e, 0x829bff80, 0x801300e0, + 0x1434b800, 0x5c35b801, 0x8013001f, 0x1454b800, + 0x5c50b802, 0x8073007f, 0x9863ffff, 0xb002000f, + 0xb4800001, 0x90210001, 0x84210004, 0xb0010000, + 0xb4a00001, 0x6861b803, 0x005f9040, 0x4082b803, + 0x80af001f, 0x808f0000, 0x806f0000, 0x8007ffff, + 0x8033ffff, 0x80171000, 0x81df0000, 0x00000000, + 0x00000000, 0xb6001811, 0xb6002010, 0x14618000, + 0x6068b803, 0x40c4b803, 0x14608000, 0x00c8b806, + 0x5870b803, 0x6068b803, 0x4104b803, 0x58c8b806, + 0x0108b808, 0x14c6b801, 0x00000000, 0x00000000, + 0x5d08b808, 0x1508b800, 0x1806a028, 0x81df0004, + 0x80670400, 0x5d22b80a, 0x81df0000, 0x00000000, + 0x00000000, 0xb600180a, 0x00cfb803, 0x013fb0bc, + 0x5922b809, 0x01afb809, 0x013f90bc, 0x0047b86f, + 0xb0020001, 0xb4c0fffd, 0x90630020, 0x91290020, + 0x81df0004, 0x808f0000, 0x801b4b14, 0x80270001, + 0xb0000001, 0xb4000002, 0x802600a0, 0x803e4b14, + 0x81270c00, 0xb00a0000, 0xb4000001, 0x81270000, + 0x813e4b0c, 0x80270001, 0x003f2013, 0x80050086, + 0x001fb044, 0x00ffb81b, 0x00000000, 0x00000000, + 0x029fb00a, 0x02bfb00b, 0x02dfb00c, 0x02ffb00d, + 0x031fb00e, 0x033fb00f, 0x033f400f, 0x0287b86f, + 0x029fb005, 0x8285009c, 0x96b48000, 0xb0158000, + 0xb4000191, 0x96b40100, 0xb0150100, 0xb40001ad, + 0x96b40400, 0xb0150400, 0xb40001bf, 0x96b40001, + 0xb0150001, 0xb400000c, 0x96b40008, 0xb0150008, + 0xb400019a, 0x96b44000, 0xb0154000, 0xb40001be, + 0x96b40002, 0xb0150002, 0xb400015e, 0x00000000, + 0x00000000, 0xb50001d0, 0x02bf9017, 0x92b50001, + 0x02bfb017, 0x82850082, 0x83050081, 0x82a5009a, + 0x96b50001, 0xb0150001, 0xb4200014, 0x82a70000, + 0x02bfb017, 0x96b41840, 0xb0150800, 0xb420000c, + 0x96b40008, 0x5aa9b815, 0x96d46000, 0x5ec3b816, + 0x82f3000f, 0x9af7c00f, 0x1718b817, 0x1ab5b818, + 0x1ab5b816, 0x9ab50340, 0x82a60081, 0xb500013d, + 0x9b180180, 0x83060081, 0xb500013a, 0x82a5009a, + 0x96b50002, 0xb0150002, 0xb420001b, 0x82a70000, + 0x02bfb017, 0x96b41800, 0xb0151800, 0xb4000013, + 0x96b40040, 0xb0150040, 0xb4200004, 0xa3180c00, + 0x9b180340, 0x83060081, 0xb500012a, 0x96b40008, + 0x5aa9b815, 0x96d46000, 0x5ec3b816, 0x82f3000f, + 0x9af7c00f, 0x1718b817, 0x1ab5b818, 0x1ab5b816, + 0x9ab50340, 0x82a60081, 0xb500011e, 0x9b180180, + 0x83060081, 0xb500011b, 0x82a500c1, 0x96b5000f, + 0xb015000b, 0xb420000e, 0x96b40020, 0xb0150020, + 0xb400000b, 0x96b40200, 0xb0150200, 0xb4000008, + 0x82c50086, 0x82e50094, 0x3016b817, 0xb4400004, + 0x06f7b816, 0xb017ff00, 0xb4400001, 0xb5000109, + 0x96b46000, 0xb0156000, 0xb4000011, 0x96b41820, + 0xb0150820, 0xb4200004, 0x9b391000, 0x82a5009a, + 0x96b5feff, 0x82a6009a, 0x96b40040, 0xb0150040, + 0xb4200001, 0x9739efff, 0x96b91000, 0xb0151000, + 0xb4200003, 0x82a5009a, 0x9ab50100, 0x82a6009a, + 0x96b40040, 0xb0150040, 0xb4200019, 0x96b41800, + 0xb0151800, 0xb4200006, 0x96b98000, 0xb0158000, + 0xb4200003, 0x9b180180, 0x83060081, 0xb50000e9, + 0x96d80c00, 0x82b300ff, 0x9ab5f3ff, 0x1718b815, + 0xb0160c00, 0xb4000007, 0x82e50098, 0x96f70400, + 0xb0170400, 0xb4200002, 0x82c70c00, 0xb5000001, + 0xa2d60c00, 0x1b18b816, 0x9b180340, 0xb50000cf, + 0x96b40220, 0xb0150000, 0xb4e00033, 0x82a5009d, + 0x82f3ffff, 0x16b5b817, 0x82f3000e, 0x3015b817, + 0xb420002d, 0x96f98000, 0xb0178000, 0xb400002a, + 0x82a70000, 0x02bfb017, 0x82c50081, 0x9ab60020, + 0x82a60081, 0x82a50086, 0x92b50bb8, 0x82a60094, + 0x82c60081, 0x82c5009d, 0x96d6ffff, 0x82b30032, + 0x9ab58001, 0x82e500c1, 0x96f7000f, 0xb017000b, + 0xb4000002, 0x82b30022, 0x9ab58001, 0x1ab5b816, + 0x82c5009a, 0x96d60020, 0xb0160020, 0xb4200002, + 0x82b30032, 0x9ab58001, 0x82a6009d, 0x02ff9017, + 0x00000000, 0xb0170040, 0xb480000b, 0x96f41c00, + 0xb0171c00, 0xb4200008, 0x82e50086, 0x82c50094, + 0x92d63000, 0x3016b817, 0xb4400003, 0x9b180180, + 0x83060081, 0xb50000a3, 0x5eb5b814, 0x96b500f0, + 0x96f46000, 0x5eedb817, 0x1ab5b817, 0xb0170003, + 0xb4000004, 0x96b500ef, 0x96f70001, 0x5ae4b817, + 0x1ab5b817, 0x96d41800, 0xb0161800, 0xb400000a, + 0x96f900ff, 0x96b500ff, 0x9739ff00, 0x1b39b815, + 0x02a7b817, 0x96b500f3, 0x96d40008, 0x5ec1b816, + 0x1ab5b816, 0xb500000c, 0x96f98000, 0xb0178000, + 0xb4200007, 0x5efeb814, 0x96f70001, 0xb0170001, + 0xb4000003, 0x9b180180, 0x83060081, 0xb5000081, + 0x96b500f3, 0x9ab50008, 0x9739fff3, 0x96d40020, + 0xb0160020, 0xb4200017, 0x9b398000, 0x82c70000, + 0x02dfb017, 0x96d40010, 0x5ac8b816, 0x82f300ff, + 0x9af7cfff, 0x1718b817, 0x1b18b816, 0x9b180340, + 0x82c5009d, 0x96d6ffff, 0x82f3000e, 0x9af78001, + 0x1af7b816, 0x82c5009a, 0x96d60020, 0xb0160020, + 0xb4200002, 0x82f30032, 0x9af78001, 0x82e6009d, + 0xb500005a, 0x97397fff, 0x96b500ff, 0x5aaab815, + 0x82f300fc, 0x9af703ff, 0x1718b817, 0x1b18b815, + 0x9b180340, 0x82c5009a, 0x96d60010, 0xb0160010, + 0xb4200024, 0x82c70000, 0x02dfb017, 0x82c50086, + 0x92d60bb8, 0x82c60086, 0x82c50094, 0x5eefb818, + 0x96f70003, 0xb0170003, 0xb4200002, 0x82e70bb8, + 0xb5000001, 0x82e70bb8, 0x12d6b817, 0x82e50081, + 0x9af70020, 0x82e60081, 0x82c60094, 0xa2f70020, + 0x82e60081, 0x82f30001, 0x16f7b818, 0x5ef0b817, + 0xb0170001, 0xb4000004, 0x96f84000, 0x5ee4b817, + 0x9718f3ff, 0x1b18b817, 0x82f3000a, 0x9af78000, + 0x82e6009d, 0x83060081, 0x83070001, 0x8306009f, + 0xb50000ad, 0x82c5009d, 0x82f3000e, 0x9af78001, + 0x3016b817, 0xb420000f, 0x82b30032, 0x9ab58001, + 0x82e500c1, 0x96f7000f, 0xb017000b, 0xb4000002, + 0x82b30022, 0x9ab58001, 0x82c5009a, 0x96d60020, + 0xb0160020, 0xb4200002, 0x82b30032, 0x9ab58001, + 0x82a6009d, 0x82c5009a, 0x96d60080, 0xb0160080, + 0xb4000011, 0x02df9017, 0x00000000, 0xb0160010, + 0xb480000d, 0x82c500c1, 0x96d6000f, 0xb016000b, + 0xb4000009, 0x82c50087, 0x96d60080, 0x5ac7b816, + 0x96f84000, 0x3017b816, 0xb4200003, 0x033f400f, + 0x9b394000, 0xb500000b, 0x9739bfff, 0x82e50061, + 0x96f70008, 0xb0170008, 0xb4000005, 0x5eefb818, + 0x96f70003, 0xb0170003, 0xb4000001, 0x9718ffff, + 0x83060081, 0x83070001, 0x8306009f, 0x00000000, + 0xb5000075, 0x82850083, 0x96b400ff, 0xb015003c, + 0xb4200019, 0x96b92000, 0xb0152000, 0xb4000002, + 0x9b392000, 0xb5000014, 0x9739d3ff, 0x82870000, + 0x82860087, 0x82870008, 0x82860083, 0x829bff78, + 0x82a7001f, 0xb0140400, 0xb4000001, 0x82a70010, + 0x82a600c9, 0x829bff78, 0x00000000, 0x828600cb, + 0x8285009d, 0x82b3ffff, 0x9ab5fffd, 0x1694b815, + 0x8286009d, 0xb5000000, 0x83070002, 0x8306009f, + 0x00000000, 0xb5000054, 0x96b90800, 0xb0150800, + 0xb4200009, 0x9739f7ff, 0x82a703fd, 0x82a600cb, + 0x82a7003c, 0x82a60083, 0x8285009d, 0x9a940002, + 0x8286009d, 0xb5000004, 0x82850087, 0x5a82b814, + 0xa2940200, 0x82860087, 0xb5000000, 0x83078000, + 0x8306009f, 0x00000000, 0xb500003f, 0x82850086, + 0x82a50094, 0x3015b814, 0xb4800002, 0x86b50bb8, + 0x82a60086, 0x83070008, 0x8306009f, 0x00000000, + 0xb5000035, 0x83050069, 0x9718003f, 0x82e50064, + 0x12f7b818, 0x86f70088, 0x82feff74, 0x02e7b86f, + 0x9af74000, 0x01ffb817, 0x96f7bfff, 0x01ffb817, + 0x83050081, 0x82f3001c, 0x9af703ff, 0x1718b817, + 0x9b180140, 0x83060081, 0x83070100, 0x8306009f, + 0x00000000, 0xb5000020, 0x83070000, 0x83050081, + 0x9b180180, 0x83060081, 0x83070400, 0x8306009f, + 0x00000000, 0xb5000018, 0x82870000, 0x82850082, + 0x5eb7b814, 0x96b500fc, 0x96d40006, 0x5ec1b816, + 0x1ab5b816, 0x5aacb815, 0x83050081, 0x82d3001c, + 0x9ad600ff, 0x1718b816, 0x1b18b815, 0x9b180e00, + 0x83060081, 0x83074000, 0x8306009f, 0x8305009d, + 0x82d300ff, 0x9ad6bfff, 0x1718b816, 0x8306009d, + 0x00000000, 0xb5000000, 0x029f9005, 0x01ffb814, + 0x033f600f, 0x029f900a, 0x02bf900b, 0x02df900c, + 0x02ff900d, 0x031f900e, 0x033f900f, 0x00ffb81e, + 0x02ff9010, 0x92f70b43, 0x02ffb010, 0x02ff90cb, + 0x82bbffdc, 0x829bffd8, 0x93150004, 0x3014b815, + 0xb4000010, 0x02dbb818, 0x029bb815, 0x3017b816, + 0xb480000c, 0x5a81b814, 0x029fb010, 0x82860095, + 0x8293001f, 0x9294fe00, 0x92b50008, 0x3015b814, + 0xb4800002, 0x82b3001f, 0x92b5fa00, 0x82beffdc, + 0xb500ffeb, 0x029f9010, 0x83250094, 0x06d4b819, + 0x02d6b816, 0xb016ffff, 0xb4a0000a, 0x8293000e, + 0x9a948001, 0x82c5009d, 0x96d6ffff, 0x1a94b816, + 0x82c5009a, 0x96d60010, 0xb0160010, 0xb4000001, + 0x8286009d, 0x00ffb81c, 0x00000000, 0x00000000, + 0x001f9012, 0x001fb100, 0x001f004c, 0x001f2404, + 0x801bfef0, 0x8058fef4, 0x803bff68, 0x8078ff6c, + 0x2000b801, 0x2042b803, 0x001fb104, 0x005f2414, + 0x82e70001, 0x83640048, 0x029fb014, 0x829efef0, + 0x8286000f, 0x02bf2054, 0x82bcfef4, 0x82a6000e, + 0x00ffb81a, 0x80e70001, 0x801336e3, 0x9800eb76, + 0x001fb100, 0x800700ab, 0x001f2404, 0x801bc3e8, + 0x8058c3ec, 0x83640024, 0x82e70000, 0x83640036, + 0x029fb300, 0x029fb100, 0x02bf2c04, 0x02bf2404, + 0x801bc000, 0x8058c004, 0x8364001b, 0x82e70000, + 0x8364002d, 0x001f9300, 0x3000b814, 0xb420000a, + 0x001f0c04, 0x3000b815, 0xb4200007, 0x829efef0, + 0x82bcfef4, 0x029fb012, 0x02bf204c, 0x82870001, + 0x829cfef5, 0x00ffb81a, 0xb0070000, 0xb4000007, + 0x80e70000, 0x801399fa, 0x9800c92e, 0x001fb100, + 0x800700af, 0x001f2404, 0xb500ffdc, 0x82870000, + 0x829cfef5, 0x00ffb81a, 0x80c700ff, 0x803bff68, + 0x8078ff6c, 0x14a0b806, 0x2063b805, 0x007f2414, + 0x2021b802, 0x58c8b806, 0x14a0b806, 0x58b0b805, + 0x2021b805, 0x58c8b806, 0x14a0b806, 0x2021b805, + 0x58c8b806, 0x14a0b806, 0x5cb0b805, 0x2021b805, + 0x003fb104, 0x00ffb81b, 0x82c70000, 0x83070400, + 0x83270005, 0x8197040c, 0x81d7ffff, 0x83840126, + 0x83840001, 0x00ffb81b, 0x808f0000, 0x806f001f, + 0x80af001f, 0x80270140, 0x81e70228, 0x5de2b80f, + 0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, + 0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020, + 0x90210020, 0x80270180, 0x81e70120, 0x5de2b80f, + 0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, + 0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020, + 0x90210020, 0x8057ffff, 0x80170430, 0x80070410, + 0x80270408, 0xb6000509, 0x005ff000, 0x90420500, + 0x007ff001, 0x90630600, 0x009ff002, 0x00bff003, + 0x2004a025, 0x90000001, 0x90210001, 0x80070414, + 0x80d7ffff, 0x8097045c, 0x8017043c, 0xb6000404, + 0x005ff000, 0x007f87e0, 0x84000001, 0x2082a7e3, + 0x80970460, 0x80170440, 0x2082b803, 0x007f8000, + 0x2083a004, 0x80170430, 0x80970450, 0x80270408, + 0xb6000508, 0x005f8024, 0x90420500, 0x007ff001, + 0x90630600, 0x009ff002, 0x00bff003, 0x2004a025, + 0x90210001, 0x80170440, 0x00000000, 0x02bf87e0, + 0x80970460, 0x82870000, 0xb6000404, 0x005f87e4, + 0x5a88b814, 0x204287e0, 0x1a94b802, 0x00ffb81c, + 0x001f0a49, 0x001f2709, 0x001f0a41, 0x001f2708, + 0x001f0a46, 0x001f2707, 0x001f0a48, 0x001f2706, + 0x001f0a42, 0x001f2705, 0x001f0a47, 0x001f2704, + 0x001f0a45, 0x001f2703, 0x001f0a43, 0x001f2702, + 0x001f0a40, 0x001f2701, 0x001f0a44, 0x001f2700, + 0x001f0c25, 0xa020000c, 0x94400001, 0x94600002, + 0x94810004, 0x94a10008, 0x94c00010, 0x5943b802, + 0x5861b803, 0x5882b804, 0x5ca2b805, 0x5cc4b806, + 0x194ab803, 0x194ab804, 0x194ab805, 0x194ab806, + 0x015f2738, 0x801b0220, 0x003f91c1, 0x5c28b801, + 0x005f91c2, 0x5858b802, 0x1821b802, 0x2000b801, + 0x001fb1c4, 0x80180224, 0x003f0709, 0x2000b801, + 0x001f2714, 0x82c70001, 0x82e70001, 0x83070710, + 0x8327001e, 0x81970735, 0x8384009f, 0x02df0738, + 0x82170a30, 0x838400f1, 0x819efef0, 0x817cfef4, + 0x819eff68, 0x817cff6c, 0x00ffb81b, 0x820f001f, + 0x8018fef8, 0x8057ffff, 0x001f2709, 0x8018fef6, + 0x80d7ffff, 0x001f2708, 0x8018fefa, 0x8157ffff, + 0x001f2707, 0x8018fefd, 0x81d7ffff, 0x001f2706, + 0x8018fefb, 0x802f001f, 0x001f2705, 0x8018fefe, + 0x00000000, 0x001f2704, 0x8018fef9, 0x00000000, + 0x001f2703, 0x8018feff, 0x00000000, 0x001f2702, + 0x8018fef7, 0x00000000, 0x001f2701, 0x8018fefc, + 0x00000000, 0x001f2700, 0x001f0c25, 0xa0200011, + 0x94410001, 0x94600002, 0x94800004, 0x94a00008, + 0x94c10010, 0x5941b802, 0x5861b803, 0x5c82b804, + 0x58a1b805, 0x5cc1b806, 0x194ab803, 0x194ab804, + 0x194ab805, 0x194ab806, 0x015f2738, 0x801b0220, + 0x003f91c1, 0x5c28b801, 0x005f91c2, 0x5858b802, + 0x1821b802, 0x2000b801, 0x001fb1c4, 0x80180224, + 0x003f0709, 0x2000b801, 0x001f2714, 0x82c70001, + 0x82e70001, 0x83070710, 0x8327001e, 0x81970735, + 0x83840055, 0x02df0738, 0x82170a20, 0x838400a7, + 0x819efef0, 0x817cfef4, 0x5ac8b80c, 0x02ff0a44, + 0x1ad6b817, 0x02dfb291, 0x5ed8b80c, 0x5968b80b, + 0x1ad6b80b, 0x02df6524, 0x00ffb81b, 0x820f001f, + 0x8018fefe, 0x8057ffff, 0x001f2709, 0x8018fefa, + 0x80d7ffff, 0x001f2708, 0x8018fefc, 0x8157ffff, + 0x001f2707, 0x8018feff, 0x81d7ffff, 0x001f2706, + 0x8018fef8, 0x802f001f, 0x001f2705, 0x8018fefb, + 0x00000000, 0x001f2704, 0x8018fefd, 0x00000000, + 0x001f2703, 0x8018fef6, 0x00000000, 0x001f2702, + 0x8018fef9, 0x00000000, 0x001f2701, 0x8018fef7, + 0x00000000, 0x001f2700, 0x801b0220, 0x003f91c1, + 0x5c28b801, 0x005f91c2, 0x5858b802, 0x1821b802, + 0x2000b801, 0x001fb1c4, 0x80180224, 0x003f0709, + 0x2000b801, 0x001f2714, 0x82c70001, 0x82e70001, + 0x83070710, 0x8327001e, 0x81970735, 0x83840016, + 0x83270000, 0x831bfef0, 0x82f8fef4, 0x02c7b819, + 0x82170a28, 0x83840065, 0x300cb818, 0xb4200002, + 0x300bb817, 0xb4000006, 0x93390001, 0xb0190020, + 0xb480fff6, 0x83270000, 0x833cfef5, 0x00ffb81b, + 0x019fb290, 0x017f2a44, 0x033f2c25, 0x83270001, + 0x833cfef5, 0x00ffb81b, 0x0007b818, 0x90000003, + 0x00000000, 0x015ff000, 0x90000001, 0x5949b80a, + 0x013ff000, 0x194ab809, 0x84000002, 0x994a0100, + 0x017ff000, 0x958b00f8, 0x5981b80c, 0x956b0007, + 0x198cb80b, 0x84000002, 0x998c0008, 0x017ff000, + 0x90000001, 0x5971b80b, 0x198cb80b, 0x017ff000, + 0x5969b80b, 0x198cb80b, 0x81a70000, 0x94d90003, + 0x82a70000, 0xb6260019, 0xb6000818, 0x5df0b80a, + 0x5e02b80a, 0x21efb810, 0x95ef0001, 0x5941b80a, + 0x194ab80f, 0x21efb816, 0x5e18b80c, 0x5e35b80c, + 0x5e54b80c, 0x5e6cb80c, 0x2210b811, 0x2252b813, + 0x2210b812, 0x96100001, 0x5981b80c, 0x198cb810, + 0x2210b817, 0x10afb810, 0x10a5b80d, 0x5da1b805, + 0x94a50001, 0x5aa1b815, 0x1ab5b805, 0x019fa7f5, + 0x5cc2b819, 0xb626001c, 0x82870000, 0xb6000419, + 0xb6000818, 0x5df0b80a, 0x5e02b80a, 0x21efb810, + 0x95ef0001, 0x5941b80a, 0x194ab80f, 0x21efb816, + 0x5e18b80c, 0x5e35b80c, 0x5e54b80c, 0x5e6cb80c, + 0x2210b811, 0x2252b813, 0x2210b812, 0x96100001, + 0x5981b80c, 0x198cb810, 0x2210b817, 0x10afb810, + 0x10a5b80d, 0x5da1b805, 0x94a50001, 0x5a81b814, + 0x1a94b805, 0x019fa7f4, 0x00ffb81c, 0x8257ffff, + 0x808f0000, 0x806f001f, 0x80af001f, 0x80270200, + 0x81e7ff00, 0x5de2b80f, 0xb6000208, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0xb520ffff, 0x91ef0020, 0x90210020, 0x80270240, + 0x81e70000, 0x5de2b80f, 0xb6000208, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0xb520ffff, 0x91ef0020, 0x90210020, 0x80270180, + 0x81e70120, 0x5de2b80f, 0xb6000208, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0xb520ffff, 0x91ef0020, 0x90210020, 0x806f0007, + 0x80af0007, 0x80270280, 0x81e70100, 0x5de2b80f, + 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, + 0x01ff90bc, 0xb520ffff, 0x91ef0020, 0x90210020, + 0x80170760, 0x001f0700, 0x001fa020, 0x001f0701, + 0x001fa020, 0x001f0702, 0x001fa020, 0x001f0703, + 0x001fa020, 0x001f0704, 0x001fa000, 0x80970750, + 0x81170770, 0x82a70735, 0x83a40060, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a4005c, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750, + 0x81170750, 0x81970740, 0x82a70730, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a40050, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a4004c, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970750, 0x80170770, + 0x81170770, 0x81970760, 0x82a7072b, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a40040, 0x83a4004e, + 0xb6000407, 0x86b50001, 0x83a4003c, 0x001f8004, + 0x003f87e8, 0x2080a001, 0x83a40047, 0x00000000, + 0x80970770, 0x80170750, 0x81170750, 0x81970740, + 0x82a70726, 0x001f800c, 0x003f8008, 0x2100a001, + 0x83a4002e, 0x83a4003c, 0xb6000407, 0x86b50001, + 0x83a4002a, 0x001f8004, 0x003f87e8, 0x2080a001, + 0x83a40035, 0x00000000, 0x80970750, 0x80170770, + 0x81170770, 0x81970760, 0x82a70721, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a4001c, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a40018, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750, + 0x81170750, 0x81970740, 0x82a7071c, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a4000c, 0x017f87e4, + 0x81870000, 0xb6000406, 0x86b50001, 0x83a40007, + 0x001f87e4, 0x200087e8, 0x5988b80c, 0x198cb800, + 0x021fa02c, 0x021fa00b, 0x00ffb81c, 0x005ff015, + 0x90420600, 0x003f87e0, 0x001ff002, 0x2060b801, + 0x90630800, 0x90960a00, 0x001ff003, 0x003ff004, + 0x20a0b801, 0x90a50900, 0x00000000, 0x001ff005, + 0x009fa000, 0x00ffb81d, 0x001f8004, 0x5c21b800, + 0x5847b800, 0x1821b802, 0x942100ff, 0x2080a7e1, + 0x00ffb81d, 0x00000000, 0x00000000, 0x00000000, + 0x829bff80, 0x80af001f, 0x808f0000, 0x806f0000, + 0x82bbffec, 0x82fbffe4, 0x00000000, 0x82beffb8, + 0x95540700, 0x5d48b80a, 0x914a0001, 0x0227b80a, + 0x94343000, 0x5c2cb801, 0xb0010000, 0xb4000001, + 0x5a21b811, 0x9574c000, 0x5d6eb80b, 0x918b4b08, + 0x01b8b80c, 0x96d5ffff, 0x5ec2b816, 0x96f7ffff, + 0x5ee2b817, 0x8057ffff, 0x80d7ffff, 0x8157ffff, + 0x81d7ffff, 0x81f3ff00, 0x99efff00, 0x821300ff, + 0x9a1000ff, 0x81971000, 0x82670000, 0x82470000, + 0x80270280, 0x81df0000, 0x00000000, 0x00000000, + 0xb62d000d, 0x3016b817, 0xb4800001, 0x86d62800, + 0x00cfb801, 0x02dfb0bc, 0x5ac2b816, 0x01cfb816, + 0x02df90bc, 0x0067b86f, 0xb0030001, 0xb4c0fffd, + 0x92d60020, 0x90210020, 0x81df0004, 0x80170a00, + 0x81df0000, 0x00000000, 0x00000000, 0xb62d0006, + 0xb6002005, 0x146f8000, 0x14908000, 0x5c68b803, + 0x5888b804, 0x1803a024, 0x81df0004, 0x80170a00, + 0x80970d00, 0xb00b0000, 0xb4000004, 0xb00b0001, + 0xb400000a, 0xb00b0002, 0xb4000027, 0x81df0000, + 0x00000000, 0x00000000, 0xb6008002, 0x007f8020, + 0x009fa023, 0x81df0004, 0xb5000029, 0x80d3ffff, + 0x81df0000, 0x00000000, 0x00000000, 0xb6002018, + 0x5c648000, 0x9463ffff, 0x5c888020, 0x58b88000, + 0x1884b805, 0x1484b806, 0x1883a024, 0x5c6c8020, + 0x9463ffff, 0x58908000, 0x1883a024, 0x5c748020, + 0x588c8000, 0x1863b804, 0x9463ffff, 0x58888000, + 0x1484b806, 0x1883a024, 0x5c7c8020, 0x58848000, + 0x1863b804, 0x9463ffff, 0x14868020, 0x1883a024, + 0x81df0004, 0xb500000a, 0x80d3ffff, 0x81df0000, + 0x00000000, 0x00000000, 0xb6004004, 0x007f8020, + 0x009fa023, 0x007f8040, 0x009fa023, 0x81df0004, + 0x00000000, 0x81170d00, 0x80070000, 0x94343000, + 0x5c2cb801, 0xb0010001, 0xb400008e, 0xb00a0001, + 0xb400000e, 0xb00a0002, 0xb400001c, 0xb00a0003, + 0xb4000024, 0xb00a0004, 0xb4000052, 0xb00a0005, + 0xb400005b, 0xb00a0006, 0xb400007f, 0xb00a0007, + 0xb400007d, 0xb00a0008, 0xb400007b, 0x81df0000, + 0x00000000, 0x00000000, 0xb600800a, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020, + 0x5c708028, 0x9463ffff, 0x019fa023, 0x019fa020, + 0x019fa020, 0x81df0004, 0xb500006b, 0x81df0000, + 0x00000000, 0x00000000, 0xb6008004, 0x007f8028, + 0x019fa023, 0x019fa020, 0x019fa020, 0x81df0004, + 0xb5000061, 0xb0130000, 0xb4000004, 0xb0130001, + 0xb4000009, 0xb0130002, 0xb400001a, 0x83a400fa, + 0x80170f00, 0x007f8028, 0x001fa023, 0x007f8028, + 0x001fa023, 0xb5000054, 0x80170f00, 0x00000000, + 0x007f8020, 0x019fa023, 0x007f8000, 0x9463ffff, + 0x019fa023, 0x019fa020, 0x5c708020, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020, + 0x83a400e5, 0x80170f00, 0x007f8028, 0x001fa023, + 0xb5000041, 0x80170f00, 0x00000000, 0x007f8020, + 0x019fa023, 0x007f8008, 0x9463ffff, 0x019fa023, + 0x019fa020, 0x5c708028, 0x58908008, 0x1983a024, + 0x5c708028, 0x019fa023, 0x019fa020, 0x83a400d2, + 0xb5000031, 0x81df0000, 0x00000000, 0x00000000, + 0xb6004005, 0x007f8008, 0x019fa023, 0x007f8008, + 0x019fa023, 0x019fa020, 0x81df0004, 0xb5000026, + 0xb0130000, 0xb4000008, 0xb0130001, 0xb4000012, + 0xb0130002, 0xb400001f, 0xb0130003, 0xb400001d, + 0xb0130004, 0xb400001b, 0x83a400cd, 0x007f8028, + 0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x80170f00, 0x007f8028, + 0x001fa023, 0xb5000010, 0x80170f00, 0x00000000, + 0x5c708020, 0x58908008, 0x1983a024, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x83a400b7, 0x80170f00, 0x007f8028, 0x001fa023, + 0xb5000001, 0xb5000000, 0x00000000, 0x00000000, + 0xb5000086, 0xb00a0001, 0xb400000e, 0xb00a0002, + 0xb4000017, 0xb00a0003, 0xb400001f, 0xb00a0004, + 0xb400004d, 0xb00a0005, 0xb4000056, 0xb00a0006, + 0xb400007a, 0xb00a0007, 0xb4000078, 0xb00a0008, + 0xb4000076, 0x81df0000, 0x00000000, 0x00000000, + 0xb6008005, 0x007f8028, 0x9463ffff, 0x019fa023, + 0x019fa020, 0x019fa020, 0x81df0004, 0xb500006b, + 0x81df0000, 0x00000000, 0x00000000, 0xb6004004, + 0x007f8048, 0x019fa023, 0x019fa020, 0x019fa020, + 0x81df0004, 0xb5000061, 0xb0130000, 0xb4000004, + 0xb0130001, 0xb4000009, 0xb0130002, 0xb400001a, + 0x83a40098, 0x80170f00, 0x007f8028, 0x001fa023, + 0x007f8028, 0x001fa023, 0xb5000054, 0x80170f00, + 0x00000000, 0x007f8020, 0x019fa023, 0x007f8000, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708020, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x019fa020, 0x83a40083, 0x80170f00, 0x007f8028, + 0x001fa023, 0xb5000041, 0x80170f00, 0x00000000, + 0x007f8020, 0x019fa023, 0x007f8008, 0x9463ffff, + 0x019fa023, 0x019fa020, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020, + 0x83a40070, 0xb5000031, 0x81df0000, 0x00000000, + 0x00000000, 0xb6004005, 0x007f8008, 0x019fa023, + 0x007f8008, 0x019fa023, 0x019fa020, 0x81df0004, + 0xb5000026, 0xb0130000, 0xb4000008, 0xb0130001, + 0xb4000012, 0xb0130002, 0xb400001f, 0xb0130003, + 0xb400001d, 0xb0130004, 0xb400001b, 0x83a4006b, + 0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023, + 0x007f8008, 0x9463ffff, 0x019fa023, 0x80170f00, + 0x007f8028, 0x001fa023, 0xb5000010, 0x80170f00, + 0x00000000, 0x5c708020, 0x58908008, 0x1983a024, + 0x5c708028, 0x58908008, 0x1983a024, 0x5c708028, + 0x019fa023, 0x83a40055, 0x80170f00, 0x007f8028, + 0x001fa023, 0xb5000001, 0xb5000000, 0x92730001, + 0x92520001, 0x3012b811, 0xb480fe89, 0x003f0324, + 0x90210001, 0xb0010006, 0xb4a00001, 0x80270001, + 0x003f2324, 0x2c8db811, 0x803bffe0, 0x805bffe4, + 0x5887b804, 0x1015b804, 0xad440003, 0x3000b802, + 0xb4800001, 0x8400a000, 0x801effec, 0x015f6193, + 0x809e4b04, 0x00ffb81f, 0x81df0000, 0x00000000, + 0x00000000, 0xb6002a0c, 0x007f8028, 0x019fa023, + 0x007f8008, 0x9463ffff, 0x019fa023, 0x019fa020, + 0x5c708028, 0x58908008, 0x1983a024, 0x5c708028, + 0x019fa023, 0x019fa020, 0x81df0004, 0x00ffb81d, + 0x81df0000, 0x00000000, 0x00000000, 0xb600190f, + 0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023, + 0x007f8008, 0x9463ffff, 0x019fa023, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x81df0004, + 0x00ffb81d, 0x81df0000, 0x00000000, 0x00000000, + 0xb6002a0c, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x019fa020, 0x81df0004, 0x00ffb81d, 0x81df0000, + 0x00000000, 0x00000000, 0xb600190f, 0x007f8028, + 0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x58908008, 0x1983a024, + 0x5c708028, 0x019fa023, 0x81df0004, 0x00ffb81d, + 0x829bff80, 0x80af001f, 0x808f0000, 0x806f0000, + 0x82bbffec, 0x82fbffe4, 0x00000000, 0x82beffb8, + 0x95540700, 0x5d48b80a, 0x914a0001, 0x0227b80a, + 0x94343000, 0x5c2cb801, 0xb0010000, 0xb4000001, + 0x5a21b811, 0x9574c000, 0x5d6eb80b, 0x918b4b08, + 0x01b8b80c, 0x96d5ffff, 0x5ec2b816, 0x96f7ffff, + 0x5ee2b817, 0x8057ffff, 0x80d7ffff, 0x8157ffff, + 0x81d7ffff, 0x81f3ff00, 0x99efff00, 0x821300ff, + 0x9a1000ff, 0x81971000, 0x82670000, 0x82470000, + 0x80270280, 0x81df0000, 0x00000000, 0x00000000, + 0xb62d000d, 0x3016b817, 0xb4800001, 0x86d62800, + 0x00cfb801, 0x02dfb0bc, 0x5ac2b816, 0x01cfb816, + 0x02df90bc, 0x0067b86f, 0xb0030001, 0xb4c0fffd, + 0x92d60020, 0x90210020, 0x81df0004, 0x80170a00, + 0x81df0000, 0x00000000, 0x00000000, 0xb62d0006, + 0xb6002005, 0x146f8000, 0x14908000, 0x5c68b803, + 0x5888b804, 0x1803a024, 0x81df0004, 0x80170a00, + 0x80970d00, 0xb00b0000, 0xb4000004, 0xb00b0001, + 0xb400000a, 0xb00b0002, 0xb4000027, 0x81df0000, + 0x00000000, 0x00000000, 0xb6008002, 0x007f8020, + 0x009fa023, 0x81df0004, 0xb5000029, 0x80d3ffff, + 0x81df0000, 0x00000000, 0x00000000, 0xb6002018, + 0x5c648000, 0x9463ffff, 0x5c888020, 0x58b88000, + 0x1884b805, 0x1484b806, 0x1883a024, 0x5c6c8020, + 0x9463ffff, 0x58908000, 0x1883a024, 0x5c748020, + 0x588c8000, 0x1863b804, 0x9463ffff, 0x58888000, + 0x1484b806, 0x1883a024, 0x5c7c8020, 0x58848000, + 0x1863b804, 0x9463ffff, 0x14868020, 0x1883a024, + 0x81df0004, 0xb500000a, 0x80d3ffff, 0x81df0000, + 0x00000000, 0x00000000, 0xb6004004, 0x007f8020, + 0x009fa023, 0x007f8040, 0x009fa023, 0x81df0004, + 0x00000000, 0x81170d00, 0x80070000, 0x94343000, + 0x5c2cb801, 0xb0010001, 0xb400008e, 0xb00a0001, + 0xb400000e, 0xb00a0002, 0xb400001c, 0xb00a0003, + 0xb4000024, 0xb00a0004, 0xb4000052, 0xb00a0005, + 0xb400005b, 0xb00a0006, 0xb400007f, 0xb00a0007, + 0xb400007d, 0xb00a0008, 0xb400007b, 0x81df0000, + 0x00000000, 0x00000000, 0xb600800a, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020, + 0x5c708028, 0x9463ffff, 0x019fa023, 0x019fa020, + 0x019fa020, 0x81df0004, 0xb500006b, 0x81df0000, + 0x00000000, 0x00000000, 0xb6008004, 0x007f8028, + 0x019fa023, 0x019fa020, 0x019fa020, 0x81df0004, + 0xb5000061, 0xb0130000, 0xb4000004, 0xb0130001, + 0xb4000009, 0xb0130002, 0xb400001a, 0x83a400fa, + 0x80170f00, 0x007f8028, 0x001fa023, 0x007f8028, + 0x001fa023, 0xb5000054, 0x80170f00, 0x00000000, + 0x007f8020, 0x019fa023, 0x007f8000, 0x9463ffff, + 0x019fa023, 0x019fa020, 0x5c708020, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020, + 0x83a400e5, 0x80170f00, 0x007f8028, 0x001fa023, + 0xb5000041, 0x80170f00, 0x00000000, 0x007f8020, + 0x019fa023, 0x007f8008, 0x9463ffff, 0x019fa023, + 0x019fa020, 0x5c708028, 0x58908008, 0x1983a024, + 0x5c708028, 0x019fa023, 0x019fa020, 0x83a400d2, + 0xb5000031, 0x81df0000, 0x00000000, 0x00000000, + 0xb6004005, 0x007f8008, 0x019fa023, 0x007f8008, + 0x019fa023, 0x019fa020, 0x81df0004, 0xb5000026, + 0xb0130000, 0xb4000008, 0xb0130001, 0xb4000012, + 0xb0130002, 0xb400001f, 0xb0130003, 0xb400001d, + 0xb0130004, 0xb400001b, 0x83a400cd, 0x007f8028, + 0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x80170f00, 0x007f8028, + 0x001fa023, 0xb5000010, 0x80170f00, 0x00000000, + 0x5c708020, 0x58908008, 0x1983a024, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x83a400b7, 0x80170f00, 0x007f8028, 0x001fa023, + 0xb5000001, 0xb5000000, 0x00000000, 0x00000000, + 0xb5000086, 0xb00a0001, 0xb400000e, 0xb00a0002, + 0xb4000017, 0xb00a0003, 0xb400001f, 0xb00a0004, + 0xb400004d, 0xb00a0005, 0xb4000056, 0xb00a0006, + 0xb400007a, 0xb00a0007, 0xb4000078, 0xb00a0008, + 0xb4000076, 0x81df0000, 0x00000000, 0x00000000, + 0xb6008005, 0x007f8028, 0x9463ffff, 0x019fa023, + 0x019fa020, 0x019fa020, 0x81df0004, 0xb500006b, + 0x81df0000, 0x00000000, 0x00000000, 0xb6004004, + 0x007f8048, 0x019fa023, 0x019fa020, 0x019fa020, + 0x81df0004, 0xb5000061, 0xb0130000, 0xb4000004, + 0xb0130001, 0xb4000009, 0xb0130002, 0xb400001a, + 0x83a40098, 0x80170f00, 0x007f8028, 0x001fa023, + 0x007f8028, 0x001fa023, 0xb5000054, 0x80170f00, + 0x00000000, 0x007f8020, 0x019fa023, 0x007f8000, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708020, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x019fa020, 0x83a40083, 0x80170f00, 0x007f8028, + 0x001fa023, 0xb5000041, 0x80170f00, 0x00000000, + 0x007f8020, 0x019fa023, 0x007f8008, 0x9463ffff, + 0x019fa023, 0x019fa020, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020, + 0x83a40070, 0xb5000031, 0x81df0000, 0x00000000, + 0x00000000, 0xb6004005, 0x007f8008, 0x019fa023, + 0x007f8008, 0x019fa023, 0x019fa020, 0x81df0004, + 0xb5000026, 0xb0130000, 0xb4000008, 0xb0130001, + 0xb4000012, 0xb0130002, 0xb400001f, 0xb0130003, + 0xb400001d, 0xb0130004, 0xb400001b, 0x83a4006b, + 0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023, + 0x007f8008, 0x9463ffff, 0x019fa023, 0x80170f00, + 0x007f8028, 0x001fa023, 0xb5000010, 0x80170f00, + 0x00000000, 0x5c708020, 0x58908008, 0x1983a024, + 0x5c708028, 0x58908008, 0x1983a024, 0x5c708028, + 0x019fa023, 0x83a40055, 0x80170f00, 0x007f8028, + 0x001fa023, 0xb5000001, 0xb5000000, 0x92730001, + 0x92520001, 0x3012b811, 0xb480fe89, 0x003f0324, + 0x90210001, 0xb0010006, 0xb4a00001, 0x80270001, + 0x003f2324, 0x2c8db811, 0x803bffe0, 0x805bffe4, + 0x5887b804, 0x1015b804, 0xad440003, 0x3000b802, + 0xb4800001, 0x8400a000, 0x801effec, 0x015f6193, + 0x809e4b04, 0x00ffb81f, 0x81df0000, 0x00000000, + 0x00000000, 0xb6002a0c, 0x007f8028, 0x019fa023, + 0x007f8008, 0x9463ffff, 0x019fa023, 0x019fa020, + 0x5c708028, 0x58908008, 0x1983a024, 0x5c708028, + 0x019fa023, 0x019fa020, 0x81df0004, 0x00ffb81d, + 0x81df0000, 0x00000000, 0x00000000, 0xb600190f, + 0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023, + 0x007f8008, 0x9463ffff, 0x019fa023, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x81df0004, + 0x00ffb81d, 0x81df0000, 0x00000000, 0x00000000, + 0xb6002a0c, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x019fa020, 0x81df0004, 0x00ffb81d, 0x81df0000, + 0x00000000, 0x00000000, 0xb600190f, 0x007f8028, + 0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x58908008, 0x1983a024, + 0x5c708028, 0x019fa023, 0x81df0004, 0x00ffb81d, + 0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000, + 0xb4000011, 0x815b4b0c, 0x81070000, 0x81270bf4, + 0xb00a0000, 0xb4000002, 0x81070c00, 0x812717f4, + 0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc, + 0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809, + 0xb4a00060, 0xb5000008, 0xb0040000, 0xb4200003, + 0x802717ff, 0x81470000, 0xb5000003, 0x80270001, + 0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200006, + 0x039f4193, 0x5b81b81c, 0x003f90cb, 0x1021b81c, + 0x003fb0cb, 0x8384f922, 0x829bff80, 0x801300e0, + 0x1434b800, 0x5c35b801, 0x8013001f, 0x1454b800, + 0x5c50b802, 0x8073007f, 0x9863ffff, 0xb002000f, + 0xb4800001, 0x90210001, 0x84210004, 0xb0010000, + 0xb4a00001, 0x6861b803, 0x005f9040, 0x4082b803, + 0x80af001f, 0x808f0000, 0x806f0000, 0x8007ffff, + 0x8033ffff, 0x80171000, 0x81df0000, 0x00000000, + 0x00000000, 0xb6001811, 0xb6002010, 0x14618000, + 0x6068b803, 0x40c4b803, 0x14608000, 0x00c8b806, + 0x5870b803, 0x6068b803, 0x4104b803, 0x58c8b806, + 0x0108b808, 0x14c6b801, 0x00000000, 0x00000000, + 0x5d08b808, 0x1508b800, 0x1806a028, 0x81df0004, + 0x80670400, 0x5d22b80a, 0x81df0000, 0x00000000, + 0x00000000, 0xb600180a, 0x00cfb803, 0x013fb0bc, + 0x5922b809, 0x01afb809, 0x013f90bc, 0x0047b86f, + 0xb0020001, 0xb4c0fffd, 0x90630020, 0x91290020, + 0x81df0004, 0x808f0000, 0x801b4b14, 0x80270001, + 0xb0000001, 0xb4000002, 0x802600a0, 0x803e4b14, + 0x81270c00, 0xb00a0000, 0xb4000001, 0x81270000, + 0x813e4b0c, 0x80270001, 0x003f2013, 0x80050086, + 0x001fb044, 0x00ffb81b, 0x00000000, 0x00000000, +}; + +static u32 PCMUcode1f4b00[] = { + 0x00000000, 0x00000000, 0x00060504, 0x00000000, + 0x00000000, 0x00000000, 0x00300000, 0xffcfcfff, + 0x00302000, 0xffcfcfff, 0x00380000, 0xffc7c7ff, + 0xcbcecdc4, 0xcfcac9c8, 0xc3c6c5cc, 0xc7c2c1c0, + 0x1b1e1d14, 0x1f1a1918, 0x1316151c, 0x17121110, + 0x2b2e2d24, 0x2f2a2928, 0x2326252c, 0x27222120, + 0x3b3e3d34, 0x3f3a3938, 0x3336353c, 0x37323130, + 0x0b0e0d04, 0x0f0a0908, 0x0306050c, 0x07020100, + 0xdbdeddd4, 0xdfdad9d8, 0xd3d6d5dc, 0xd7d2d1d0, + 0xebeeede4, 0xefeae9e8, 0xe3e6e5ec, 0xe7e2e1e0, + 0xfbfefdf4, 0xfffaf9f8, 0xf3f6f5fc, 0xf7f2f1f0, + 0x4b4e4d44, 0x4f4a4948, 0x4346454c, 0x47424140, + 0x9b9e9d94, 0x9f9a9998, 0x9396959c, 0x97929190, + 0xabaeada4, 0xafaaa9a8, 0xa3a6a5ac, 0xa7a2a1a0, + 0xbbbebdb4, 0xbfbab9b8, 0xb3b6b5bc, 0xb7b2b1b0, + 0x8b8e8d84, 0x8f8a8988, 0x8386858c, 0x87828180, + 0x5b5e5d54, 0x5f5a5958, 0x5356555c, 0x57525150, + 0x6b6e6d64, 0x6f6a6968, 0x6366656c, 0x67626160, + 0x7b7e7d74, 0x7f7a7978, 0x7376757c, 0x77727170, + 0x341424c4, 0x3e1e2ece, 0x3d1d2dcd, 0x3b1b2bcb, + 0xb494a444, 0xbe9eae4e, 0xbd9dad4d, 0xbb9bab4b, + 0xf4d4e404, 0xfedeee0e, 0xfddded0d, 0xfbdbeb0b, + 0x74546484, 0x7e5e6e8e, 0x7d5d6d8d, 0x7b5b6b8b, + 0x3c1c2ccc, 0x361626c6, 0x351525c5, 0x331323c3, + 0xbc9cac4c, 0xb696a646, 0xb595a545, 0xb393a343, + 0xfcdcec0c, 0xf6d6e606, 0xf5d5e505, 0xf3d3e303, + 0x7c5c6c8c, 0x76566686, 0x75556585, 0x73536383, + 0x381828c8, 0x3a1a2aca, 0x391929c9, 0x3f1f2fcf, + 0xb898a848, 0xba9aaa4a, 0xb999a949, 0xbf9faf4f, + 0xf8d8e808, 0xfadaea0a, 0xf9d9e909, 0xffdfef0f, + 0x78586888, 0x7a5a6a8a, 0x79596989, 0x7f5f6f8f, + 0x301020c0, 0x321222c2, 0x311121c1, 0x371727c7, + 0xb090a040, 0xb292a242, 0xb191a141, 0xb797a747, + 0xf0d0e000, 0xf2d2e202, 0xf1d1e101, 0xf7d7e707, + 0x70506080, 0x72526282, 0x71516181, 0x77576787, + 0x05040100, 0x15141110, 0x25242120, 0x35343130, + 0x85848180, 0x95949190, 0xa5a4a1a0, 0xb5b4b1b0, + 0xc0408000, 0xe060a020, 0xd0509010, 0xf070b030, + 0xc8488808, 0xe868a828, 0xd8589818, 0xf878b838, + 0xc4448404, 0xe464a424, 0xd4549414, 0xf474b434, + 0xcc4c8c0c, 0xec6cac2c, 0xdc5c9c1c, 0xfc7cbc3c, + 0xc2428202, 0xe262a222, 0xd2529212, 0xf272b232, + 0xca4a8a0a, 0xea6aaa2a, 0xda5a9a1a, 0xfa7aba3a, + 0xc6468606, 0xe666a626, 0xd6569616, 0xf676b636, + 0xce4e8e0e, 0xee6eae2e, 0xde5e9e1e, 0xfe7ebe3e, + 0xc1418101, 0xe161a121, 0xd1519111, 0xf171b131, + 0xc9498909, 0xe969a929, 0xd9599919, 0xf979b939, + 0xc5458505, 0xe565a525, 0xd5559515, 0xf575b535, + 0xcd4d8d0d, 0xed6dad2d, 0xdd5d9d1d, 0xfd7dbd3d, + 0xc3438303, 0xe363a323, 0xd3539313, 0xf373b333, + 0xcb4b8b0b, 0xeb6bab2b, 0xdb5b9b1b, 0xfb7bbb3b, + 0xc7478707, 0xe767a727, 0xd7579717, 0xf777b737, + 0xcf4f8f0f, 0xef6faf2f, 0xdf5f9f1f, 0xff7fbf3f, + 0x1045a3e2, 0x000000f4, 0x263b7333, 0x766b2363, + 0x2b367e3e, 0x7b662e6e, 0x06db93d3, 0x964b0343, + 0x0bd69ede, 0x9b460e4e, 0x825f1757, 0x12cf87c7, + 0x8f521a5a, 0x1fc28aca, 0x00d199d9, 0x90410949, + 0x01d098d8, 0x91400848, 0x24357d3d, 0x74652d6d, + 0x25347c3c, 0x75642c6c, 0x04d59ddd, 0x94450d4d, + 0x05d49cdc, 0x95440c4c, 0x80511959, 0x10c189c9, + 0x81501858, 0x11c088c8, 0x02df97d7, 0x924f0747, + 0x0fd29ada, 0x9f420a4a, 0x865b1353, 0x16cb83c3, + 0x8b561e5e, 0x1bc68ece, 0xa6bbf3b3, 0xf6eba3e3, + 0xabb6febe, 0xfbe6aeee, 0x223f7737, 0x726f2767, + 0x2f327a3a, 0x7f622a6a, 0xa0b1f9b9, 0xf0e1a9e9, + 0xa1b0f8b8, 0xf1e0a8e8, 0x84551d5d, 0x14c58dcd, + 0x85541c5c, 0x15c48ccc, 0xa4b5fdbd, 0xf4e5aded, + 0xa5b4fcbc, 0xf5e4acec, 0x20317939, 0x70612969, + 0x21307838, 0x71602868, 0xa2bff7b7, 0xf2efa7e7, + 0xafb2faba, 0xffe2aaea, 0x00000000, 0x00000000, +}; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/pcm_240.h linux.19pre5-ac1/drivers/media/video/ls220/pcm_240.h --- linux.19p5/drivers/media/video/ls220/pcm_240.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/ls220/pcm_240.h Thu Feb 21 21:25:16 2002 @@ -0,0 +1,868 @@ +static u32 PCM240Ucode1f1800[] = { + 0xb500000f, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xb50001fb, 0x00000000, 0x00000000, 0x00000000, + 0x820f001f, 0x802f001f, 0x029f9014, 0x829efef0, + 0x8286000f, 0x02bf0054, 0x82bcfef4, 0x82a6000e, + 0x80074000, 0x001f6193, 0x8013001f, 0x9020c000, + 0x003fb006, 0x803effe8, 0x803effec, 0x9020fa00, + 0x803effd0, 0x803effdc, 0x803effd8, 0x9020fe00, + 0x803effd4, 0x90400000, 0x804600a2, 0x90421800, + 0x804600a3, 0x80132000, 0x98000040, 0x800600a6, + 0x80050080, 0x98000002, 0x80060080, 0x80070001, + 0x001f2013, 0x80070000, 0x001f23f9, 0x801e4b0c, + 0x001f210c, 0x80070001, 0x001f2324, 0x80070800, + 0x001f600f, 0x001fb0cb, 0x001fb010, 0x801efff0, + 0x98004000, 0x001f600e, 0x83e4011b, 0x80070000, + 0x801e4b14, 0x800500a0, 0xb0000001, 0xb4000009, + 0x80070001, 0x800600a0, 0x80050080, 0x98000020, + 0x80060080, 0x9400ffdf, 0x80060080, 0x80070000, + 0x800600a0, 0x80074000, 0x801e4b04, 0x81df0004, + 0x801bfff0, 0x00000000, 0x940000ff, 0xb0000000, + 0xb4200033, 0x003f400e, 0x94010010, 0xb0000000, + 0xb400fff7, 0x003f0013, 0xb0010001, 0xb420001f, + 0x803bffe8, 0x801bffec, 0x805b4b04, 0x00000000, + 0x3001b800, 0xb4600001, 0x9021a000, 0x0421b800, + 0x3001b802, 0xb460000d, 0x80050086, 0x005f9044, + 0x0420b802, 0xb00101e0, 0xb4a0ffe5, 0x001fb010, + 0x001f010c, 0xb0000001, 0xb400ffe1, 0x80070001, + 0x001f210c, 0x83e400e8, 0xb500ffdd, 0x8007001f, + 0x94000003, 0x5810b800, 0x83e719ec, 0x1bffb800, + 0x003f9008, 0x1821b800, 0x00ffb801, 0x80270000, + 0x003f2013, 0x8007001f, 0x94000003, 0x5810b800, + 0x83671a14, 0x1b7bb800, 0x003f9009, 0x1821b800, + 0x00ffb801, 0x80070000, 0x001f210c, 0xb500ffc8, + 0x003f400e, 0xb0000086, 0xb4400051, 0xb0000084, + 0xb400003b, 0xb0000085, 0xb4000041, 0xb0000086, + 0xb4000043, 0xb0000083, 0xb4000000, 0x815bff7c, + 0x00000000, 0x940a0080, 0x5c07b800, 0xb0000001, + 0xb400006f, 0x81674b18, 0x940a0007, 0x5803b800, + 0x116bb800, 0x005bb80b, 0x916b0004, 0x001bb80b, + 0x806500d4, 0x1463b800, 0x1863b802, 0x806600d4, + 0x80073c21, 0x801e4b00, 0x800600a1, 0x80074000, + 0x801e4b04, 0x8013001f, 0x98405000, 0x805effe0, + 0x005fb006, 0x805effe8, 0x805effec, 0x9042a000, + 0x805effe4, 0x9040fa00, 0x805effd0, 0x805effdc, + 0x805effd8, 0x9040fe00, 0x805effd4, 0x8013007f, + 0x9800ffff, 0x001fb040, 0x80070001, 0x001f2013, + 0x80070000, 0x001f2324, 0x001fb0cb, 0x001fb010, + 0x001fb041, 0x001fb042, 0x80073370, 0x001fb008, + 0x80071e40, 0x001fb009, 0x98214000, 0xb5000010, + 0x94011000, 0xb0001000, 0xb4200001, 0x9421efff, + 0x98210010, 0xb500000a, 0x80070000, 0x001fb0cb, + 0x83e40099, 0x003f400e, 0x9421ffef, 0xb5000004, + 0x83e40095, 0x003f400e, 0x98211000, 0x9421ffef, + 0x003f600e, 0x80070100, 0x801efff0, 0xb500ff74, + 0xb000008b, 0xb4000018, 0xb0000087, 0xb400ffee, + 0xb0000088, 0xb4000016, 0xb000008a, 0xb4000016, + 0xb000008c, 0xb4000017, 0xb0000089, 0xb4000019, + 0xb00000a0, 0xb400001b, 0xb00000a1, 0xb4000047, + 0xb00000a2, 0xb4000054, 0xb00000a3, 0xb400004c, + 0xb00000a4, 0xb4000056, 0xb00000a5, 0xb400005a, + 0xb00000a6, 0xb400005e, 0x803efff8, 0xb500ffe1, + 0x9421ffdf, 0xb500ffde, 0x80270100, 0x803efff8, + 0xb500ffdc, 0x803bffb0, 0x00000000, 0x003fb040, + 0xb500ffd8, 0x803bff80, 0x00000000, 0x003f6001, + 0xb500ffd4, 0x003f90ba, 0x803efff8, 0xb500ffd1, + 0x81674b18, 0x940a0007, 0x5803b800, 0x116bb800, + 0x005bb80b, 0x916b0004, 0x001bb80b, 0x806500d4, + 0x1463b800, 0x1863b802, 0x806600d4, 0x80130001, + 0x98003d21, 0x800600a1, 0x801e4b00, 0x80074000, + 0x801e4b04, 0x8013001f, 0x98405000, 0x805effe0, + 0x005fb006, 0x805effe8, 0x805effec, 0x9042a000, + 0x805effe4, 0x9040fa00, 0x805effd0, 0x805effdc, + 0x805effd8, 0x9040fe00, 0x805effd4, 0x80070001, + 0x001f2013, 0x80070000, 0x001f2324, 0x001fb0cb, + 0x001fb010, 0x80073b60, 0x001fb008, 0x80074350, + 0x001fb009, 0x98214000, 0xb500ffa5, 0x80270000, + 0x8047fef0, 0x003eb802, 0x90420004, 0x003eb802, + 0x90420004, 0x003eb802, 0x90420004, 0x003eb802, + 0x81df0000, 0x00000000, 0x00000000, 0x83640443, + 0x81df0004, 0xb500ff97, 0x81df0000, 0x00000000, + 0x00000000, 0x836403ed, 0x81df0004, 0xb500ff91, + 0x81df0000, 0x00000000, 0x00000000, 0x836403a8, + 0x81df0004, 0xb500ff8b, 0x81df0000, 0x00000000, + 0x00000000, 0x8344030b, 0x81df0004, 0xb500ff85, + 0x81df0000, 0x00000000, 0x00000000, 0x834402f0, + 0x81df0004, 0xb500ff7f, 0x80070000, 0x80470000, + 0x81df0000, 0x00000000, 0x00000000, 0xb6002003, + 0xb6003002, 0x001eb802, 0x90420004, 0x80171000, + 0x8057ffff, 0xb6002002, 0xb6001801, 0x001fa020, + 0x81df0004, 0x00ffb81f, 0x83a70000, 0x8057ffff, + 0x80770000, 0x8073007d, 0x98636d4a, 0x0207b803, + 0x81df0000, 0x00000000, 0x00000000, 0x80171000, + 0xb6000007, 0x003fc020, 0x005fc7e0, 0x40c1b810, + 0x4102b810, 0x001fe026, 0x001fe0a8, 0x4210b803, + 0x81df0004, 0x80270000, 0x003f2013, 0x8007001f, + 0x94000003, 0x5810b800, 0x83671e1c, 0x1b7bb800, + 0x003f9009, 0x1821b800, 0x00ffb801, 0x003f0013, + 0xb0010001, 0xb420fff3, 0x93bd0001, 0xb01d0004, + 0xb480ffe3, 0x00ffb81f, 0x00000000, 0x00000000, + 0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000, + 0xb4000011, 0x815b4b0c, 0x81070000, 0x81270bf4, + 0xb00a0000, 0xb4000002, 0x81070c00, 0x812717f4, + 0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc, + 0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809, + 0xb4a00060, 0xb5000008, 0xb0040000, 0xb4200003, + 0x802717ff, 0x81470000, 0xb5000003, 0x80270001, + 0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200006, + 0x039f4193, 0x5b81b81c, 0x003f90cb, 0x1021b81c, + 0x003fb0cb, 0x83840266, 0x829bff80, 0x801300e0, + 0x1434b800, 0x5c35b801, 0x8013001f, 0x1454b800, + 0x5c50b802, 0x8073007f, 0x9863ffff, 0xb002000f, + 0xb4800001, 0x90210001, 0x84210004, 0xb0010000, + 0xb4a00001, 0x6861b803, 0x005f9040, 0x4082b803, + 0x80af001f, 0x808f0000, 0x806f0000, 0x8007ffff, + 0x8033ffff, 0x80171000, 0x81df0000, 0x00000000, + 0x00000000, 0xb6001811, 0xb6002010, 0x14618000, + 0x6068b803, 0x40c4b803, 0x14608000, 0x00c8b806, + 0x5870b803, 0x6068b803, 0x4104b803, 0x58c8b806, + 0x0108b808, 0x14c6b801, 0x00000000, 0x00000000, + 0x5d08b808, 0x1508b800, 0x1806a028, 0x81df0004, + 0x80670400, 0x5d22b80a, 0x81df0000, 0x00000000, + 0x00000000, 0xb600180a, 0x00cfb803, 0x013fb0bc, + 0x5922b809, 0x01afb809, 0x013f90bc, 0x0047b86f, + 0xb0020001, 0xb4c0fffd, 0x90630020, 0x91290020, + 0x81df0004, 0x808f0000, 0x801b4b14, 0x80270001, + 0xb0000001, 0xb4000002, 0x802600a0, 0x803e4b14, + 0x81270c00, 0xb00a0000, 0xb4000001, 0x81270000, + 0x813e4b0c, 0x80270001, 0x003f2013, 0x80050086, + 0x001fb044, 0x00ffb81b, 0x00000000, 0x00000000, + 0x029fb00a, 0x02bfb00b, 0x02dfb00c, 0x02ffb00d, + 0x031fb00e, 0x033fb00f, 0x033f400f, 0x0287b86f, + 0x029fb005, 0x8285009d, 0x82b30002, 0x9ab50040, + 0x1a94b815, 0x8286009d, 0x8285009c, 0x96b48000, + 0xb0158000, 0xb400019c, 0x96b40100, 0xb0150100, + 0xb40001b8, 0x96b40400, 0xb0150400, 0xb40001ca, + 0x96b40001, 0xb0150001, 0xb4000014, 0x96b40008, + 0xb0150008, 0xb40001a5, 0x96b44000, 0xb0154000, + 0xb40001c9, 0x96b40002, 0xb0150002, 0xb4000169, + 0x96b40040, 0xb0150040, 0xb40001dc, 0x82d30002, + 0x9ad60000, 0x16b6b814, 0x3015b816, 0xb40001da, + 0x00000000, 0x00000000, 0xb50001db, 0x02bf9017, + 0x92b50001, 0x02bfb017, 0x82850082, 0x83050081, + 0x82a5009a, 0x96b50001, 0xb0150001, 0xb4200014, + 0x82a70000, 0x02bfb017, 0x96b41840, 0xb0150800, + 0xb420000c, 0x96b40008, 0x5aa9b815, 0x96d46000, + 0x5ec3b816, 0x82f3000f, 0x9af7c00f, 0x1718b817, + 0x1ab5b818, 0x1ab5b816, 0x9ab50340, 0x82a60081, + 0xb5000140, 0x9b180180, 0x83060081, 0xb500013d, + 0x82a5009a, 0x96b50002, 0xb0150002, 0xb420001b, + 0x82a70000, 0x02bfb017, 0x96b41800, 0xb0151800, + 0xb4000013, 0x96b40040, 0xb0150040, 0xb4200004, + 0xa3180c00, 0x9b180340, 0x83060081, 0xb500012d, + 0x96b40008, 0x5aa9b815, 0x96d46000, 0x5ec3b816, + 0x82f3000f, 0x9af7c00f, 0x1718b817, 0x1ab5b818, + 0x1ab5b816, 0x9ab50340, 0x82a60081, 0xb5000121, + 0x9b180180, 0x83060081, 0xb500011e, 0x82a500c1, + 0x96b5000f, 0xb015000b, 0xb420000e, 0x96b40020, + 0xb0150020, 0xb400000b, 0x96b40200, 0xb0150200, + 0xb4000008, 0x82c50086, 0x82e50094, 0x3016b817, + 0xb4400004, 0x06f7b816, 0xb017ff00, 0xb4400001, + 0xb500010c, 0x96b46000, 0xb0156000, 0xb4000011, + 0x96b41820, 0xb0150820, 0xb4200004, 0x9b391000, + 0x82a5009a, 0x96b5feff, 0x82a6009a, 0x96b40040, + 0xb0150040, 0xb4200001, 0x9739efff, 0x96b91000, + 0xb0151000, 0xb4200003, 0x82a5009a, 0x9ab50100, + 0x82a6009a, 0x96b40040, 0xb0150040, 0xb4200019, + 0x96b41800, 0xb0151800, 0xb4200006, 0x96b98000, + 0xb0158000, 0xb4200003, 0x9b180180, 0x83060081, + 0xb50000ec, 0x96d80c00, 0x82b300ff, 0x9ab5f3ff, + 0x1718b815, 0xb0160c00, 0xb4000007, 0x82e50098, + 0x96f70400, 0xb0170400, 0xb4200002, 0x82c70c00, + 0xb5000001, 0xa2d60c00, 0x1b18b816, 0x9b180340, + 0xb50000d2, 0x96b40220, 0xb0150000, 0xb4e00033, + 0x82a5009d, 0x82f3ffff, 0x16b5b817, 0x82f33802, + 0x3015b817, 0xb420002d, 0x96f98000, 0xb0178000, + 0xb400002a, 0x82a70000, 0x02bfb017, 0x82c50081, + 0x9ab60020, 0x82a60081, 0x82a50086, 0x92b50bb8, + 0x82a60094, 0x82c60081, 0x82c5009d, 0x96d6ffff, + 0x82b3c802, 0x9ab50041, 0x82e500c1, 0x96f7000f, + 0xb017000b, 0xb4000002, 0x82b38802, 0x9ab50041, + 0x1ab5b816, 0x82c5009a, 0x96d60020, 0xb0160020, + 0xb4200002, 0x82b3c802, 0x9ab50041, 0x82a6009d, + 0x02ff9017, 0x00000000, 0xb0170040, 0xb480000b, + 0x96f41c00, 0xb0171c00, 0xb4200008, 0x82e50086, + 0x82c50094, 0x92d63000, 0x3016b817, 0xb4400003, + 0x9b180180, 0x83060081, 0xb50000a6, 0x5eb5b814, + 0x96b500f0, 0x96f46000, 0x5eedb817, 0x1ab5b817, + 0xb0170003, 0xb4000004, 0x96b500ef, 0x96f70001, + 0x5ae4b817, 0x1ab5b817, 0x96d41800, 0xb0161800, + 0xb400000a, 0x96f900ff, 0x96b500ff, 0x9739ff00, + 0x1b39b815, 0x02a7b817, 0x96b500f3, 0x96d40008, + 0x5ec1b816, 0x1ab5b816, 0xb500000c, 0x96f98000, + 0xb0178000, 0xb4200007, 0x5efeb814, 0x96f70001, + 0xb0170001, 0xb4000003, 0x9b180180, 0x83060081, + 0xb5000084, 0x96b500f3, 0x9ab50008, 0x9739fff3, + 0x96d40020, 0xb0160020, 0xb4200017, 0x9b398000, + 0x82c70000, 0x02dfb017, 0x96d40010, 0x5ac8b816, + 0x82f300ff, 0x9af7cfff, 0x1718b817, 0x1b18b816, + 0x9b180340, 0x82c5009d, 0x96d6ffff, 0x82f33802, + 0x9af70041, 0x1af7b816, 0x82c5009a, 0x96d60020, + 0xb0160020, 0xb4200002, 0x82f3c802, 0x9af70041, + 0x82e6009d, 0xb500005d, 0x97397fff, 0x96b500ff, + 0x5aaab815, 0x82f300fc, 0x9af703ff, 0x1718b817, + 0x1b18b815, 0x9b180340, 0x82c5009a, 0x96d60010, + 0xb0160010, 0xb4200024, 0x82c70000, 0x02dfb017, + 0x82c50086, 0x92d60bb8, 0x82c60086, 0x82c50094, + 0x5eefb818, 0x96f70003, 0xb0170003, 0xb4200002, + 0x82e70bb8, 0xb5000001, 0x82e70bb8, 0x12d6b817, + 0x82e50081, 0x9af70020, 0x82e60081, 0x82c60094, + 0xa2f70020, 0x82e60081, 0x82f30001, 0x16f7b818, + 0x5ef0b817, 0xb0170001, 0xb4000004, 0x96f84000, + 0x5ee4b817, 0x9718f3ff, 0x1b18b817, 0x82f32802, + 0x9af70040, 0x82e6009d, 0x83060081, 0x83070001, + 0x8306009f, 0xb50000b8, 0x82c5009d, 0x82f33802, + 0x9af70041, 0x3016b817, 0xb420000f, 0x82b3c802, + 0x9ab50041, 0x82e500c1, 0x96f7000f, 0xb017000b, + 0xb4000002, 0x82b38802, 0x9ab50041, 0x82c5009a, + 0x96d60020, 0xb0160020, 0xb4200002, 0x82b3c802, + 0x9ab50041, 0x82a6009d, 0x82c5009a, 0x96d60080, + 0xb0160080, 0xb4000014, 0x02df9017, 0x00000000, + 0xb0160010, 0xb4800010, 0x82c500c1, 0x96d6000f, + 0xb016000b, 0xb400000c, 0x82c50087, 0x96d60080, + 0x5ac7b816, 0x82c50098, 0x96d60800, 0x5ac3b816, + 0x96f84000, 0x3017b816, 0xb4200003, 0x033f400f, + 0x9b394000, 0xb500000b, 0x9739bfff, 0x82e50061, + 0x96f70008, 0xb0170008, 0xb4000005, 0x5eefb818, + 0x96f70003, 0xb0170003, 0xb4000001, 0x9718ffff, + 0x83060081, 0x83070001, 0x8306009f, 0x00000000, + 0xb500007d, 0x82850083, 0x96b400ff, 0xb015003c, + 0xb4200019, 0x96b92000, 0xb0152000, 0xb4000002, + 0x9b392000, 0xb5000014, 0x9739d3ff, 0x82870000, + 0x82860087, 0x82870008, 0x82860083, 0x829bff78, + 0x82a7001f, 0xb0140400, 0xb4000001, 0x82a70010, + 0x82a600c9, 0x829bff78, 0x00000000, 0x828600cb, + 0x8285009d, 0x82b3ffff, 0x9ab5fffd, 0x1694b815, + 0x8286009d, 0xb5000000, 0x83070002, 0x8306009f, + 0x00000000, 0xb500005c, 0x96b90800, 0xb0150800, + 0xb4200009, 0x9739f7ff, 0x82a703fd, 0x82a600cb, + 0x82a7003c, 0x82a60083, 0x8285009d, 0x9a940002, + 0x8286009d, 0xb5000004, 0x82850087, 0x5a82b814, + 0xa2940200, 0x82860087, 0xb5000000, 0x83078000, + 0x8306009f, 0x00000000, 0xb5000047, 0x82850086, + 0x82a50094, 0x3015b814, 0xb4800002, 0x86b50bb8, + 0x82a60086, 0x83070008, 0x8306009f, 0x00000000, + 0xb500003d, 0x83050069, 0x9718003f, 0x82e50064, + 0x12f7b818, 0x86f70088, 0x82feff74, 0x02e7b86f, + 0x9af74000, 0x01ffb817, 0x96f7bfff, 0x01ffb817, + 0x83050081, 0x82f3001c, 0x9af703ff, 0x1718b817, + 0x9b180140, 0x83060081, 0x83070100, 0x8306009f, + 0x00000000, 0xb5000028, 0x83070000, 0x83050081, + 0x9b180180, 0x83060081, 0x83070400, 0x8306009f, + 0x00000000, 0xb5000020, 0x82870000, 0x82850082, + 0x5eb7b814, 0x96b500fc, 0x96d40006, 0x5ec1b816, + 0x1ab5b816, 0x5aacb815, 0x83050081, 0x82d3001c, + 0x9ad600ff, 0x1718b816, 0x1b18b815, 0x9b180e00, + 0x83060081, 0x83074000, 0x8306009f, 0x8305009d, + 0x82d3ffff, 0x9ad6bfff, 0x1718b816, 0x8306009d, + 0x00000000, 0xb5000008, 0xb5000007, 0x83070040, + 0x8306009f, 0xb5000004, 0x83130002, 0x9b180000, + 0x8306009f, 0xb5000000, 0x029f9005, 0x01ffb814, + 0x033f600f, 0x029f900a, 0x02bf900b, 0x02df900c, + 0x02ff900d, 0x031f900e, 0x033f900f, 0x00ffb81e, + 0x02ff9010, 0x92f70b43, 0x02ffb010, 0x02ff90cb, + 0x82bbffdc, 0x829bffd8, 0x93150004, 0x3014b815, + 0xb4000010, 0x02dbb818, 0x029bb815, 0x3017b816, + 0xb480000c, 0x5a81b814, 0x029fb010, 0x82860095, + 0x8293001f, 0x9294fe00, 0x92b50008, 0x3015b814, + 0xb4800002, 0x82b3001f, 0x92b5fa00, 0x82beffdc, + 0xb500ffeb, 0x029f9010, 0x83250094, 0x06d4b819, + 0x02d6b816, 0xb016ffff, 0xb4a0000a, 0x82933802, + 0x9a940041, 0x82c5009d, 0x96d6ffff, 0x1a94b816, + 0x82c5009a, 0x96d60010, 0xb0160010, 0xb4000001, + 0x8286009d, 0x00ffb81c, 0x00000000, 0x00000000, + 0x001f9012, 0x001fb100, 0x001f004c, 0x001f2404, + 0x801bfef0, 0x8058fef4, 0x803bff68, 0x8078ff6c, + 0x2000b801, 0x2042b803, 0x001fb104, 0x005f2414, + 0x82e70001, 0x83640048, 0x029fb014, 0x829efef0, + 0x8286000f, 0x02bf2054, 0x82bcfef4, 0x82a6000e, + 0x00ffb81a, 0x80e70001, 0x801336e3, 0x9800eb76, + 0x001fb100, 0x800700ab, 0x001f2404, 0x801bc3e8, + 0x8058c3ec, 0x83640024, 0x82e70000, 0x83640036, + 0x029fb300, 0x029fb100, 0x02bf2c04, 0x02bf2404, + 0x801bc000, 0x8058c004, 0x8364001b, 0x82e70000, + 0x8364002d, 0x001f9300, 0x3000b814, 0xb420000a, + 0x001f0c04, 0x3000b815, 0xb4200007, 0x829efef0, + 0x82bcfef4, 0x029fb012, 0x02bf204c, 0x82870001, + 0x829cfef5, 0x00ffb81a, 0xb0070000, 0xb4000007, + 0x80e70000, 0x801399fa, 0x9800c92e, 0x001fb100, + 0x800700af, 0x001f2404, 0xb500ffdc, 0x82870000, + 0x829cfef5, 0x00ffb81a, 0x80c700ff, 0x803bff68, + 0x8078ff6c, 0x14a0b806, 0x2063b805, 0x007f2414, + 0x2021b802, 0x58c8b806, 0x14a0b806, 0x58b0b805, + 0x2021b805, 0x58c8b806, 0x14a0b806, 0x2021b805, + 0x58c8b806, 0x14a0b806, 0x5cb0b805, 0x2021b805, + 0x003fb104, 0x00ffb81b, 0x82c70000, 0x83070400, + 0x83270005, 0x8197040c, 0x81d7ffff, 0x83840126, + 0x83840001, 0x00ffb81b, 0x808f0000, 0x806f001f, + 0x80af001f, 0x80270140, 0x81e70228, 0x5de2b80f, + 0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, + 0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020, + 0x90210020, 0x80270180, 0x81e70120, 0x5de2b80f, + 0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, + 0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020, + 0x90210020, 0x8057ffff, 0x80170430, 0x80070410, + 0x80270408, 0xb6000509, 0x005ff000, 0x90420500, + 0x007ff001, 0x90630600, 0x009ff002, 0x00bff003, + 0x2004a025, 0x90000001, 0x90210001, 0x80070414, + 0x80d7ffff, 0x8097045c, 0x8017043c, 0xb6000404, + 0x005ff000, 0x007f87e0, 0x84000001, 0x2082a7e3, + 0x80970460, 0x80170440, 0x2082b803, 0x007f8000, + 0x2083a004, 0x80170430, 0x80970450, 0x80270408, + 0xb6000508, 0x005f8024, 0x90420500, 0x007ff001, + 0x90630600, 0x009ff002, 0x00bff003, 0x2004a025, + 0x90210001, 0x80170440, 0x00000000, 0x02bf87e0, + 0x80970460, 0x82870000, 0xb6000404, 0x005f87e4, + 0x5a88b814, 0x204287e0, 0x1a94b802, 0x00ffb81c, + 0x001f0a49, 0x001f2709, 0x001f0a41, 0x001f2708, + 0x001f0a46, 0x001f2707, 0x001f0a48, 0x001f2706, + 0x001f0a42, 0x001f2705, 0x001f0a47, 0x001f2704, + 0x001f0a45, 0x001f2703, 0x001f0a43, 0x001f2702, + 0x001f0a40, 0x001f2701, 0x001f0a44, 0x001f2700, + 0x001f0c25, 0xa020000c, 0x94400001, 0x94600002, + 0x94810004, 0x94a10008, 0x94c00010, 0x5943b802, + 0x5861b803, 0x5882b804, 0x5ca2b805, 0x5cc4b806, + 0x194ab803, 0x194ab804, 0x194ab805, 0x194ab806, + 0x015f2738, 0x801b0220, 0x003f91c1, 0x5c28b801, + 0x005f91c2, 0x5858b802, 0x1821b802, 0x2000b801, + 0x001fb1c4, 0x80180224, 0x003f0709, 0x2000b801, + 0x001f2714, 0x82c70001, 0x82e70001, 0x83070710, + 0x8327001e, 0x81970735, 0x8384009f, 0x02df0738, + 0x82170a30, 0x838400f1, 0x819efef0, 0x817cfef4, + 0x819eff68, 0x817cff6c, 0x00ffb81b, 0x820f001f, + 0x8018fef8, 0x8057ffff, 0x001f2709, 0x8018fef6, + 0x80d7ffff, 0x001f2708, 0x8018fefa, 0x8157ffff, + 0x001f2707, 0x8018fefd, 0x81d7ffff, 0x001f2706, + 0x8018fefb, 0x802f001f, 0x001f2705, 0x8018fefe, + 0x00000000, 0x001f2704, 0x8018fef9, 0x00000000, + 0x001f2703, 0x8018feff, 0x00000000, 0x001f2702, + 0x8018fef7, 0x00000000, 0x001f2701, 0x8018fefc, + 0x00000000, 0x001f2700, 0x001f0c25, 0xa0200011, + 0x94410001, 0x94600002, 0x94800004, 0x94a00008, + 0x94c10010, 0x5941b802, 0x5861b803, 0x5c82b804, + 0x58a1b805, 0x5cc1b806, 0x194ab803, 0x194ab804, + 0x194ab805, 0x194ab806, 0x015f2738, 0x801b0220, + 0x003f91c1, 0x5c28b801, 0x005f91c2, 0x5858b802, + 0x1821b802, 0x2000b801, 0x001fb1c4, 0x80180224, + 0x003f0709, 0x2000b801, 0x001f2714, 0x82c70001, + 0x82e70001, 0x83070710, 0x8327001e, 0x81970735, + 0x83840055, 0x02df0738, 0x82170a20, 0x838400a7, + 0x819efef0, 0x817cfef4, 0x5ac8b80c, 0x02ff0a44, + 0x1ad6b817, 0x02dfb291, 0x5ed8b80c, 0x5968b80b, + 0x1ad6b80b, 0x02df6524, 0x00ffb81b, 0x820f001f, + 0x8018fefe, 0x8057ffff, 0x001f2709, 0x8018fefa, + 0x80d7ffff, 0x001f2708, 0x8018fefc, 0x8157ffff, + 0x001f2707, 0x8018feff, 0x81d7ffff, 0x001f2706, + 0x8018fef8, 0x802f001f, 0x001f2705, 0x8018fefb, + 0x00000000, 0x001f2704, 0x8018fefd, 0x00000000, + 0x001f2703, 0x8018fef6, 0x00000000, 0x001f2702, + 0x8018fef9, 0x00000000, 0x001f2701, 0x8018fef7, + 0x00000000, 0x001f2700, 0x801b0220, 0x003f91c1, + 0x5c28b801, 0x005f91c2, 0x5858b802, 0x1821b802, + 0x2000b801, 0x001fb1c4, 0x80180224, 0x003f0709, + 0x2000b801, 0x001f2714, 0x82c70001, 0x82e70001, + 0x83070710, 0x8327001e, 0x81970735, 0x83840016, + 0x83270000, 0x831bfef0, 0x82f8fef4, 0x02c7b819, + 0x82170a28, 0x83840065, 0x300cb818, 0xb4200002, + 0x300bb817, 0xb4000006, 0x93390001, 0xb0190020, + 0xb480fff6, 0x83270000, 0x833cfef5, 0x00ffb81b, + 0x019fb290, 0x017f2a44, 0x033f2c25, 0x83270001, + 0x833cfef5, 0x00ffb81b, 0x0007b818, 0x90000003, + 0x00000000, 0x015ff000, 0x90000001, 0x5949b80a, + 0x013ff000, 0x194ab809, 0x84000002, 0x994a0100, + 0x017ff000, 0x958b00f8, 0x5981b80c, 0x956b0007, + 0x198cb80b, 0x84000002, 0x998c0008, 0x017ff000, + 0x90000001, 0x5971b80b, 0x198cb80b, 0x017ff000, + 0x5969b80b, 0x198cb80b, 0x81a70000, 0x94d90003, + 0x82a70000, 0xb6260019, 0xb6000818, 0x5df0b80a, + 0x5e02b80a, 0x21efb810, 0x95ef0001, 0x5941b80a, + 0x194ab80f, 0x21efb816, 0x5e18b80c, 0x5e35b80c, + 0x5e54b80c, 0x5e6cb80c, 0x2210b811, 0x2252b813, + 0x2210b812, 0x96100001, 0x5981b80c, 0x198cb810, + 0x2210b817, 0x10afb810, 0x10a5b80d, 0x5da1b805, + 0x94a50001, 0x5aa1b815, 0x1ab5b805, 0x019fa7f5, + 0x5cc2b819, 0xb626001c, 0x82870000, 0xb6000419, + 0xb6000818, 0x5df0b80a, 0x5e02b80a, 0x21efb810, + 0x95ef0001, 0x5941b80a, 0x194ab80f, 0x21efb816, + 0x5e18b80c, 0x5e35b80c, 0x5e54b80c, 0x5e6cb80c, + 0x2210b811, 0x2252b813, 0x2210b812, 0x96100001, + 0x5981b80c, 0x198cb810, 0x2210b817, 0x10afb810, + 0x10a5b80d, 0x5da1b805, 0x94a50001, 0x5a81b814, + 0x1a94b805, 0x019fa7f4, 0x00ffb81c, 0x8257ffff, + 0x808f0000, 0x806f001f, 0x80af001f, 0x80270200, + 0x81e7ff00, 0x5de2b80f, 0xb6000208, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0xb520ffff, 0x91ef0020, 0x90210020, 0x80270240, + 0x81e70000, 0x5de2b80f, 0xb6000208, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0xb520ffff, 0x91ef0020, 0x90210020, 0x80270180, + 0x81e70120, 0x5de2b80f, 0xb6000208, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0xb520ffff, 0x91ef0020, 0x90210020, 0x806f0007, + 0x80af0007, 0x80270280, 0x81e70100, 0x5de2b80f, + 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, + 0x01ff90bc, 0xb520ffff, 0x91ef0020, 0x90210020, + 0x80170760, 0x001f0700, 0x001fa020, 0x001f0701, + 0x001fa020, 0x001f0702, 0x001fa020, 0x001f0703, + 0x001fa020, 0x001f0704, 0x001fa000, 0x80970750, + 0x81170770, 0x82a70735, 0x83a40060, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a4005c, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750, + 0x81170750, 0x81970740, 0x82a70730, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a40050, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a4004c, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970750, 0x80170770, + 0x81170770, 0x81970760, 0x82a7072b, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a40040, 0x83a4004e, + 0xb6000407, 0x86b50001, 0x83a4003c, 0x001f8004, + 0x003f87e8, 0x2080a001, 0x83a40047, 0x00000000, + 0x80970770, 0x80170750, 0x81170750, 0x81970740, + 0x82a70726, 0x001f800c, 0x003f8008, 0x2100a001, + 0x83a4002e, 0x83a4003c, 0xb6000407, 0x86b50001, + 0x83a4002a, 0x001f8004, 0x003f87e8, 0x2080a001, + 0x83a40035, 0x00000000, 0x80970750, 0x80170770, + 0x81170770, 0x81970760, 0x82a70721, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a4001c, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a40018, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750, + 0x81170750, 0x81970740, 0x82a7071c, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a4000c, 0x017f87e4, + 0x81870000, 0xb6000406, 0x86b50001, 0x83a40007, + 0x001f87e4, 0x200087e8, 0x5988b80c, 0x198cb800, + 0x021fa02c, 0x021fa00b, 0x00ffb81c, 0x005ff015, + 0x90420600, 0x003f87e0, 0x001ff002, 0x2060b801, + 0x90630800, 0x90960a00, 0x001ff003, 0x003ff004, + 0x20a0b801, 0x90a50900, 0x00000000, 0x001ff005, + 0x009fa000, 0x00ffb81d, 0x001f8004, 0x5c21b800, + 0x5847b800, 0x1821b802, 0x942100ff, 0x2080a7e1, + 0x00ffb81d, 0x00000000, 0x00000000, 0x00000000, + 0x829bff80, 0x80af001f, 0x808f0000, 0x806f0000, + 0x82bbffec, 0x82fbffe4, 0x00000000, 0x82beffb8, + 0x95540700, 0x5d48b80a, 0x914a0001, 0x0227b80a, + 0x94343000, 0x5c2cb801, 0xb0010000, 0xb4000001, + 0x5a21b811, 0x9574c000, 0x5d6eb80b, 0x918b4b08, + 0x01b8b80c, 0x96d5ffff, 0x5ec2b816, 0x96f7ffff, + 0x5ee2b817, 0x8057ffff, 0x80d7ffff, 0x8157ffff, + 0x81d7ffff, 0x81f3ff00, 0x99efff00, 0x821300ff, + 0x9a1000ff, 0x81971000, 0x82670000, 0x82470000, + 0x80270280, 0x81df0000, 0x00000000, 0x00000000, + 0xb62d000d, 0x3016b817, 0xb4800001, 0x86d62800, + 0x00cfb801, 0x02dfb0bc, 0x5ac2b816, 0x01cfb816, + 0x02df90bc, 0x0067b86f, 0xb0030001, 0xb4c0fffd, + 0x92d60020, 0x90210020, 0x81df0004, 0x80170a00, + 0x81df0000, 0x00000000, 0x00000000, 0xb62d0006, + 0xb6002005, 0x146f8000, 0x14908000, 0x5c68b803, + 0x5888b804, 0x1803a024, 0x81df0004, 0x80170a00, + 0x80970d00, 0xb00b0000, 0xb4000004, 0xb00b0001, + 0xb400000a, 0xb00b0002, 0xb4000027, 0x81df0000, + 0x00000000, 0x00000000, 0xb6008002, 0x007f8020, + 0x009fa023, 0x81df0004, 0xb5000029, 0x80d3ffff, + 0x81df0000, 0x00000000, 0x00000000, 0xb6002018, + 0x5c648000, 0x9463ffff, 0x5c888020, 0x58b88000, + 0x1884b805, 0x1484b806, 0x1883a024, 0x5c6c8020, + 0x9463ffff, 0x58908000, 0x1883a024, 0x5c748020, + 0x588c8000, 0x1863b804, 0x9463ffff, 0x58888000, + 0x1484b806, 0x1883a024, 0x5c7c8020, 0x58848000, + 0x1863b804, 0x9463ffff, 0x14868020, 0x1883a024, + 0x81df0004, 0xb500000a, 0x80d3ffff, 0x81df0000, + 0x00000000, 0x00000000, 0xb6004004, 0x007f8020, + 0x009fa023, 0x007f8040, 0x009fa023, 0x81df0004, + 0x00000000, 0x81170d00, 0x80070000, 0x94343000, + 0x5c2cb801, 0xb0010001, 0xb400008e, 0xb00a0001, + 0xb400000e, 0xb00a0002, 0xb400001c, 0xb00a0003, + 0xb4000024, 0xb00a0004, 0xb4000052, 0xb00a0005, + 0xb400005b, 0xb00a0006, 0xb400007f, 0xb00a0007, + 0xb400007d, 0xb00a0008, 0xb400007b, 0x81df0000, + 0x00000000, 0x00000000, 0xb600800a, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020, + 0x5c708028, 0x9463ffff, 0x019fa023, 0x019fa020, + 0x019fa020, 0x81df0004, 0xb500006b, 0x81df0000, + 0x00000000, 0x00000000, 0xb6008004, 0x007f8028, + 0x019fa023, 0x019fa020, 0x019fa020, 0x81df0004, + 0xb5000061, 0xb0130000, 0xb4000004, 0xb0130001, + 0xb4000009, 0xb0130002, 0xb400001a, 0x83a400fa, + 0x80170f00, 0x007f8028, 0x001fa023, 0x007f8028, + 0x001fa023, 0xb5000054, 0x80170f00, 0x00000000, + 0x007f8020, 0x019fa023, 0x007f8000, 0x9463ffff, + 0x019fa023, 0x019fa020, 0x5c708020, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020, + 0x83a400e5, 0x80170f00, 0x007f8028, 0x001fa023, + 0xb5000041, 0x80170f00, 0x00000000, 0x007f8020, + 0x019fa023, 0x007f8008, 0x9463ffff, 0x019fa023, + 0x019fa020, 0x5c708028, 0x58908008, 0x1983a024, + 0x5c708028, 0x019fa023, 0x019fa020, 0x83a400d2, + 0xb5000031, 0x81df0000, 0x00000000, 0x00000000, + 0xb6004005, 0x007f8008, 0x019fa023, 0x007f8008, + 0x019fa023, 0x019fa020, 0x81df0004, 0xb5000026, + 0xb0130000, 0xb4000008, 0xb0130001, 0xb4000012, + 0xb0130002, 0xb400001f, 0xb0130003, 0xb400001d, + 0xb0130004, 0xb400001b, 0x83a400cd, 0x007f8028, + 0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x80170f00, 0x007f8028, + 0x001fa023, 0xb5000010, 0x80170f00, 0x00000000, + 0x5c708020, 0x58908008, 0x1983a024, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x83a400b7, 0x80170f00, 0x007f8028, 0x001fa023, + 0xb5000001, 0xb5000000, 0x00000000, 0x00000000, + 0xb5000086, 0xb00a0001, 0xb400000e, 0xb00a0002, + 0xb4000017, 0xb00a0003, 0xb400001f, 0xb00a0004, + 0xb400004d, 0xb00a0005, 0xb4000056, 0xb00a0006, + 0xb400007a, 0xb00a0007, 0xb4000078, 0xb00a0008, + 0xb4000076, 0x81df0000, 0x00000000, 0x00000000, + 0xb6008005, 0x007f8028, 0x9463ffff, 0x019fa023, + 0x019fa020, 0x019fa020, 0x81df0004, 0xb500006b, + 0x81df0000, 0x00000000, 0x00000000, 0xb6004004, + 0x007f8048, 0x019fa023, 0x019fa020, 0x019fa020, + 0x81df0004, 0xb5000061, 0xb0130000, 0xb4000004, + 0xb0130001, 0xb4000009, 0xb0130002, 0xb400001a, + 0x83a40098, 0x80170f00, 0x007f8028, 0x001fa023, + 0x007f8028, 0x001fa023, 0xb5000054, 0x80170f00, + 0x00000000, 0x007f8020, 0x019fa023, 0x007f8000, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708020, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x019fa020, 0x83a40083, 0x80170f00, 0x007f8028, + 0x001fa023, 0xb5000041, 0x80170f00, 0x00000000, + 0x007f8020, 0x019fa023, 0x007f8008, 0x9463ffff, + 0x019fa023, 0x019fa020, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020, + 0x83a40070, 0xb5000031, 0x81df0000, 0x00000000, + 0x00000000, 0xb6004005, 0x007f8008, 0x019fa023, + 0x007f8008, 0x019fa023, 0x019fa020, 0x81df0004, + 0xb5000026, 0xb0130000, 0xb4000008, 0xb0130001, + 0xb4000012, 0xb0130002, 0xb400001f, 0xb0130003, + 0xb400001d, 0xb0130004, 0xb400001b, 0x83a4006b, + 0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023, + 0x007f8008, 0x9463ffff, 0x019fa023, 0x80170f00, + 0x007f8028, 0x001fa023, 0xb5000010, 0x80170f00, + 0x00000000, 0x5c708020, 0x58908008, 0x1983a024, + 0x5c708028, 0x58908008, 0x1983a024, 0x5c708028, + 0x019fa023, 0x83a40055, 0x80170f00, 0x007f8028, + 0x001fa023, 0xb5000001, 0xb5000000, 0x92730001, + 0x92520001, 0x3012b811, 0xb480fe89, 0x003f0324, + 0x90210001, 0xb0010006, 0xb4a00001, 0x80270001, + 0x003f2324, 0x2c8db811, 0x803bffe0, 0x805bffe4, + 0x5887b804, 0x1015b804, 0xad440003, 0x3000b802, + 0xb4800001, 0x8400a000, 0x801effec, 0x015f6193, + 0x809e4b04, 0x00ffb81f, 0x81df0000, 0x00000000, + 0x00000000, 0xb6002a0c, 0x007f8028, 0x019fa023, + 0x007f8008, 0x9463ffff, 0x019fa023, 0x019fa020, + 0x5c708028, 0x58908008, 0x1983a024, 0x5c708028, + 0x019fa023, 0x019fa020, 0x81df0004, 0x00ffb81d, + 0x81df0000, 0x00000000, 0x00000000, 0xb600190f, + 0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023, + 0x007f8008, 0x9463ffff, 0x019fa023, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x81df0004, + 0x00ffb81d, 0x81df0000, 0x00000000, 0x00000000, + 0xb6002a0c, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x019fa020, 0x81df0004, 0x00ffb81d, 0x81df0000, + 0x00000000, 0x00000000, 0xb600190f, 0x007f8028, + 0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x58908008, 0x1983a024, + 0x5c708028, 0x019fa023, 0x81df0004, 0x00ffb81d, + 0x829bff80, 0x80af001f, 0x808f0000, 0x806f0000, + 0x82bbffec, 0x82fbffe4, 0x00000000, 0x82beffb8, + 0x95540700, 0x5d48b80a, 0x914a0001, 0x0227b80a, + 0x94343000, 0x5c2cb801, 0xb0010000, 0xb4000001, + 0x5a21b811, 0x9574c000, 0x5d6eb80b, 0x918b4b08, + 0x01b8b80c, 0x96d5ffff, 0x5ec2b816, 0x96f7ffff, + 0x5ee2b817, 0x8057ffff, 0x80d7ffff, 0x8157ffff, + 0x81d7ffff, 0x81f3ff00, 0x99efff00, 0x821300ff, + 0x9a1000ff, 0x81971000, 0x82670000, 0x82470000, + 0x80270280, 0x81df0000, 0x00000000, 0x00000000, + 0xb62d000d, 0x3016b817, 0xb4800001, 0x86d62800, + 0x00cfb801, 0x02dfb0bc, 0x5ac2b816, 0x01cfb816, + 0x02df90bc, 0x0067b86f, 0xb0030001, 0xb4c0fffd, + 0x92d60020, 0x90210020, 0x81df0004, 0x80170a00, + 0x81df0000, 0x00000000, 0x00000000, 0xb62d0006, + 0xb6002005, 0x146f8000, 0x14908000, 0x5c68b803, + 0x5888b804, 0x1803a024, 0x81df0004, 0x80170a00, + 0x80970d00, 0xb00b0000, 0xb4000004, 0xb00b0001, + 0xb400000a, 0xb00b0002, 0xb4000027, 0x81df0000, + 0x00000000, 0x00000000, 0xb6008002, 0x007f8020, + 0x009fa023, 0x81df0004, 0xb5000029, 0x80d3ffff, + 0x81df0000, 0x00000000, 0x00000000, 0xb6002018, + 0x5c648000, 0x9463ffff, 0x5c888020, 0x58b88000, + 0x1884b805, 0x1484b806, 0x1883a024, 0x5c6c8020, + 0x9463ffff, 0x58908000, 0x1883a024, 0x5c748020, + 0x588c8000, 0x1863b804, 0x9463ffff, 0x58888000, + 0x1484b806, 0x1883a024, 0x5c7c8020, 0x58848000, + 0x1863b804, 0x9463ffff, 0x14868020, 0x1883a024, + 0x81df0004, 0xb500000a, 0x80d3ffff, 0x81df0000, + 0x00000000, 0x00000000, 0xb6004004, 0x007f8020, + 0x009fa023, 0x007f8040, 0x009fa023, 0x81df0004, + 0x00000000, 0x81170d00, 0x80070000, 0x94343000, + 0x5c2cb801, 0xb0010001, 0xb400008e, 0xb00a0001, + 0xb400000e, 0xb00a0002, 0xb400001c, 0xb00a0003, + 0xb4000024, 0xb00a0004, 0xb4000052, 0xb00a0005, + 0xb400005b, 0xb00a0006, 0xb400007f, 0xb00a0007, + 0xb400007d, 0xb00a0008, 0xb400007b, 0x81df0000, + 0x00000000, 0x00000000, 0xb600800a, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020, + 0x5c708028, 0x9463ffff, 0x019fa023, 0x019fa020, + 0x019fa020, 0x81df0004, 0xb500006b, 0x81df0000, + 0x00000000, 0x00000000, 0xb6008004, 0x007f8028, + 0x019fa023, 0x019fa020, 0x019fa020, 0x81df0004, + 0xb5000061, 0xb0130000, 0xb4000004, 0xb0130001, + 0xb4000009, 0xb0130002, 0xb400001a, 0x83a400fa, + 0x80170f00, 0x007f8028, 0x001fa023, 0x007f8028, + 0x001fa023, 0xb5000054, 0x80170f00, 0x00000000, + 0x007f8020, 0x019fa023, 0x007f8000, 0x9463ffff, + 0x019fa023, 0x019fa020, 0x5c708020, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020, + 0x83a400e5, 0x80170f00, 0x007f8028, 0x001fa023, + 0xb5000041, 0x80170f00, 0x00000000, 0x007f8020, + 0x019fa023, 0x007f8008, 0x9463ffff, 0x019fa023, + 0x019fa020, 0x5c708028, 0x58908008, 0x1983a024, + 0x5c708028, 0x019fa023, 0x019fa020, 0x83a400d2, + 0xb5000031, 0x81df0000, 0x00000000, 0x00000000, + 0xb6004005, 0x007f8008, 0x019fa023, 0x007f8008, + 0x019fa023, 0x019fa020, 0x81df0004, 0xb5000026, + 0xb0130000, 0xb4000008, 0xb0130001, 0xb4000012, + 0xb0130002, 0xb400001f, 0xb0130003, 0xb400001d, + 0xb0130004, 0xb400001b, 0x83a400cd, 0x007f8028, + 0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x80170f00, 0x007f8028, + 0x001fa023, 0xb5000010, 0x80170f00, 0x00000000, + 0x5c708020, 0x58908008, 0x1983a024, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x83a400b7, 0x80170f00, 0x007f8028, 0x001fa023, + 0xb5000001, 0xb5000000, 0x00000000, 0x00000000, + 0xb5000086, 0xb00a0001, 0xb400000e, 0xb00a0002, + 0xb4000017, 0xb00a0003, 0xb400001f, 0xb00a0004, + 0xb400004d, 0xb00a0005, 0xb4000056, 0xb00a0006, + 0xb400007a, 0xb00a0007, 0xb4000078, 0xb00a0008, + 0xb4000076, 0x81df0000, 0x00000000, 0x00000000, + 0xb6008005, 0x007f8028, 0x9463ffff, 0x019fa023, + 0x019fa020, 0x019fa020, 0x81df0004, 0xb500006b, + 0x81df0000, 0x00000000, 0x00000000, 0xb6004004, + 0x007f8048, 0x019fa023, 0x019fa020, 0x019fa020, + 0x81df0004, 0xb5000061, 0xb0130000, 0xb4000004, + 0xb0130001, 0xb4000009, 0xb0130002, 0xb400001a, + 0x83a40098, 0x80170f00, 0x007f8028, 0x001fa023, + 0x007f8028, 0x001fa023, 0xb5000054, 0x80170f00, + 0x00000000, 0x007f8020, 0x019fa023, 0x007f8000, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708020, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x019fa020, 0x83a40083, 0x80170f00, 0x007f8028, + 0x001fa023, 0xb5000041, 0x80170f00, 0x00000000, + 0x007f8020, 0x019fa023, 0x007f8008, 0x9463ffff, + 0x019fa023, 0x019fa020, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020, + 0x83a40070, 0xb5000031, 0x81df0000, 0x00000000, + 0x00000000, 0xb6004005, 0x007f8008, 0x019fa023, + 0x007f8008, 0x019fa023, 0x019fa020, 0x81df0004, + 0xb5000026, 0xb0130000, 0xb4000008, 0xb0130001, + 0xb4000012, 0xb0130002, 0xb400001f, 0xb0130003, + 0xb400001d, 0xb0130004, 0xb400001b, 0x83a4006b, + 0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023, + 0x007f8008, 0x9463ffff, 0x019fa023, 0x80170f00, + 0x007f8028, 0x001fa023, 0xb5000010, 0x80170f00, + 0x00000000, 0x5c708020, 0x58908008, 0x1983a024, + 0x5c708028, 0x58908008, 0x1983a024, 0x5c708028, + 0x019fa023, 0x83a40055, 0x80170f00, 0x007f8028, + 0x001fa023, 0xb5000001, 0xb5000000, 0x92730001, + 0x92520001, 0x3012b811, 0xb480fe89, 0x003f0324, + 0x90210001, 0xb0010006, 0xb4a00001, 0x80270001, + 0x003f2324, 0x2c8db811, 0x803bffe0, 0x805bffe4, + 0x5887b804, 0x1015b804, 0xad440003, 0x3000b802, + 0xb4800001, 0x8400a000, 0x801effec, 0x015f6193, + 0x809e4b04, 0x00ffb81f, 0x81df0000, 0x00000000, + 0x00000000, 0xb6002a0c, 0x007f8028, 0x019fa023, + 0x007f8008, 0x9463ffff, 0x019fa023, 0x019fa020, + 0x5c708028, 0x58908008, 0x1983a024, 0x5c708028, + 0x019fa023, 0x019fa020, 0x81df0004, 0x00ffb81d, + 0x81df0000, 0x00000000, 0x00000000, 0xb600190f, + 0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023, + 0x007f8008, 0x9463ffff, 0x019fa023, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x81df0004, + 0x00ffb81d, 0x81df0000, 0x00000000, 0x00000000, + 0xb6002a0c, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x019fa020, 0x81df0004, 0x00ffb81d, 0x81df0000, + 0x00000000, 0x00000000, 0xb600190f, 0x007f8028, + 0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x58908008, 0x1983a024, + 0x5c708028, 0x019fa023, 0x81df0004, 0x00ffb81d, + 0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000, + 0xb4000011, 0x815b4b0c, 0x81070000, 0x81270bf4, + 0xb00a0000, 0xb4000002, 0x81070c00, 0x812717f4, + 0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc, + 0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809, + 0xb4a00060, 0xb5000008, 0xb0040000, 0xb4200003, + 0x802717ff, 0x81470000, 0xb5000003, 0x80270001, + 0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200006, + 0x039f4193, 0x5b81b81c, 0x003f90cb, 0x1021b81c, + 0x003fb0cb, 0x8384f922, 0x829bff80, 0x801300e0, + 0x1434b800, 0x5c35b801, 0x8013001f, 0x1454b800, + 0x5c50b802, 0x8073007f, 0x9863ffff, 0xb002000f, + 0xb4800001, 0x90210001, 0x84210004, 0xb0010000, + 0xb4a00001, 0x6861b803, 0x005f9040, 0x4082b803, + 0x80af001f, 0x808f0000, 0x806f0000, 0x8007ffff, + 0x8033ffff, 0x80171000, 0x81df0000, 0x00000000, + 0x00000000, 0xb6001811, 0xb6002010, 0x14618000, + 0x6068b803, 0x40c4b803, 0x14608000, 0x00c8b806, + 0x5870b803, 0x6068b803, 0x4104b803, 0x58c8b806, + 0x0108b808, 0x14c6b801, 0x00000000, 0x00000000, + 0x5d08b808, 0x1508b800, 0x1806a028, 0x81df0004, + 0x80670400, 0x5d22b80a, 0x81df0000, 0x00000000, + 0x00000000, 0xb600180a, 0x00cfb803, 0x013fb0bc, + 0x5922b809, 0x01afb809, 0x013f90bc, 0x0047b86f, + 0xb0020001, 0xb4c0fffd, 0x90630020, 0x91290020, + 0x81df0004, 0x808f0000, 0x801b4b14, 0x80270001, + 0xb0000001, 0xb4000002, 0x802600a0, 0x803e4b14, + 0x81270c00, 0xb00a0000, 0xb4000001, 0x81270000, + 0x813e4b0c, 0x80270001, 0x003f2013, 0x80050086, + 0x001fb044, 0x00ffb81b, 0x00000000, 0x00000000, +}; + +static u32 PCM240Ucode1f4b00[] = { + 0x00000000, 0x00000000, 0x00060504, 0x00000000, + 0x00000000, 0x00000000, 0x00300000, 0xffcfcfff, + 0x00302000, 0xffcfcfff, 0x00380000, 0xffc7c7ff, + 0xcbcecdc4, 0xcfcac9c8, 0xc3c6c5cc, 0xc7c2c1c0, + 0x1b1e1d14, 0x1f1a1918, 0x1316151c, 0x17121110, + 0x2b2e2d24, 0x2f2a2928, 0x2326252c, 0x27222120, + 0x3b3e3d34, 0x3f3a3938, 0x3336353c, 0x37323130, + 0x0b0e0d04, 0x0f0a0908, 0x0306050c, 0x07020100, + 0xdbdeddd4, 0xdfdad9d8, 0xd3d6d5dc, 0xd7d2d1d0, + 0xebeeede4, 0xefeae9e8, 0xe3e6e5ec, 0xe7e2e1e0, + 0xfbfefdf4, 0xfffaf9f8, 0xf3f6f5fc, 0xf7f2f1f0, + 0x4b4e4d44, 0x4f4a4948, 0x4346454c, 0x47424140, + 0x9b9e9d94, 0x9f9a9998, 0x9396959c, 0x97929190, + 0xabaeada4, 0xafaaa9a8, 0xa3a6a5ac, 0xa7a2a1a0, + 0xbbbebdb4, 0xbfbab9b8, 0xb3b6b5bc, 0xb7b2b1b0, + 0x8b8e8d84, 0x8f8a8988, 0x8386858c, 0x87828180, + 0x5b5e5d54, 0x5f5a5958, 0x5356555c, 0x57525150, + 0x6b6e6d64, 0x6f6a6968, 0x6366656c, 0x67626160, + 0x7b7e7d74, 0x7f7a7978, 0x7376757c, 0x77727170, + 0x341424c4, 0x3e1e2ece, 0x3d1d2dcd, 0x3b1b2bcb, + 0xb494a444, 0xbe9eae4e, 0xbd9dad4d, 0xbb9bab4b, + 0xf4d4e404, 0xfedeee0e, 0xfddded0d, 0xfbdbeb0b, + 0x74546484, 0x7e5e6e8e, 0x7d5d6d8d, 0x7b5b6b8b, + 0x3c1c2ccc, 0x361626c6, 0x351525c5, 0x331323c3, + 0xbc9cac4c, 0xb696a646, 0xb595a545, 0xb393a343, + 0xfcdcec0c, 0xf6d6e606, 0xf5d5e505, 0xf3d3e303, + 0x7c5c6c8c, 0x76566686, 0x75556585, 0x73536383, + 0x381828c8, 0x3a1a2aca, 0x391929c9, 0x3f1f2fcf, + 0xb898a848, 0xba9aaa4a, 0xb999a949, 0xbf9faf4f, + 0xf8d8e808, 0xfadaea0a, 0xf9d9e909, 0xffdfef0f, + 0x78586888, 0x7a5a6a8a, 0x79596989, 0x7f5f6f8f, + 0x301020c0, 0x321222c2, 0x311121c1, 0x371727c7, + 0xb090a040, 0xb292a242, 0xb191a141, 0xb797a747, + 0xf0d0e000, 0xf2d2e202, 0xf1d1e101, 0xf7d7e707, + 0x70506080, 0x72526282, 0x71516181, 0x77576787, + 0x05040100, 0x15141110, 0x25242120, 0x35343130, + 0x85848180, 0x95949190, 0xa5a4a1a0, 0xb5b4b1b0, + 0xc0408000, 0xe060a020, 0xd0509010, 0xf070b030, + 0xc8488808, 0xe868a828, 0xd8589818, 0xf878b838, + 0xc4448404, 0xe464a424, 0xd4549414, 0xf474b434, + 0xcc4c8c0c, 0xec6cac2c, 0xdc5c9c1c, 0xfc7cbc3c, + 0xc2428202, 0xe262a222, 0xd2529212, 0xf272b232, + 0xca4a8a0a, 0xea6aaa2a, 0xda5a9a1a, 0xfa7aba3a, + 0xc6468606, 0xe666a626, 0xd6569616, 0xf676b636, + 0xce4e8e0e, 0xee6eae2e, 0xde5e9e1e, 0xfe7ebe3e, + 0xc1418101, 0xe161a121, 0xd1519111, 0xf171b131, + 0xc9498909, 0xe969a929, 0xd9599919, 0xf979b939, + 0xc5458505, 0xe565a525, 0xd5559515, 0xf575b535, + 0xcd4d8d0d, 0xed6dad2d, 0xdd5d9d1d, 0xfd7dbd3d, + 0xc3438303, 0xe363a323, 0xd3539313, 0xf373b333, + 0xcb4b8b0b, 0xeb6bab2b, 0xdb5b9b1b, 0xfb7bbb3b, + 0xc7478707, 0xe767a727, 0xd7579717, 0xf777b737, + 0xcf4f8f0f, 0xef6faf2f, 0xdf5f9f1f, 0xff7fbf3f, + 0x1045a3e2, 0x000000f4, 0x263b7333, 0x766b2363, + 0x2b367e3e, 0x7b662e6e, 0x06db93d3, 0x964b0343, + 0x0bd69ede, 0x9b460e4e, 0x825f1757, 0x12cf87c7, + 0x8f521a5a, 0x1fc28aca, 0x00d199d9, 0x90410949, + 0x01d098d8, 0x91400848, 0x24357d3d, 0x74652d6d, + 0x25347c3c, 0x75642c6c, 0x04d59ddd, 0x94450d4d, + 0x05d49cdc, 0x95440c4c, 0x80511959, 0x10c189c9, + 0x81501858, 0x11c088c8, 0x02df97d7, 0x924f0747, + 0x0fd29ada, 0x9f420a4a, 0x865b1353, 0x16cb83c3, + 0x8b561e5e, 0x1bc68ece, 0xa6bbf3b3, 0xf6eba3e3, + 0xabb6febe, 0xfbe6aeee, 0x223f7737, 0x726f2767, + 0x2f327a3a, 0x7f622a6a, 0xa0b1f9b9, 0xf0e1a9e9, + 0xa1b0f8b8, 0xf1e0a8e8, 0x84551d5d, 0x14c58dcd, + 0x85541c5c, 0x15c48ccc, 0xa4b5fdbd, 0xf4e5aded, + 0xa5b4fcbc, 0xf5e4acec, 0x20317939, 0x70612969, + 0x21307838, 0x71602868, 0xa2bff7b7, 0xf2efa7e7, + 0xafb2faba, 0xffe2aaea, 0x00000000, 0x00000000, +}; + +static u32 PCM240Ucode1fff00[] = { + 0xcbcecdc4, 0xcfcac9c8, 0xc3c6c5cc, 0xc7c2c1c0, + 0x1b1e1d14, 0x1f1a1918, 0x1316151c, 0x17121110, + 0x2b2e2d24, 0x2f2a2928, 0x2326252c, 0x27222120, + 0x3b3e3d34, 0x3f3a3938, 0x3336353c, 0x37323130, + 0x0b0e0d04, 0x0f0a0908, 0x0306050c, 0x07020100, + 0xdbdeddd4, 0xdfdad9d8, 0xd3d6d5dc, 0xd7d2d1d0, + 0xebeeede4, 0xefeae9e8, 0xe3e6e5ec, 0xe7e2e1e0, + 0xfbfefdf4, 0xfffaf9f8, 0xf3f6f5fc, 0xf7f2f1f0, + 0x4b4e4d44, 0x4f4a4948, 0x4346454c, 0x47424140, + 0x9b9e9d94, 0x9f9a9998, 0x9396959c, 0x97929190, + 0xabaeada4, 0xafaaa9a8, 0xa3a6a5ac, 0xa7a2a1a0, + 0xbbbebdb4, 0xbfbab9b8, 0xb3b6b5bc, 0xb7b2b1b0, + 0x8b8e8d84, 0x8f8a8988, 0x8386858c, 0x87828180, + 0x5b5e5d54, 0x5f5a5958, 0x5356555c, 0x57525150, + 0x6b6e6d64, 0x6f6a6968, 0x6366656c, 0x67626160, + 0x7b7e7d74, 0x7f7a7978, 0x7376757c, 0x77727170, + 0x341424c4, 0x3e1e2ece, 0x3d1d2dcd, 0x3b1b2bcb, + 0xb494a444, 0xbe9eae4e, 0xbd9dad4d, 0xbb9bab4b, + 0xf4d4e404, 0xfedeee0e, 0xfddded0d, 0xfbdbeb0b, + 0x74546484, 0x7e5e6e8e, 0x7d5d6d8d, 0x7b5b6b8b, + 0x3c1c2ccc, 0x361626c6, 0x351525c5, 0x331323c3, + 0xbc9cac4c, 0xb696a646, 0xb595a545, 0xb393a343, + 0xfcdcec0c, 0xf6d6e606, 0xf5d5e505, 0xf3d3e303, + 0x7c5c6c8c, 0x76566686, 0x75556585, 0x73536383, + 0x381828c8, 0x3a1a2aca, 0x391929c9, 0x3f1f2fcf, + 0xb898a848, 0xba9aaa4a, 0xb999a949, 0xbf9faf4f, + 0xf8d8e808, 0xfadaea0a, 0xf9d9e909, 0xffdfef0f, + 0x78586888, 0x7a5a6a8a, 0x79596989, 0x7f5f6f8f, + 0x301020c0, 0x321222c2, 0x311121c1, 0x371727c7, + 0xb090a040, 0xb292a242, 0xb191a141, 0xb797a747, + 0xf0d0e000, 0xf2d2e202, 0xf1d1e101, 0xf7d7e707, + 0x70506080, 0x72526282, 0x71516181, 0x77576787, + 0x05040100, 0x15141110, 0x25242120, 0x35343130, + 0x85848180, 0x95949190, 0xa5a4a1a0, 0xb5b4b1b0, + 0xc0408000, 0xe060a020, 0xd0509010, 0xf070b030, + 0xc8488808, 0xe868a828, 0xd8589818, 0xf878b838, + 0xc4448404, 0xe464a424, 0xd4549414, 0xf474b434, + 0xcc4c8c0c, 0xec6cac2c, 0xdc5c9c1c, 0xfc7cbc3c, + 0xc2428202, 0xe262a222, 0xd2529212, 0xf272b232, + 0xca4a8a0a, 0xea6aaa2a, 0xda5a9a1a, 0xfa7aba3a, + 0xc6468606, 0xe666a626, 0xd6569616, 0xf676b636, + 0xce4e8e0e, 0xee6eae2e, 0xde5e9e1e, 0xfe7ebe3e, + 0xc1418101, 0xe161a121, 0xd1519111, 0xf171b131, + 0xc9498909, 0xe969a929, 0xd9599919, 0xf979b939, + 0xc5458505, 0xe565a525, 0xd5559515, 0xf575b535, + 0xcd4d8d0d, 0xed6dad2d, 0xdd5d9d1d, 0xfd7dbd3d, + 0xc3438303, 0xe363a323, 0xd3539313, 0xf373b333, + 0xcb4b8b0b, 0xeb6bab2b, 0xdb5b9b1b, 0xfb7bbb3b, + 0xc7478707, 0xe767a727, 0xd7579717, 0xf777b737, + 0xcf4f8f0f, 0xef6faf2f, 0xdf5f9f1f, 0xff7fbf3f, + 0x1045a3e2, 0x000000f4, 0x263b7333, 0x766b2363, + 0x2b367e3e, 0x7b662e6e, 0x06db93d3, 0x964b0343, + 0x0bd69ede, 0x9b460e4e, 0x825f1757, 0x12cf87c7, + 0x8f521a5a, 0x1fc28aca, 0x00d199d9, 0x90410949, + 0x01d098d8, 0x91400848, 0x24357d3d, 0x74652d6d, + 0x25347c3c, 0x75642c6c, 0x04d59ddd, 0x94450d4d, + 0x05d49cdc, 0x95440c4c, 0x80511959, 0x10c189c9, + 0x81501858, 0x11c088c8, 0x02df97d7, 0x924f0747, + 0x0fd29ada, 0x9f420a4a, 0x865b1353, 0x16cb83c3, + 0x8b561e5e, 0x1bc68ece, 0xa6bbf3b3, 0xf6eba3e3, + 0xabb6febe, 0xfbe6aeee, 0x223f7737, 0x726f2767, + 0x2f327a3a, 0x7f622a6a, 0xa0b1f9b9, 0xf0e1a9e9, + 0xa1b0f8b8, 0xf1e0a8e8, 0x84551d5d, 0x14c58dcd, + 0x85541c5c, 0x15c48ccc, 0xa4b5fdbd, 0xf4e5aded, + 0xa5b4fcbc, 0xf5e4acec, 0x20317939, 0x70612969, + 0x21307838, 0x71602868, 0xa2bff7b7, 0xf2efa7e7, + 0xafb2faba, 0xffe2aaea, 0x00000000, 0x00000000, +}; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/pcmi2s.h linux.19pre5-ac1/drivers/media/video/ls220/pcmi2s.h --- linux.19p5/drivers/media/video/ls220/pcmi2s.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/ls220/pcmi2s.h Thu Feb 21 21:25:25 2002 @@ -0,0 +1,801 @@ +static u32 PCMI2SUcode1f1800[] = { + 0xb500000f, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xb500020b, 0x00000000, 0x00000000, 0x00000000, + 0x820f001f, 0x802f001f, 0x029f9014, 0x829efef0, + 0x8286000f, 0x02bf0054, 0x82bcfef4, 0x82a6000e, + 0x80074000, 0x001f6193, 0x8013001f, 0x9020c000, + 0x003fb006, 0x803effe8, 0x803effec, 0x9020fa00, + 0x803effd0, 0x803effdc, 0x803effd8, 0x9020fe00, + 0x803effd4, 0x90400000, 0x804600a2, 0x90421800, + 0x804600a3, 0x80132000, 0x98000040, 0x800600a6, + 0x80050080, 0x98000002, 0x80060080, 0x80070001, + 0x001f2013, 0x80070000, 0x001f23f9, 0x801e4b0c, + 0x001f210c, 0x80070001, 0x001f2324, 0x80070800, + 0x001f600f, 0x001fb0cb, 0x001fb010, 0x801efff0, + 0x98004000, 0x001f600e, 0x83e4011f, 0x80070000, + 0x801e4b14, 0x800500a0, 0xb0000001, 0xb4000009, + 0x80070001, 0x800600a0, 0x80050080, 0x98000020, + 0x80060080, 0x9400ffdf, 0x80060080, 0x80070000, + 0x800600a0, 0x80074000, 0x801e4b04, 0x81df0004, + 0x801bfff0, 0x00000000, 0x940000ff, 0xb0000000, + 0xb4200033, 0x003f400e, 0x94010010, 0xb0000000, + 0xb400fff7, 0x003f0013, 0xb0010001, 0xb420001f, + 0x803bffe8, 0x801bffec, 0x805b4b04, 0x00000000, + 0x3001b800, 0xb4600001, 0x9021a000, 0x0421b800, + 0x3001b802, 0xb460000d, 0x80050086, 0x005f9044, + 0x0420b802, 0xb00101e0, 0xb4a0ffe5, 0x001fb010, + 0x001f010c, 0xb0000001, 0xb400ffe1, 0x80070001, + 0x001f210c, 0x83e400ec, 0xb500ffdd, 0x8007001f, + 0x94000003, 0x5810b800, 0x83e719ec, 0x1bffb800, + 0x003f9008, 0x1821b800, 0x00ffb801, 0x80270000, + 0x003f2013, 0x8007001f, 0x94000003, 0x5810b800, + 0x83671a14, 0x1b7bb800, 0x003f9009, 0x1821b800, + 0x00ffb801, 0x80070000, 0x001f210c, 0xb500ffc8, + 0x003f400e, 0xb0000086, 0xb4400055, 0xb0000084, + 0xb400003f, 0xb0000085, 0xb4000045, 0xb0000086, + 0xb4000047, 0xb0000083, 0xb4000000, 0x815bff7c, + 0x00000000, 0x940a0080, 0x5c07b800, 0xb0000001, + 0xb4000073, 0x81674b18, 0x940a0007, 0x5803b800, + 0x116bb800, 0x005bb80b, 0x916b0004, 0x001bb80b, + 0x80530030, 0x98422000, 0x8013ffcf, 0x9800cfff, + 0x806500d4, 0x1463b800, 0x1863b802, 0x806600d4, + 0x80073cfb, 0x801e4b00, 0x800600a1, 0x80074000, + 0x801e4b04, 0x8013001f, 0x98405000, 0x805effe0, + 0x005fb006, 0x805effe8, 0x805effec, 0x9042a000, + 0x805effe4, 0x9040fa00, 0x805effd0, 0x805effdc, + 0x805effd8, 0x9040fe00, 0x805effd4, 0x8013007f, + 0x9800ffff, 0x001fb040, 0x80070001, 0x001f2013, + 0x80070000, 0x001f2324, 0x001fb0cb, 0x001fb010, + 0x001fb041, 0x001fb042, 0x80073350, 0x001fb008, + 0x80071ea0, 0x001fb009, 0x98214000, 0xb5000010, + 0x94011000, 0xb0001000, 0xb4200001, 0x9421efff, + 0x98210010, 0xb500000a, 0x80070000, 0x001fb0cb, + 0x83e40099, 0x003f400e, 0x9421ffef, 0xb5000004, + 0x83e40095, 0x003f400e, 0x98211000, 0x9421ffef, + 0x003f600e, 0x80070100, 0x801efff0, 0xb500ff70, + 0xb000008b, 0xb4000018, 0xb0000087, 0xb400ffee, + 0xb0000088, 0xb4000016, 0xb000008a, 0xb4000016, + 0xb000008c, 0xb4000017, 0xb0000089, 0xb4000019, + 0xb00000a0, 0xb400001b, 0xb00000a1, 0xb4000047, + 0xb00000a2, 0xb4000054, 0xb00000a3, 0xb400004c, + 0xb00000a4, 0xb4000056, 0xb00000a5, 0xb400005a, + 0xb00000a6, 0xb400005e, 0x803efff8, 0xb500ffe1, + 0x9421ffdf, 0xb500ffde, 0x80270100, 0x803efff8, + 0xb500ffdc, 0x803bffb0, 0x00000000, 0x003fb040, + 0xb500ffd8, 0x803bff80, 0x00000000, 0x003f6001, + 0xb500ffd4, 0x003f90ba, 0x803efff8, 0xb500ffd1, + 0x81674b18, 0x940a0007, 0x5803b800, 0x116bb800, + 0x005bb80b, 0x916b0004, 0x001bb80b, 0x806500d4, + 0x1463b800, 0x1863b802, 0x806600d4, 0x80130001, + 0x98003d21, 0x800600a1, 0x801e4b00, 0x80074000, + 0x801e4b04, 0x8013001f, 0x98405000, 0x805effe0, + 0x005fb006, 0x805effe8, 0x805effec, 0x9042a000, + 0x805effe4, 0x9040fa00, 0x805effd0, 0x805effdc, + 0x805effd8, 0x9040fe00, 0x805effd4, 0x80070001, + 0x001f2013, 0x80070000, 0x001f2324, 0x001fb0cb, + 0x001fb010, 0x80073b90, 0x001fb008, 0x80074380, + 0x001fb009, 0x98214000, 0xb500ffa5, 0x80270000, + 0x8047fef0, 0x003eb802, 0x90420004, 0x003eb802, + 0x90420004, 0x003eb802, 0x90420004, 0x003eb802, + 0x81df0000, 0x00000000, 0x00000000, 0x83640437, + 0x81df0004, 0xb500ff97, 0x81df0000, 0x00000000, + 0x00000000, 0x836403e1, 0x81df0004, 0xb500ff91, + 0x81df0000, 0x00000000, 0x00000000, 0x8364039c, + 0x81df0004, 0xb500ff8b, 0x81df0000, 0x00000000, + 0x00000000, 0x834402ff, 0x81df0004, 0xb500ff85, + 0x81df0000, 0x00000000, 0x00000000, 0x834402e4, + 0x81df0004, 0xb500ff7f, 0x80070000, 0x80470000, + 0x81df0000, 0x00000000, 0x00000000, 0xb6002003, + 0xb6003002, 0x001eb802, 0x90420004, 0x80171000, + 0x8057ffff, 0xb6002002, 0xb6001801, 0x001fa020, + 0x81df0004, 0x00ffb81f, 0x817bff7c, 0x00000000, + 0x956b0080, 0x5d67b80b, 0x83a70000, 0x8057ffff, + 0x80770000, 0x8073007a, 0x9863e7d2, 0xb00b0001, + 0xb4200002, 0x8073007d, 0x98636d4a, 0x0207b803, + 0x81df0000, 0x00000000, 0x00000000, 0xb00b0001, + 0xb400000a, 0x80171000, 0xb6008007, 0x003fc0c0, + 0x005fc740, 0x40c1b810, 0x4102b810, 0x001fe0c6, + 0x001fe0c8, 0x4210b803, 0xb5000009, 0x80171000, + 0xb6000007, 0x003fc020, 0x005fc7e0, 0x40c1b810, + 0x4102b810, 0x001fe026, 0x001fe0a8, 0x4210b803, + 0x81df0004, 0x80270000, 0x003f2013, 0x8007001f, + 0x94000003, 0x5810b800, 0x83671e7c, 0x1b7bb800, + 0x003f9009, 0x1821b800, 0x00ffb801, 0x003f0013, + 0xb0010001, 0xb420fff3, 0x93bd0001, 0xb01d0004, + 0xb480ffd7, 0x00ffb81f, 0x00000000, 0x00000000, + 0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000, + 0xb4000011, 0x815b4b0c, 0x81070000, 0x81270be8, + 0xb00a0000, 0xb4000002, 0x81070c00, 0x812717e8, + 0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc, + 0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809, + 0xb4a00059, 0xb5000008, 0xb0040000, 0xb4200003, + 0x802717ff, 0x81470000, 0xb5000003, 0x80270001, + 0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200006, + 0x039f4193, 0x5b81b81c, 0x003f90cb, 0x1021b81c, + 0x003fb0cb, 0x83840246, 0x829bff80, 0x801300e0, + 0x1434b800, 0x5c35b801, 0x8013001f, 0x1454b800, + 0x5c50b802, 0x8073007f, 0x9863ffff, 0xb002000f, + 0xb4800001, 0x90210001, 0x84210004, 0xb0010000, + 0xb4a00001, 0x6861b803, 0x005f9040, 0x4082b803, + 0x80af001f, 0x808f0000, 0x806f0000, 0x8007ffff, + 0x8033ffff, 0x80171000, 0x81df0000, 0x00000000, + 0x00000000, 0xb600180a, 0xb6002009, 0x58708000, + 0x6068b803, 0x40c4b803, 0x00000000, 0x00c8b806, + 0x00000000, 0x00000000, 0x00000000, 0x5807a026, + 0x81df0004, 0x80670400, 0x5d22b80a, 0x81df0000, + 0x00000000, 0x00000000, 0xb600180a, 0x00cfb803, + 0x013fb0bc, 0x5922b809, 0x01afb809, 0x013f90bc, + 0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x90630020, + 0x91290020, 0x81df0004, 0x808f0000, 0x801b4b14, + 0x80270001, 0xb0000001, 0xb4000002, 0x802600a0, + 0x803e4b14, 0x81270c00, 0xb00a0000, 0xb4000001, + 0x81270000, 0x813e4b0c, 0x80270001, 0x003f2013, + 0x80050086, 0x001fb044, 0x00ffb81b, 0x00000000, + 0x029fb00a, 0x02bfb00b, 0x02dfb00c, 0x02ffb00d, + 0x031fb00e, 0x033fb00f, 0x033f400f, 0x0287b86f, + 0x029fb005, 0x8285009c, 0x96b48000, 0xb0158000, + 0xb4000191, 0x96b40100, 0xb0150100, 0xb40001ad, + 0x96b40400, 0xb0150400, 0xb40001bf, 0x96b40001, + 0xb0150001, 0xb400000c, 0x96b40008, 0xb0150008, + 0xb400019a, 0x96b44000, 0xb0154000, 0xb40001be, + 0x96b40002, 0xb0150002, 0xb400015e, 0x00000000, + 0x00000000, 0xb50001d0, 0x02bf9017, 0x92b50001, + 0x02bfb017, 0x82850082, 0x83050081, 0x82a5009a, + 0x96b50001, 0xb0150001, 0xb4200014, 0x82a70000, + 0x02bfb017, 0x96b41840, 0xb0150800, 0xb420000c, + 0x96b40008, 0x5aa9b815, 0x96d46000, 0x5ec3b816, + 0x82f3000f, 0x9af7c00f, 0x1718b817, 0x1ab5b818, + 0x1ab5b816, 0x9ab50340, 0x82a60081, 0xb500013d, + 0x9b180180, 0x83060081, 0xb500013a, 0x82a5009a, + 0x96b50002, 0xb0150002, 0xb420001b, 0x82a70000, + 0x02bfb017, 0x96b41800, 0xb0151800, 0xb4000013, + 0x96b40040, 0xb0150040, 0xb4200004, 0xa3180c00, + 0x9b180340, 0x83060081, 0xb500012a, 0x96b40008, + 0x5aa9b815, 0x96d46000, 0x5ec3b816, 0x82f3000f, + 0x9af7c00f, 0x1718b817, 0x1ab5b818, 0x1ab5b816, + 0x9ab50340, 0x82a60081, 0xb500011e, 0x9b180180, + 0x83060081, 0xb500011b, 0x82a500c1, 0x96b5000f, + 0xb015000b, 0xb420000e, 0x96b40020, 0xb0150020, + 0xb400000b, 0x96b40200, 0xb0150200, 0xb4000008, + 0x82c50086, 0x82e50094, 0x3016b817, 0xb4400004, + 0x06f7b816, 0xb017ff00, 0xb4400001, 0xb5000109, + 0x96b46000, 0xb0156000, 0xb4000011, 0x96b41820, + 0xb0150820, 0xb4200004, 0x9b391000, 0x82a5009a, + 0x96b5feff, 0x82a6009a, 0x96b40040, 0xb0150040, + 0xb4200001, 0x9739efff, 0x96b91000, 0xb0151000, + 0xb4200003, 0x82a5009a, 0x9ab50100, 0x82a6009a, + 0x96b40040, 0xb0150040, 0xb4200019, 0x96b41800, + 0xb0151800, 0xb4200006, 0x96b98000, 0xb0158000, + 0xb4200003, 0x9b180180, 0x83060081, 0xb50000e9, + 0x96d80c00, 0x82b300ff, 0x9ab5f3ff, 0x1718b815, + 0xb0160c00, 0xb4000007, 0x82e50098, 0x96f70400, + 0xb0170400, 0xb4200002, 0x82c70c00, 0xb5000001, + 0xa2d60c00, 0x1b18b816, 0x9b180340, 0xb50000cf, + 0x96b40220, 0xb0150000, 0xb4e00033, 0x82a5009d, + 0x82f3ffff, 0x16b5b817, 0x82f3000e, 0x3015b817, + 0xb420002d, 0x96f98000, 0xb0178000, 0xb400002a, + 0x82a70000, 0x02bfb017, 0x82c50081, 0x9ab60020, + 0x82a60081, 0x82a50086, 0x92b50bb8, 0x82a60094, + 0x82c60081, 0x82c5009d, 0x96d6ffff, 0x82b30032, + 0x9ab58001, 0x82e500c1, 0x96f7000f, 0xb017000b, + 0xb4000002, 0x82b30022, 0x9ab58001, 0x1ab5b816, + 0x82c5009a, 0x96d60020, 0xb0160020, 0xb4200002, + 0x82b30032, 0x9ab58001, 0x82a6009d, 0x02ff9017, + 0x00000000, 0xb0170040, 0xb480000b, 0x96f41c00, + 0xb0171c00, 0xb4200008, 0x82e50086, 0x82c50094, + 0x92d63000, 0x3016b817, 0xb4400003, 0x9b180180, + 0x83060081, 0xb50000a3, 0x5eb5b814, 0x96b500f0, + 0x96f46000, 0x5eedb817, 0x1ab5b817, 0xb0170003, + 0xb4000004, 0x96b500ef, 0x96f70001, 0x5ae4b817, + 0x1ab5b817, 0x96d41800, 0xb0161800, 0xb400000a, + 0x96f900ff, 0x96b500ff, 0x9739ff00, 0x1b39b815, + 0x02a7b817, 0x96b500f3, 0x96d40008, 0x5ec1b816, + 0x1ab5b816, 0xb500000c, 0x96f98000, 0xb0178000, + 0xb4200007, 0x5efeb814, 0x96f70001, 0xb0170001, + 0xb4000003, 0x9b180180, 0x83060081, 0xb5000081, + 0x96b500f3, 0x9ab50008, 0x9739fff3, 0x96d40020, + 0xb0160020, 0xb4200017, 0x9b398000, 0x82c70000, + 0x02dfb017, 0x96d40010, 0x5ac8b816, 0x82f300ff, + 0x9af7cfff, 0x1718b817, 0x1b18b816, 0x9b180340, + 0x82c5009d, 0x96d6ffff, 0x82f3000e, 0x9af78001, + 0x1af7b816, 0x82c5009a, 0x96d60020, 0xb0160020, + 0xb4200002, 0x82f30032, 0x9af78001, 0x82e6009d, + 0xb500005a, 0x97397fff, 0x96b500ff, 0x5aaab815, + 0x82f300fc, 0x9af703ff, 0x1718b817, 0x1b18b815, + 0x9b180340, 0x82c5009a, 0x96d60010, 0xb0160010, + 0xb4200024, 0x82c70000, 0x02dfb017, 0x82c50086, + 0x92d60bb8, 0x82c60086, 0x82c50094, 0x5eefb818, + 0x96f70003, 0xb0170003, 0xb4200002, 0x82e70bb8, + 0xb5000001, 0x82e70bb8, 0x12d6b817, 0x82e50081, + 0x9af70020, 0x82e60081, 0x82c60094, 0xa2f70020, + 0x82e60081, 0x82f30001, 0x16f7b818, 0x5ef0b817, + 0xb0170001, 0xb4000004, 0x96f84000, 0x5ee4b817, + 0x9718f3ff, 0x1b18b817, 0x82f3000a, 0x9af78000, + 0x82e6009d, 0x83060081, 0x83070001, 0x8306009f, + 0xb50000ad, 0x82c5009d, 0x82f3000e, 0x9af78001, + 0x3016b817, 0xb420000f, 0x82b30032, 0x9ab58001, + 0x82e500c1, 0x96f7000f, 0xb017000b, 0xb4000002, + 0x82b30022, 0x9ab58001, 0x82c5009a, 0x96d60020, + 0xb0160020, 0xb4200002, 0x82b30032, 0x9ab58001, + 0x82a6009d, 0x82c5009a, 0x96d60080, 0xb0160080, + 0xb4000011, 0x02df9017, 0x00000000, 0xb0160010, + 0xb480000d, 0x82c500c1, 0x96d6000f, 0xb016000b, + 0xb4000009, 0x82c50087, 0x96d60080, 0x5ac7b816, + 0x96f84000, 0x3017b816, 0xb4200003, 0x033f400f, + 0x9b394000, 0xb500000b, 0x9739bfff, 0x82e50061, + 0x96f70008, 0xb0170008, 0xb4000005, 0x5eefb818, + 0x96f70003, 0xb0170003, 0xb4000001, 0x9718ffff, + 0x83060081, 0x83070001, 0x8306009f, 0x00000000, + 0xb5000075, 0x82850083, 0x96b400ff, 0xb015003c, + 0xb4200019, 0x96b92000, 0xb0152000, 0xb4000002, + 0x9b392000, 0xb5000014, 0x9739d3ff, 0x82870000, + 0x82860087, 0x82870008, 0x82860083, 0x829bff78, + 0x82a7001f, 0xb0140400, 0xb4000001, 0x82a70010, + 0x82a600c9, 0x829bff78, 0x00000000, 0x828600cb, + 0x8285009d, 0x82b3ffff, 0x9ab5fffd, 0x1694b815, + 0x8286009d, 0xb5000000, 0x83070002, 0x8306009f, + 0x00000000, 0xb5000054, 0x96b90800, 0xb0150800, + 0xb4200009, 0x9739f7ff, 0x82a703fd, 0x82a600cb, + 0x82a7003c, 0x82a60083, 0x8285009d, 0x9a940002, + 0x8286009d, 0xb5000004, 0x82850087, 0x5a82b814, + 0xa2940200, 0x82860087, 0xb5000000, 0x83078000, + 0x8306009f, 0x00000000, 0xb500003f, 0x82850086, + 0x82a50094, 0x3015b814, 0xb4800002, 0x86b50bb8, + 0x82a60086, 0x83070008, 0x8306009f, 0x00000000, + 0xb5000035, 0x83050069, 0x9718003f, 0x82e50064, + 0x12f7b818, 0x86f70088, 0x82feff74, 0x02e7b86f, + 0x9af74000, 0x01ffb817, 0x96f7bfff, 0x01ffb817, + 0x83050081, 0x82f3001c, 0x9af703ff, 0x1718b817, + 0x9b180140, 0x83060081, 0x83070100, 0x8306009f, + 0x00000000, 0xb5000020, 0x83070000, 0x83050081, + 0x9b180180, 0x83060081, 0x83070400, 0x8306009f, + 0x00000000, 0xb5000018, 0x82870000, 0x82850082, + 0x5eb7b814, 0x96b500fc, 0x96d40006, 0x5ec1b816, + 0x1ab5b816, 0x5aacb815, 0x83050081, 0x82d3001c, + 0x9ad600ff, 0x1718b816, 0x1b18b815, 0x9b180e00, + 0x83060081, 0x83074000, 0x8306009f, 0x8305009d, + 0x82d300ff, 0x9ad6bfff, 0x1718b816, 0x8306009d, + 0x00000000, 0xb5000000, 0x029f9005, 0x01ffb814, + 0x033f600f, 0x029f900a, 0x02bf900b, 0x02df900c, + 0x02ff900d, 0x031f900e, 0x033f900f, 0x00ffb81e, + 0x02ff9010, 0x92f70b43, 0x02ffb010, 0x02ff90cb, + 0x82bbffdc, 0x829bffd8, 0x93150004, 0x3014b815, + 0xb4000010, 0x02dbb818, 0x029bb815, 0x3017b816, + 0xb480000c, 0x5a81b814, 0x029fb010, 0x82860095, + 0x8293001f, 0x9294fe00, 0x92b50008, 0x3015b814, + 0xb4800002, 0x82b3001f, 0x92b5fa00, 0x82beffdc, + 0xb500ffeb, 0x029f9010, 0x83250094, 0x06d4b819, + 0x02d6b816, 0xb016ffff, 0xb4a0000a, 0x8293000e, + 0x9a948001, 0x82c5009d, 0x96d6ffff, 0x1a94b816, + 0x82c5009a, 0x96d60010, 0xb0160010, 0xb4000001, + 0x8286009d, 0x00ffb81c, 0x00000000, 0x00000000, + 0x001f9012, 0x001fb100, 0x001f004c, 0x001f2404, + 0x801bfef0, 0x8058fef4, 0x803bff68, 0x8078ff6c, + 0x2000b801, 0x2042b803, 0x001fb104, 0x005f2414, + 0x82e70001, 0x83640048, 0x029fb014, 0x829efef0, + 0x8286000f, 0x02bf2054, 0x82bcfef4, 0x82a6000e, + 0x00ffb81a, 0x80e70001, 0x801336e3, 0x9800eb76, + 0x001fb100, 0x800700ab, 0x001f2404, 0x801bc3e8, + 0x8058c3ec, 0x83640024, 0x82e70000, 0x83640036, + 0x029fb300, 0x029fb100, 0x02bf2c04, 0x02bf2404, + 0x801bc000, 0x8058c004, 0x8364001b, 0x82e70000, + 0x8364002d, 0x001f9300, 0x3000b814, 0xb420000a, + 0x001f0c04, 0x3000b815, 0xb4200007, 0x829efef0, + 0x82bcfef4, 0x029fb012, 0x02bf204c, 0x82870001, + 0x829cfef5, 0x00ffb81a, 0xb0070000, 0xb4000007, + 0x80e70000, 0x801399fa, 0x9800c92e, 0x001fb100, + 0x800700af, 0x001f2404, 0xb500ffdc, 0x82870000, + 0x829cfef5, 0x00ffb81a, 0x80c700ff, 0x803bff68, + 0x8078ff6c, 0x14a0b806, 0x2063b805, 0x007f2414, + 0x2021b802, 0x58c8b806, 0x14a0b806, 0x58b0b805, + 0x2021b805, 0x58c8b806, 0x14a0b806, 0x2021b805, + 0x58c8b806, 0x14a0b806, 0x5cb0b805, 0x2021b805, + 0x003fb104, 0x00ffb81b, 0x82c70000, 0x83070400, + 0x83270005, 0x8197040c, 0x81d7ffff, 0x83840126, + 0x83840001, 0x00ffb81b, 0x808f0000, 0x806f001f, + 0x80af001f, 0x80270140, 0x81e70228, 0x5de2b80f, + 0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, + 0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020, + 0x90210020, 0x80270180, 0x81e70120, 0x5de2b80f, + 0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, + 0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020, + 0x90210020, 0x8057ffff, 0x80170430, 0x80070410, + 0x80270408, 0xb6000509, 0x005ff000, 0x90420500, + 0x007ff001, 0x90630600, 0x009ff002, 0x00bff003, + 0x2004a025, 0x90000001, 0x90210001, 0x80070414, + 0x80d7ffff, 0x8097045c, 0x8017043c, 0xb6000404, + 0x005ff000, 0x007f87e0, 0x84000001, 0x2082a7e3, + 0x80970460, 0x80170440, 0x2082b803, 0x007f8000, + 0x2083a004, 0x80170430, 0x80970450, 0x80270408, + 0xb6000508, 0x005f8024, 0x90420500, 0x007ff001, + 0x90630600, 0x009ff002, 0x00bff003, 0x2004a025, + 0x90210001, 0x80170440, 0x00000000, 0x02bf87e0, + 0x80970460, 0x82870000, 0xb6000404, 0x005f87e4, + 0x5a88b814, 0x204287e0, 0x1a94b802, 0x00ffb81c, + 0x001f0a49, 0x001f2709, 0x001f0a41, 0x001f2708, + 0x001f0a46, 0x001f2707, 0x001f0a48, 0x001f2706, + 0x001f0a42, 0x001f2705, 0x001f0a47, 0x001f2704, + 0x001f0a45, 0x001f2703, 0x001f0a43, 0x001f2702, + 0x001f0a40, 0x001f2701, 0x001f0a44, 0x001f2700, + 0x001f0c25, 0xa020000c, 0x94400001, 0x94600002, + 0x94810004, 0x94a10008, 0x94c00010, 0x5943b802, + 0x5861b803, 0x5882b804, 0x5ca2b805, 0x5cc4b806, + 0x194ab803, 0x194ab804, 0x194ab805, 0x194ab806, + 0x015f2738, 0x801b0220, 0x003f91c1, 0x5c28b801, + 0x005f91c2, 0x5858b802, 0x1821b802, 0x2000b801, + 0x001fb1c4, 0x80180224, 0x003f0709, 0x2000b801, + 0x001f2714, 0x82c70001, 0x82e70001, 0x83070710, + 0x8327001e, 0x81970735, 0x8384009f, 0x02df0738, + 0x82170a30, 0x838400f1, 0x819efef0, 0x817cfef4, + 0x819eff68, 0x817cff6c, 0x00ffb81b, 0x820f001f, + 0x8018fef8, 0x8057ffff, 0x001f2709, 0x8018fef6, + 0x80d7ffff, 0x001f2708, 0x8018fefa, 0x8157ffff, + 0x001f2707, 0x8018fefd, 0x81d7ffff, 0x001f2706, + 0x8018fefb, 0x802f001f, 0x001f2705, 0x8018fefe, + 0x00000000, 0x001f2704, 0x8018fef9, 0x00000000, + 0x001f2703, 0x8018feff, 0x00000000, 0x001f2702, + 0x8018fef7, 0x00000000, 0x001f2701, 0x8018fefc, + 0x00000000, 0x001f2700, 0x001f0c25, 0xa0200011, + 0x94410001, 0x94600002, 0x94800004, 0x94a00008, + 0x94c10010, 0x5941b802, 0x5861b803, 0x5c82b804, + 0x58a1b805, 0x5cc1b806, 0x194ab803, 0x194ab804, + 0x194ab805, 0x194ab806, 0x015f2738, 0x801b0220, + 0x003f91c1, 0x5c28b801, 0x005f91c2, 0x5858b802, + 0x1821b802, 0x2000b801, 0x001fb1c4, 0x80180224, + 0x003f0709, 0x2000b801, 0x001f2714, 0x82c70001, + 0x82e70001, 0x83070710, 0x8327001e, 0x81970735, + 0x83840055, 0x02df0738, 0x82170a20, 0x838400a7, + 0x819efef0, 0x817cfef4, 0x5ac8b80c, 0x02ff0a44, + 0x1ad6b817, 0x02dfb291, 0x5ed8b80c, 0x5968b80b, + 0x1ad6b80b, 0x02df6524, 0x00ffb81b, 0x820f001f, + 0x8018fefe, 0x8057ffff, 0x001f2709, 0x8018fefa, + 0x80d7ffff, 0x001f2708, 0x8018fefc, 0x8157ffff, + 0x001f2707, 0x8018feff, 0x81d7ffff, 0x001f2706, + 0x8018fef8, 0x802f001f, 0x001f2705, 0x8018fefb, + 0x00000000, 0x001f2704, 0x8018fefd, 0x00000000, + 0x001f2703, 0x8018fef6, 0x00000000, 0x001f2702, + 0x8018fef9, 0x00000000, 0x001f2701, 0x8018fef7, + 0x00000000, 0x001f2700, 0x801b0220, 0x003f91c1, + 0x5c28b801, 0x005f91c2, 0x5858b802, 0x1821b802, + 0x2000b801, 0x001fb1c4, 0x80180224, 0x003f0709, + 0x2000b801, 0x001f2714, 0x82c70001, 0x82e70001, + 0x83070710, 0x8327001e, 0x81970735, 0x83840016, + 0x83270000, 0x831bfef0, 0x82f8fef4, 0x02c7b819, + 0x82170a28, 0x83840065, 0x300cb818, 0xb4200002, + 0x300bb817, 0xb4000006, 0x93390001, 0xb0190020, + 0xb480fff6, 0x83270000, 0x833cfef5, 0x00ffb81b, + 0x019fb290, 0x017f2a44, 0x033f2c25, 0x83270001, + 0x833cfef5, 0x00ffb81b, 0x0007b818, 0x90000003, + 0x00000000, 0x015ff000, 0x90000001, 0x5949b80a, + 0x013ff000, 0x194ab809, 0x84000002, 0x994a0100, + 0x017ff000, 0x958b00f8, 0x5981b80c, 0x956b0007, + 0x198cb80b, 0x84000002, 0x998c0008, 0x017ff000, + 0x90000001, 0x5971b80b, 0x198cb80b, 0x017ff000, + 0x5969b80b, 0x198cb80b, 0x81a70000, 0x94d90003, + 0x82a70000, 0xb6260019, 0xb6000818, 0x5df0b80a, + 0x5e02b80a, 0x21efb810, 0x95ef0001, 0x5941b80a, + 0x194ab80f, 0x21efb816, 0x5e18b80c, 0x5e35b80c, + 0x5e54b80c, 0x5e6cb80c, 0x2210b811, 0x2252b813, + 0x2210b812, 0x96100001, 0x5981b80c, 0x198cb810, + 0x2210b817, 0x10afb810, 0x10a5b80d, 0x5da1b805, + 0x94a50001, 0x5aa1b815, 0x1ab5b805, 0x019fa7f5, + 0x5cc2b819, 0xb626001c, 0x82870000, 0xb6000419, + 0xb6000818, 0x5df0b80a, 0x5e02b80a, 0x21efb810, + 0x95ef0001, 0x5941b80a, 0x194ab80f, 0x21efb816, + 0x5e18b80c, 0x5e35b80c, 0x5e54b80c, 0x5e6cb80c, + 0x2210b811, 0x2252b813, 0x2210b812, 0x96100001, + 0x5981b80c, 0x198cb810, 0x2210b817, 0x10afb810, + 0x10a5b80d, 0x5da1b805, 0x94a50001, 0x5a81b814, + 0x1a94b805, 0x019fa7f4, 0x00ffb81c, 0x8257ffff, + 0x808f0000, 0x806f001f, 0x80af001f, 0x80270200, + 0x81e7ff00, 0x5de2b80f, 0xb6000208, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0xb520ffff, 0x91ef0020, 0x90210020, 0x80270240, + 0x81e70000, 0x5de2b80f, 0xb6000208, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0xb520ffff, 0x91ef0020, 0x90210020, 0x80270180, + 0x81e70120, 0x5de2b80f, 0xb6000208, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0xb520ffff, 0x91ef0020, 0x90210020, 0x806f0007, + 0x80af0007, 0x80270280, 0x81e70100, 0x5de2b80f, + 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, + 0x01ff90bc, 0xb520ffff, 0x91ef0020, 0x90210020, + 0x80170760, 0x001f0700, 0x001fa020, 0x001f0701, + 0x001fa020, 0x001f0702, 0x001fa020, 0x001f0703, + 0x001fa020, 0x001f0704, 0x001fa000, 0x80970750, + 0x81170770, 0x82a70735, 0x83a40060, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a4005c, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750, + 0x81170750, 0x81970740, 0x82a70730, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a40050, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a4004c, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970750, 0x80170770, + 0x81170770, 0x81970760, 0x82a7072b, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a40040, 0x83a4004e, + 0xb6000407, 0x86b50001, 0x83a4003c, 0x001f8004, + 0x003f87e8, 0x2080a001, 0x83a40047, 0x00000000, + 0x80970770, 0x80170750, 0x81170750, 0x81970740, + 0x82a70726, 0x001f800c, 0x003f8008, 0x2100a001, + 0x83a4002e, 0x83a4003c, 0xb6000407, 0x86b50001, + 0x83a4002a, 0x001f8004, 0x003f87e8, 0x2080a001, + 0x83a40035, 0x00000000, 0x80970750, 0x80170770, + 0x81170770, 0x81970760, 0x82a70721, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a4001c, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a40018, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750, + 0x81170750, 0x81970740, 0x82a7071c, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a4000c, 0x017f87e4, + 0x81870000, 0xb6000406, 0x86b50001, 0x83a40007, + 0x001f87e4, 0x200087e8, 0x5988b80c, 0x198cb800, + 0x021fa02c, 0x021fa00b, 0x00ffb81c, 0x005ff015, + 0x90420600, 0x003f87e0, 0x001ff002, 0x2060b801, + 0x90630800, 0x90960a00, 0x001ff003, 0x003ff004, + 0x20a0b801, 0x90a50900, 0x00000000, 0x001ff005, + 0x009fa000, 0x00ffb81d, 0x001f8004, 0x5c21b800, + 0x5847b800, 0x1821b802, 0x942100ff, 0x2080a7e1, + 0x00ffb81d, 0x00000000, 0x00000000, 0x00000000, + 0x829bff80, 0x80af000f, 0x808f0000, 0x806f0000, + 0x82bbffec, 0x82fbffe4, 0x00000000, 0x82beffb8, + 0x95540700, 0x5d48b80a, 0x914a0001, 0x0227b80a, + 0x94343000, 0x5c2cb801, 0xb0010000, 0xb4000001, + 0x5a21b811, 0x9574c000, 0x5d6eb80b, 0x918b4b08, + 0x01b8b80c, 0x96d5ffff, 0x5ec2b816, 0x96f7ffff, + 0x5ee2b817, 0x8057ffff, 0x80d7ffff, 0x8157ffff, + 0x81d7ffff, 0x81f3ff00, 0x99efff00, 0x821300ff, + 0x9a1000ff, 0x81971000, 0x82670000, 0x82470000, + 0x80270280, 0x81df0000, 0x00000000, 0x00000000, + 0xb62d000d, 0x3016b817, 0xb4800001, 0x86d62800, + 0x00cfb801, 0x02dfb0bc, 0x5ac2b816, 0x01cfb816, + 0x02df90bc, 0x0067b86f, 0xb0030001, 0xb4c0fffd, + 0x92d60010, 0x90210010, 0x81df0004, 0x80170a00, + 0x81df0000, 0x00000000, 0x00000000, 0xb62d0006, + 0xb6001005, 0x146f8000, 0x14908000, 0x5c68b803, + 0x5888b804, 0x1803a024, 0x81df0004, 0x80170a00, + 0x80970d00, 0xb00b0000, 0xb4000004, 0xb00b0001, + 0xb400000a, 0xb00b0002, 0xb4000027, 0x81df0000, + 0x00000000, 0x00000000, 0xb6004002, 0x007f8020, + 0x009fa023, 0x81df0004, 0xb5000029, 0x80d3ffff, + 0x81df0000, 0x00000000, 0x00000000, 0xb6001018, + 0x5c648000, 0x9463ffff, 0x5c888020, 0x58b88000, + 0x1884b805, 0x1484b806, 0x1883a024, 0x5c6c8020, + 0x9463ffff, 0x58908000, 0x1883a024, 0x5c748020, + 0x588c8000, 0x1863b804, 0x9463ffff, 0x58888000, + 0x1484b806, 0x1883a024, 0x5c7c8020, 0x58848000, + 0x1863b804, 0x9463ffff, 0x14868020, 0x1883a024, + 0x81df0004, 0xb500000a, 0x80d3ffff, 0x81df0000, + 0x00000000, 0x00000000, 0xb6002004, 0x007f8020, + 0x009fa023, 0x007f8040, 0x009fa023, 0x81df0004, + 0x00000000, 0x81170d00, 0x80070000, 0x94343000, + 0x5c2cb801, 0xb0010001, 0xb4000099, 0xb00a0001, + 0xb400000e, 0xb00a0002, 0xb4000022, 0xb00a0003, + 0xb400002f, 0xb00a0004, 0xb400005d, 0xb00a0005, + 0xb4000066, 0xb00a0006, 0xb400008a, 0xb00a0007, + 0xb4000088, 0xb00a0008, 0xb4000086, 0x81df0000, + 0x00000000, 0x00000000, 0xb6004010, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020, + 0x019fa020, 0x019fa020, 0x019fa020, 0x5c708028, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020, + 0x019fa020, 0x019fa020, 0x019fa020, 0x81df0004, + 0xb5000070, 0x81df0000, 0x00000000, 0x00000000, + 0x8027ffff, 0xb6004008, 0x14618008, 0x019fa023, + 0x019fa020, 0x019fa020, 0x5c708028, 0x019fa023, + 0x019fa020, 0x019fa020, 0x81df0004, 0xb5000061, + 0xb0130000, 0xb4000004, 0xb0130001, 0xb4000009, + 0xb0130002, 0xb400001a, 0x83a40102, 0x80170f00, + 0x007f8028, 0x001fa023, 0x007f8028, 0x001fa023, + 0xb5000054, 0x80170f00, 0x00000000, 0x007f8020, + 0x019fa023, 0x007f8000, 0x9463ffff, 0x019fa023, + 0x019fa020, 0x5c708020, 0x58908008, 0x1983a024, + 0x5c708028, 0x019fa023, 0x019fa020, 0x83a400ed, + 0x80170f00, 0x007f8028, 0x001fa023, 0xb5000041, + 0x80170f00, 0x00000000, 0x007f8020, 0x019fa023, + 0x007f8008, 0x9463ffff, 0x019fa023, 0x019fa020, + 0x5c708028, 0x58908008, 0x1983a024, 0x5c708028, + 0x019fa023, 0x019fa020, 0x83a400da, 0xb5000031, + 0x81df0000, 0x00000000, 0x00000000, 0xb6002005, + 0x007f8008, 0x019fa023, 0x007f8008, 0x019fa023, + 0x019fa020, 0x81df0004, 0xb5000026, 0xb0130000, + 0xb4000008, 0xb0130001, 0xb4000012, 0xb0130002, + 0xb400001f, 0xb0130003, 0xb400001d, 0xb0130004, + 0xb400001b, 0x83a400d5, 0x007f8028, 0x019fa023, + 0x007f8028, 0x019fa023, 0x007f8008, 0x9463ffff, + 0x019fa023, 0x80170f00, 0x007f8028, 0x001fa023, + 0xb5000010, 0x80170f00, 0x00000000, 0x5c708020, + 0x58908008, 0x1983a024, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x83a400bf, + 0x80170f00, 0x007f8028, 0x001fa023, 0xb5000001, + 0xb5000000, 0x00000000, 0x00000000, 0xb500008e, + 0xb00a0001, 0xb400000e, 0xb00a0002, 0xb400001a, + 0xb00a0003, 0xb4000027, 0xb00a0004, 0xb4000055, + 0xb00a0005, 0xb400005e, 0xb00a0006, 0xb4000082, + 0xb00a0007, 0xb4000080, 0xb00a0008, 0xb400007e, + 0x81df0000, 0x00000000, 0x00000000, 0xb6004008, + 0x007f8028, 0x9463ffff, 0x019fa023, 0x019fa020, + 0x019fa020, 0x019fa020, 0x019fa020, 0x019fa020, + 0x81df0004, 0xb5000070, 0x81df0000, 0x00000000, + 0x00000000, 0x8027ffff, 0xb6002008, 0x14618008, + 0x019fa023, 0x019fa020, 0x019fa020, 0x5c708048, + 0x019fa023, 0x019fa020, 0x019fa020, 0x81df0004, + 0xb5000061, 0xb0130000, 0xb4000004, 0xb0130001, + 0xb4000009, 0xb0130002, 0xb400001a, 0x83a40098, + 0x80170f00, 0x007f8028, 0x001fa023, 0x007f8028, + 0x001fa023, 0xb5000054, 0x80170f00, 0x00000000, + 0x007f8020, 0x019fa023, 0x007f8000, 0x9463ffff, + 0x019fa023, 0x019fa020, 0x5c708020, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020, + 0x83a40083, 0x80170f00, 0x007f8028, 0x001fa023, + 0xb5000041, 0x80170f00, 0x00000000, 0x007f8020, + 0x019fa023, 0x007f8008, 0x9463ffff, 0x019fa023, + 0x019fa020, 0x5c708028, 0x58908008, 0x1983a024, + 0x5c708028, 0x019fa023, 0x019fa020, 0x83a40070, + 0xb5000031, 0x81df0000, 0x00000000, 0x00000000, + 0xb6002005, 0x007f8008, 0x019fa023, 0x007f8008, + 0x019fa023, 0x019fa020, 0x81df0004, 0xb5000026, + 0xb0130000, 0xb4000008, 0xb0130001, 0xb4000012, + 0xb0130002, 0xb400001f, 0xb0130003, 0xb400001d, + 0xb0130004, 0xb400001b, 0x83a4006b, 0x007f8028, + 0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x80170f00, 0x007f8028, + 0x001fa023, 0xb5000010, 0x80170f00, 0x00000000, + 0x5c708020, 0x58908008, 0x1983a024, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x83a40055, 0x80170f00, 0x007f8028, 0x001fa023, + 0xb5000001, 0xb5000000, 0x92730001, 0x92520001, + 0x3012b811, 0xb480fe76, 0x003f0324, 0x90210001, + 0xb0010006, 0xb4a00001, 0x80270001, 0x003f2324, + 0x2c8db811, 0x803bffe0, 0x805bffe4, 0x5886b804, + 0x1015b804, 0xad440003, 0x3000b802, 0xb4800001, + 0x8400a000, 0x801effec, 0x015f6193, 0x809e4b04, + 0x00ffb81f, 0x81df0000, 0x00000000, 0x00000000, + 0xb6002a0c, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x019fa020, 0x81df0004, 0x00ffb81d, 0x81df0000, + 0x00000000, 0x00000000, 0xb600190f, 0x007f8028, + 0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x58908008, 0x1983a024, + 0x5c708028, 0x019fa023, 0x81df0004, 0x00ffb81d, + 0x81df0000, 0x00000000, 0x00000000, 0xb6002a0c, + 0x007f8028, 0x019fa023, 0x007f8008, 0x9463ffff, + 0x019fa023, 0x019fa020, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020, + 0x81df0004, 0x00ffb81d, 0x81df0000, 0x00000000, + 0x00000000, 0xb600190f, 0x007f8028, 0x019fa023, + 0x007f8028, 0x019fa023, 0x007f8008, 0x9463ffff, + 0x019fa023, 0x5c708028, 0x58908008, 0x1983a024, + 0x5c708028, 0x58908008, 0x1983a024, 0x5c708028, + 0x019fa023, 0x81df0004, 0x00ffb81d, 0x00000000, + 0x829bff80, 0x80af001f, 0x808f0000, 0x806f0000, + 0x82bbffec, 0x82fbffe4, 0x00000000, 0x82beffb8, + 0x95540700, 0x5d48b80a, 0x914a0001, 0x0227b80a, + 0x94343000, 0x5c2cb801, 0xb0010000, 0xb4000001, + 0x5a21b811, 0x9574c000, 0x5d6eb80b, 0x918b4b08, + 0x01b8b80c, 0x96d5ffff, 0x5ec2b816, 0x96f7ffff, + 0x5ee2b817, 0x8057ffff, 0x80d7ffff, 0x8157ffff, + 0x81d7ffff, 0x81f3ff00, 0x99efff00, 0x821300ff, + 0x9a1000ff, 0x81971000, 0x82670000, 0x82470000, + 0x80270280, 0x81df0000, 0x00000000, 0x00000000, + 0xb62d000d, 0x3016b817, 0xb4800001, 0x86d62800, + 0x00cfb801, 0x02dfb0bc, 0x5ac2b816, 0x01cfb816, + 0x02df90bc, 0x0067b86f, 0xb0030001, 0xb4c0fffd, + 0x92d60020, 0x90210020, 0x81df0004, 0x80170a00, + 0x81df0000, 0x00000000, 0x00000000, 0xb62d0006, + 0xb6002005, 0x146f8000, 0x14908000, 0x5c68b803, + 0x5888b804, 0x1803a024, 0x81df0004, 0x80170a00, + 0x80970d00, 0xb00b0000, 0xb4000004, 0xb00b0001, + 0xb400000a, 0xb00b0002, 0xb4000027, 0x81df0000, + 0x00000000, 0x00000000, 0xb6008002, 0x007f8020, + 0x009fa023, 0x81df0004, 0xb5000029, 0x80d3ffff, + 0x81df0000, 0x00000000, 0x00000000, 0xb6002018, + 0x5c648000, 0x9463ffff, 0x5c888020, 0x58b88000, + 0x1884b805, 0x1484b806, 0x1883a024, 0x5c6c8020, + 0x9463ffff, 0x58908000, 0x1883a024, 0x5c748020, + 0x588c8000, 0x1863b804, 0x9463ffff, 0x58888000, + 0x1484b806, 0x1883a024, 0x5c7c8020, 0x58848000, + 0x1863b804, 0x9463ffff, 0x14868020, 0x1883a024, + 0x81df0004, 0xb500000a, 0x80d3ffff, 0x81df0000, + 0x00000000, 0x00000000, 0xb6004004, 0x007f8020, + 0x009fa023, 0x007f8040, 0x009fa023, 0x81df0004, + 0x00000000, 0x81170d00, 0x80070000, 0x94343000, + 0x5c2cb801, 0xb0010001, 0xb400008e, 0xb00a0001, + 0xb400000e, 0xb00a0002, 0xb400001c, 0xb00a0003, + 0xb4000024, 0xb00a0004, 0xb4000052, 0xb00a0005, + 0xb400005b, 0xb00a0006, 0xb400007f, 0xb00a0007, + 0xb400007d, 0xb00a0008, 0xb400007b, 0x81df0000, + 0x00000000, 0x00000000, 0xb600800a, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020, + 0x5c708028, 0x9463ffff, 0x019fa023, 0x019fa020, + 0x019fa020, 0x81df0004, 0xb500006b, 0x81df0000, + 0x00000000, 0x00000000, 0xb6008004, 0x007f8028, + 0x019fa023, 0x019fa020, 0x019fa020, 0x81df0004, + 0xb5000061, 0xb0130000, 0xb4000004, 0xb0130001, + 0xb4000009, 0xb0130002, 0xb400001a, 0x83a400fa, + 0x80170f00, 0x007f8028, 0x001fa023, 0x007f8028, + 0x001fa023, 0xb5000054, 0x80170f00, 0x00000000, + 0x007f8020, 0x019fa023, 0x007f8000, 0x9463ffff, + 0x019fa023, 0x019fa020, 0x5c708020, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020, + 0x83a400e5, 0x80170f00, 0x007f8028, 0x001fa023, + 0xb5000041, 0x80170f00, 0x00000000, 0x007f8020, + 0x019fa023, 0x007f8008, 0x9463ffff, 0x019fa023, + 0x019fa020, 0x5c708028, 0x58908008, 0x1983a024, + 0x5c708028, 0x019fa023, 0x019fa020, 0x83a400d2, + 0xb5000031, 0x81df0000, 0x00000000, 0x00000000, + 0xb6004005, 0x007f8008, 0x019fa023, 0x007f8008, + 0x019fa023, 0x019fa020, 0x81df0004, 0xb5000026, + 0xb0130000, 0xb4000008, 0xb0130001, 0xb4000012, + 0xb0130002, 0xb400001f, 0xb0130003, 0xb400001d, + 0xb0130004, 0xb400001b, 0x83a400cd, 0x007f8028, + 0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x80170f00, 0x007f8028, + 0x001fa023, 0xb5000010, 0x80170f00, 0x00000000, + 0x5c708020, 0x58908008, 0x1983a024, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x83a400b7, 0x80170f00, 0x007f8028, 0x001fa023, + 0xb5000001, 0xb5000000, 0x00000000, 0x00000000, + 0xb5000086, 0xb00a0001, 0xb400000e, 0xb00a0002, + 0xb4000017, 0xb00a0003, 0xb400001f, 0xb00a0004, + 0xb400004d, 0xb00a0005, 0xb4000056, 0xb00a0006, + 0xb400007a, 0xb00a0007, 0xb4000078, 0xb00a0008, + 0xb4000076, 0x81df0000, 0x00000000, 0x00000000, + 0xb6008005, 0x007f8028, 0x9463ffff, 0x019fa023, + 0x019fa020, 0x019fa020, 0x81df0004, 0xb500006b, + 0x81df0000, 0x00000000, 0x00000000, 0xb6004004, + 0x007f8048, 0x019fa023, 0x019fa020, 0x019fa020, + 0x81df0004, 0xb5000061, 0xb0130000, 0xb4000004, + 0xb0130001, 0xb4000009, 0xb0130002, 0xb400001a, + 0x83a40098, 0x80170f00, 0x007f8028, 0x001fa023, + 0x007f8028, 0x001fa023, 0xb5000054, 0x80170f00, + 0x00000000, 0x007f8020, 0x019fa023, 0x007f8000, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708020, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x019fa020, 0x83a40083, 0x80170f00, 0x007f8028, + 0x001fa023, 0xb5000041, 0x80170f00, 0x00000000, + 0x007f8020, 0x019fa023, 0x007f8008, 0x9463ffff, + 0x019fa023, 0x019fa020, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020, + 0x83a40070, 0xb5000031, 0x81df0000, 0x00000000, + 0x00000000, 0xb6004005, 0x007f8008, 0x019fa023, + 0x007f8008, 0x019fa023, 0x019fa020, 0x81df0004, + 0xb5000026, 0xb0130000, 0xb4000008, 0xb0130001, + 0xb4000012, 0xb0130002, 0xb400001f, 0xb0130003, + 0xb400001d, 0xb0130004, 0xb400001b, 0x83a4006b, + 0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023, + 0x007f8008, 0x9463ffff, 0x019fa023, 0x80170f00, + 0x007f8028, 0x001fa023, 0xb5000010, 0x80170f00, + 0x00000000, 0x5c708020, 0x58908008, 0x1983a024, + 0x5c708028, 0x58908008, 0x1983a024, 0x5c708028, + 0x019fa023, 0x83a40055, 0x80170f00, 0x007f8028, + 0x001fa023, 0xb5000001, 0xb5000000, 0x92730001, + 0x92520001, 0x3012b811, 0xb480fe89, 0x003f0324, + 0x90210001, 0xb0010006, 0xb4a00001, 0x80270001, + 0x003f2324, 0x2c8db811, 0x803bffe0, 0x805bffe4, + 0x5887b804, 0x1015b804, 0xad440003, 0x3000b802, + 0xb4800001, 0x8400a000, 0x801effec, 0x015f6193, + 0x809e4b04, 0x00ffb81f, 0x81df0000, 0x00000000, + 0x00000000, 0xb6002a0c, 0x007f8028, 0x019fa023, + 0x007f8008, 0x9463ffff, 0x019fa023, 0x019fa020, + 0x5c708028, 0x58908008, 0x1983a024, 0x5c708028, + 0x019fa023, 0x019fa020, 0x81df0004, 0x00ffb81d, + 0x81df0000, 0x00000000, 0x00000000, 0xb600190f, + 0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023, + 0x007f8008, 0x9463ffff, 0x019fa023, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x81df0004, + 0x00ffb81d, 0x81df0000, 0x00000000, 0x00000000, + 0xb6002a0c, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x019fa020, 0x81df0004, 0x00ffb81d, 0x81df0000, + 0x00000000, 0x00000000, 0xb600190f, 0x007f8028, + 0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x58908008, 0x1983a024, + 0x5c708028, 0x019fa023, 0x81df0004, 0x00ffb81d, + 0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000, + 0xb4000011, 0x815b4b0c, 0x81070000, 0x81270be8, + 0xb00a0000, 0xb4000002, 0x81070c00, 0x812717e8, + 0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc, + 0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809, + 0xb4a00060, 0xb5000008, 0xb0040000, 0xb4200003, + 0x802717ff, 0x81470000, 0xb5000003, 0x80270001, + 0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200006, + 0x039f4193, 0x5b81b81c, 0x003f90cb, 0x1021b81c, + 0x003fb0cb, 0x8384f90e, 0x829bff80, 0x801300e0, + 0x1434b800, 0x5c35b801, 0x8013001f, 0x1454b800, + 0x5c50b802, 0x8073007f, 0x9863ffff, 0xb002000f, + 0xb4800001, 0x90210001, 0x84210004, 0xb0010000, + 0xb4a00001, 0x6861b803, 0x005f9040, 0x4082b803, + 0x80af001f, 0x808f0000, 0x806f0000, 0x8007ffff, + 0x8033ffff, 0x80171000, 0x81df0000, 0x00000000, + 0x00000000, 0xb6001811, 0xb6002010, 0x14618000, + 0x6068b803, 0x40c4b803, 0x14608000, 0x00c8b806, + 0x5870b803, 0x6068b803, 0x4104b803, 0x58c8b806, + 0x0108b808, 0x14c6b801, 0x00000000, 0x00000000, + 0x5d08b808, 0x1508b800, 0x1806a028, 0x81df0004, + 0x80670400, 0x5d22b80a, 0x81df0000, 0x00000000, + 0x00000000, 0xb600180a, 0x00cfb803, 0x013fb0bc, + 0x5922b809, 0x01afb809, 0x013f90bc, 0x0047b86f, + 0xb0020001, 0xb4c0fffd, 0x90630020, 0x91290020, + 0x81df0004, 0x808f0000, 0x801b4b14, 0x80270001, + 0xb0000001, 0xb4000002, 0x802600a0, 0x803e4b14, + 0x81270c00, 0xb00a0000, 0xb4000001, 0x81270000, + 0x813e4b0c, 0x80270001, 0x003f2013, 0x80050086, + 0x001fb044, 0x00ffb81b, 0x00000000, 0x00000000, +}; + +static u32 PCMI2SUcode1f4b00[] = { + 0x00000000, 0x00000000, 0x00060504, 0x00000000, + 0x00000000, 0x00000000, 0x00300000, 0xffcfcfff, + 0x00302000, 0xffcfcfff, 0x00380000, 0xffc7c7ff, + 0xcbcecdc4, 0xcfcac9c8, 0xc3c6c5cc, 0xc7c2c1c0, + 0x1b1e1d14, 0x1f1a1918, 0x1316151c, 0x17121110, + 0x2b2e2d24, 0x2f2a2928, 0x2326252c, 0x27222120, + 0x3b3e3d34, 0x3f3a3938, 0x3336353c, 0x37323130, + 0x0b0e0d04, 0x0f0a0908, 0x0306050c, 0x07020100, + 0xdbdeddd4, 0xdfdad9d8, 0xd3d6d5dc, 0xd7d2d1d0, + 0xebeeede4, 0xefeae9e8, 0xe3e6e5ec, 0xe7e2e1e0, + 0xfbfefdf4, 0xfffaf9f8, 0xf3f6f5fc, 0xf7f2f1f0, + 0x4b4e4d44, 0x4f4a4948, 0x4346454c, 0x47424140, + 0x9b9e9d94, 0x9f9a9998, 0x9396959c, 0x97929190, + 0xabaeada4, 0xafaaa9a8, 0xa3a6a5ac, 0xa7a2a1a0, + 0xbbbebdb4, 0xbfbab9b8, 0xb3b6b5bc, 0xb7b2b1b0, + 0x8b8e8d84, 0x8f8a8988, 0x8386858c, 0x87828180, + 0x5b5e5d54, 0x5f5a5958, 0x5356555c, 0x57525150, + 0x6b6e6d64, 0x6f6a6968, 0x6366656c, 0x67626160, + 0x7b7e7d74, 0x7f7a7978, 0x7376757c, 0x77727170, + 0x341424c4, 0x3e1e2ece, 0x3d1d2dcd, 0x3b1b2bcb, + 0xb494a444, 0xbe9eae4e, 0xbd9dad4d, 0xbb9bab4b, + 0xf4d4e404, 0xfedeee0e, 0xfddded0d, 0xfbdbeb0b, + 0x74546484, 0x7e5e6e8e, 0x7d5d6d8d, 0x7b5b6b8b, + 0x3c1c2ccc, 0x361626c6, 0x351525c5, 0x331323c3, + 0xbc9cac4c, 0xb696a646, 0xb595a545, 0xb393a343, + 0xfcdcec0c, 0xf6d6e606, 0xf5d5e505, 0xf3d3e303, + 0x7c5c6c8c, 0x76566686, 0x75556585, 0x73536383, + 0x381828c8, 0x3a1a2aca, 0x391929c9, 0x3f1f2fcf, + 0xb898a848, 0xba9aaa4a, 0xb999a949, 0xbf9faf4f, + 0xf8d8e808, 0xfadaea0a, 0xf9d9e909, 0xffdfef0f, + 0x78586888, 0x7a5a6a8a, 0x79596989, 0x7f5f6f8f, + 0x301020c0, 0x321222c2, 0x311121c1, 0x371727c7, + 0xb090a040, 0xb292a242, 0xb191a141, 0xb797a747, + 0xf0d0e000, 0xf2d2e202, 0xf1d1e101, 0xf7d7e707, + 0x70506080, 0x72526282, 0x71516181, 0x77576787, + 0x05040100, 0x15141110, 0x25242120, 0x35343130, + 0x85848180, 0x95949190, 0xa5a4a1a0, 0xb5b4b1b0, + 0xc0408000, 0xe060a020, 0xd0509010, 0xf070b030, + 0xc8488808, 0xe868a828, 0xd8589818, 0xf878b838, + 0xc4448404, 0xe464a424, 0xd4549414, 0xf474b434, + 0xcc4c8c0c, 0xec6cac2c, 0xdc5c9c1c, 0xfc7cbc3c, + 0xc2428202, 0xe262a222, 0xd2529212, 0xf272b232, + 0xca4a8a0a, 0xea6aaa2a, 0xda5a9a1a, 0xfa7aba3a, + 0xc6468606, 0xe666a626, 0xd6569616, 0xf676b636, + 0xce4e8e0e, 0xee6eae2e, 0xde5e9e1e, 0xfe7ebe3e, + 0xc1418101, 0xe161a121, 0xd1519111, 0xf171b131, + 0xc9498909, 0xe969a929, 0xd9599919, 0xf979b939, + 0xc5458505, 0xe565a525, 0xd5559515, 0xf575b535, + 0xcd4d8d0d, 0xed6dad2d, 0xdd5d9d1d, 0xfd7dbd3d, + 0xc3438303, 0xe363a323, 0xd3539313, 0xf373b333, + 0xcb4b8b0b, 0xeb6bab2b, 0xdb5b9b1b, 0xfb7bbb3b, + 0xc7478707, 0xe767a727, 0xd7579717, 0xf777b737, + 0xcf4f8f0f, 0xef6faf2f, 0xdf5f9f1f, 0xff7fbf3f, + 0x1045a3e2, 0x000000f4, 0x263b7333, 0x766b2363, + 0x2b367e3e, 0x7b662e6e, 0x06db93d3, 0x964b0343, + 0x0bd69ede, 0x9b460e4e, 0x825f1757, 0x12cf87c7, + 0x8f521a5a, 0x1fc28aca, 0x00d199d9, 0x90410949, + 0x01d098d8, 0x91400848, 0x24357d3d, 0x74652d6d, + 0x25347c3c, 0x75642c6c, 0x04d59ddd, 0x94450d4d, + 0x05d49cdc, 0x95440c4c, 0x80511959, 0x10c189c9, + 0x81501858, 0x11c088c8, 0x02df97d7, 0x924f0747, + 0x0fd29ada, 0x9f420a4a, 0x865b1353, 0x16cb83c3, + 0x8b561e5e, 0x1bc68ece, 0xa6bbf3b3, 0xf6eba3e3, + 0xabb6febe, 0xfbe6aeee, 0x223f7737, 0x726f2767, + 0x2f327a3a, 0x7f622a6a, 0xa0b1f9b9, 0xf0e1a9e9, + 0xa1b0f8b8, 0xf1e0a8e8, 0x84551d5d, 0x14c58dcd, + 0x85541c5c, 0x15c48ccc, 0xa4b5fdbd, 0xf4e5aded, + 0xa5b4fcbc, 0xf5e4acec, 0x20317939, 0x70612969, + 0x21307838, 0x71602868, 0xa2bff7b7, 0xf2efa7e7, + 0xafb2faba, 0xffe2aaea, 0x00000000, 0x00000000, +}; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/pcmi2s_240.h linux.19pre5-ac1/drivers/media/video/ls220/pcmi2s_240.h --- linux.19p5/drivers/media/video/ls220/pcmi2s_240.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/ls220/pcmi2s_240.h Thu Feb 21 21:25:36 2002 @@ -0,0 +1,877 @@ +static u32 PCMI2S240Ucode1f1800[] = { + 0xb500000f, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xb500020b, 0x00000000, 0x00000000, 0x00000000, + 0x820f001f, 0x802f001f, 0x029f9014, 0x829efef0, + 0x8286000f, 0x02bf0054, 0x82bcfef4, 0x82a6000e, + 0x80074000, 0x001f6193, 0x8013001f, 0x9020c000, + 0x003fb006, 0x803effe8, 0x803effec, 0x9020fa00, + 0x803effd0, 0x803effdc, 0x803effd8, 0x9020fe00, + 0x803effd4, 0x90400000, 0x804600a2, 0x90421800, + 0x804600a3, 0x80132000, 0x98000040, 0x800600a6, + 0x80050080, 0x98000002, 0x80060080, 0x80070001, + 0x001f2013, 0x80070000, 0x001f23f9, 0x801e4b0c, + 0x001f210c, 0x80070001, 0x001f2324, 0x80070800, + 0x001f600f, 0x001fb0cb, 0x001fb010, 0x801efff0, + 0x98004000, 0x001f600e, 0x83e4011f, 0x80070000, + 0x801e4b14, 0x800500a0, 0xb0000001, 0xb4000009, + 0x80070001, 0x800600a0, 0x80050080, 0x98000020, + 0x80060080, 0x9400ffdf, 0x80060080, 0x80070000, + 0x800600a0, 0x80074000, 0x801e4b04, 0x81df0004, + 0x801bfff0, 0x00000000, 0x940000ff, 0xb0000000, + 0xb4200033, 0x003f400e, 0x94010010, 0xb0000000, + 0xb400fff7, 0x003f0013, 0xb0010001, 0xb420001f, + 0x803bffe8, 0x801bffec, 0x805b4b04, 0x00000000, + 0x3001b800, 0xb4600001, 0x9021a000, 0x0421b800, + 0x3001b802, 0xb460000d, 0x80050086, 0x005f9044, + 0x0420b802, 0xb00101e0, 0xb4a0ffe5, 0x001fb010, + 0x001f010c, 0xb0000001, 0xb400ffe1, 0x80070001, + 0x001f210c, 0x83e400ec, 0xb500ffdd, 0x8007001f, + 0x94000003, 0x5810b800, 0x83e719ec, 0x1bffb800, + 0x003f9008, 0x1821b800, 0x00ffb801, 0x80270000, + 0x003f2013, 0x8007001f, 0x94000003, 0x5810b800, + 0x83671a14, 0x1b7bb800, 0x003f9009, 0x1821b800, + 0x00ffb801, 0x80070000, 0x001f210c, 0xb500ffc8, + 0x003f400e, 0xb0000086, 0xb4400055, 0xb0000084, + 0xb400003f, 0xb0000085, 0xb4000045, 0xb0000086, + 0xb4000047, 0xb0000083, 0xb4000000, 0x815bff7c, + 0x00000000, 0x940a0080, 0x5c07b800, 0xb0000001, + 0xb4000073, 0x81674b18, 0x940a0007, 0x5803b800, + 0x116bb800, 0x005bb80b, 0x916b0004, 0x001bb80b, + 0x80530030, 0x98422000, 0x8013ffcf, 0x9800cfff, + 0x806500d4, 0x1463b800, 0x1863b802, 0x806600d4, + 0x80073cfb, 0x801e4b00, 0x800600a1, 0x80074000, + 0x801e4b04, 0x8013001f, 0x98405000, 0x805effe0, + 0x005fb006, 0x805effe8, 0x805effec, 0x9042a000, + 0x805effe4, 0x9040fa00, 0x805effd0, 0x805effdc, + 0x805effd8, 0x9040fe00, 0x805effd4, 0x8013007f, + 0x9800ffff, 0x001fb040, 0x80070001, 0x001f2013, + 0x80070000, 0x001f2324, 0x001fb0cb, 0x001fb010, + 0x001fb041, 0x001fb042, 0x800733b0, 0x001fb008, + 0x80071ea0, 0x001fb009, 0x98214000, 0xb5000010, + 0x94011000, 0xb0001000, 0xb4200001, 0x9421efff, + 0x98210010, 0xb500000a, 0x80070000, 0x001fb0cb, + 0x83e40099, 0x003f400e, 0x9421ffef, 0xb5000004, + 0x83e40095, 0x003f400e, 0x98211000, 0x9421ffef, + 0x003f600e, 0x80070100, 0x801efff0, 0xb500ff70, + 0xb000008b, 0xb4000018, 0xb0000087, 0xb400ffee, + 0xb0000088, 0xb4000016, 0xb000008a, 0xb4000016, + 0xb000008c, 0xb4000017, 0xb0000089, 0xb4000019, + 0xb00000a0, 0xb400001b, 0xb00000a1, 0xb4000047, + 0xb00000a2, 0xb4000054, 0xb00000a3, 0xb400004c, + 0xb00000a4, 0xb4000056, 0xb00000a5, 0xb400005a, + 0xb00000a6, 0xb400005e, 0x803efff8, 0xb500ffe1, + 0x9421ffdf, 0xb500ffde, 0x80270100, 0x803efff8, + 0xb500ffdc, 0x803bffb0, 0x00000000, 0x003fb040, + 0xb500ffd8, 0x803bff80, 0x00000000, 0x003f6001, + 0xb500ffd4, 0x003f90ba, 0x803efff8, 0xb500ffd1, + 0x81674b18, 0x940a0007, 0x5803b800, 0x116bb800, + 0x005bb80b, 0x916b0004, 0x001bb80b, 0x806500d4, + 0x1463b800, 0x1863b802, 0x806600d4, 0x80130001, + 0x98003d21, 0x800600a1, 0x801e4b00, 0x80074000, + 0x801e4b04, 0x8013001f, 0x98405000, 0x805effe0, + 0x005fb006, 0x805effe8, 0x805effec, 0x9042a000, + 0x805effe4, 0x9040fa00, 0x805effd0, 0x805effdc, + 0x805effd8, 0x9040fe00, 0x805effd4, 0x80070001, + 0x001f2013, 0x80070000, 0x001f2324, 0x001fb0cb, + 0x001fb010, 0x80073bf0, 0x001fb008, 0x800743e0, + 0x001fb009, 0x98214000, 0xb500ffa5, 0x80270000, + 0x8047fef0, 0x003eb802, 0x90420004, 0x003eb802, + 0x90420004, 0x003eb802, 0x90420004, 0x003eb802, + 0x81df0000, 0x00000000, 0x00000000, 0x8364044f, + 0x81df0004, 0xb500ff97, 0x81df0000, 0x00000000, + 0x00000000, 0x836403f9, 0x81df0004, 0xb500ff91, + 0x81df0000, 0x00000000, 0x00000000, 0x836403b4, + 0x81df0004, 0xb500ff8b, 0x81df0000, 0x00000000, + 0x00000000, 0x83440317, 0x81df0004, 0xb500ff85, + 0x81df0000, 0x00000000, 0x00000000, 0x834402fc, + 0x81df0004, 0xb500ff7f, 0x80070000, 0x80470000, + 0x81df0000, 0x00000000, 0x00000000, 0xb6002003, + 0xb6003002, 0x001eb802, 0x90420004, 0x80171000, + 0x8057ffff, 0xb6002002, 0xb6001801, 0x001fa020, + 0x81df0004, 0x00ffb81f, 0x817bff7c, 0x00000000, + 0x956b0080, 0x5d67b80b, 0x83a70000, 0x8057ffff, + 0x80770000, 0x8073007a, 0x9863e7d2, 0xb00b0001, + 0xb4200002, 0x8073007d, 0x98636d4a, 0x0207b803, + 0x81df0000, 0x00000000, 0x00000000, 0xb00b0001, + 0xb400000a, 0x80171000, 0xb6008007, 0x003fc0c0, + 0x005fc740, 0x40c1b810, 0x4102b810, 0x001fe0c6, + 0x001fe0c8, 0x4210b803, 0xb5000009, 0x80171000, + 0xb6000007, 0x003fc020, 0x005fc7e0, 0x40c1b810, + 0x4102b810, 0x001fe026, 0x001fe0a8, 0x4210b803, + 0x81df0004, 0x80270000, 0x003f2013, 0x8007001f, + 0x94000003, 0x5810b800, 0x83671e7c, 0x1b7bb800, + 0x003f9009, 0x1821b800, 0x00ffb801, 0x003f0013, + 0xb0010001, 0xb420fff3, 0x93bd0001, 0xb01d0004, + 0xb480ffd7, 0x00ffb81f, 0x00000000, 0x00000000, + 0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000, + 0xb4000011, 0x815b4b0c, 0x81070000, 0x81270be8, + 0xb00a0000, 0xb4000002, 0x81070c00, 0x812717e8, + 0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc, + 0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809, + 0xb4a00059, 0xb5000008, 0xb0040000, 0xb4200003, + 0x802717ff, 0x81470000, 0xb5000003, 0x80270001, + 0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200006, + 0x039f4193, 0x5b81b81c, 0x003f90cb, 0x1021b81c, + 0x003fb0cb, 0x8384025e, 0x829bff80, 0x801300e0, + 0x1434b800, 0x5c35b801, 0x8013001f, 0x1454b800, + 0x5c50b802, 0x8073007f, 0x9863ffff, 0xb002000f, + 0xb4800001, 0x90210001, 0x84210004, 0xb0010000, + 0xb4a00001, 0x6861b803, 0x005f9040, 0x4082b803, + 0x80af001f, 0x808f0000, 0x806f0000, 0x8007ffff, + 0x8033ffff, 0x80171000, 0x81df0000, 0x00000000, + 0x00000000, 0xb600180a, 0xb6002009, 0x58708000, + 0x6068b803, 0x40c4b803, 0x00000000, 0x00c8b806, + 0x00000000, 0x00000000, 0x00000000, 0x5807a026, + 0x81df0004, 0x80670400, 0x5d22b80a, 0x81df0000, + 0x00000000, 0x00000000, 0xb600180a, 0x00cfb803, + 0x013fb0bc, 0x5922b809, 0x01afb809, 0x013f90bc, + 0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x90630020, + 0x91290020, 0x81df0004, 0x808f0000, 0x801b4b14, + 0x80270001, 0xb0000001, 0xb4000002, 0x802600a0, + 0x803e4b14, 0x81270c00, 0xb00a0000, 0xb4000001, + 0x81270000, 0x813e4b0c, 0x80270001, 0x003f2013, + 0x80050086, 0x001fb044, 0x00ffb81b, 0x00000000, + 0x029fb00a, 0x02bfb00b, 0x02dfb00c, 0x02ffb00d, + 0x031fb00e, 0x033fb00f, 0x033f400f, 0x0287b86f, + 0x029fb005, 0x8285009d, 0x82b30002, 0x9ab50040, + 0x1a94b815, 0x8286009d, 0x8285009c, 0x96b48000, + 0xb0158000, 0xb400019c, 0x96b40100, 0xb0150100, + 0xb40001b8, 0x96b40400, 0xb0150400, 0xb40001ca, + 0x96b40001, 0xb0150001, 0xb4000014, 0x96b40008, + 0xb0150008, 0xb40001a5, 0x96b44000, 0xb0154000, + 0xb40001c9, 0x96b40002, 0xb0150002, 0xb4000169, + 0x96b40040, 0xb0150040, 0xb40001dc, 0x82d30002, + 0x9ad60000, 0x16b6b814, 0x3015b816, 0xb40001da, + 0x00000000, 0x00000000, 0xb50001db, 0x02bf9017, + 0x92b50001, 0x02bfb017, 0x82850082, 0x83050081, + 0x82a5009a, 0x96b50001, 0xb0150001, 0xb4200014, + 0x82a70000, 0x02bfb017, 0x96b41840, 0xb0150800, + 0xb420000c, 0x96b40008, 0x5aa9b815, 0x96d46000, + 0x5ec3b816, 0x82f3000f, 0x9af7c00f, 0x1718b817, + 0x1ab5b818, 0x1ab5b816, 0x9ab50340, 0x82a60081, + 0xb5000140, 0x9b180180, 0x83060081, 0xb500013d, + 0x82a5009a, 0x96b50002, 0xb0150002, 0xb420001b, + 0x82a70000, 0x02bfb017, 0x96b41800, 0xb0151800, + 0xb4000013, 0x96b40040, 0xb0150040, 0xb4200004, + 0xa3180c00, 0x9b180340, 0x83060081, 0xb500012d, + 0x96b40008, 0x5aa9b815, 0x96d46000, 0x5ec3b816, + 0x82f3000f, 0x9af7c00f, 0x1718b817, 0x1ab5b818, + 0x1ab5b816, 0x9ab50340, 0x82a60081, 0xb5000121, + 0x9b180180, 0x83060081, 0xb500011e, 0x82a500c1, + 0x96b5000f, 0xb015000b, 0xb420000e, 0x96b40020, + 0xb0150020, 0xb400000b, 0x96b40200, 0xb0150200, + 0xb4000008, 0x82c50086, 0x82e50094, 0x3016b817, + 0xb4400004, 0x06f7b816, 0xb017ff00, 0xb4400001, + 0xb500010c, 0x96b46000, 0xb0156000, 0xb4000011, + 0x96b41820, 0xb0150820, 0xb4200004, 0x9b391000, + 0x82a5009a, 0x96b5feff, 0x82a6009a, 0x96b40040, + 0xb0150040, 0xb4200001, 0x9739efff, 0x96b91000, + 0xb0151000, 0xb4200003, 0x82a5009a, 0x9ab50100, + 0x82a6009a, 0x96b40040, 0xb0150040, 0xb4200019, + 0x96b41800, 0xb0151800, 0xb4200006, 0x96b98000, + 0xb0158000, 0xb4200003, 0x9b180180, 0x83060081, + 0xb50000ec, 0x96d80c00, 0x82b300ff, 0x9ab5f3ff, + 0x1718b815, 0xb0160c00, 0xb4000007, 0x82e50098, + 0x96f70400, 0xb0170400, 0xb4200002, 0x82c70c00, + 0xb5000001, 0xa2d60c00, 0x1b18b816, 0x9b180340, + 0xb50000d2, 0x96b40220, 0xb0150000, 0xb4e00033, + 0x82a5009d, 0x82f3ffff, 0x16b5b817, 0x82f33802, + 0x3015b817, 0xb420002d, 0x96f98000, 0xb0178000, + 0xb400002a, 0x82a70000, 0x02bfb017, 0x82c50081, + 0x9ab60020, 0x82a60081, 0x82a50086, 0x92b50bb8, + 0x82a60094, 0x82c60081, 0x82c5009d, 0x96d6ffff, + 0x82b3c802, 0x9ab50041, 0x82e500c1, 0x96f7000f, + 0xb017000b, 0xb4000002, 0x82b38802, 0x9ab50041, + 0x1ab5b816, 0x82c5009a, 0x96d60020, 0xb0160020, + 0xb4200002, 0x82b3c802, 0x9ab50041, 0x82a6009d, + 0x02ff9017, 0x00000000, 0xb0170040, 0xb480000b, + 0x96f41c00, 0xb0171c00, 0xb4200008, 0x82e50086, + 0x82c50094, 0x92d63000, 0x3016b817, 0xb4400003, + 0x9b180180, 0x83060081, 0xb50000a6, 0x5eb5b814, + 0x96b500f0, 0x96f46000, 0x5eedb817, 0x1ab5b817, + 0xb0170003, 0xb4000004, 0x96b500ef, 0x96f70001, + 0x5ae4b817, 0x1ab5b817, 0x96d41800, 0xb0161800, + 0xb400000a, 0x96f900ff, 0x96b500ff, 0x9739ff00, + 0x1b39b815, 0x02a7b817, 0x96b500f3, 0x96d40008, + 0x5ec1b816, 0x1ab5b816, 0xb500000c, 0x96f98000, + 0xb0178000, 0xb4200007, 0x5efeb814, 0x96f70001, + 0xb0170001, 0xb4000003, 0x9b180180, 0x83060081, + 0xb5000084, 0x96b500f3, 0x9ab50008, 0x9739fff3, + 0x96d40020, 0xb0160020, 0xb4200017, 0x9b398000, + 0x82c70000, 0x02dfb017, 0x96d40010, 0x5ac8b816, + 0x82f300ff, 0x9af7cfff, 0x1718b817, 0x1b18b816, + 0x9b180340, 0x82c5009d, 0x96d6ffff, 0x82f33802, + 0x9af70041, 0x1af7b816, 0x82c5009a, 0x96d60020, + 0xb0160020, 0xb4200002, 0x82f3c802, 0x9af70041, + 0x82e6009d, 0xb500005d, 0x97397fff, 0x96b500ff, + 0x5aaab815, 0x82f300fc, 0x9af703ff, 0x1718b817, + 0x1b18b815, 0x9b180340, 0x82c5009a, 0x96d60010, + 0xb0160010, 0xb4200024, 0x82c70000, 0x02dfb017, + 0x82c50086, 0x92d60bb8, 0x82c60086, 0x82c50094, + 0x5eefb818, 0x96f70003, 0xb0170003, 0xb4200002, + 0x82e70bb8, 0xb5000001, 0x82e70bb8, 0x12d6b817, + 0x82e50081, 0x9af70020, 0x82e60081, 0x82c60094, + 0xa2f70020, 0x82e60081, 0x82f30001, 0x16f7b818, + 0x5ef0b817, 0xb0170001, 0xb4000004, 0x96f84000, + 0x5ee4b817, 0x9718f3ff, 0x1b18b817, 0x82f32802, + 0x9af70040, 0x82e6009d, 0x83060081, 0x83070001, + 0x8306009f, 0xb50000b8, 0x82c5009d, 0x82f33802, + 0x9af70041, 0x3016b817, 0xb420000f, 0x82b3c802, + 0x9ab50041, 0x82e500c1, 0x96f7000f, 0xb017000b, + 0xb4000002, 0x82b38802, 0x9ab50041, 0x82c5009a, + 0x96d60020, 0xb0160020, 0xb4200002, 0x82b3c802, + 0x9ab50041, 0x82a6009d, 0x82c5009a, 0x96d60080, + 0xb0160080, 0xb4000014, 0x02df9017, 0x00000000, + 0xb0160010, 0xb4800010, 0x82c500c1, 0x96d6000f, + 0xb016000b, 0xb400000c, 0x82c50087, 0x96d60080, + 0x5ac7b816, 0x82c50098, 0x96d60800, 0x5ac3b816, + 0x96f84000, 0x3017b816, 0xb4200003, 0x033f400f, + 0x9b394000, 0xb500000b, 0x9739bfff, 0x82e50061, + 0x96f70008, 0xb0170008, 0xb4000005, 0x5eefb818, + 0x96f70003, 0xb0170003, 0xb4000001, 0x9718ffff, + 0x83060081, 0x83070001, 0x8306009f, 0x00000000, + 0xb500007d, 0x82850083, 0x96b400ff, 0xb015003c, + 0xb4200019, 0x96b92000, 0xb0152000, 0xb4000002, + 0x9b392000, 0xb5000014, 0x9739d3ff, 0x82870000, + 0x82860087, 0x82870008, 0x82860083, 0x829bff78, + 0x82a7001f, 0xb0140400, 0xb4000001, 0x82a70010, + 0x82a600c9, 0x829bff78, 0x00000000, 0x828600cb, + 0x8285009d, 0x82b3ffff, 0x9ab5fffd, 0x1694b815, + 0x8286009d, 0xb5000000, 0x83070002, 0x8306009f, + 0x00000000, 0xb500005c, 0x96b90800, 0xb0150800, + 0xb4200009, 0x9739f7ff, 0x82a703fd, 0x82a600cb, + 0x82a7003c, 0x82a60083, 0x8285009d, 0x9a940002, + 0x8286009d, 0xb5000004, 0x82850087, 0x5a82b814, + 0xa2940200, 0x82860087, 0xb5000000, 0x83078000, + 0x8306009f, 0x00000000, 0xb5000047, 0x82850086, + 0x82a50094, 0x3015b814, 0xb4800002, 0x86b50bb8, + 0x82a60086, 0x83070008, 0x8306009f, 0x00000000, + 0xb500003d, 0x83050069, 0x9718003f, 0x82e50064, + 0x12f7b818, 0x86f70088, 0x82feff74, 0x02e7b86f, + 0x9af74000, 0x01ffb817, 0x96f7bfff, 0x01ffb817, + 0x83050081, 0x82f3001c, 0x9af703ff, 0x1718b817, + 0x9b180140, 0x83060081, 0x83070100, 0x8306009f, + 0x00000000, 0xb5000028, 0x83070000, 0x83050081, + 0x9b180180, 0x83060081, 0x83070400, 0x8306009f, + 0x00000000, 0xb5000020, 0x82870000, 0x82850082, + 0x5eb7b814, 0x96b500fc, 0x96d40006, 0x5ec1b816, + 0x1ab5b816, 0x5aacb815, 0x83050081, 0x82d3001c, + 0x9ad600ff, 0x1718b816, 0x1b18b815, 0x9b180e00, + 0x83060081, 0x83074000, 0x8306009f, 0x8305009d, + 0x82d3ffff, 0x9ad6bfff, 0x1718b816, 0x8306009d, + 0x00000000, 0xb5000008, 0xb5000007, 0x83070040, + 0x8306009f, 0xb5000004, 0x83130002, 0x9b180000, + 0x8306009f, 0xb5000000, 0x029f9005, 0x01ffb814, + 0x033f600f, 0x029f900a, 0x02bf900b, 0x02df900c, + 0x02ff900d, 0x031f900e, 0x033f900f, 0x00ffb81e, + 0x02ff9010, 0x92f70b43, 0x02ffb010, 0x02ff90cb, + 0x82bbffdc, 0x829bffd8, 0x93150004, 0x3014b815, + 0xb4000010, 0x02dbb818, 0x029bb815, 0x3017b816, + 0xb480000c, 0x5a81b814, 0x029fb010, 0x82860095, + 0x8293001f, 0x9294fe00, 0x92b50008, 0x3015b814, + 0xb4800002, 0x82b3001f, 0x92b5fa00, 0x82beffdc, + 0xb500ffeb, 0x029f9010, 0x83250094, 0x06d4b819, + 0x02d6b816, 0xb016ffff, 0xb4a0000a, 0x82933802, + 0x9a940041, 0x82c5009d, 0x96d6ffff, 0x1a94b816, + 0x82c5009a, 0x96d60010, 0xb0160010, 0xb4000001, + 0x8286009d, 0x00ffb81c, 0x00000000, 0x00000000, + 0x001f9012, 0x001fb100, 0x001f004c, 0x001f2404, + 0x801bfef0, 0x8058fef4, 0x803bff68, 0x8078ff6c, + 0x2000b801, 0x2042b803, 0x001fb104, 0x005f2414, + 0x82e70001, 0x83640048, 0x029fb014, 0x829efef0, + 0x8286000f, 0x02bf2054, 0x82bcfef4, 0x82a6000e, + 0x00ffb81a, 0x80e70001, 0x801336e3, 0x9800eb76, + 0x001fb100, 0x800700ab, 0x001f2404, 0x801bc3e8, + 0x8058c3ec, 0x83640024, 0x82e70000, 0x83640036, + 0x029fb300, 0x029fb100, 0x02bf2c04, 0x02bf2404, + 0x801bc000, 0x8058c004, 0x8364001b, 0x82e70000, + 0x8364002d, 0x001f9300, 0x3000b814, 0xb420000a, + 0x001f0c04, 0x3000b815, 0xb4200007, 0x829efef0, + 0x82bcfef4, 0x029fb012, 0x02bf204c, 0x82870001, + 0x829cfef5, 0x00ffb81a, 0xb0070000, 0xb4000007, + 0x80e70000, 0x801399fa, 0x9800c92e, 0x001fb100, + 0x800700af, 0x001f2404, 0xb500ffdc, 0x82870000, + 0x829cfef5, 0x00ffb81a, 0x80c700ff, 0x803bff68, + 0x8078ff6c, 0x14a0b806, 0x2063b805, 0x007f2414, + 0x2021b802, 0x58c8b806, 0x14a0b806, 0x58b0b805, + 0x2021b805, 0x58c8b806, 0x14a0b806, 0x2021b805, + 0x58c8b806, 0x14a0b806, 0x5cb0b805, 0x2021b805, + 0x003fb104, 0x00ffb81b, 0x82c70000, 0x83070400, + 0x83270005, 0x8197040c, 0x81d7ffff, 0x83840126, + 0x83840001, 0x00ffb81b, 0x808f0000, 0x806f001f, + 0x80af001f, 0x80270140, 0x81e70228, 0x5de2b80f, + 0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, + 0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020, + 0x90210020, 0x80270180, 0x81e70120, 0x5de2b80f, + 0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, + 0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020, + 0x90210020, 0x8057ffff, 0x80170430, 0x80070410, + 0x80270408, 0xb6000509, 0x005ff000, 0x90420500, + 0x007ff001, 0x90630600, 0x009ff002, 0x00bff003, + 0x2004a025, 0x90000001, 0x90210001, 0x80070414, + 0x80d7ffff, 0x8097045c, 0x8017043c, 0xb6000404, + 0x005ff000, 0x007f87e0, 0x84000001, 0x2082a7e3, + 0x80970460, 0x80170440, 0x2082b803, 0x007f8000, + 0x2083a004, 0x80170430, 0x80970450, 0x80270408, + 0xb6000508, 0x005f8024, 0x90420500, 0x007ff001, + 0x90630600, 0x009ff002, 0x00bff003, 0x2004a025, + 0x90210001, 0x80170440, 0x00000000, 0x02bf87e0, + 0x80970460, 0x82870000, 0xb6000404, 0x005f87e4, + 0x5a88b814, 0x204287e0, 0x1a94b802, 0x00ffb81c, + 0x001f0a49, 0x001f2709, 0x001f0a41, 0x001f2708, + 0x001f0a46, 0x001f2707, 0x001f0a48, 0x001f2706, + 0x001f0a42, 0x001f2705, 0x001f0a47, 0x001f2704, + 0x001f0a45, 0x001f2703, 0x001f0a43, 0x001f2702, + 0x001f0a40, 0x001f2701, 0x001f0a44, 0x001f2700, + 0x001f0c25, 0xa020000c, 0x94400001, 0x94600002, + 0x94810004, 0x94a10008, 0x94c00010, 0x5943b802, + 0x5861b803, 0x5882b804, 0x5ca2b805, 0x5cc4b806, + 0x194ab803, 0x194ab804, 0x194ab805, 0x194ab806, + 0x015f2738, 0x801b0220, 0x003f91c1, 0x5c28b801, + 0x005f91c2, 0x5858b802, 0x1821b802, 0x2000b801, + 0x001fb1c4, 0x80180224, 0x003f0709, 0x2000b801, + 0x001f2714, 0x82c70001, 0x82e70001, 0x83070710, + 0x8327001e, 0x81970735, 0x8384009f, 0x02df0738, + 0x82170a30, 0x838400f1, 0x819efef0, 0x817cfef4, + 0x819eff68, 0x817cff6c, 0x00ffb81b, 0x820f001f, + 0x8018fef8, 0x8057ffff, 0x001f2709, 0x8018fef6, + 0x80d7ffff, 0x001f2708, 0x8018fefa, 0x8157ffff, + 0x001f2707, 0x8018fefd, 0x81d7ffff, 0x001f2706, + 0x8018fefb, 0x802f001f, 0x001f2705, 0x8018fefe, + 0x00000000, 0x001f2704, 0x8018fef9, 0x00000000, + 0x001f2703, 0x8018feff, 0x00000000, 0x001f2702, + 0x8018fef7, 0x00000000, 0x001f2701, 0x8018fefc, + 0x00000000, 0x001f2700, 0x001f0c25, 0xa0200011, + 0x94410001, 0x94600002, 0x94800004, 0x94a00008, + 0x94c10010, 0x5941b802, 0x5861b803, 0x5c82b804, + 0x58a1b805, 0x5cc1b806, 0x194ab803, 0x194ab804, + 0x194ab805, 0x194ab806, 0x015f2738, 0x801b0220, + 0x003f91c1, 0x5c28b801, 0x005f91c2, 0x5858b802, + 0x1821b802, 0x2000b801, 0x001fb1c4, 0x80180224, + 0x003f0709, 0x2000b801, 0x001f2714, 0x82c70001, + 0x82e70001, 0x83070710, 0x8327001e, 0x81970735, + 0x83840055, 0x02df0738, 0x82170a20, 0x838400a7, + 0x819efef0, 0x817cfef4, 0x5ac8b80c, 0x02ff0a44, + 0x1ad6b817, 0x02dfb291, 0x5ed8b80c, 0x5968b80b, + 0x1ad6b80b, 0x02df6524, 0x00ffb81b, 0x820f001f, + 0x8018fefe, 0x8057ffff, 0x001f2709, 0x8018fefa, + 0x80d7ffff, 0x001f2708, 0x8018fefc, 0x8157ffff, + 0x001f2707, 0x8018feff, 0x81d7ffff, 0x001f2706, + 0x8018fef8, 0x802f001f, 0x001f2705, 0x8018fefb, + 0x00000000, 0x001f2704, 0x8018fefd, 0x00000000, + 0x001f2703, 0x8018fef6, 0x00000000, 0x001f2702, + 0x8018fef9, 0x00000000, 0x001f2701, 0x8018fef7, + 0x00000000, 0x001f2700, 0x801b0220, 0x003f91c1, + 0x5c28b801, 0x005f91c2, 0x5858b802, 0x1821b802, + 0x2000b801, 0x001fb1c4, 0x80180224, 0x003f0709, + 0x2000b801, 0x001f2714, 0x82c70001, 0x82e70001, + 0x83070710, 0x8327001e, 0x81970735, 0x83840016, + 0x83270000, 0x831bfef0, 0x82f8fef4, 0x02c7b819, + 0x82170a28, 0x83840065, 0x300cb818, 0xb4200002, + 0x300bb817, 0xb4000006, 0x93390001, 0xb0190020, + 0xb480fff6, 0x83270000, 0x833cfef5, 0x00ffb81b, + 0x019fb290, 0x017f2a44, 0x033f2c25, 0x83270001, + 0x833cfef5, 0x00ffb81b, 0x0007b818, 0x90000003, + 0x00000000, 0x015ff000, 0x90000001, 0x5949b80a, + 0x013ff000, 0x194ab809, 0x84000002, 0x994a0100, + 0x017ff000, 0x958b00f8, 0x5981b80c, 0x956b0007, + 0x198cb80b, 0x84000002, 0x998c0008, 0x017ff000, + 0x90000001, 0x5971b80b, 0x198cb80b, 0x017ff000, + 0x5969b80b, 0x198cb80b, 0x81a70000, 0x94d90003, + 0x82a70000, 0xb6260019, 0xb6000818, 0x5df0b80a, + 0x5e02b80a, 0x21efb810, 0x95ef0001, 0x5941b80a, + 0x194ab80f, 0x21efb816, 0x5e18b80c, 0x5e35b80c, + 0x5e54b80c, 0x5e6cb80c, 0x2210b811, 0x2252b813, + 0x2210b812, 0x96100001, 0x5981b80c, 0x198cb810, + 0x2210b817, 0x10afb810, 0x10a5b80d, 0x5da1b805, + 0x94a50001, 0x5aa1b815, 0x1ab5b805, 0x019fa7f5, + 0x5cc2b819, 0xb626001c, 0x82870000, 0xb6000419, + 0xb6000818, 0x5df0b80a, 0x5e02b80a, 0x21efb810, + 0x95ef0001, 0x5941b80a, 0x194ab80f, 0x21efb816, + 0x5e18b80c, 0x5e35b80c, 0x5e54b80c, 0x5e6cb80c, + 0x2210b811, 0x2252b813, 0x2210b812, 0x96100001, + 0x5981b80c, 0x198cb810, 0x2210b817, 0x10afb810, + 0x10a5b80d, 0x5da1b805, 0x94a50001, 0x5a81b814, + 0x1a94b805, 0x019fa7f4, 0x00ffb81c, 0x8257ffff, + 0x808f0000, 0x806f001f, 0x80af001f, 0x80270200, + 0x81e7ff00, 0x5de2b80f, 0xb6000208, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0xb520ffff, 0x91ef0020, 0x90210020, 0x80270240, + 0x81e70000, 0x5de2b80f, 0xb6000208, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0xb520ffff, 0x91ef0020, 0x90210020, 0x80270180, + 0x81e70120, 0x5de2b80f, 0xb6000208, 0x00cfb801, + 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc, + 0xb520ffff, 0x91ef0020, 0x90210020, 0x806f0007, + 0x80af0007, 0x80270280, 0x81e70100, 0x5de2b80f, + 0x00cfb801, 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, + 0x01ff90bc, 0xb520ffff, 0x91ef0020, 0x90210020, + 0x80170760, 0x001f0700, 0x001fa020, 0x001f0701, + 0x001fa020, 0x001f0702, 0x001fa020, 0x001f0703, + 0x001fa020, 0x001f0704, 0x001fa000, 0x80970750, + 0x81170770, 0x82a70735, 0x83a40060, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a4005c, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750, + 0x81170750, 0x81970740, 0x82a70730, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a40050, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a4004c, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970750, 0x80170770, + 0x81170770, 0x81970760, 0x82a7072b, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a40040, 0x83a4004e, + 0xb6000407, 0x86b50001, 0x83a4003c, 0x001f8004, + 0x003f87e8, 0x2080a001, 0x83a40047, 0x00000000, + 0x80970770, 0x80170750, 0x81170750, 0x81970740, + 0x82a70726, 0x001f800c, 0x003f8008, 0x2100a001, + 0x83a4002e, 0x83a4003c, 0xb6000407, 0x86b50001, + 0x83a4002a, 0x001f8004, 0x003f87e8, 0x2080a001, + 0x83a40035, 0x00000000, 0x80970750, 0x80170770, + 0x81170770, 0x81970760, 0x82a70721, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a4001c, 0x001f87e4, + 0xb6000405, 0x86b50001, 0x83a40018, 0x001f8004, + 0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750, + 0x81170750, 0x81970740, 0x82a7071c, 0x001f800c, + 0x003f8008, 0x2100a001, 0x83a4000c, 0x017f87e4, + 0x81870000, 0xb6000406, 0x86b50001, 0x83a40007, + 0x001f87e4, 0x200087e8, 0x5988b80c, 0x198cb800, + 0x021fa02c, 0x021fa00b, 0x00ffb81c, 0x005ff015, + 0x90420600, 0x003f87e0, 0x001ff002, 0x2060b801, + 0x90630800, 0x90960a00, 0x001ff003, 0x003ff004, + 0x20a0b801, 0x90a50900, 0x00000000, 0x001ff005, + 0x009fa000, 0x00ffb81d, 0x001f8004, 0x5c21b800, + 0x5847b800, 0x1821b802, 0x942100ff, 0x2080a7e1, + 0x00ffb81d, 0x00000000, 0x00000000, 0x00000000, + 0x829bff80, 0x80af000f, 0x808f0000, 0x806f0000, + 0x82bbffec, 0x82fbffe4, 0x00000000, 0x82beffb8, + 0x95540700, 0x5d48b80a, 0x914a0001, 0x0227b80a, + 0x94343000, 0x5c2cb801, 0xb0010000, 0xb4000001, + 0x5a21b811, 0x9574c000, 0x5d6eb80b, 0x918b4b08, + 0x01b8b80c, 0x96d5ffff, 0x5ec2b816, 0x96f7ffff, + 0x5ee2b817, 0x8057ffff, 0x80d7ffff, 0x8157ffff, + 0x81d7ffff, 0x81f3ff00, 0x99efff00, 0x821300ff, + 0x9a1000ff, 0x81971000, 0x82670000, 0x82470000, + 0x80270280, 0x81df0000, 0x00000000, 0x00000000, + 0xb62d000d, 0x3016b817, 0xb4800001, 0x86d62800, + 0x00cfb801, 0x02dfb0bc, 0x5ac2b816, 0x01cfb816, + 0x02df90bc, 0x0067b86f, 0xb0030001, 0xb4c0fffd, + 0x92d60010, 0x90210010, 0x81df0004, 0x80170a00, + 0x81df0000, 0x00000000, 0x00000000, 0xb62d0006, + 0xb6001005, 0x146f8000, 0x14908000, 0x5c68b803, + 0x5888b804, 0x1803a024, 0x81df0004, 0x80170a00, + 0x80970d00, 0xb00b0000, 0xb4000004, 0xb00b0001, + 0xb400000a, 0xb00b0002, 0xb4000027, 0x81df0000, + 0x00000000, 0x00000000, 0xb6004002, 0x007f8020, + 0x009fa023, 0x81df0004, 0xb5000029, 0x80d3ffff, + 0x81df0000, 0x00000000, 0x00000000, 0xb6001018, + 0x5c648000, 0x9463ffff, 0x5c888020, 0x58b88000, + 0x1884b805, 0x1484b806, 0x1883a024, 0x5c6c8020, + 0x9463ffff, 0x58908000, 0x1883a024, 0x5c748020, + 0x588c8000, 0x1863b804, 0x9463ffff, 0x58888000, + 0x1484b806, 0x1883a024, 0x5c7c8020, 0x58848000, + 0x1863b804, 0x9463ffff, 0x14868020, 0x1883a024, + 0x81df0004, 0xb500000a, 0x80d3ffff, 0x81df0000, + 0x00000000, 0x00000000, 0xb6002004, 0x007f8020, + 0x009fa023, 0x007f8040, 0x009fa023, 0x81df0004, + 0x00000000, 0x81170d00, 0x80070000, 0x94343000, + 0x5c2cb801, 0xb0010001, 0xb4000099, 0xb00a0001, + 0xb400000e, 0xb00a0002, 0xb4000022, 0xb00a0003, + 0xb400002f, 0xb00a0004, 0xb400005d, 0xb00a0005, + 0xb4000066, 0xb00a0006, 0xb400008a, 0xb00a0007, + 0xb4000088, 0xb00a0008, 0xb4000086, 0x81df0000, + 0x00000000, 0x00000000, 0xb6004010, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020, + 0x019fa020, 0x019fa020, 0x019fa020, 0x5c708028, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020, + 0x019fa020, 0x019fa020, 0x019fa020, 0x81df0004, + 0xb5000070, 0x81df0000, 0x00000000, 0x00000000, + 0x8027ffff, 0xb6004008, 0x14618008, 0x019fa023, + 0x019fa020, 0x019fa020, 0x5c708028, 0x019fa023, + 0x019fa020, 0x019fa020, 0x81df0004, 0xb5000061, + 0xb0130000, 0xb4000004, 0xb0130001, 0xb4000009, + 0xb0130002, 0xb400001a, 0x83a40102, 0x80170f00, + 0x007f8028, 0x001fa023, 0x007f8028, 0x001fa023, + 0xb5000054, 0x80170f00, 0x00000000, 0x007f8020, + 0x019fa023, 0x007f8000, 0x9463ffff, 0x019fa023, + 0x019fa020, 0x5c708020, 0x58908008, 0x1983a024, + 0x5c708028, 0x019fa023, 0x019fa020, 0x83a400ed, + 0x80170f00, 0x007f8028, 0x001fa023, 0xb5000041, + 0x80170f00, 0x00000000, 0x007f8020, 0x019fa023, + 0x007f8008, 0x9463ffff, 0x019fa023, 0x019fa020, + 0x5c708028, 0x58908008, 0x1983a024, 0x5c708028, + 0x019fa023, 0x019fa020, 0x83a400da, 0xb5000031, + 0x81df0000, 0x00000000, 0x00000000, 0xb6002005, + 0x007f8008, 0x019fa023, 0x007f8008, 0x019fa023, + 0x019fa020, 0x81df0004, 0xb5000026, 0xb0130000, + 0xb4000008, 0xb0130001, 0xb4000012, 0xb0130002, + 0xb400001f, 0xb0130003, 0xb400001d, 0xb0130004, + 0xb400001b, 0x83a400d5, 0x007f8028, 0x019fa023, + 0x007f8028, 0x019fa023, 0x007f8008, 0x9463ffff, + 0x019fa023, 0x80170f00, 0x007f8028, 0x001fa023, + 0xb5000010, 0x80170f00, 0x00000000, 0x5c708020, + 0x58908008, 0x1983a024, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x83a400bf, + 0x80170f00, 0x007f8028, 0x001fa023, 0xb5000001, + 0xb5000000, 0x00000000, 0x00000000, 0xb500008e, + 0xb00a0001, 0xb400000e, 0xb00a0002, 0xb400001a, + 0xb00a0003, 0xb4000027, 0xb00a0004, 0xb4000055, + 0xb00a0005, 0xb400005e, 0xb00a0006, 0xb4000082, + 0xb00a0007, 0xb4000080, 0xb00a0008, 0xb400007e, + 0x81df0000, 0x00000000, 0x00000000, 0xb6004008, + 0x007f8028, 0x9463ffff, 0x019fa023, 0x019fa020, + 0x019fa020, 0x019fa020, 0x019fa020, 0x019fa020, + 0x81df0004, 0xb5000070, 0x81df0000, 0x00000000, + 0x00000000, 0x8027ffff, 0xb6002008, 0x14618008, + 0x019fa023, 0x019fa020, 0x019fa020, 0x5c708048, + 0x019fa023, 0x019fa020, 0x019fa020, 0x81df0004, + 0xb5000061, 0xb0130000, 0xb4000004, 0xb0130001, + 0xb4000009, 0xb0130002, 0xb400001a, 0x83a40098, + 0x80170f00, 0x007f8028, 0x001fa023, 0x007f8028, + 0x001fa023, 0xb5000054, 0x80170f00, 0x00000000, + 0x007f8020, 0x019fa023, 0x007f8000, 0x9463ffff, + 0x019fa023, 0x019fa020, 0x5c708020, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020, + 0x83a40083, 0x80170f00, 0x007f8028, 0x001fa023, + 0xb5000041, 0x80170f00, 0x00000000, 0x007f8020, + 0x019fa023, 0x007f8008, 0x9463ffff, 0x019fa023, + 0x019fa020, 0x5c708028, 0x58908008, 0x1983a024, + 0x5c708028, 0x019fa023, 0x019fa020, 0x83a40070, + 0xb5000031, 0x81df0000, 0x00000000, 0x00000000, + 0xb6002005, 0x007f8008, 0x019fa023, 0x007f8008, + 0x019fa023, 0x019fa020, 0x81df0004, 0xb5000026, + 0xb0130000, 0xb4000008, 0xb0130001, 0xb4000012, + 0xb0130002, 0xb400001f, 0xb0130003, 0xb400001d, + 0xb0130004, 0xb400001b, 0x83a4006b, 0x007f8028, + 0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x80170f00, 0x007f8028, + 0x001fa023, 0xb5000010, 0x80170f00, 0x00000000, + 0x5c708020, 0x58908008, 0x1983a024, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x83a40055, 0x80170f00, 0x007f8028, 0x001fa023, + 0xb5000001, 0xb5000000, 0x92730001, 0x92520001, + 0x3012b811, 0xb480fe76, 0x003f0324, 0x90210001, + 0xb0010006, 0xb4a00001, 0x80270001, 0x003f2324, + 0x2c8db811, 0x803bffe0, 0x805bffe4, 0x5886b804, + 0x1015b804, 0xad440003, 0x3000b802, 0xb4800001, + 0x8400a000, 0x801effec, 0x015f6193, 0x809e4b04, + 0x00ffb81f, 0x81df0000, 0x00000000, 0x00000000, + 0xb6002a0c, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x019fa020, 0x81df0004, 0x00ffb81d, 0x81df0000, + 0x00000000, 0x00000000, 0xb600190f, 0x007f8028, + 0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x58908008, 0x1983a024, + 0x5c708028, 0x019fa023, 0x81df0004, 0x00ffb81d, + 0x81df0000, 0x00000000, 0x00000000, 0xb6002a0c, + 0x007f8028, 0x019fa023, 0x007f8008, 0x9463ffff, + 0x019fa023, 0x019fa020, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020, + 0x81df0004, 0x00ffb81d, 0x81df0000, 0x00000000, + 0x00000000, 0xb600190f, 0x007f8028, 0x019fa023, + 0x007f8028, 0x019fa023, 0x007f8008, 0x9463ffff, + 0x019fa023, 0x5c708028, 0x58908008, 0x1983a024, + 0x5c708028, 0x58908008, 0x1983a024, 0x5c708028, + 0x019fa023, 0x81df0004, 0x00ffb81d, 0x00000000, + 0x829bff80, 0x80af001f, 0x808f0000, 0x806f0000, + 0x82bbffec, 0x82fbffe4, 0x00000000, 0x82beffb8, + 0x95540700, 0x5d48b80a, 0x914a0001, 0x0227b80a, + 0x94343000, 0x5c2cb801, 0xb0010000, 0xb4000001, + 0x5a21b811, 0x9574c000, 0x5d6eb80b, 0x918b4b08, + 0x01b8b80c, 0x96d5ffff, 0x5ec2b816, 0x96f7ffff, + 0x5ee2b817, 0x8057ffff, 0x80d7ffff, 0x8157ffff, + 0x81d7ffff, 0x81f3ff00, 0x99efff00, 0x821300ff, + 0x9a1000ff, 0x81971000, 0x82670000, 0x82470000, + 0x80270280, 0x81df0000, 0x00000000, 0x00000000, + 0xb62d000d, 0x3016b817, 0xb4800001, 0x86d62800, + 0x00cfb801, 0x02dfb0bc, 0x5ac2b816, 0x01cfb816, + 0x02df90bc, 0x0067b86f, 0xb0030001, 0xb4c0fffd, + 0x92d60020, 0x90210020, 0x81df0004, 0x80170a00, + 0x81df0000, 0x00000000, 0x00000000, 0xb62d0006, + 0xb6002005, 0x146f8000, 0x14908000, 0x5c68b803, + 0x5888b804, 0x1803a024, 0x81df0004, 0x80170a00, + 0x80970d00, 0xb00b0000, 0xb4000004, 0xb00b0001, + 0xb400000a, 0xb00b0002, 0xb4000027, 0x81df0000, + 0x00000000, 0x00000000, 0xb6008002, 0x007f8020, + 0x009fa023, 0x81df0004, 0xb5000029, 0x80d3ffff, + 0x81df0000, 0x00000000, 0x00000000, 0xb6002018, + 0x5c648000, 0x9463ffff, 0x5c888020, 0x58b88000, + 0x1884b805, 0x1484b806, 0x1883a024, 0x5c6c8020, + 0x9463ffff, 0x58908000, 0x1883a024, 0x5c748020, + 0x588c8000, 0x1863b804, 0x9463ffff, 0x58888000, + 0x1484b806, 0x1883a024, 0x5c7c8020, 0x58848000, + 0x1863b804, 0x9463ffff, 0x14868020, 0x1883a024, + 0x81df0004, 0xb500000a, 0x80d3ffff, 0x81df0000, + 0x00000000, 0x00000000, 0xb6004004, 0x007f8020, + 0x009fa023, 0x007f8040, 0x009fa023, 0x81df0004, + 0x00000000, 0x81170d00, 0x80070000, 0x94343000, + 0x5c2cb801, 0xb0010001, 0xb400008e, 0xb00a0001, + 0xb400000e, 0xb00a0002, 0xb400001c, 0xb00a0003, + 0xb4000024, 0xb00a0004, 0xb4000052, 0xb00a0005, + 0xb400005b, 0xb00a0006, 0xb400007f, 0xb00a0007, + 0xb400007d, 0xb00a0008, 0xb400007b, 0x81df0000, + 0x00000000, 0x00000000, 0xb600800a, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020, + 0x5c708028, 0x9463ffff, 0x019fa023, 0x019fa020, + 0x019fa020, 0x81df0004, 0xb500006b, 0x81df0000, + 0x00000000, 0x00000000, 0xb6008004, 0x007f8028, + 0x019fa023, 0x019fa020, 0x019fa020, 0x81df0004, + 0xb5000061, 0xb0130000, 0xb4000004, 0xb0130001, + 0xb4000009, 0xb0130002, 0xb400001a, 0x83a400fa, + 0x80170f00, 0x007f8028, 0x001fa023, 0x007f8028, + 0x001fa023, 0xb5000054, 0x80170f00, 0x00000000, + 0x007f8020, 0x019fa023, 0x007f8000, 0x9463ffff, + 0x019fa023, 0x019fa020, 0x5c708020, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020, + 0x83a400e5, 0x80170f00, 0x007f8028, 0x001fa023, + 0xb5000041, 0x80170f00, 0x00000000, 0x007f8020, + 0x019fa023, 0x007f8008, 0x9463ffff, 0x019fa023, + 0x019fa020, 0x5c708028, 0x58908008, 0x1983a024, + 0x5c708028, 0x019fa023, 0x019fa020, 0x83a400d2, + 0xb5000031, 0x81df0000, 0x00000000, 0x00000000, + 0xb6004005, 0x007f8008, 0x019fa023, 0x007f8008, + 0x019fa023, 0x019fa020, 0x81df0004, 0xb5000026, + 0xb0130000, 0xb4000008, 0xb0130001, 0xb4000012, + 0xb0130002, 0xb400001f, 0xb0130003, 0xb400001d, + 0xb0130004, 0xb400001b, 0x83a400cd, 0x007f8028, + 0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x80170f00, 0x007f8028, + 0x001fa023, 0xb5000010, 0x80170f00, 0x00000000, + 0x5c708020, 0x58908008, 0x1983a024, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x83a400b7, 0x80170f00, 0x007f8028, 0x001fa023, + 0xb5000001, 0xb5000000, 0x00000000, 0x00000000, + 0xb5000086, 0xb00a0001, 0xb400000e, 0xb00a0002, + 0xb4000017, 0xb00a0003, 0xb400001f, 0xb00a0004, + 0xb400004d, 0xb00a0005, 0xb4000056, 0xb00a0006, + 0xb400007a, 0xb00a0007, 0xb4000078, 0xb00a0008, + 0xb4000076, 0x81df0000, 0x00000000, 0x00000000, + 0xb6008005, 0x007f8028, 0x9463ffff, 0x019fa023, + 0x019fa020, 0x019fa020, 0x81df0004, 0xb500006b, + 0x81df0000, 0x00000000, 0x00000000, 0xb6004004, + 0x007f8048, 0x019fa023, 0x019fa020, 0x019fa020, + 0x81df0004, 0xb5000061, 0xb0130000, 0xb4000004, + 0xb0130001, 0xb4000009, 0xb0130002, 0xb400001a, + 0x83a40098, 0x80170f00, 0x007f8028, 0x001fa023, + 0x007f8028, 0x001fa023, 0xb5000054, 0x80170f00, + 0x00000000, 0x007f8020, 0x019fa023, 0x007f8000, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708020, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x019fa020, 0x83a40083, 0x80170f00, 0x007f8028, + 0x001fa023, 0xb5000041, 0x80170f00, 0x00000000, + 0x007f8020, 0x019fa023, 0x007f8008, 0x9463ffff, + 0x019fa023, 0x019fa020, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020, + 0x83a40070, 0xb5000031, 0x81df0000, 0x00000000, + 0x00000000, 0xb6004005, 0x007f8008, 0x019fa023, + 0x007f8008, 0x019fa023, 0x019fa020, 0x81df0004, + 0xb5000026, 0xb0130000, 0xb4000008, 0xb0130001, + 0xb4000012, 0xb0130002, 0xb400001f, 0xb0130003, + 0xb400001d, 0xb0130004, 0xb400001b, 0x83a4006b, + 0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023, + 0x007f8008, 0x9463ffff, 0x019fa023, 0x80170f00, + 0x007f8028, 0x001fa023, 0xb5000010, 0x80170f00, + 0x00000000, 0x5c708020, 0x58908008, 0x1983a024, + 0x5c708028, 0x58908008, 0x1983a024, 0x5c708028, + 0x019fa023, 0x83a40055, 0x80170f00, 0x007f8028, + 0x001fa023, 0xb5000001, 0xb5000000, 0x92730001, + 0x92520001, 0x3012b811, 0xb480fe89, 0x003f0324, + 0x90210001, 0xb0010006, 0xb4a00001, 0x80270001, + 0x003f2324, 0x2c8db811, 0x803bffe0, 0x805bffe4, + 0x5887b804, 0x1015b804, 0xad440003, 0x3000b802, + 0xb4800001, 0x8400a000, 0x801effec, 0x015f6193, + 0x809e4b04, 0x00ffb81f, 0x81df0000, 0x00000000, + 0x00000000, 0xb6002a0c, 0x007f8028, 0x019fa023, + 0x007f8008, 0x9463ffff, 0x019fa023, 0x019fa020, + 0x5c708028, 0x58908008, 0x1983a024, 0x5c708028, + 0x019fa023, 0x019fa020, 0x81df0004, 0x00ffb81d, + 0x81df0000, 0x00000000, 0x00000000, 0xb600190f, + 0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023, + 0x007f8008, 0x9463ffff, 0x019fa023, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x019fa023, 0x81df0004, + 0x00ffb81d, 0x81df0000, 0x00000000, 0x00000000, + 0xb6002a0c, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708028, + 0x58908008, 0x1983a024, 0x5c708028, 0x019fa023, + 0x019fa020, 0x81df0004, 0x00ffb81d, 0x81df0000, + 0x00000000, 0x00000000, 0xb600190f, 0x007f8028, + 0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008, + 0x9463ffff, 0x019fa023, 0x5c708028, 0x58908008, + 0x1983a024, 0x5c708028, 0x58908008, 0x1983a024, + 0x5c708028, 0x019fa023, 0x81df0004, 0x00ffb81d, + 0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000, + 0xb4000011, 0x815b4b0c, 0x81070000, 0x81270be8, + 0xb00a0000, 0xb4000002, 0x81070c00, 0x812717e8, + 0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc, + 0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809, + 0xb4a00060, 0xb5000008, 0xb0040000, 0xb4200003, + 0x802717ff, 0x81470000, 0xb5000003, 0x80270001, + 0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200006, + 0x039f4193, 0x5b81b81c, 0x003f90cb, 0x1021b81c, + 0x003fb0cb, 0x8384f90e, 0x829bff80, 0x801300e0, + 0x1434b800, 0x5c35b801, 0x8013001f, 0x1454b800, + 0x5c50b802, 0x8073007f, 0x9863ffff, 0xb002000f, + 0xb4800001, 0x90210001, 0x84210004, 0xb0010000, + 0xb4a00001, 0x6861b803, 0x005f9040, 0x4082b803, + 0x80af001f, 0x808f0000, 0x806f0000, 0x8007ffff, + 0x8033ffff, 0x80171000, 0x81df0000, 0x00000000, + 0x00000000, 0xb6001811, 0xb6002010, 0x14618000, + 0x6068b803, 0x40c4b803, 0x14608000, 0x00c8b806, + 0x5870b803, 0x6068b803, 0x4104b803, 0x58c8b806, + 0x0108b808, 0x14c6b801, 0x00000000, 0x00000000, + 0x5d08b808, 0x1508b800, 0x1806a028, 0x81df0004, + 0x80670400, 0x5d22b80a, 0x81df0000, 0x00000000, + 0x00000000, 0xb600180a, 0x00cfb803, 0x013fb0bc, + 0x5922b809, 0x01afb809, 0x013f90bc, 0x0047b86f, + 0xb0020001, 0xb4c0fffd, 0x90630020, 0x91290020, + 0x81df0004, 0x808f0000, 0x801b4b14, 0x80270001, + 0xb0000001, 0xb4000002, 0x802600a0, 0x803e4b14, + 0x81270c00, 0xb00a0000, 0xb4000001, 0x81270000, + 0x813e4b0c, 0x80270001, 0x003f2013, 0x80050086, + 0x001fb044, 0x00ffb81b, 0x00000000, 0x00000000, +}; + +static u32 PCMI2S240Ucode1f4b00[] = { + 0x00000000, 0x00000000, 0x00060504, 0x00000000, + 0x00000000, 0x00000000, 0x00300000, 0xffcfcfff, + 0x00302000, 0xffcfcfff, 0x00380000, 0xffc7c7ff, + 0xcbcecdc4, 0xcfcac9c8, 0xc3c6c5cc, 0xc7c2c1c0, + 0x1b1e1d14, 0x1f1a1918, 0x1316151c, 0x17121110, + 0x2b2e2d24, 0x2f2a2928, 0x2326252c, 0x27222120, + 0x3b3e3d34, 0x3f3a3938, 0x3336353c, 0x37323130, + 0x0b0e0d04, 0x0f0a0908, 0x0306050c, 0x07020100, + 0xdbdeddd4, 0xdfdad9d8, 0xd3d6d5dc, 0xd7d2d1d0, + 0xebeeede4, 0xefeae9e8, 0xe3e6e5ec, 0xe7e2e1e0, + 0xfbfefdf4, 0xfffaf9f8, 0xf3f6f5fc, 0xf7f2f1f0, + 0x4b4e4d44, 0x4f4a4948, 0x4346454c, 0x47424140, + 0x9b9e9d94, 0x9f9a9998, 0x9396959c, 0x97929190, + 0xabaeada4, 0xafaaa9a8, 0xa3a6a5ac, 0xa7a2a1a0, + 0xbbbebdb4, 0xbfbab9b8, 0xb3b6b5bc, 0xb7b2b1b0, + 0x8b8e8d84, 0x8f8a8988, 0x8386858c, 0x87828180, + 0x5b5e5d54, 0x5f5a5958, 0x5356555c, 0x57525150, + 0x6b6e6d64, 0x6f6a6968, 0x6366656c, 0x67626160, + 0x7b7e7d74, 0x7f7a7978, 0x7376757c, 0x77727170, + 0x341424c4, 0x3e1e2ece, 0x3d1d2dcd, 0x3b1b2bcb, + 0xb494a444, 0xbe9eae4e, 0xbd9dad4d, 0xbb9bab4b, + 0xf4d4e404, 0xfedeee0e, 0xfddded0d, 0xfbdbeb0b, + 0x74546484, 0x7e5e6e8e, 0x7d5d6d8d, 0x7b5b6b8b, + 0x3c1c2ccc, 0x361626c6, 0x351525c5, 0x331323c3, + 0xbc9cac4c, 0xb696a646, 0xb595a545, 0xb393a343, + 0xfcdcec0c, 0xf6d6e606, 0xf5d5e505, 0xf3d3e303, + 0x7c5c6c8c, 0x76566686, 0x75556585, 0x73536383, + 0x381828c8, 0x3a1a2aca, 0x391929c9, 0x3f1f2fcf, + 0xb898a848, 0xba9aaa4a, 0xb999a949, 0xbf9faf4f, + 0xf8d8e808, 0xfadaea0a, 0xf9d9e909, 0xffdfef0f, + 0x78586888, 0x7a5a6a8a, 0x79596989, 0x7f5f6f8f, + 0x301020c0, 0x321222c2, 0x311121c1, 0x371727c7, + 0xb090a040, 0xb292a242, 0xb191a141, 0xb797a747, + 0xf0d0e000, 0xf2d2e202, 0xf1d1e101, 0xf7d7e707, + 0x70506080, 0x72526282, 0x71516181, 0x77576787, + 0x05040100, 0x15141110, 0x25242120, 0x35343130, + 0x85848180, 0x95949190, 0xa5a4a1a0, 0xb5b4b1b0, + 0xc0408000, 0xe060a020, 0xd0509010, 0xf070b030, + 0xc8488808, 0xe868a828, 0xd8589818, 0xf878b838, + 0xc4448404, 0xe464a424, 0xd4549414, 0xf474b434, + 0xcc4c8c0c, 0xec6cac2c, 0xdc5c9c1c, 0xfc7cbc3c, + 0xc2428202, 0xe262a222, 0xd2529212, 0xf272b232, + 0xca4a8a0a, 0xea6aaa2a, 0xda5a9a1a, 0xfa7aba3a, + 0xc6468606, 0xe666a626, 0xd6569616, 0xf676b636, + 0xce4e8e0e, 0xee6eae2e, 0xde5e9e1e, 0xfe7ebe3e, + 0xc1418101, 0xe161a121, 0xd1519111, 0xf171b131, + 0xc9498909, 0xe969a929, 0xd9599919, 0xf979b939, + 0xc5458505, 0xe565a525, 0xd5559515, 0xf575b535, + 0xcd4d8d0d, 0xed6dad2d, 0xdd5d9d1d, 0xfd7dbd3d, + 0xc3438303, 0xe363a323, 0xd3539313, 0xf373b333, + 0xcb4b8b0b, 0xeb6bab2b, 0xdb5b9b1b, 0xfb7bbb3b, + 0xc7478707, 0xe767a727, 0xd7579717, 0xf777b737, + 0xcf4f8f0f, 0xef6faf2f, 0xdf5f9f1f, 0xff7fbf3f, + 0x1045a3e2, 0x000000f4, 0x263b7333, 0x766b2363, + 0x2b367e3e, 0x7b662e6e, 0x06db93d3, 0x964b0343, + 0x0bd69ede, 0x9b460e4e, 0x825f1757, 0x12cf87c7, + 0x8f521a5a, 0x1fc28aca, 0x00d199d9, 0x90410949, + 0x01d098d8, 0x91400848, 0x24357d3d, 0x74652d6d, + 0x25347c3c, 0x75642c6c, 0x04d59ddd, 0x94450d4d, + 0x05d49cdc, 0x95440c4c, 0x80511959, 0x10c189c9, + 0x81501858, 0x11c088c8, 0x02df97d7, 0x924f0747, + 0x0fd29ada, 0x9f420a4a, 0x865b1353, 0x16cb83c3, + 0x8b561e5e, 0x1bc68ece, 0xa6bbf3b3, 0xf6eba3e3, + 0xabb6febe, 0xfbe6aeee, 0x223f7737, 0x726f2767, + 0x2f327a3a, 0x7f622a6a, 0xa0b1f9b9, 0xf0e1a9e9, + 0xa1b0f8b8, 0xf1e0a8e8, 0x84551d5d, 0x14c58dcd, + 0x85541c5c, 0x15c48ccc, 0xa4b5fdbd, 0xf4e5aded, + 0xa5b4fcbc, 0xf5e4acec, 0x20317939, 0x70612969, + 0x21307838, 0x71602868, 0xa2bff7b7, 0xf2efa7e7, + 0xafb2faba, 0xffe2aaea, 0x00000000, 0x00000000, +}; + +static u32 PCMI2S240Ucode1fff00[] = { + 0xcbcecdc4, 0xcfcac9c8, 0xc3c6c5cc, 0xc7c2c1c0, + 0x1b1e1d14, 0x1f1a1918, 0x1316151c, 0x17121110, + 0x2b2e2d24, 0x2f2a2928, 0x2326252c, 0x27222120, + 0x3b3e3d34, 0x3f3a3938, 0x3336353c, 0x37323130, + 0x0b0e0d04, 0x0f0a0908, 0x0306050c, 0x07020100, + 0xdbdeddd4, 0xdfdad9d8, 0xd3d6d5dc, 0xd7d2d1d0, + 0xebeeede4, 0xefeae9e8, 0xe3e6e5ec, 0xe7e2e1e0, + 0xfbfefdf4, 0xfffaf9f8, 0xf3f6f5fc, 0xf7f2f1f0, + 0x4b4e4d44, 0x4f4a4948, 0x4346454c, 0x47424140, + 0x9b9e9d94, 0x9f9a9998, 0x9396959c, 0x97929190, + 0xabaeada4, 0xafaaa9a8, 0xa3a6a5ac, 0xa7a2a1a0, + 0xbbbebdb4, 0xbfbab9b8, 0xb3b6b5bc, 0xb7b2b1b0, + 0x8b8e8d84, 0x8f8a8988, 0x8386858c, 0x87828180, + 0x5b5e5d54, 0x5f5a5958, 0x5356555c, 0x57525150, + 0x6b6e6d64, 0x6f6a6968, 0x6366656c, 0x67626160, + 0x7b7e7d74, 0x7f7a7978, 0x7376757c, 0x77727170, + 0x341424c4, 0x3e1e2ece, 0x3d1d2dcd, 0x3b1b2bcb, + 0xb494a444, 0xbe9eae4e, 0xbd9dad4d, 0xbb9bab4b, + 0xf4d4e404, 0xfedeee0e, 0xfddded0d, 0xfbdbeb0b, + 0x74546484, 0x7e5e6e8e, 0x7d5d6d8d, 0x7b5b6b8b, + 0x3c1c2ccc, 0x361626c6, 0x351525c5, 0x331323c3, + 0xbc9cac4c, 0xb696a646, 0xb595a545, 0xb393a343, + 0xfcdcec0c, 0xf6d6e606, 0xf5d5e505, 0xf3d3e303, + 0x7c5c6c8c, 0x76566686, 0x75556585, 0x73536383, + 0x381828c8, 0x3a1a2aca, 0x391929c9, 0x3f1f2fcf, + 0xb898a848, 0xba9aaa4a, 0xb999a949, 0xbf9faf4f, + 0xf8d8e808, 0xfadaea0a, 0xf9d9e909, 0xffdfef0f, + 0x78586888, 0x7a5a6a8a, 0x79596989, 0x7f5f6f8f, + 0x301020c0, 0x321222c2, 0x311121c1, 0x371727c7, + 0xb090a040, 0xb292a242, 0xb191a141, 0xb797a747, + 0xf0d0e000, 0xf2d2e202, 0xf1d1e101, 0xf7d7e707, + 0x70506080, 0x72526282, 0x71516181, 0x77576787, + 0x05040100, 0x15141110, 0x25242120, 0x35343130, + 0x85848180, 0x95949190, 0xa5a4a1a0, 0xb5b4b1b0, + 0xc0408000, 0xe060a020, 0xd0509010, 0xf070b030, + 0xc8488808, 0xe868a828, 0xd8589818, 0xf878b838, + 0xc4448404, 0xe464a424, 0xd4549414, 0xf474b434, + 0xcc4c8c0c, 0xec6cac2c, 0xdc5c9c1c, 0xfc7cbc3c, + 0xc2428202, 0xe262a222, 0xd2529212, 0xf272b232, + 0xca4a8a0a, 0xea6aaa2a, 0xda5a9a1a, 0xfa7aba3a, + 0xc6468606, 0xe666a626, 0xd6569616, 0xf676b636, + 0xce4e8e0e, 0xee6eae2e, 0xde5e9e1e, 0xfe7ebe3e, + 0xc1418101, 0xe161a121, 0xd1519111, 0xf171b131, + 0xc9498909, 0xe969a929, 0xd9599919, 0xf979b939, + 0xc5458505, 0xe565a525, 0xd5559515, 0xf575b535, + 0xcd4d8d0d, 0xed6dad2d, 0xdd5d9d1d, 0xfd7dbd3d, + 0xc3438303, 0xe363a323, 0xd3539313, 0xf373b333, + 0xcb4b8b0b, 0xeb6bab2b, 0xdb5b9b1b, 0xfb7bbb3b, + 0xc7478707, 0xe767a727, 0xd7579717, 0xf777b737, + 0xcf4f8f0f, 0xef6faf2f, 0xdf5f9f1f, 0xff7fbf3f, + 0x1045a3e2, 0x000000f4, 0x263b7333, 0x766b2363, + 0x2b367e3e, 0x7b662e6e, 0x06db93d3, 0x964b0343, + 0x0bd69ede, 0x9b460e4e, 0x825f1757, 0x12cf87c7, + 0x8f521a5a, 0x1fc28aca, 0x00d199d9, 0x90410949, + 0x01d098d8, 0x91400848, 0x24357d3d, 0x74652d6d, + 0x25347c3c, 0x75642c6c, 0x04d59ddd, 0x94450d4d, + 0x05d49cdc, 0x95440c4c, 0x80511959, 0x10c189c9, + 0x81501858, 0x11c088c8, 0x02df97d7, 0x924f0747, + 0x0fd29ada, 0x9f420a4a, 0x865b1353, 0x16cb83c3, + 0x8b561e5e, 0x1bc68ece, 0xa6bbf3b3, 0xf6eba3e3, + 0xabb6febe, 0xfbe6aeee, 0x223f7737, 0x726f2767, + 0x2f327a3a, 0x7f622a6a, 0xa0b1f9b9, 0xf0e1a9e9, + 0xa1b0f8b8, 0xf1e0a8e8, 0x84551d5d, 0x14c58dcd, + 0x85541c5c, 0x15c48ccc, 0xa4b5fdbd, 0xf4e5aded, + 0xa5b4fcbc, 0xf5e4acec, 0x20317939, 0x70612969, + 0x21307838, 0x71602868, 0xa2bff7b7, 0xf2efa7e7, + 0xafb2faba, 0xffe2aaea, 0x00000000, 0x00000000, +}; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/luxsonor.c linux.19pre5-ac1/drivers/media/video/luxsonor.c --- linux.19p5/drivers/media/video/luxsonor.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/luxsonor.c Mon Mar 18 21:43:07 2002 @@ -0,0 +1,2123 @@ +/* + * Luxsonor LS220/LS240 series DVD/Mpeg card drivers + * + * (c) Copyright 2002 Red Hat + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + * + * Made possible by Luxsonor's rather nice gesture of publishing their + * windows code to allow people to write new drivers based on it. + * + * The firmware is (c) Copyright Luxsonor and a seperate program run + * on the dsp not part of Linux itself. + * + * Note: the hardware css is not supported as Luxsonor decided not to + * document it even though the chip can do all the work. The citizens + * of free countries will need to use software decryption to play such + * films via the card. US citizens should simply report to the district + * attorney for termination. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * Firmware modules + */ + +#include "ls220/ac3.h" +#include "ls220/ac3_240.h" +#include "ls220/ac3i2s.h" +#include "ls220/ac3i2s_240.h" + +#include "ls220/mpg.h" +#include "ls220/mpg_240.h" +#include "ls220/mpgi2s.h" +#include "ls220/mpgi2s_240.h" + +#include "ls220/pcm.h" +#include "ls220/pcm_240.h" +#include "ls220/pcmi2s.h" +#include "ls220/pcmi2s_240.h" + +/* + * Board types + */ + +#define LS220C 0 +#define LS220D 1 +#define LS240 2 + +static char *lux_names[3] = { "LS220C", "LS220D", "LS240" }; + +/* + * TV encoder types + */ + +#define BT865 0 +#define BT864 1 +#define SAA7120 2 +#define SAA7121 3 +#define AD7175 4 +#define AD7176 5 +#define CS4953 6 +#define CS4952 7 +#define HS8171 8 +#define HS8170 9 + +static char *lux_tv_names[10] = { + "BT865", "BT864", "SAA7120", "SAA7121", "AD7175", + "AD7176", "CS4953", "CS4952", "HS8171", "HS8170" +}; + +/* + * EEPROM bytes + */ + +#define EPROM_REGION 0x4 +#define EPROM_REGION_COUNT 0x5 +#define EPROM_PARENTAL 0x6 +#define EPROM_BOARDTYPE 0x7 +#define EPROM_CLOCKTYPE 0x8 +#define EPROM_I2S 0x9 +#define EPROM_SPDIF_CH 0xa +#define EPROM_SPDIF_ONOFF 0xb +#define EPROM_TVOUT 0xc +#define EPROM_LEFT_CH_POL 0xf + +/* + * Registers + */ + +/* -- for field lock use -- */ +#define CHANGE_MPGVID_CONTROL +#define CHANGE_REG274 +#define DO_NOT_TOUCH_REG324 + + +#define LS220_DRAM_BASE 0x200000L +#define LS240_DRAM_BASE 0x400000L + +#define DRAM_BASE(dev) ((dev)->dram_base) + +#define VID_FIFO_OFF 0x1a3000L +#define VID_FIFO_LEN 0x3e000L +#define PTS_FIFO_OFF 0x1a2800L +#define PTS_FIFO_LEN 0x800L +#define SUB_FIFO_OFF 0x1e2000L +#define OSD_FIFO_OFF 0x1e1000L +#define OSD_FIFO_LEN 0x1000L +#define LS220_VID_FIFO(dev) (dev->dram_base+VID_FIFO_OFF) + +#define DSPMEM_BASE(dev) (dev->dram_base+0x1f0000L) +#define DSPPROG_BASE(dev) (DSPMEM_BASE(dev)-dev->dram_base) +#define DSPPROG_OFF 0x1800L +#define DSPPROG_SIZE 0x6000L + + +#define AUD_FIFO_LEN 0x2000L +#define AUD_FIFO_OFF 0x1fc000L +#define AUD_PTS_LEN 0x400L +#define AUD_PTS_OFF 0x1ffa00L + +/* Subpict definition */ +#define FIFO_SIZE 8 /* PTS FIFO entry count */ +#define HIGH_FIFO 32 /* HighLight Fifo size */ +#define SCRM_FIFO 0x800 /* Scramble buffer size */ +#define SPBLOCK ( 0xE000 - HIGH_FIFO - SCRM_FIFO ) /* 56K - 32 bytes - 2k */ +#define SubBLOCK 0xE00 /* PTS + DCI = 3.5K */ +#define DCIBLOCK ( SubBLOCK - 8*FIFO_SIZE ) +#define PxdBLOCK ( SPBLOCK - SubBLOCK ) +#define FStart 0x20 /* PTS FIFO Start Address */ + +#define SUBBASE(dev) ( DRAM_BASE(dev) + SUB_FIFO_OFF ) + +#define LS220_DSP_REG 0x100L +#define LS220_MPG_REG 0x180L +#define LS220_SYNC_REG 0x200L +#define LS220_PCM_REG 0x280L +#define LS220_VID_REG 0x300L + +/* SYNC REGS */ +#define SYNC_AUD_CONTROL (LS220_SYNC_REG+0x00) +#define SYNC_VID_CONTROL (LS220_SYNC_REG+0x04) +#define SYNC_WAIT_LINE (LS220_SYNC_REG+0x0c) +#define SYNC_FRAME_PERIOD (LS220_SYNC_REG+0x10) +#define SYNC_STC (LS220_SYNC_REG+0x18) +#define PTS_FIFO_START (LS220_SYNC_REG+0x20) +#define PTS_FIFO_END (LS220_SYNC_REG+0x24) +#define PTS_FIFO_WRITE (LS220_SYNC_REG+0x28) +#define PTS_FIFO_READ (LS220_SYNC_REG+0x2c) +#define SYNC_VIDEO_PTS (LS220_SYNC_REG+0x50) +#define SYNC_INT_CTRL (LS220_SYNC_REG+0x74) +#define SYNC_INT_FORCE (LS220_SYNC_REG+0x78) + +/* MPEG VIDEO REGS */ +#define MPGVID_CONTROL (LS220_MPG_REG+0x0) +#define MPGVID_SETUP (LS220_MPG_REG+0x4) +#define MPGVID_FIFO_START (LS220_MPG_REG+0x8) +#define MPGVID_FIFO_END (LS220_MPG_REG+0xc) +#define MPGVID_FIFO_POS (LS220_MPG_REG+0x10) +#define MPGVID_FIFO_FORCE (LS220_MPG_REG+0x14) +#define MPGVID_FIFO_ADDBLOCK (LS220_MPG_REG+0x18) +#define MPGVID_FIFO_BYTES (LS220_MPG_REG+0x1c) +#define MPGVID_FIFO_INTLEVEL (LS220_MPG_REG+0x20) +#define MPGVID_TOTAL_BYTES (LS220_MPG_REG+0x24) +#define MPGVID_ERROR (LS220_MPG_REG+0x28) +#define MPGVID_MB_WIDTH (LS220_MPG_REG+0x2c) +#define MPGVID_MB_HEIGHT (LS220_MPG_REG+0x30) +#define MPGVID_DEBUG1 (LS220_MPG_REG+0x38) +#define MPGVID_DEBUG2 (LS220_MPG_REG+0x3c) + +/* VID_REG */ +#define VIDP_GPIO (LS220_VID_REG+0x50) + +/* PCM REG */ +#define PCM_FREQ_CONTROL (LS220_PCM_REG+0x0) +#define PCM_OUTPUT_CONTROL (LS220_PCM_REG+0x4) +#define PCM_FIFO_START (LS220_PCM_REG+0x8) +#define PCM_FIFO_END (LS220_PCM_REG+0xc) + +/* DSP REGS */ +#define DSP_CODE_ADDR (LS220_DSP_REG+0x0) + +/* DSP INTERAL MEMORY */ + +#define DSPMEM_DRV_RET(dev) (DSPMEM_BASE(dev)+0xfef0L) +#define DSPMEM_ACC(dev) (DSPMEM_BASE(dev)+0xfef5L) +#define DSPMEM_ACC4(dev) (DSPMEM_BASE(dev)+0xfef4L) +#define DSPMEM_CHAL_KEY(dev) (DSPMEM_BASE(dev)+0xfef6L) + +#define DSPMEM_LOCK(dev) (DSPMEM_BASE(dev)+0xff78L) + +#define DSPMEM_AUDIO_CONF(dev) (DSPMEM_BASE(dev)+0xff7cL) +#define DSPMEM_AC3_CONF(dev) (DSPMEM_BASE(dev)+0xff80L) + +#define DSPMEM_KARAOKE(dev) (DSPMEM_BASE(dev)+0xff8c) + +#define DSPMEM_INT_MASK(dev) (DSPMEM_BASE(dev)+0xffa4L) +#define DSPMEM_INT_STATUS(dev) (DSPMEM_BASE(dev)+0xffa8L) +#define DSPMEM_INT_THREHOLD(dev) (DSPMEM_BASE(dev)+0xffacL) + +#define DSPMEM_VOLUME_LEVEL(dev) (DSPMEM_BASE(dev)+0xffb0L) + +#define DSPMEM_PTS_START(dev) (DSPMEM_BASE(dev)+0xffd0L) +#define DSPMEM_PTS_END(dev) (DSPMEM_BASE(dev)+0xffd4L) +#define DSPMEM_PTS_WR(dev) (DSPMEM_BASE(dev)+0xffd8L) +#define DSPMEM_PTS_RD(dev) (DSPMEM_BASE(dev)+0xffdcL) + +#define DSPMEM_FIFO_START(dev) (DSPMEM_BASE(dev)+0xffe0L) +#define DSPMEM_FIFO_END(dev) (DSPMEM_BASE(dev)+0xffe4L) +#define DSPMEM_FIFO_WR(dev) (DSPMEM_BASE(dev)+0xffe8L) +#define DSPMEM_FIFO_RD(dev) (DSPMEM_BASE(dev)+0xffecL) + + +#define DSPMEM_CMD(dev) (DSPMEM_BASE(dev)+0xfff0L) +#define DSPMEM_STATUS(dev) (DSPMEM_BASE(dev)+0xfff8L) + + +#define DSP_CMD_NOP 0x00 +#define DSP_CMD_AC3 0x80 +#define DSP_CMD_MPEG1 0x81 +#define DSP_CMD_MPEG2 0x82 +#define DSP_CMD_PCM 0x83 + +#define DSP_CMD_PLAY 0x84 +#define DSP_CMD_STOPF 0x85 +#define DSP_CMD_PAUSE 0x86 +#define DSP_CMD_MUTE 0x87 +#define DSP_CMD_UNMUTE 0x88 +#define DSP_CMD_CONFIG 0x89 +#define DSP_CMD_VER 0x8a +#define DSP_CMD_STATUS 0x8b + +#define DSP_CMD_VOLUME 0x8c +#define DSP_CMD_INITDONE 0x8d + +#define DSP_CMD_FRAME 0xa0 +#define DSP_CMD_CLRAUTH 0xa1 +#define DSP_CMD_DECAUTH 0xa2 +#define DSP_CMD_DRVAUTH 0xa3 +#define DSP_CMD_KEYSHARE 0xa4 +#define DSP_CMD_DISCKEY 0xa5 +#define DSP_CMD_TITLEKEY 0xa6 + + +#define I2C_CLIENTS_MAX 16 + + +struct ls220_dev +{ + struct ls220_dev *next; + struct pci_dev *pdev; + void *membase; + int type; + u8 eprom[16]; + int has_eprom; + int tvencoder; + + u32 dram_base; + + u32 audio_fifo_off; + u32 audio_fifo_len; + + u32 audio_m_vol; + u32 audio_m_adj; + int audio_mute; + int audio_ac3; + + u32 audio_pts; + u32 audio_ptscount; + u32 audio_m_total; + u32 audio_speed; + + int audio_spdif; + + int spdif_first_play; + int stop_read; + + /* Buffer management */ + u8 audio_buffer[2048]; + u8 *audio_p; + u8 *audio_cp; + u16 audio_dlen; + + int video_mode; +#define VIDEO_PAL 0 +#define VIDEO_NTSC 1 + int video_mpeg1; + int video_hw_wrap; + int video_letter; + int video_zoomin; + int video_speed; + int video_pts; + int video_total; + int video_remainder; + int video_wptr; + int vga_mode; + + struct i2c_adapter i2c_adap; + struct i2c_algo_bit_data i2c_algo; + struct i2c_client i2c_client; + int i2c_rc; + struct i2c_client *i2c_clients[I2C_CLIENTS_MAX]; +}; + +/* FIXME - spinlock the list */ +static struct ls220_dev *ls_devs; + +static int old = 1; /* Old v new style board */ + +/* + * Hardware access + */ + +static void ls220_dv_write(struct ls220_dev *dev, u32 offset, u32 data) +{ + writel(data, dev->membase+offset); +} + +static u32 ls220_dv_read(struct ls220_dev *dev, u32 offset) +{ + return readl(dev->membase+offset); +} + +static void ls220_write_dram(struct ls220_dev *dev, u32 offset, u32 data) +{ + writel(data, dev->membase+offset); +} + +static u32 ls220_read_dram(struct ls220_dev *dev, u32 offset) +{ + return readl(dev->membase+offset); +} + +static void ls220_memsetl(struct ls220_dev *dev, u32 offset, u32 fill, int len) +{ + int i; + for(i=0;idstoff, f->length); + if(f->dstoff) + { + for(i=0; ilength; i++) + { + ls220_write_dram(dev, DRAM_BASE(dev) + f->dstoff + 4 * i, f->firmware[i]); + if(ls220_read_dram(dev, DRAM_BASE(dev) + f->dstoff + 4 * i)!=f->firmware[i]) + { + printk("luxsonor: firmware upload error.\n"); + printk("%d: Got 0x%X want 0x%X\n", + i, ls220_read_dram(dev, DRAM_BASE(dev) + f->dstoff + 4 * i), + f->firmware[i]); + return; + } + } + } +} + +static void load_firmware_set(struct ls220_dev *dev, int card, int mode) +{ + int i; + for(i=0;i<3;i++) + load_firmware_block(dev, &firmware[card][mode][i]); +} + +static void ls220_load_firmware(struct ls220_dev *dev, int format) +{ + int card = 0; + if(dev->type==LS240) + card = 1; + + if(dev->eprom[EPROM_I2S]==0x03) + format += 3; /* Second table for i2s */ + + format--; /* Numbered 1 to 3 */ + + load_firmware_set(dev, card, format); +} + +/* + * LS220 I2C bus implementation + */ + +static void ls220_i2c_init(struct ls220_dev *dev) +{ + if(!dev->eprom[EPROM_BOARDTYPE]) + ls220_dv_write(dev, 0x350, 0x4f70100); + else + ls220_dv_write(dev, 0x350, 0x4f70f00); + ls220_dv_write(dev, 0x364, 0xff031f); +} + +static void ls220_bit_setscl(void *data, int state) +{ + struct ls220_dev *dev = data; + u32 reg; + + reg = ls220_dv_read(dev, 0x350); + reg &= 0x7FFFFF; + if(state == 0) + reg |= 0x00800000; + ls220_dv_write(dev, 0x350, reg); +// printk("SCL = %d\n", state); + ls220_dv_read(dev, 0x350); +} + +static void ls220_bit_setsda(void *data, int state) +{ + struct ls220_dev *dev = data; + u32 reg; + + reg = ls220_dv_read(dev, 0x350); + reg &= 0xBFFFFF; + if(state == 0) + reg |= 0x00400000; + ls220_dv_write(dev, 0x350, reg); +// printk("SDA = %d\n", state); + ls220_dv_read(dev, 0x350); +} + +static int ls220_bit_getsda(void *data) +{ + struct ls220_dev *dev = data; + if(ls220_dv_read(dev, 0x350)&0x40) + { +// printk("get SDA=0\n"); + return 0; + } +// printk("get SDA=1\n"); + return 1; +} + +static void ls220_i2c_use(struct i2c_adapter *adap) +{ + MOD_INC_USE_COUNT; +} + +static void ls220_i2c_unuse(struct i2c_adapter *adap) +{ + MOD_DEC_USE_COUNT; +} + +static int ls220_attach_inform(struct i2c_client *client) +{ + struct ls220_dev *dev = client->adapter->data; + return 0; +} + +static int ls220_detach_inform(struct i2c_client *client) +{ + struct ls220_dev *dev = client->adapter->data; + return 0; +} + +static int ls220_call_i2c_clients(struct ls220_dev *dev, unsigned int cmd, void *arg) +{ + return 0; +} + +/* + * Structures to define our hardware with the i2c core code. It + * will do all the i2c bus management and locking for us. + */ + +static struct i2c_algo_bit_data ls220_i2c_algo_template = { + setsda: ls220_bit_setsda, + setscl: ls220_bit_setscl, + getsda: ls220_bit_getsda, + udelay: 30, + mdelay: 10, + timeout: 200, +}; + +static struct i2c_adapter ls220_i2c_adap_template = { + name: "ls220", + id: I2C_HW_B_BT848, /* FIXME */ + inc_use: ls220_i2c_use, + dec_use: ls220_i2c_unuse, + client_register: ls220_attach_inform, + client_unregister: ls220_detach_inform, +}; + +static struct i2c_client ls220_i2c_client_template = { + name: "ls220 internal", + id: -1, +}; + +/* + * Register our i2c bus + */ + +static int ls220_i2c_register(struct ls220_dev *dev) +{ + /* Copy template */ + memcpy(&dev->i2c_adap, &ls220_i2c_adap_template, sizeof(struct i2c_adapter)); + memcpy(&dev->i2c_algo, &ls220_i2c_algo_template, sizeof(struct i2c_algo_bit_data)); + memcpy(&dev->i2c_client, &ls220_i2c_client_template, sizeof(struct i2c_client)); + /* Device backlinks */ + dev->i2c_algo.data = dev; + dev->i2c_adap.data = dev; + /* Fix up links */ + dev->i2c_adap.algo_data = &dev->i2c_algo; + dev->i2c_client.adapter = &dev->i2c_adap; + /* Set up */ + ls220_bit_setscl(dev, 1); + ls220_bit_setsda(dev, 1); + dev->i2c_rc = i2c_bit_add_bus(&dev->i2c_adap); + return dev->i2c_rc; +} + +/* + * I2C read interfaces + */ + +static int ls220_new_i2c_read(struct ls220_dev *dev, u8 addr) +{ + u8 buffer; + + if(dev->i2c_rc == -1) + BUG(); + printk("i2c recv from 0x%02X\n", addr); + + dev->i2c_client.addr = addr>>1; + if(i2c_master_recv(&dev->i2c_client, &buffer, 1)) + { + printk("i2c - read error.\n"); + return -EIO; + } + printk("Received %d\n", buffer); + return buffer; +} + +static int ls220_new_i2c_probe(struct ls220_dev *dev, u8 addr) +{ + u8 buffer; + int err; + + if(dev->i2c_rc == -1) + BUG(); + printk("i2c probe for 0x%02X\n", addr); + + dev->i2c_client.addr = addr>>1; + if((err=i2c_master_send(&dev->i2c_client, &buffer, 0))) + { + printk(" - probe failed (%d).\n", err); + return 0; + } + printk(" - found.\n"); + return 1; +} + +/*=================----------------*/ + +/* + * Old built in i2c code - this is here until I find why the generic + * kernel code won't play + */ + +static void iic_delay(struct ls220_dev *dev) +{ + udelay(30); +} + +static void iic_startcode(struct ls220_dev *dev) +{ + u32 tmp; + + tmp = ls220_dv_read(dev, 0x350) & 0x3fffffL; + ls220_dv_write(dev, 0x350, tmp); // both = 1 + iic_delay(dev); + + ls220_dv_write(dev, 0x350, tmp | 0x400000L); // SDA = 0 + + iic_delay(dev); + + ls220_dv_write(dev, 0x350, tmp | 0xc00000L); // SCL = 0 + iic_delay(dev); +} + +////////////////////////////////////////////////////////////////////////// + +static void iic_dataxfer(struct ls220_dev *dev, u8 val) +{ + u32 tmp; + u8 data; + int i; + + data = ~val; + for (i = 0; i < 8; i++) { + tmp = ls220_dv_read(dev, 0x350) & 0xbfffffL; + tmp |= (u32) ((data >> (7 - i)) & 0x1) << 22; // set SDA + ls220_dv_write(dev, 0x350, tmp); + iic_delay(dev); + tmp = ls220_dv_read(dev, 0x350); + ls220_dv_write(dev, 0x350, tmp & 0x7fffffL); // set SCL = 1 + iic_delay(dev); + ls220_dv_write(dev, 0x350, tmp | 0x800000L); // set SCL = 0 + iic_delay(dev); + } +} + +////////////////////////////////////////////////////////////////////////// + +static int iic_ack(struct ls220_dev *dev) +{ + u32 tmp, ack; + + tmp = ls220_dv_read(dev, 0x350); + ls220_dv_write(dev, 0x350, tmp & 0xbfffffL); // disable SDA = 1 + iic_delay(dev); + ack = ls220_dv_read(dev, 0x350) & 0x40; + ls220_dv_write(dev, 0x350, tmp & 0x3fffffL); // SCL = 1 + iic_delay(dev); + tmp = ls220_dv_read(dev, 0x350); + ls220_dv_write(dev, 0x350, tmp | 0x800000L); // set SCL = 0 + iic_delay(dev); + + if (!ack) + return 1; + else + return 0; +} + +////////////////////////////////////////////////////////////////////////// + +static void iic_endcode(struct ls220_dev *dev) +{ + u32 tmp; + + tmp = ls220_dv_read(dev, 0x350); + ls220_dv_write(dev, 0x350, tmp | 0x400000L); // SDA = 0 + iic_delay(dev); + tmp = ls220_dv_read(dev, 0x350); + ls220_dv_write(dev, 0x350, tmp & 0x7fffffL); // set SCL = 1 + iic_delay(dev); + ls220_dv_write(dev, 0x350, tmp & 0x3fffffL); // SDA = 1 + iic_delay(dev); +} + +////////////////////////////////////////////////////////////////////////// + +static u8 iic_dataget(struct ls220_dev *dev) +{ + u8 val, i; + u32 tmp; + + val = 0; + for (i = 0; i < 8; i++) { + iic_delay(dev); + tmp = ls220_dv_read(dev, 0x350); + val <<= 1; + if (tmp & 0x40) + val = val | 0x1; + + tmp = tmp & 0x3fffffL; + ls220_dv_write(dev, 0x350, tmp); // set SCL = 1 + iic_delay(dev); + ls220_dv_write(dev, 0x350, tmp | 0x800000L); // set SCL = 0 + iic_delay(dev); + } + + return val; +} + +////////////////////////////////////////////////////////////////////////// + +static void send_ack(struct ls220_dev *dev) +{ + u32 tmp; + + tmp = ls220_dv_read(dev, 0x350); + tmp = tmp | 0xc00000L; // SCLK SDA + ls220_dv_write(dev, 0x350, tmp); // set 00 + iic_delay(dev); + tmp = tmp & 0x7fffffL; + ls220_dv_write(dev, 0x350, tmp); // set 10 + iic_delay(dev); + tmp = tmp | 0xc00000L; + ls220_dv_write(dev, 0x350, tmp); // set 00 + iic_delay(dev); + tmp = tmp & 0xb00000L; + ls220_dv_write(dev, 0x350, tmp); // set 01 + iic_delay(dev); +} + +static int i2c_readeprom(struct ls220_dev *dev, u8 addr, u8 subaddr, u8 num, u8 * pb) +{ + u8 val; + int i; + + iic_startcode(dev); + iic_dataxfer(dev, addr); // write command + iic_ack(dev); + iic_dataxfer(dev, subaddr); + iic_ack(dev); + iic_startcode(dev); + iic_dataxfer(dev, (u8) (addr | 0x1)); // read command + iic_ack(dev); + + for (i = 0; i < num; i++) { + pb[i] = iic_dataget(dev); // load array here + if (i < (num - 1)) + send_ack(dev); + else + iic_endcode(dev); + } + return 1; +} + +static int ls220_i2c_probe(struct ls220_dev *dev, u8 addr) +{ + int val; +// return ls220_new_i2c_probe(dev,addr); + iic_startcode(dev); + iic_dataxfer(dev, addr); // write command + val = iic_ack(dev); + iic_endcode(dev); + return val; +} + +////////////////////////////////////////////////////////////////////////// + +static int read_i2c(struct ls220_dev *dev, u8 addr) +{ + u32 tmp, val; + u32 dwcnt = 0; + + val = 0xff; + tmp = ls220_dv_read(dev, 0x350); + ls220_dv_write(dev, 0x350, tmp | 0x4000000); // set bit 26=1 + iic_delay(dev); + ls220_dv_write(dev, 0x354, addr << 24 | 0x1000000L); + iic_delay(dev); + + while (!(ls220_dv_read(dev, 0x368) & 0x1000)) { + iic_delay(dev); + if (dwcnt++ > 0xffff) + break; + } + val = (u8) ls220_dv_read(dev, 0x36c); + ls220_dv_write(dev, 0x350, tmp); + iic_delay(dev); + return val; +} + +static void send_i2c(struct ls220_dev *dev, u8 addr,u8 subaddr,u8 data) +{ + iic_startcode(dev); + iic_dataxfer(dev, addr); + iic_ack(dev); + iic_dataxfer(dev, subaddr); + iic_ack(dev); + iic_dataxfer(dev, data); + iic_ack(dev); + iic_endcode(dev); +} + +/*=================----------------*/ + +static int ls220_i2c_read(struct ls220_dev *dev, u8 addr) +{ +// return ls220_new_i2c_read(dev, addr); + return read_i2c(dev, addr); +} + + +static int ls220_i2c_write(struct ls220_dev *dev, u8 addr, u8 b1, u8 b2, int both) +{ + u8 buffer[2]; + int bytes = both ? 2 : 1; + if(dev->i2c_rc == -1) + BUG(); + +// printk("Write to i2c client 0x%02X - 0x%2X (0x%02X, %d)\n", addr, b1, b2, both); + dev->i2c_client.addr = addr >> 1; + buffer[0] = b1; + buffer[1] = b2; + if(i2c_master_send(&dev->i2c_client, buffer, bytes)!=bytes) + { + printk(KERN_ERR "i2c write failed.\n"); + return -EIO; + } + return 0; +} + +static int ls220_load_eeprom(struct ls220_dev *dev, u8 addr, u8 subaddr, u8 len, u8 *buf) +{ + int i; + + i2c_readeprom(dev, addr, subaddr, len, buf); +#if 0 + if(ls220_i2c_write(dev, addr, subaddr, -1, 0)<0) + return -EIO; + dev->i2c_client.addr = addr >> 1; + + if(i2c_master_recv(&dev->i2c_client, buf, 16)!=16) + return -EIO; +#endif +#if 0 + printk("luxsonor: EEPROM "); + for(i=0;i<16;i++) + printk("%02X ", buf[i]); + printk("\n"); +#endif + return 0; +} + +static int ls220_detect_tvencoder(struct ls220_dev *dev) +{ + int type; + u8 id; + + if(ls220_i2c_write(dev, 0x00, 0x0f, 0x40, 1)) + printk("i2c_write failed.\n"); + if(ls220_i2c_probe(dev, 0x80)) + { + u8 id; + ls220_load_eeprom(dev, 0x80, 0x3d, 1, &id); + if(id & 0xf0) + type = CS4953; + else + type = CS4952; + return type; + } + if(ls220_i2c_probe(dev, 0x8A)) + { + id = ls220_i2c_read(dev, 0x8A); + if(((id>>5)&7) == 5) + type = BT865; + else + type = BT864; + return type; + } + if(ls220_i2c_probe(dev, 0x42)) + { + ls220_load_eeprom(dev, 0x42, 0x00, 1, &id); + if(id & 0x0f) + type = HS8171; + else + type = HS8170; + return type; + } + if(ls220_i2c_probe(dev, 0x8c)) + return SAA7120; + if(ls220_i2c_probe(dev, 0xd4)) + return AD7175; + if(ls220_i2c_probe(dev, 0x54)) + return AD7176; + printk("No TV encoder ??\n"); + return -ENODEV; +} + +/* + * The LS220 also has some other i2c like stuff on the same + * registers, so we have to watch our locking. + * + * FIXME:pci posting.. + */ + +#define G_EN 0x60000 +#define G_SC 0x0200 +#define G_SD 0x0400 + +static void ls220_gpio_startcode(struct ls220_dev *dev) +{ + u32 r350 = ls220_dv_read(dev, 0x350); + r350&=0xFF000000; + r350|=G_EN; + ls220_dv_write(dev, 0x350, r350|G_SC|G_SD); + udelay(100); + ls220_dv_write(dev, 0x350, r350|G_SC); + udelay(100); + ls220_dv_write(dev, 0x350, r350); + udelay(100); +} + +static void ls220_gpio_endcode(struct ls220_dev *dev) +{ + u32 r350 = ls220_dv_read(dev, 0x350); + r350&=0xFF000000; + r350|=G_EN; + ls220_dv_write(dev, 0x350, r350); + udelay(10); + ls220_dv_write(dev, 0x350, r350|G_SC); + udelay(10); + ls220_dv_write(dev, 0x350, r350); + udelay(10); + ls220_dv_write(dev, 0x350, r350|G_SC); + udelay(10); + ls220_dv_write(dev, 0x350, r350|G_SC|G_SD); +} + +static void ls220_gpio_addr(struct ls220_dev *dev, u8 addr) +{ + int i; + int sd; + u32 r350 = ls220_dv_read(dev, 0x350); + r350&=0xFF000000; + r350|=G_EN; + + for(i=2;i>=0;i--) + { + if(addr&(1<=0;i--) + { + if(data&(1<type == LS240) + { + ls220_dv_write(dev, 0x10, 1); + ls220_dv_write(dev, 0x10, 0x30); + ls220_dv_write(dev, 0x300, 0); + ls220_dv_write(dev, 0x84, 0x04400000); + udelay(10); + ls220_dv_write(dev, 0x80, 0x66a428ec); + udelay(10); + ls220_dv_write(dev, 0x84, 0x80400000); + ls220_dv_write(dev, 0x30, 0x12c5); + } + else + { + ls220_dv_write(dev, 0x10, 1); + ls220_dv_write(dev, 0x10, 0); + } + + ls220_i2c_init(dev); +} + +/* + * LS220 Audio drivers + */ + +static void ls240_dsp_poke(struct ls220_dev *dev) +{ + if(dev->type == LS240) + { + u32 reg = ls220_dv_read(dev, 0x10); + reg &= ~8; + reg |= 0x30; + ls220_dv_write(dev, 0x10,reg); + } +} + +static int ls220_dsp_wait(struct ls220_dev *dev) +{ + int count; + + ls240_dsp_poke(dev); + + ls220_dv_read(dev, 0x250); + + for(count = 0; count < 4096; count ++) + { + if(ls220_read_dram(dev, DSPMEM_CMD(dev)) == 0x100) + return 0; + ls240_dsp_poke(dev); + udelay(50); + } + printk(KERN_ERR "ls220: dsp not responding.\n"); + return -ETIMEDOUT; +} + +static u32 vol_table[16] = { + 0x7fffff, 0x6046c5, 0x4c79a0, 0x3cbf0f, + 0x3040a5, 0x26540e, 0x1e71fe, 0x182efd, + 0x1335ad, 0xf4240, 0xc1ed8, 0x9a0ad, + 0x7a5c3, 0x6131b, 0x4d343, 0x0 +}; + +static void ls220_audio_set_volume(struct ls220_dev *dev, int vol) +{ + if(dev->audio_mute) + return; + if(vol == 0xFF) + { + ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_MUTE); + ls220_dsp_wait(dev); + vol = 0; + } + else + dev->audio_m_vol = vol; + if(vol > 15 || vol < 0) + BUG(); + ls220_write_dram(dev, DSPMEM_VOLUME_LEVEL(dev), vol_table[15-vol]); + ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_VOLUME); +} + +static void ls220_dsp_init(struct ls220_dev *dev, int type) +{ + ls220_write_dram(dev, DSPMEM_AC3_CONF(dev) ,0x3400); + + if(type == 1) /* AC3 */ + { + ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_AC3); + dev->audio_m_adj = 0x600; + } + else if(type == 0) /* PCM */ + { + ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_PCM); + dev->audio_m_adj = 0x600; + } + else if(type == 2) /* MPG1 */ + { + ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_MPEG1); + dev->audio_m_adj = 0x0; + } + ls220_dsp_wait(dev); + ls220_audio_set_volume(dev, dev->audio_m_vol); + + dev->audio_fifo_off = ls220_read_dram(dev, DSPMEM_FIFO_START(dev)); + dev->audio_fifo_len = ls220_read_dram(dev, DSPMEM_FIFO_END(dev)) - dev->audio_fifo_off; +// printk("FIFO at 0x%X, size %d.\n", dev->audio_fifo_off, dev->audio_fifo_len); +} + +static void ls220_audio_init(struct ls220_dev *dev, int type) +{ + dev->audio_mute = 0; + dev->audio_m_vol = 15; + dev->audio_ac3 = 1; + dev->audio_m_total = 0; + dev->audio_pts = 0; + dev->audio_ptscount = 0; + dev->audio_speed = 1000; + dev->stop_read = 0; + ls220_dv_write(dev, 0x24, 0); + + if(old) + { + ls220_dv_write(dev, 0x104, 0); + ls220_dv_write(dev, 0x100, 0x7C600); + ls220_dv_write(dev, 0x104, 1); + udelay(200); + ls220_write_dram(dev, DSPMEM_FIFO_WR(dev), AUD_FIFO_OFF); + ls220_write_dram(dev, DSPMEM_FIFO_RD(dev), AUD_FIFO_OFF); + ls220_write_dram(dev, DSPMEM_PTS_WR(dev), AUD_PTS_OFF); + ls220_write_dram(dev, DSPMEM_PTS_RD(dev), AUD_PTS_OFF); + } + ls220_dsp_init(dev, type); + dev->audio_m_total = 0; + dev->audio_pts = 0; + dev->audio_ptscount = 0; + + if(type == 2) /* Mpeg audio */ + dev->audio_ptscount = 1; +} + +static void ls240_audiopcm_enable_tristate(struct ls220_dev *dev) +{ + ls220_dv_write(dev, 0x284, ls220_dv_read(dev, 0x284)|0x200000); +} + +static void ls220_audio_set_info(struct ls220_dev *dev) +{ + u16 clock_chip; /* clock chip defition */ + u16 left_ch; /* left channel polarity */ + u16 pcm_size; /* PCM ( output ) size */ + u16 i2s_pin; /* I2S pin */ + + clock_chip = (u16)dev->eprom[EPROM_CLOCKTYPE]; + left_ch = (u16)dev->eprom[EPROM_LEFT_CH_POL]<<3; + pcm_size = 0; + + if(dev->eprom[EPROM_I2S] == 0x3) + i2s_pin = 0x40; + else + i2s_pin = 0; + + ls220_write_dram(dev, DSPMEM_AUDIO_CONF(dev), i2s_pin|pcm_size|left_ch|clock_chip); +} + +static void ls220_audio_set_spdif(struct ls220_dev *dev, int onoff) +{ + u32 data; + + dev->audio_spdif = onoff; + + data = ls220_read_dram(dev, DSPMEM_AUDIO_CONF(dev)); + data &= 0x7F; + if(onoff) + data |= 0x80; + ls220_write_dram(dev, DSPMEM_AUDIO_CONF(dev), data); +} + +static int ls220_audio_write(struct ls220_dev *dev, const char *buf, int len) +{ + return 0; +} + +static void ls220_play_audio(struct ls220_dev *dev, int speed) +{ + dev->audio_speed = speed; + if(speed == 1000) + { + /* + * Normal speed - engage hardware synchronization + */ + if(dev->type == LS240) + { + ls220_dv_write(dev, 0x280, 0x8); + ls220_dv_write(dev, 0x280, 0x9); + ls220_dv_write(dev, 0x29C, 0x30008235); + ls220_dv_write(dev, 0x200, 0x419); + ls220_dv_write(dev, 0x200, 0x3b); + } + else + { + u32 tmp = ls220_dv_read(dev, SYNC_AUD_CONTROL); + ls220_dv_write(dev, SYNC_AUD_CONTROL, tmp|0x20); + } + ls220_dv_write(dev, DSPMEM_CMD(dev), DSP_CMD_PLAY); + ls220_dsp_wait(dev); + /* Locking needed on 0x350 */ + if(dev->eprom[EPROM_BOARDTYPE] == 3 && !dev->audio_spdif) + ls220_dv_write(dev, 0x350, ls220_dv_read(dev, 0x350)|0x010100); + if(!(dev->eprom[EPROM_SPDIF_CH]&0x02) && dev->audio_spdif && dev->spdif_first_play) + { + dev->spdif_first_play = 0; + ls220_dv_write(dev, DSPMEM_CMD(dev), DSP_CMD_INITDONE); + ls220_dsp_wait(dev); + } + } +} + +static void ls220_audio_set_speed(struct ls220_dev *dev, int speed) +{ + dev->audio_speed = speed; +} + +static void ls220_audio_set_config(struct ls220_dev *dev, int sixchannel) +{ + if(dev->audio_ac3) + { + if(sixchannel && !(dev->eprom[EPROM_SPDIF_CH]&0x1)) + ls220_write_dram(dev, DSPMEM_AC3_CONF(dev), 0x340F); + else + { + switch(sixchannel) + { + case 0: /* Want prologic */ + case 1: /* Board doesnt do 6 */ + case 3: /* Default to prologic */ + ls220_write_dram(dev, DSPMEM_AC3_CONF(dev), 0x3400); + break; + case 2: /* No six channels but use 2 channel scheme */ + ls220_write_dram(dev, DSPMEM_AC3_CONF(dev), 0x3402); + break; + } + } + } + else + { + /* PCM mode */ + if(sixchannel > 1) + ls220_write_dram(dev, DSPMEM_AC3_CONF(dev), sixchannel); + } +} + +static void ls220_audio_set_type(struct ls220_dev *dev, int type) +{ + dev->audio_ac3 = type; +} + + +static void ls220_audio_stop(struct ls220_dev *dev) +{ + dev->stop_read = 0; + ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_MUTE); + ls220_dsp_wait(dev); + ls220_write_dram(dev, DSPMEM_PTS_WR(dev), AUD_PTS_OFF); + ls220_write_dram(dev, DSPMEM_PTS_RD(dev), AUD_PTS_OFF); + + if(dev->audio_ac3 == 1) + ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_AC3); + else if(dev->audio_ac3 == 0) + ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_PCM); + else if(dev->audio_ac3 == 2) + ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_MPEG1); + ls220_dsp_wait(dev); + ls220_audio_set_volume(dev, dev->audio_m_vol); + + dev->audio_m_total = 0; + dev->audio_pts = 0; + dev->audio_ptscount = 0; + if(dev->audio_ac3 == 2) + dev->audio_ptscount = 1; +} + +static void ls220_audio_mute(struct ls220_dev *dev) +{ + ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_STOPF); + ls220_dsp_wait(dev); +} + +static void ls220_audio_pause(struct ls220_dev *dev) +{ + ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_PAUSE); + ls220_dsp_wait(dev); +} + +static void ls220_audio_continue(struct ls220_dev *dev) +{ + ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_PLAY); + ls220_dsp_wait(dev); +} + +static u32 ls220_audio_report_frame(struct ls220_dev *dev) +{ + ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_FRAME); + ls220_dsp_wait(dev); + return ls220_read_dram(dev, DSPMEM_STATUS(dev)); +} + +static u32 ls220_audio_report_status(struct ls220_dev *dev) +{ + ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_STATUS); + ls220_dsp_wait(dev); + return ls220_read_dram(dev, DSPMEM_STATUS(dev)); +} + +static void ls220_audio_onoff(struct ls220_dev *dev, int onoff) +{ + dev->audio_mute = onoff; + if(!dev->audio_mute) + ls220_audio_set_volume(dev, dev->audio_m_vol); + else + { + ls220_write_dram(dev, DSPMEM_VOLUME_LEVEL(dev), vol_table[15]); + ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_VOLUME); + ls220_dsp_wait(dev); + } +} + +static void ls220_audio_after_seek(struct ls220_dev *dev) +{ + if(old) + { + ls220_write_dram(dev, DSPMEM_FIFO_WR(dev), AUD_FIFO_OFF); + ls220_write_dram(dev, DSPMEM_FIFO_RD(dev), AUD_FIFO_OFF); + } + ls220_write_dram(dev, DSPMEM_FIFO_WR(dev), dev->audio_fifo_off); + ls220_write_dram(dev, DSPMEM_FIFO_RD(dev), dev->audio_fifo_off); + ls220_write_dram(dev, DSPMEM_PTS_WR(dev), AUD_PTS_OFF); + ls220_write_dram(dev, DSPMEM_PTS_RD(dev), AUD_PTS_OFF); +} + +int ls220_audio_write_pts(struct ls220_dev *dev, u32 pts, u16 aoff) +{ + u32 rdptr; + u32 wrptr; + u32 space; + u32 val; + + rdptr = ls220_dv_read(dev, DSPMEM_PTS_RD(dev)); + wrptr = ls220_dv_read(dev, DSPMEM_PTS_WR(dev)); + space = (wrptr > rdptr) ? (AUD_PTS_LEN + rdptr - wrptr) : (rdptr - wrptr); + + if(space < 0x8) + return 0; + + if(dev->type != LS240) + { + if(!dev->audio_pts) + { + val = ls220_dv_read(dev, 0x200); + ls220_dv_write(dev, 0x200, val&0xFBF); /* Audio master */ + } + } + ls220_write_dram(dev, DRAM_BASE(dev)+wrptr, pts); + wrptr+=4; + ls220_write_dram(dev, DRAM_BASE(dev)+wrptr, dev->audio_m_total+aoff); + wrptr+=4; + if(wrptr >= AUD_PTS_OFF+AUD_PTS_LEN) + wrptr -= AUD_PTS_LEN; + ls220_dv_write(dev, DSPMEM_PTS_WR(dev), wrptr); + dev->audio_pts = pts; + return 1; +} + +static void ls220_audio_stop_dsp(struct ls220_dev *dev) +{ + ls220_dv_write(dev, 0x104, 0); + ls220_dv_write(dev, SYNC_INT_CTRL, 0x8000); +} + +static void ls220_audio_enable_dsp(struct ls220_dev *dev) +{ + ls220_dv_write(dev, 0x100, 0x7c600); + ls220_dv_write(dev, 0x104, 0x1); + udelay(100); + if(dev->type == LS240) + ls220_dv_write(dev, SYNC_INT_CTRL, 0x38000001); + else + ls220_dv_write(dev, SYNC_INT_CTRL, 0xE8001); +} + +static void ls220_audio_setuclock(struct ls220_dev *dev, int type) +{ + if(!old) + return; +#if 0 + if(type && dev->eprom[EPROM_CLOCKTYPE]==1) + ls220_write_dram(dev, DSPMEM_UCLOCK(dev), 1); + else + ls220_write_dram(dev, DSPMEM_UCLOCK(dev), 0); +#endif +} + +static void ls220_audio_set_karaoke(struct ls220_dev *dev, int mode) +{ + if(mode < 0 || mode > 3) + BUG(); + /* bit 0 = vocal 1 enable bit 1 = vocal 2 enable */ + ls220_write_dram(dev, DSPMEM_KARAOKE(dev), mode); +} + +static u32 ls220_audio_send_data(struct ls220_dev *dev, u8 *p, u32 len, u16 pts, int scramble, u16 aoff) +{ + if(dev->audio_speed != 1000) + return len; + /* TODO */ + return 0; +} + +static u32 ls220_audio_mpeg_packet(struct ls220_dev *dev, u8 *mbuf, u8 *pp, u32 used) +{ + /* mbuf is a 2K packet, pp is a pes len ptr */ + u8 aid; + u16 pes_len; + u32 curpts = 0; + u8 scramble; + int m_ext = 0; + u16 ext_pes_len = 0; + int m_exthead = 0; + + memcpy(dev->audio_buffer, mbuf, 2048); + dev->audio_p = dev->audio_buffer + (pp - mbuf); + + aid = dev->audio_p[-1]&7; + + if(dev->stop_read) + { + dev->audio_p+=2; + scramble = dev->audio_p[0]&0x30; + pes_len = dev->audio_p[2]; + dev->audio_p+=3; + if((dev->audio_p[0] & 0xf0)==0x20 && pes_len > 0) /* Found PTS */ + { + curpts = dev->audio_p[1]<<8 | dev->audio_p[2]; + curpts = (curpts << 14) | ((dev->audio_p[3]<<8 | dev->audio_p[4])>>2); + curpts |= (dev->audio_p[0] & 0xE) << 28; + } + dev->audio_p += pes_len; + goto tryit; + } + if((dev->audio_p[-1]&0xF0) == 0xD0) + { + m_exthead = 1; + m_ext = 1; + } + dev->audio_dlen = dev->audio_p[0]<<8 | dev->audio_p[1]; + dev->audio_p+=2; + dev->audio_cp = dev->audio_p+dev->audio_dlen; /* Find A_PKT end */ + if (dev->audio_cp < dev->audio_buffer + 0x0800) + { + if((((dev->audio_cp[0]<<8) | dev->audio_cp[1])&0xFFFFFFF0) != 0x01c0) + m_ext = 1; + } + scramble = dev->audio_p[0]&0x30; + pes_len = dev->audio_p[2]; + dev->audio_p+=3; + + dev->audio_dlen = dev->audio_dlen -3 - pes_len; + + if(((*dev->audio_p & 0xf0) == 0x20) && (pes_len > 0)) + { + curpts = dev->audio_p[1]<<8|dev->audio_p[2]; + curpts <<= 14; + curpts |= (dev->audio_p[3]<< 8 | dev->audio_p[4])>>2; + curpts |= (dev->audio_p[0]&0x0E)<<28; + } + + dev->audio_p+=pes_len; + + if(m_exthead) + { + dev->audio_cp = dev->audio_p; + dev->audio_dlen = 0; + curpts = 0; + } + + if(m_ext) + { + dev->audio_p = dev->audio_cp; + while(dev->audio_p < dev->audio_buffer + 0x800) + { + while(((dev->audio_p[0]<<8 | dev->audio_p[1]) & 0xFFFF00) != 0x100) + { + if(dev->audio_p++ >= dev->audio_buffer + 0x800) + goto tryit; + } + + if((dev->audio_p[3]&0xF0) != 0xC0) + { + dev->audio_p += 4; + ext_pes_len = dev->audio_p[0]<<8 | dev->audio_p[1]; + dev->audio_p += ext_pes_len; + continue; + } + if((((dev->audio_p[0]<<24)|(dev->audio_p[1]<<1)|(dev->audio_p[2]<<8)|dev->audio_p[3]) & 0xFFFFFFF0) != 0x1c0) + { + dev->audio_p+=4; + ext_pes_len = dev->audio_p[0] << 8 | dev->audio_p[1]; + dev->audio_p+=2; + pes_len = dev->audio_p[2]; + dev->audio_p+=3; + ext_pes_len = ext_pes_len - 3 - pes_len; + + if(m_exthead) + { + if((dev->audio_p[0]&0xF0) == 0x20 && pes_len > 0) + { + curpts = dev->audio_p[1]<<8|dev->audio_p[2]; + curpts <<= 14; + curpts |= dev->audio_p[3]<<8|dev->audio_p[4]; + curpts |= (dev->audio_p[0]&0xE)<<28; + } + m_exthead = 0; + } + + dev->audio_p += pes_len; + + memmove(dev->audio_cp, dev->audio_p, ext_pes_len); + dev->audio_dlen += ext_pes_len; + dev->audio_cp += ext_pes_len; + dev->audio_p += ext_pes_len; + } + } + } +tryit: + if(dev->audio_dlen == 0) + { + dev->stop_read = 0; + return used; + } + if(ls220_audio_send_data(dev, dev->audio_p, dev->audio_dlen, curpts, scramble, 0)) + { + dev->stop_read = 0; + return used; + } + else + { + dev->stop_read = 1; + return 0; + } +} + +/* + * Video side drivers + */ + +static void ls240_zoomvideo_enable_tristate(struct ls220_dev *dev) +{ + ls220_dv_write(dev, 0x37c, ls220_dv_read(dev, 0x37c)&0xe0ffffff); +} + +static void ls220_video_set_vpm(struct ls220_dev *dev, int type) +{ + /* TODO */ +} + +static void ls220_configure_tvout(struct ls220_dev *dev, int tvmode) +{ + static u8 bt865_pal[]={ + 0x00, 0x60, 0x7e, 0xfe, 0x54, 0x01, 0xff, 0x01, + 0xd5, 0x73, 0xa8, 0x22, 0x55, 0xa4, 0x05, 0x55, + 0x27, 0x40 + }; + int i; + + switch(dev->tvencoder) + { + case BT865: + for(i=0;i<18;i++) + send_i2c(dev, 0x8A, 0xD8+2*i, bt865_pal[i]); + break; + default: + printk("Sorry only PAL BT865 is supported right now.\n"); + } +} + +/* + * Video gamma table from Luxsonor + */ + +static u32 gamma[][8] = { + {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}, + {0x0,0x0,0x1000000,0x05040302,0x07070606,0x0b0a0908,0x0b0c0b0b,0xe0e0d}, + {0x0,0x03020200,0x07060505,0x0a090808,0x0b0b0b0a,0x0d0d0c0c,0x0e0e0e0d,0x010f0f0f}, + {0x03000000,0x09080706,0x0c0b0b0b,0x0e0e0d0d,0x0f0f0f0f,0x10100f0f,0x1010100f,0x010f1010}, + {0x08050100,0x0e0d0d0b,0x11101010,0x12121112,0x12121212,0x12121212,0x11111111,0x020f1011}, + {0x0d0a0500,0x13121210,0x15151515,0x16161616,0x15151616,0x14141415,0x12131313,0x020f1112}, + {0x120e0900,0x18171615,0x19191919,0x1919191a,0x17181919,0x16161617,0x13141415,0x020f1212}, + {0x16130d00,0x1c1c1b19,0x1d1d1d1e,0x1d1d1d1e,0x1a1b1c1c,0x1818191a,0x14151616,0x020f1213}, + {0x1b171000,0x21201f1e,0x21212122,0x20202021,0x1c1d1e1f,0x191a1a1c,0x15161718,0x020f1314}, + {0x1f1b1400,0x24242322,0x24252525,0x22232324,0x1e1f2121,0x1b1c1c1e,0x16171819,0x020f1315} +}; + +/* + * U chroma values from Luxsonor + */ + +static u32 chroma_U[][7] = { + {0x2,0x0,0x0,0x0,0x0,0x0,0x0}, + {0x3f3f3f02,0x3f3f3f3f,0x0,0x0,0x0,0x01010100,0x02020201}, + {0x3e3d3d02,0x3e3e3e3e,0x3f3f3f3f,0x0,0x01000000,0x03020201,0x04040403}, + {0x3c3c3b02,0x3d3d3d3c,0x3f3e3e3e,0x3f3f,0x02010000,0x04040302,0x07060605}, + {0x3b3a3a02,0x3c3c3c3b,0x3e3e3d3d,0x3f3f,0x02010000,0x06050403,0x09080807}, + {0x39393a02,0x3b3b3a3a,0x3e3d3d3c,0x3f3f3e,0x03020100,0x07060504,0x0c0b0a08}, + {0x38373a02,0x3a3a3938,0x3d3c3c3b,0x3f3e3e,0x04020100,0x09080605,0x0e0d0c0a}, + {0x36363a02,0x39393837,0x3d3c3b3a,0x3f3e3d,0x04030100,0x0a090706,0x100f0e0c}, + {0x35343a02,0x38383736,0x3c3b3a39,0x3f3e3d,0x05030100,0x0c0a0807,0x1011100e}, + {0x33323a02,0x37363534,0x3b3a3938,0x3f3e3d3c,0x06040200,0x0e0c0a08,0x10141210} +}; + +/* + * V chroma values from Luxsonor (remember mpeg is YUV) + */ +static u32 chroma_V[][7] = { + {0x023a0202,0x02020202,0x02020202,0x02020202,0x02020202,0x02020202,0x02020202}, + {0x380002,0x0,0x01010101,0x02020101,0x03030202,0x04040303,0x05050404}, + {0x3f3e3e07,0x3f3f,0x01000000,0x02020101,0x04040302,0x06060505,0x08080707}, + {0x3d3c3c0a,0x3f3e3e3d,0x3f,0x02020101,0x06050403,0x09080706,0x0c0b0a0a}, + {0x3b3a3a0a,0x3e3d3c3c,0x3f3e,0x02020100,0x07060503,0x0b0a0908,0x0f0e0d0c}, + {0x39383a0a,0x3d3c3b3a,0x3f3e3d,0x02020100,0x08070603,0x0e0c0b0a,0x1012100f}, + {0x373e3a0a,0x3b3a3938,0x3f3e3d3c,0x03020100,0x0a080604,0x100e0d0b,0x10151312}, + {0x363c3a0a,0x3a393837,0x3f3e3d3b,0x03020000,0x0b090704,0x12100f0d,0x10181614}, + {0x343a3a0a,0x39383635,0x3e3d3c3a,0x03020000,0x0c0a0804,0x1513100e,0x10181917}, + {0x323a3a0a,0x38363533,0x3e3c3b39,0x0302003f,0x0e0b0905,0x17151210,0x10181c1a} +}; + +static void ls220_video_clear_screen(struct ls220_dev *dev) +{ + ls220_dv_write(dev, 0x3D0, 0); /* Wipe OSD */ + if(dev->video_mode == VIDEO_NTSC || dev->video_mpeg1) + { + ls220_memsetl(dev, 0x200000, 0x0, 0x54600); + ls220_memsetl(dev, 0x254600, 0x80808080, 0x2a300); + ls220_memsetl(dev, 0x27e900, 0x0, 0x54600); + ls220_memsetl(dev, 0x2d2f00, 0x80808080, 0x2a300); + ls220_memsetl(dev, 0x2fd200, 0x0, 0x54600); + ls220_memsetl(dev, 0x351800, 0x80808080, 0x2a300); + } + else + { + ls220_memsetl(dev, 0x200000, 0x0, 0x65400); + ls220_memsetl(dev, 0x265400, 0x80808080, 0x32a00); + ls220_memsetl(dev, 0x297e00, 0x0, 0x65400); + ls220_memsetl(dev, 0x2fd200, 0x80808080, 0x32a00); + ls220_memsetl(dev, 0x32fc00, 0x0, 0x65400); + ls220_memsetl(dev, 0x395000, 0x80808080, 0x32a00); + } +} + +static void ls220_video_init(struct ls220_dev *dev) +{ + dev->video_hw_wrap = 0xF00000; +// ls220_video_set(dev); + ls220_video_clear_screen(dev); +// ls220_video_set_gamma(dev, 1); +} + +static void ls220_video_reset(struct ls220_dev *dev) +{ +// FILL ME IN +} + +static void ls220_video_set_letter(struct ls220_dev *dev, int onoff) +{ +} + +static void ls220_video_set_speed(struct ls220_dev *dev, int speed) +{ +} + +static void ls220_video_release(struct ls220_dev *dev) +{ + ls220_video_clear_screen(dev); + ls220_video_reset(dev); +} + +static void ls220_video_still(struct ls220_dev *dev) +{ + u32 r180; + + ls220_dv_write(dev, 0x200, 0x7b); + r180 = ls220_dv_read(dev, MPGVID_CONTROL) & 0x1E0; + ls220_dv_write(dev, MPGVID_CONTROL, r180|4); /* Start pointer */ + ls220_video_set_vpm(dev, dev->vga_mode); + ls220_video_set_letter(dev, dev->video_letter); + if(dev->type == LS240) + ls220_dv_write(dev, SYNC_INT_CTRL, 0x88004401); + else + ls220_dv_write(dev, SYNC_INT_CTRL, 0x224401); + ls220_dv_write(dev, 0x278, 0x4000); +} + +static void ls220_video_play(struct ls220_dev *dev, int speed) +{ + u32 reg; + + if(dev->type < LS240) /* might be wrong */ + { + if(/* ?? MENU ?> */ !dev->video_mpeg1) + { + if(ls220_dv_read(dev, 0x145fc) == 0x01) + ls220_dv_write(dev, 0x145fc, 0x02); + } + } + + reg = ls220_dv_read(dev, 0x200); + ls220_dv_write(dev, 0x200, reg |0x01); + + reg = ls220_dv_read(dev, MPGVID_CONTROL); + reg &= 0x1E0; + ls220_dv_write(dev, MPGVID_CONTROL, reg|6); + + ls220_video_set_vpm(dev, dev->vga_mode); + + if(!dev->video_zoomin) + { + ls220_video_set_letter(dev, dev->video_letter); + if(dev->type == LS240) + ls220_dv_write(dev, SYNC_INT_CTRL, 0x38000001); + else + ls220_dv_write(dev, SYNC_INT_CTRL, 0x0e8001); + } + else + { + if(dev->type == LS240) + ls220_dv_write(dev, SYNC_INT_CTRL, 0xc8000001); + else + ls220_dv_write(dev, SYNC_INT_CTRL, 0x328001); + } + ls220_video_set_speed(dev, dev->video_speed); +} + +static void ls220_video_stop(struct ls220_dev *dev) +{ + u32 reg; + + reg = ls220_dv_read(dev, SYNC_INT_CTRL); + + if(dev->type == LS240) + ls220_dv_write(dev, SYNC_INT_CTRL, reg&0xFFFFFFFE); + else + ls220_dv_write(dev, SYNC_INT_CTRL, reg&0xFFFFFE); + + reg = ls220_dv_read(dev, 0x200); + ls220_dv_write(dev, 0x200, reg & 0xFFFE); + + reg = ls220_dv_read(dev, MPGVID_CONTROL); + ls220_dv_write(dev, MPGVID_CONTROL, reg & 0x1E0); + + ls220_dv_write(dev, 0x194, VID_FIFO_OFF); + + dev->video_total = 0; + dev->video_remainder = 0; + dev->video_wptr = VID_FIFO_OFF; + dev->video_pts = 0; + + reg = ls220_dv_read(dev, MPGVID_CONTROL); + ls220_dv_write(dev, MPGVID_CONTROL, (reg&0x1E0) | 1); +} + +static void ls220_video_pause(struct ls220_dev *dev) +{ + u32 reg; + + if(dev->video_speed != 1000) + ls220_dv_write(dev, 0x19C, 0x02); + reg = ls220_dv_read(dev, 0x200); + ls220_dv_write(dev, 0x200, reg&0xFFFE); + ls220_dv_write(dev, SYNC_INT_CTRL, 0x28000); +} + +static unsigned long ls220_video_stc(struct ls220_dev *dev) +{ + return ls220_dv_read(dev, 0x218); +} + +static void ls220_video_fastforward(struct ls220_dev *dev) +{ + u32 reg; + + dev->video_speed = 2000; + if(dev->type == LS240) + { + ls220_dv_write(dev, 0x274, 0x28000001); + ls220_dv_write(dev, 0x268, (ls220_dv_read(dev, 0x268) & 0xA0)|1); + } + else + { + ls220_dv_write(dev, 0x274, 0xa8001); + ls220_dv_write(dev, 0x268, (ls220_dv_read(dev, 0x268) & 0x20)|1); + } +} + +/* + * Called when we reset and reload the DSP + */ +static void ls220_change_dsp(struct ls220_dev *dev, int audio, int vga) +{ + ls220_audio_init(dev, audio); + /* FIXME - reset video vars */ + ls220_video_reset(dev); + ls220_video_set_vpm(dev, vga); + ls220_load_firmware(dev, audio); + ls220_audio_set_info(dev); + + if(dev->eprom[EPROM_SPDIF_CH/*CHECK ME*/] && !(dev->eprom[EPROM_SPDIF_CH]&0x2)) + { + /* SPDIF */ + ls220_audio_set_spdif(dev, 1); + } + else + ls220_audio_set_spdif(dev, 0); + ls220_video_reset(dev); + ls220_video_init(dev); + ls220_audio_init(dev, 1); +} + +/* + * IRQ handling + */ + +static void ls220_intr(int irq, void *dev_id, struct pt_regs *unused) +{ + struct ls220_dev *dev = dev_id; + u32 r20, r14; + + r20 = ls220_dv_read(dev, 0x20); + if(r20 == 0) + return; + + r14 = ls220_dv_read(dev, 0x14); + if(!(r14 & 0x0104)) + return; + + ls220_dv_write(dev, 0x20, r20&0xfffffefb); + + if(r14 & 0x4) + { + ; /* User event */ + } + if(r14 & 0x100) + { + ; /* Video line reached */ + } + + /* Check - should we clear both bits or clear the r14 value ?? */ + ls220_dv_write(dev, 0x18, ls220_dv_read(dev, 0x18)|0x0104); + ls220_dv_write(dev, 0x20, r20 | 0x0104); +} + +/* + * Hardware setup + */ + +static int ls220_hw_init(struct ls220_dev *dev) +{ + /* Set up base registers */ + if(dev->type == LS240) + dev->dram_base = LS240_DRAM_BASE; + else + dev->dram_base = LS220_DRAM_BASE; + if(ls220_i2c_register(dev)) + return -ENODEV; + /* Initialise video side */ + if(ls220_i2c_probe(dev, 0xA0)) + ls220_load_eeprom(dev, 0xA0, 0, 16, dev->eprom); + ls220_video_reset(dev); + if((dev->tvencoder = ls220_detect_tvencoder(dev))<0) + { + i2c_bit_del_bus(&dev->i2c_adap); + return -ENODEV; + } + printk(KERN_INFO "luxsonor: Found attached %s TV encoder.\n", + lux_tv_names[dev->tvencoder]); + /* Initialise audio side */ + ls220_audio_init(dev, 1); + /* Now reset and bring up */ + ls220_reset(dev); + /* Set up the VMI */ + ls220_video_set_vpm(dev, 0/* For now.. */); + if(ls220_i2c_probe(dev, 0xA0)) + { + ls220_load_eeprom(dev, 0xA0, 0, 16, dev->eprom); + dev->has_eprom = 1; + if(dev->eprom[EPROM_BOARDTYPE] == 1) + { + ls220_send_gpio(dev, 6, 5); /* chrontel setup */ + ls220_send_gpio(dev, 3, 0xf); + } + } + else + { + dev->has_eprom = 0; + dev->eprom[EPROM_TVOUT] = 0; /* NTSC default */ + } + + ls220_load_firmware(dev, 1); /* Default Microcode */ + + ls220_audio_set_info(dev); + + if(dev->eprom[EPROM_SPDIF_CH/*CHECK ME*/] && !(dev->eprom[EPROM_SPDIF_CH]&0x2)) + { + /* SPDIF */ + ls220_audio_set_spdif(dev, 1); + } + else + ls220_audio_set_spdif(dev, 0); + /* Reset again */ + ls220_video_reset(dev); + ls220_audio_init(dev, 1); + ls220_configure_tvout(dev, 0); + return 0; +} + +static int ls220_init_one(struct pci_dev *pdev, const struct pci_device_id *ident) +{ + struct ls220_dev *dev = kmalloc(sizeof(struct ls220_dev), GFP_KERNEL); + if(dev == NULL) + return -ENOMEM; + memset(dev, 0, sizeof(*dev)); + dev->pdev = pdev; + dev->type = ident->driver_data; + + dev->i2c_rc = -1; + + if(pci_enable_device(pdev)<0) + { + kfree(pdev); + return -ENODEV; + } + + pci_set_drvdata(pdev, dev); + + if(request_irq(pdev->irq, ls220_intr, SA_SHIRQ, "ls220", dev)<0) + { + printk(KERN_ERR "ls220: unable to obtain interrupt.\n"); + pci_set_drvdata(pdev, NULL); + kfree(dev); + return -EBUSY; + } + dev->membase = ioremap(pdev->resource[0].start, pci_resource_len(pdev, 0)); + if(dev->membase == NULL) + { + printk(KERN_ERR "ls220: unable to map device.\n"); + free_irq(pdev->irq, dev); + pci_set_drvdata(pdev, NULL); + kfree(dev); + return -ENOMEM; + } + + pci_set_master(pdev); + + printk(KERN_INFO "luxsonor %s at 0x%lX for %ld bytes, IRQ %d.\n", + lux_names[dev->type], pdev->resource[0].start, + pci_resource_len(pdev, 0), pdev->irq); + + if(ls220_hw_init(dev) < 0) + { + free_irq(pdev->irq, dev); + if(dev->i2c_rc != -1) + i2c_bit_del_bus(&dev->i2c_adap); + pci_set_drvdata(pdev, NULL); + kfree(dev); + return -ENODEV; + } + if(dev->type == LS240) + { + ls240_zoomvideo_enable_tristate(dev); + ls240_audiopcm_enable_tristate(dev); + } + + + dev->next = ls_devs; + ls_devs = dev; + + return 0; +} + +static void __devexit ls220_remove_one(struct pci_dev *pdev) +{ + struct ls220_dev *dev = pci_get_drvdata(pdev); + free_irq(dev->pdev->irq, dev); + if(dev->i2c_rc != -1) + i2c_bit_del_bus(&dev->i2c_adap); + iounmap(dev->membase); + pci_disable_device(dev->pdev); +} + +/* + * This code and tables ensures we are notified if there is a + * luxsonor card, either at boot or in the event of a PCI hotplug + */ + +static struct pci_device_id luxsonor_table[] __devinitdata = { + { 0x1287, 0x001F, PCI_ANY_ID, PCI_ANY_ID, LS220C }, /* 220C */ + { 0x1287, 0x001E, PCI_ANY_ID, PCI_ANY_ID, LS220D }, /* 220D */ + { 0x1287, 0x0020, PCI_ANY_ID, PCI_ANY_ID, LS240 }, /* 240 */ + { 0, } +}; + +MODULE_DEVICE_TABLE(pci, luxsonor_table); + +static struct pci_driver luxsonor_driver = +{ + name: "ls220", + id_table: luxsonor_table, + probe: ls220_init_one, + remove: __devexit_p(ls220_remove_one), + /* No power management yet */ +}; + +static int __init luxsonor_init_module(void) +{ + return pci_module_init(&luxsonor_driver); +} + +static void __exit luxsonor_cleanup_module(void) +{ + pci_unregister_driver(&luxsonor_driver); +} + +module_init(luxsonor_init_module); +module_exit(luxsonor_cleanup_module); + +MODULE_AUTHOR("Alan Cox "); +MODULE_LICENSE("GPL"); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/AUTHORS linux.19pre5-ac1/drivers/media/video/margi/AUTHORS --- linux.19p5/drivers/media/video/margi/AUTHORS Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/AUTHORS Mon Feb 4 17:31:47 2002 @@ -0,0 +1,6 @@ +Christian Wolff scarabaeus@convergence.de +Marcus Metzler mocm@convergence.de + +Many thanks to +Shigehiro Nomura s.nomura@mba.nifty.ne.jp +for his ZV-patches for Libretto diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/CHANGES linux.19pre5-ac1/drivers/media/video/margi/CHANGES --- linux.19p5/drivers/media/video/margi/CHANGES Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/CHANGES Mon Feb 4 17:31:47 2002 @@ -0,0 +1,30 @@ +version 0.6 +- added ZV initialisation +- added diff for ZV support in pcmcia-cs version <= 3.1.25 +- added v4l device +- added dvb api devices +- tested it with powerbook g4 and pcmcia-cs-3.1.24 +- WARNING, on some computers using FFWD and slow motion may cause hangups + +version 0.5 +- should work with 2.4.0-test12 +- added driver to public CVS at linuxtv.org + http://linuxtv.org/cgi-bin/cvsweb.cgi/ +- added 32kHz audio support +- fixed problem with PAL MPEG1 playback +- fixed problem with playback of MPEGs with lots of PTS +- fixed switching audio channels + +version 0.4.3 +- it is now working with 2.4.0-test10 and later kernels. Use pcmcia-cs-3.1.22 + and later.(Don't use kernel pcmcia,it's not tested with that. ) +- added playfile to the testsuite + +version 0.4.2 +- changed major device number to 200 until we get a new one +- changed some buffer settings for DVD playback +- added some programming examples in testsuit directory +- some other minor improvements + +version 0.4.1 +- corrected makefile error diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/COPYING linux.19pre5-ac1/drivers/media/video/margi/COPYING --- linux.19p5/drivers/media/video/margi/COPYING Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/COPYING Mon Feb 4 17:31:47 2002 @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the 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. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/Makefile linux.19pre5-ac1/drivers/media/video/margi/Makefile --- linux.19p5/drivers/media/video/margi/Makefile Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/Makefile Mon Feb 4 23:47:42 2002 @@ -0,0 +1,33 @@ +# +# Makefile for the Margi DVD-to-Go driver +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definitions are now in the main makefile... + +O_TARGET := margilib.o + +CFLAGS_margi_cs.o = -DUSE_OSD -DNOINT -DDVB -DUSE_ZV + +obj-y := +obj-m := +obj-n := +obj- := + +list-multi := margi_cs.o + +margi_cs-objs := margi.o cardbase.o i2c.o dram.o osd.o audio.o \ + video.o streams.o decoder.o spu.o crc.o ringbuffy.o \ + dvb_filter.o cvdv.o + +export-objs := dvbdev.o + +obj-m += margi_cs.o dvbdev.o dmxdev.o dvb_demux.o + +include $(TOPDIR)/Rules.make + +margi_cs.o: $(margi_cs-objs) + $(LD) $(LD_RFLAG) -r -o $@ $(margi_cs-objs) + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/README linux.19pre5-ac1/drivers/media/video/margi/README --- linux.19p5/drivers/media/video/margi/README Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/README Mon Feb 4 17:31:47 2002 @@ -0,0 +1,97 @@ +This is the driver for the Margi/Billionton MPEG decoder PC-Card. +It is still in a beta state and may cause problems with your system. + +INSTALLING +---------- +0) From now on you will need a 2.4.x kernel to make everything work + +1) Install David Hinds` PCMCIA Card Services package. The current + version is at http://pcmcia.sourceforge.org/. + This driver is known to work under versions 3.1.25 and later. Earlier + version may work too. + + % tar zxvf pcmcia-cs-3.1.25.tar.gz + +2) Enter the pcmcia directory and unpack the margi driver. + + % cd pcmcia-cs-3.1.25 + % tar zxvf margi_cs-0.5.tar.gz + +3) In the pcmcia main directory: + + % make config + % make all + # make install + + +The files for the margi are in margi2. (The name has historical reasons.) + +ATTENTION You now need video4linux support in the kernel. +You can now use /dev/video for playback. + + +Using the driver +---------------- +The driver registers a character device with major number 162. You can +cat an MPEG2 program stream into that device. +If the device doesn`t exist (usually it`s /dev/raw) just + % mknod -m 0666 /dev/margi char 200 0 +Than you + % cat nicempg2.vob > /dev/margi +or + % cat nicempg.mpg > /dev/margi + +At the moment we do not recognize the audio format of the MPEG1/2, so +MPEG audio is hard-coded as default. You can change that in cvdv.c in the +Prepare() routine, or by using the ioctl Decoder_Set_Audiotype, e.g.: + +#include "cvdvext.h" + +main() +{ + struct decodercmd decmd; + + decmd.param1=audio_AC3; + decmd.cmd=Decoder_Set_Audiotype; + DecoderCommand(device,decmd); +... + +} + +In the directory testsuite are some example programs for using the driver. +I hope they are more or less self explanatory. Just use the --help option. + + +If you want the latest drivers apart from the release versions, use +the public CVS at linuxtv.org : http://linuxtv.org/cgi-bin/cvsweb.cgi/ + + +ZV-support +---------- + +You will faind patches for ZV support in the zv-diffs directory. The +ones with the version number for pcmcia-cs ar for the respective +versions of this package. The rest is for graphics chips or sound +chips, like the patches for the Neomagic graphics chip and YMF sound +chip submitted by Shigehiro Nomura. + +There now three module parameters that are all set to 1 (=on) but can +be set to off in /etc/pcmcia/config.opts +They are : "svhs" for switching the svhs output DAC on or off (0 or 1). + "composite" for switching the composite output DAC on or off. + "use_zv" for enabling zv output if you compiled with the + -DUSE_ZV setting in margi_cs.mk. + +E.g. +module "margi_cs" opts "use_zv=0" +turns off zv output. +or +module "margi_cs" opts "composite=0 svhs=0" +turns off the external outputs. + +WHO DO I BLAME/FLAME? +=== == = ============ + +Send comments, patches, free pizza to . + + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/README.CVS linux.19pre5-ac1/drivers/media/video/margi/README.CVS --- linux.19p5/drivers/media/video/margi/README.CVS Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/README.CVS Mon Feb 4 17:31:47 2002 @@ -0,0 +1,13 @@ +1) unpack pcmcia_cs distribution + % tar zxvf pcmcia-cs-3.1.14.tar.gz + +2) cd pcmcia-cs-3.1.14 + % cvs co margi2 + +3) cp margi2/margi_cs.mk.MAIN margi_cs.mk + +4) For ZV support in pcmcia-cs use zv.diff. Remember, this is just the + first step to get to watching the output on your notebook's screen. + If you have pcmcia-cs versio >= 3.1.25 you need to use zv.diff.3.1.25. + The patches currently only work for the Rigoch 5c478 controller. + Anybody with information about ZV regarding graphic chips, please tell me. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/audio.c linux.19pre5-ac1/drivers/media/video/margi/audio.c --- linux.19p5/drivers/media/video/margi/audio.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/audio.c Mon Feb 4 22:21:05 2002 @@ -0,0 +1,248 @@ +/* + audio.c + + Copyright (C) Christian Wolff for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the 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. +*/ + +// +// Audio Decoder +// +#define __NO_VERSION__ + +#include "audio.h" +#include "l64021.h" + +// mode=0 pause +// mode=1 normal speed play +// mode=2 fast play, 16/15 +// mode=3 slow play, 16/17 + +void AudioSetPlayMode(struct cvdv_cards *card, int mode) +{ + DecoderMaskByte(card, 0x163, 0x60, (mode & 0x03) << 5); + // audio decoder play mode + DecoderMaskByte(card, 0x164, 0x60, (((mode) ? 1 : 0) & 0x03) << 5); + // S/PDIF formatter play mode +} + +void AudioStartDecode(struct cvdv_cards *card) +{ + DecoderSetByte(card, 0x163, 0x80); +} + +// Stop Decode flushes the Audio ES channel buffer +void AudioStopDecode(struct cvdv_cards *card) +{ + DecoderDelByte(card, 0x163, 0x80); +} + +void AudioStartFormat(struct cvdv_cards *card) +{ + DecoderSetByte(card, 0x164, 0x80); +} + +void AudioStopFormat(struct cvdv_cards *card) +{ + DecoderDelByte(card, 0x164, 0x80); +} + +// Audio source: S/PDIF out: +// mode 0: MPEG IEC958 +// mode 1: AC3 IEC958 +// mode 2: MPEG MPEG +// mode 3: AC3 AC3 +// mode 4: PCM IEC958 (max. 48kHz) +// mode 5: PCM 96->48kHz IEC958 (48kHz) +// mode 6: CD Bypass S/PDIF Bypass +// mode 7: PCM FIFO PCM FIFO +void AudioSetMode(struct cvdv_cards *card, int mode) +{ + mode &= 0x07; + AudioSetPlayMode(card, MAUDIO_PAUSE); + AudioStopFormat(card); + DecoderMaskByte(card, 0x165, 0xE0, mode << 5); + if ((mode == 2) || (mode == 3)) + AudioStartFormat(card); +} + + +// volume: 0..255 +void AudioSetVolume(struct cvdv_cards *card, int volume) +{ + DecoderWriteByte(card, 0x16A, volume); // Set PCM scale to volume +} + +// mute=1: mute audio +void AudioMute(struct cvdv_cards *card, int mute) +{ + DecoderMaskByte(card, 0x166, 0x40, (mute ? 0x40 : 0x00)); + // mute PCM + DecoderMaskByte(card, 0x16E, 0x10, (mute ? 0x10 : 0x00)); + // mute S/PDIF +} + +// mode=0: stereo +// mode=1: surround +void AudioAC3Mode(struct cvdv_cards *card, int mode) +{ + DecoderMaskByte(card, 0x166, 0x10, (mode ? 0x10 : 0x00)); +} + +// mode=0: custom analog +// mode=1: custom digital +// mode=2: line-out (default) +// mode=3: RF mode +void AudioAC3Compression(struct cvdv_cards *card, int mode) +{ + DecoderMaskByte(card, 0x166, 0x03, mode & 0x03); +} + +// mode=0: AC3 +// mode=1: ES1 +void AudioAC3Formatter(struct cvdv_cards *card, int mode) +{ + DecoderMaskByte(card, 0x166, 0x03, mode & 0x03); +} + +// mode=0: Stereo +// mode=1: Right channel only +// mode=2: Left channel only +// mode=3: Mono Mix +void AudioDualMono(struct cvdv_cards *card, int mode) +{ + DecoderMaskByte(card, 0x166, 0x0C, (mode & 0x03) << 2); +} + +// swap=0: L->L, R->R +// swap=1: L->R, R->L +void AudioSwap(struct cvdv_cards *card, int swap) +{ + DecoderMaskByte(card, 0x16B, 0x04, (swap ? 0x00 : 0x04)); +} + +// select=0: use clock from ACLK_441 pin -> ACLK=44.1kHz*N +// select=1: use clock from ACLK_48 pin -> ACLK=48.0kHz*N +// select=2: use clock from ACLK_32 pin -> ACLK=32.0kHz*N +// Since the programmable sample rate generator of the PCM1723 is connected to +// all 3 of them, it doen't matter wich one you choose. +// divider=0: ACLK=768*Fs / S/PDIF-BCLK=ACLK/6 / DAC-BCLK=ACLK/12 / DAC-A_ACLK=ACLK/3 +// divider=1: ACLK=768*Fs / S/PDIF-BCLK=ACLK/6 / DAC-BCLK=ACLK/12 / DAC-A_ACLK=ACLK/2 +// divider=2: ACLK=512*Fs / S/PDIF-BCLK=ACLK/4 / DAC-BCLK=ACLK/8 / DAC-A_ACLK=ACLK/2 +// divider=3: ACLK=384*Fs / S/PDIF-BCLK=ACLK/3 / DAC-BCLK=ACLK/6 / DAC-A_ACLK=ACLK/1 +// divider=4: ACLK=256*Fs / S/PDIF-BCLK=ACLK/2 / DAC-BCLK=ACLK/4 / DAC-A_ACLK=ACLK/1 +// divider=5: ACLK=768*48kHz / S/PDIF-BCLK=ACLK/6 / DAC-BCLK=ACLK/6 / DAC-A_ACLK=ACLK/1 +// divider=6: ACLK=512*48kHz / S/PDIF-BCLK=ACLK/4 / DAC-BCLK=ACLK/4 / DAC-A_ACLK=ACLK/1 +// divider=C: ACLK=768*48kHz / S/PDIF-BCLK=ACLK/9 / DAC-BCLK=ACLK/18 / DAC-A_ACLK=ACLK/3 +// divider=D: ACLK=512*48kHz / S/PDIF-BCLK=ACLK/6 / DAC-BCLK=ACLK/12 / DAC-A_ACLK=ACLK/3 +// divider=E: ACLK=512*48kHz / S/PDIF-BCLK=ACLK/6 / DAC-BCLK=ACLK/12 / DAC-A_ACLK=ACLK/2 +// divider=F: ACLK=256*48kHz / S/PDIF-BCLK=ACLK/3 / DAC-BCLK=ACLK/6 / DAC-A_ACLK=ACLK/1 +// Fs is the audio sample frequency +// For the normal cases, (32, 44.1, and 48 kHz) select divider 0 through 4 and set +// sample frequency in PCM1723 accordingly +// For 96 kHz, select divider 5 or 6, and set PCM1723 to 48kHz*768 or *512 resp. +// Divider C through F are for 32 kHz sample frequency with a 48kHz*x ACLK +void AudioSetACLK(struct cvdv_cards *card, int select, int divider) +{ + DecoderMaskByte(card, 0x16B, 0x03, select & 0x03); + DecoderMaskByte(card, 0x16C, 0x0F, divider & 0x0F); +} + +int AudioOpen(struct cvdv_cards *card) +{ + // initialize the audio card + MDEBUG(1, ": -- AudioOpen\n"); + write_indexed_register(card, IIO_OSC_AUD, 0x10); + return 0; +} + +int AudioClose(struct cvdv_cards *card) +{ + MDEBUG(1, ": -- AudioClose\n"); + card->AudioInitialized = 0; + return 0; +} + +// audiorate: 16, 32, 64, 22(.05), 44(.1), 88(.2), 24, 48, 96 kHz +// surround=0: Stereo +// surround=1: Surround +int AudioInit(struct cvdv_cards *card, int audiorate, int surround) +{ + //if ((audiorate!=44) && (audiorate!=32)) audiorate=48; + MDEBUG(1, ": -- AudioInit %d\n", audiorate); + + DACSetFrequency(card, audiorate, 256); // put Fs*256 on ACLK inputs + + if (audiorate == 96) + AudioSetACLK(card, 1, 0x06); // 512*48kHz at ACLK + else + AudioSetACLK(card, 1, 0x04); // 256 times Fs at ACLK + + DecoderDelByte(card, 0x166, 80); // no mute on error + DecoderWriteByte(card, 0x168, 0xFF); // dynscalehigh + DecoderWriteByte(card, 0x169, 0xFF); // dynscalelow + DecoderWriteByte(card, 0x16A, 0xFF); // PCM scale + + // IEC958 Setup + DecoderDelByte(card, 0x16D, 0x20); // Overwrite Emphasis off + DecoderSetByte(card, 0x16D, 0x40); // Copyright Override + DecoderDelByte(card, 0x16D, 0x80); // Copyright Bit off + DecoderDelByte(card, 0x16E, 0x01); // Overwrite Category off + DecoderDelByte(card, 0x16E, 0x08); // Overwrite Quatization off + DecoderSetByte(card, 0x170, 0x08); // Musicam Stream Debug + + AudioAC3Mode(card, (surround ? 1 : 0)); + AudioAC3Compression(card, 2); + AudioAC3Formatter(card, 0); + + AudioDualMono(card, 0); + AudioSwap(card, 0); + + AudioMute(card, 0); +// AudioSetPlayMode(card,MAUDIO_PLAY); + + card->AudioInitialized = 1; + return 0; +} + + +// returns size of the Video ES Buffer in bytes or 0=error +u32 DecoderGetAudioESSize(struct cvdv_cards * card) +{ + if (!card->ChannelBuffersAllocated) + return 0; // buffer not initialised + return (u32) ((DecoderReadWord(card, 0x04E) & 0x3FFF) - + (DecoderReadWord(card, 0x04C) & 0x3FFF)) * 256; // bytes +} + +// returns level of fullness in bytes +u32 DecoderGetAudioESLevel(struct cvdv_cards * card) +{ + u32 items; + items = DecoderReadByte(card, 0x089); + items |= ((DecoderReadWord(card, 0x08A) & 0x07FF) << 8); + items *= 8; // 64 bit per item + return items; +} + +int DecoderKaraoke(struct cvdv_cards *card, int vocal1, int vocal2, + int melody) +{ + DecoderMaskByte(card, 0x18C, 0x40, ((vocal1) ? 0x40 : 0x00)); + DecoderMaskByte(card, 0x18C, 0x80, ((vocal2) ? 0x80 : 0x00)); + DecoderMaskByte(card, 0x18C, 0x20, ((melody) ? 0x20 : 0x00)); + return 0; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/audio.h linux.19pre5-ac1/drivers/media/video/margi/audio.h --- linux.19p5/drivers/media/video/margi/audio.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/audio.h Thu Apr 4 15:55:29 2002 @@ -0,0 +1,136 @@ +/* + audio.h + + Copyright (C) Christian Wolff for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef CVDV_AUDIO_H +#define CVDV_AUDIO_H + + // + // Audio Decoder +// +#define __NO_VERSION__ + +#include "cardbase.h" + +#define MAUDIO_PAUSE 0 +#define MAUDIO_PLAY 1 +#define MAUDIO_FAST 2 +#define MAUDIO_SLOW 3 + +// mode=0 pause +// mode=1 normal speed play +// mode=2 fast play, 16/15 +// mode=3 slow play, 16/17 +void AudioSetPlayMode(struct cvdv_cards *card, int mode); + +void AudioStartDecode(struct cvdv_cards *card); + +// Stop Decode flushes the Audio ES channel buffer +void AudioStopDecode(struct cvdv_cards *card); + +void AudioStartFormat(struct cvdv_cards *card); + +void AudioStopFormat(struct cvdv_cards *card); + +// Audio source: S/PDIF out: +// mode 0: MPEG IEC958 +// mode 1: AC3 IEC958 +// mode 2: MPEG MPEG +// mode 3: AC3 AC3 +// mode 4: PCM IEC958 (max. 48kHz) +// mode 5: PCM 96->48kHz IEC958 (48kHz) +// mode 6: CD Bypass S/PDIF Bypass +// mode 7: PCM FIFO PCM FIFO +void AudioSetMode(struct cvdv_cards *card, int mode); + + +// volume: 0..255 +void AudioSetVolume(struct cvdv_cards *card, int volume); + +// mute=1: mute audio +void AudioMute(struct cvdv_cards *card, int mute); + +// mode=0: stereo +// mode=1: surround +void AudioAC3Mode(struct cvdv_cards *card, int mode); + +// mode=0: custom analog +// mode=1: custom digital +// mode=2: line-out (default) +// mode=3: RF mode +void AudioAC3Compression(struct cvdv_cards *card, int mode); + +// mode=0: AC3 +// mode=1: ES1 +void AudioAC3Formatter(struct cvdv_cards *card, int mode); + +// mode=0: Stereo +// mode=1: Right channel only +// mode=2: Left channel only +// mode=3: Mono Mix +void AudioDualMono(struct cvdv_cards *card, int mode); + +// swap=0: L->L, R->R +// swap=1: L->R, R->L +void AudioSwap(struct cvdv_cards *card, int swap); + +// select=0: use clock from ACLK_441 pin -> ACLK=44.1kHz*N +// select=1: use clock from ACLK_48 pin -> ACLK=48.0kHz*N +// select=2: use clock from ACLK_32 pin -> ACLK=32.0kHz*N +// Since the programmable sample rate generator of the PCM1723 is connected to +// all 3 of them, it doen't matter wich one you choose. +// divider=0: ACLK=768*Fs / S/PDIF-BCLK=ACLK/6 / DAC-BCLK=ACLK/12 / DAC-A_ACLK=ACLK/3 +// divider=1: ACLK=768*Fs / S/PDIF-BCLK=ACLK/6 / DAC-BCLK=ACLK/12 / DAC-A_ACLK=ACLK/2 +// divider=2: ACLK=512*Fs / S/PDIF-BCLK=ACLK/4 / DAC-BCLK=ACLK/8 / DAC-A_ACLK=ACLK/2 +// divider=3: ACLK=384*Fs / S/PDIF-BCLK=ACLK/3 / DAC-BCLK=ACLK/6 / DAC-A_ACLK=ACLK/1 +// divider=4: ACLK=256*Fs / S/PDIF-BCLK=ACLK/2 / DAC-BCLK=ACLK/4 / DAC-A_ACLK=ACLK/1 +// divider=5: ACLK=768*48kHz / S/PDIF-BCLK=ACLK/6 / DAC-BCLK=ACLK/6 / DAC-A_ACLK=ACLK/1 +// divider=6: ACLK=512*48kHz / S/PDIF-BCLK=ACLK/4 / DAC-BCLK=ACLK/4 / DAC-A_ACLK=ACLK/1 +// divider=C: ACLK=768*48kHz / S/PDIF-BCLK=ACLK/9 / DAC-BCLK=ACLK/18 / DAC-A_ACLK=ACLK/3 +// divider=D: ACLK=512*48kHz / S/PDIF-BCLK=ACLK/6 / DAC-BCLK=ACLK/12 / DAC-A_ACLK=ACLK/3 +// divider=E: ACLK=512*48kHz / S/PDIF-BCLK=ACLK/6 / DAC-BCLK=ACLK/12 / DAC-A_ACLK=ACLK/2 +// divider=F: ACLK=256*48kHz / S/PDIF-BCLK=ACLK/3 / DAC-BCLK=ACLK/6 / DAC-A_ACLK=ACLK/1 +// Fs is the audio sample frequency +// For the normal cases, (32, 44.1, and 48 kHz) select divider 0 through 4 and set +// sample frequency in PCM1723 accordingly +// For 96 kHz, select divider 5 or 6, and set PCM1723 to 48kHz*768 or *512 resp. +// Divider C through F are for 32 kHz sample frequency with a 48kHz*x ACLK +void AudioSetACLK(struct cvdv_cards *card, int select, int divider); + +int AudioOpen(struct cvdv_cards *card); + +int AudioClose(struct cvdv_cards *card); + +// audiorate: 16, 32, 64, 22(.05), 44(.1), 88(.2), 24, 48, 96 kHz +// surround=0: Stereo +// surround=1: Surround +int AudioInit(struct cvdv_cards *card, int audiorate, int surround); + + +// returns size of the Video ES Buffer in bytes or 0=error +u32 DecoderGetAudioESSize(struct cvdv_cards *card); + +// returns level of fullness in bytes +u32 DecoderGetAudioESLevel(struct cvdv_cards *card); + +int DecoderKaraoke(struct cvdv_cards *card, int vocal1, int vocal2, + int melody); + +#endif /* CVDV_AUDIO_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/cardbase.c linux.19pre5-ac1/drivers/media/video/margi/cardbase.c --- linux.19p5/drivers/media/video/margi/cardbase.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/cardbase.c Mon Feb 4 22:21:05 2002 @@ -0,0 +1,234 @@ +/* + cardbase.c + + Copyright (C) Christian Wolff for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define __NO_VERSION__ + +#include "cardbase.h" + +// List of pci cards in the system +struct cvdv_cards *first_card = NULL; +struct cvdv_cards *minorlist[MAXDEV]; + +u8 FlushPacket[32] = { + 0x00, 0x00, 0x01, 0xE0, // video stream start code + 0x00, 0x1a, // 26 more bytes + 0x81, 0xC1, // flags: copy=1, PTS_DTS=11, PES_extension=1 + 0x0D, // 13 more header bytes + 0x31, 0x00, 0x03, 0x5F, 0xEB, // PTS + 0x11, 0x00, 0x03, 0x48, 0x75, // DTS + 0x1E, // flags: P-STD_buffer=1, + 0x60, 0xE8, // P-STD_buffer_scale=1, P-STD_buffer_size=232(kByte) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +void DecoderStreamReset(struct cvdv_cards *card) +{ + card->stream.valid = 0; + card->stream.sh.valid = 0; + card->stream.se.valid = 0; + card->stream.gop.valid = 0; + card->stream.MPEG2 = 0; + card->stream.audio.valid = 0; + memset(&card->stream.audio.mpeg,0,sizeof(struct AudioMPEG)); + memset(&card->stream.audio.ac3,0,sizeof(struct AudioAC3)); + memset(&card->stream.audio.pcm,0,sizeof(struct AudioPCM)); + card->AuxFifoExt = 0; + card->AuxFifoLayer = -1; +} +void PTSStoreInit(PTSStorage * store, int size) +{ + int i; + if (size > MAX_PTS) + size = MAX_PTS; + store->size = size; + store->begin = 0; + store->end = 0; + store->LastAddr = 0; + for (i = 0; i < store->size; i++) { + store->AddrB[i] = 0; + store->AddrE[i] = 0; + store->PTS[i] = 0; + } +} + +void DecoderCSSReset(struct cvdv_cards *card) +{ + card->css.status = 0; + card->css.ChallengeReady = 0; + card->css.ResponseReady = 0; + card->css.DiskKey = 0; + card->css.TitleKey = 0; + card->css.Error = 0; + card->css.TitleKeyDiff = 0; + card->LastAddr = 0; // last used address in PES buffer + card->VPTS = 0; + card->oldVPTS = 0; + card->VSCR = 0; + card->APTS = 0; + card->oldAPTS = 0; + card->ASCR = 0; + card->SyncTime = 0; + card->paused = 0; // pause status + card->lastvattr = 0; // last set dvd video attribute + card->lastaattr = 0; // last set dvd audio attribute + card->nonblock = 0; +} + +void DecoderSetupReset(struct cvdv_cards *card) +{ + card->DecoderOpen = 0; + card->closing = 0; + card->channelrun = 0; + card->setup.streamtype = stream_none; + card->setup.audioselect = audio_none; + card->setup.videoID = 0; + card->setup.audioID = 0; + card->setup.audioIDext = -1; + card->setup.SPDIFmode = 0; + card->startingV = 0; + card->startingA = 0; + card->startingDVDV = 0; + card->startingDVDA = 0; + card->videodelay = 0; + card->videodelay_last = 0; + card->videoslow_last = 0; + card->videoslow = 0; + card->videoffwd = 0; + card->videoffwd_last = 0; + card->videoskip = 0; + card->videoskip_last = 0; + card->videosync = 0; + card->paused = 0; + PTSStoreInit(&card->VideoPTSStore, MAX_PTS); + PTSStoreInit(&card->AudioPTSStore, MAX_PTS); +#ifdef DVB + card->audiostate.AVSyncState=true; +#endif +} + + + +void card_init(struct cvdv_cards *card, unsigned int minor) +{ + card->DRAMFirstBlock = NULL; + card->DRAMSize = 0; + card->OSD.open = 0; + card->DMAABusy = 0; + card->DMABBusy = 0; + card->IntInstalled = 0; + card->ChannelBuffersAllocated = 0; + card->VideoES = BLANK; + card->AudioES = BLANK; + card->VideoPES = BLANK; + card->DataDump = BLANK; + card->AudioPES = BLANK; + card->NaviBank = BLANK; + card->FrameBuffersAllocated = 0; + card->FrameStoreLuma1 = BLANK; + card->FrameStoreChroma1 = BLANK; + card->FrameStoreLuma2 = BLANK; + card->FrameStoreChroma2 = BLANK; + card->FrameStoreLumaB = BLANK; + card->FrameStoreChromaB = BLANK; + card->DecoderOpen = 0; + card->AuxFifoHead = 0; + card->AuxFifoTail = 0; + card->DataFifoHead = 0; + card->DataFifoTail = 0; + card->FifoALast = -1; + card->FifoBLast = -1; + //reset_stream(card); + DecoderStreamReset(card); + DecoderSetupReset(card); + card->AudioInitialized = 0; + card->AudioOldMode = -1; + card->closing = 0; + card->startingV = 0; + card->startingA = 0; + card->startingDVDV = 0; + card->startingDVDA = 0; + card->channelrun = 0; + card->fields = 0; + DecoderCSSReset(card); + card->NaviPackAddress = 0; + init_waitqueue_head(&card->wqA); + init_waitqueue_head(&card->wqB); + card->navihead = 0; // write pointer for navi ring buffer + card->navitail = 0; // read pointer for navi ring buffer + card->intdecodestatus = 0; // last status of decode interrupt + card->showvideo = 0; // show video instead black as soon as picture slice is there + card->videodelay = 0; // slow counter + card->videodelay_last = 0; // slow counter + card->videoffwd = 0; // fast playback + card->videoffwd_last = 0; // fast playback + card->videoskip = 0; // fast counter + card->videoskip_last = 0; // fast counter + card->videoslow_last = 0; + card->videoslow = 0; + card->videosync = 0; // do audio/video sync basen on PTS? + PTSStoreInit(&card->VideoPTSStore, MAX_PTS); + PTSStoreInit(&card->AudioPTSStore, MAX_PTS); + card->LastAddr = 0; // last used address in PES buffer + card->VPTS = 0; + card->oldVPTS = 0; + card->VSCR = 0; + card->APTS = 0; + card->oldAPTS = 0; + card->ASCR = 0; + card->SyncTime = 0; + card->paused = 0; // pause status + card->lastvattr = 0; // last set dvd video attribute + card->lastaattr = 0; // last set dvd audio attribute + card->reg08F = 0; // mirror of decoder registers + card->reg090 = 0; + card->reg091 = 0; + card->reg092 = 0; + card->reg093 = 0; + card->highlight_valid = 0; // SPU highlight info available for next BAV int + card->do_flush = 0; + + card->open = 0; + + card->VideoESSize = 0; + card->AudioESSize = 0; + card->VideoPESSize = 0; + card->DataDumpSize = 0; + card->AudioPESSize = 0; + card->NaviBankSize = 0; + card->currentType = -1; + card->rbufA.buffy = NULL; + card->rbufB.buffy = NULL; + card->use_ringA = 0; + card->use_ringB = 0; + card->minor = minor; + card->hasZV = 0; +#ifdef NOINT + init_timer(&card->timer); + spin_lock_init(&card->timelock); +#endif +#ifdef DVB + card->dvb_registered = 0; + card->audiostate.AVSyncState=true; + card->nonblock = 0; +#endif + card->svhs = 0; + card->composite = 0; +} + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/cardbase.h linux.19pre5-ac1/drivers/media/video/margi/cardbase.h --- linux.19p5/drivers/media/video/margi/cardbase.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/cardbase.h Thu Apr 4 15:55:29 2002 @@ -0,0 +1,454 @@ +/* + cardbase.h + + Copyright (C) Christian Wolff for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef CARDBASE_H +#define CARDBASE_H + +#define __DVB_PACK__ +#define USE_OSD +#define NOINT +#define DVB +#define USE_ZV + +#ifdef PCMCIA_DEBUG +static int pc_debug = PCMCIA_DEBUG; +MODULE_PARM(pc_debug, "i"); +#define MARGI_DEBUG (pc_debug) +#else +#define MARGI_DEBUG 2 +#endif + +// all the internal structs + +#include + +#include "ringbuffy.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef DVB +#include "dvbdev.h" +#ifdef __DVB_PACK__ +#include "ost/video.h" +#include "ost/audio.h" +#include "ost/demux.h" +#include "ost/dmx.h" +#include "ost/sec.h" +#include "ost/frontend.h" +#include "ost/ca.h" +#include "ost/osd.h" +#else +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +#include "dvb_demux.h" +#include "dmxdev.h" +#include "dvb_filter.h" +#endif +// List of pci cards in the system + +#include "cvdvtypes.h" + +#define DVERSION "0.6.0" +#define SHORTDEVNAME "ConvDVD" +#define MEDDEVNAME "convergence DVD" +#define LONGDEVNAME "convergence DVD Video Decoder" +#define LOGNAME "convdvd " +#define NBBUF 8 + + +#ifdef MARGI_DEBUG +#define MDEBUG(n, args...) if (MARGI_DEBUG>(n)) printk(KERN_ERR LOGNAME args) +#else +#define MDEBUG(n, args...) +#endif + + +#define VID_PAN_SCAN_PREF 0x01 /* Pan and Scan Display preferred */ +#define VID_VERT_COMP_PREF 0x02 /* Vertical compression display preferred */ +#define VID_VC_AND_PS_PREF 0x03 /* PanScan and vertical Compression if allowed */ +#define VID_CENTRE_CUT_PREF 0x05 /* PanScan with zero vector */ + + +// Character device definitions +// char dev name +#define CVDV_PROCNAME "msc" // Media Stream Consumer +// got to get another number +#define CVDV_MAJOR 200 // 0=dynamic assignment + +// Author definitions +#define NAME "Christian Wolff" +#define EMAIL "scarabaeus@convergence.de" +#define COMPANY "convergence integrated media GmbH" +#define AUTHOR NAME " <" EMAIL "> " COMPANY + +#define MAXDEV 1 // maximum number of cards, distance between minor devices + +#define MINORNUM (256/MAXDEV) // number of minor devices + +#define NAVISIZE 1024 // size of one navi block +#define NAVIBUFFERSIZE NAVISIZE*10 // size of ten navi blocks + +#define BLANK 0xFFFFFFFF + +#define FIFO_MASK 1023 + +#define CCIR601Lines(system) (((system==NTSC) || (system==NTSC60) || (system==PALM) || (system==PALM60) || (system==PAL60))?525:625) + +// default video mode +#define VIDEO_MODE PAL +//#define VIDEO_MODE NTSC + +struct DRAMBlock { + u32 start; // start address of the block; (21 bit word address, 64 bit aligned) + u32 length; // length of the block (in 16 bit words) + struct DRAMBlock *next; // chain link +}; + +struct CSS { + u8 status; // interrupt status from Register 0x0B0 + int ChallengeReady; // 1 if challenge data valid + u8 challenge[10]; // challenge data + int ResponseReady; // 1 if response data valid + u8 response[5]; // response data + int DiskKey; // 1 if disk key extraction complete + int TitleKey; // 1 if title key decryption complete + int Error; // 1 if authentication or disc key extraction + int TitleKeyDiff; // 1 if title key different from previous +}; + +struct GOPHeader { + int valid; // 1: struct contains valid data + int timecode; + int closedgop; + int brokenlink; +}; + +struct SequenceHeader { + int valid; // 1: struct contains valid data + int hsize; + int vsize; + int aspectratio; + int frameratecode; + int bitrate; + int vbvbuffersize; + int constrained; +}; + +struct SequenceExtension { + int valid; // 1: struct contains valid data + int profilelevel; + int progressive; + int chroma; + int hsizeext; + int vsizeext; + int bitrateext; + int vbvbuffersizeext; + int lowdelay; + int frextn; + int frextd; +}; + +struct AudioMPEG { + int present; // true: MPEG audio stream present + int MPEG2; // 0:MPEG1 Audio + int layer; // 1..3 (I..III) + int bitrate; // 0=free, 32-448 kbps + int samplefreq; // 32,44,48 (44 eq. 44.1) + int mode; // 0=stereo 1=joint-stereo 2=dualchannel 3=single channel (just right channel) + int modeext; // Layer I&II: intensity stereo subbands Layer III: bit 0=intensity stereo, bit 1=ms-stereo + int copyright; // true=copyrighted material + int original; // 0=copy true=original + int emphasis; // 0=no emph. 1=50/15usec 3=CCITT J.17 +}; + +struct AudioAC3 { + int present; // 1: AC3 audio stream present + int acmod; // parameters from the AC3 documentation + int bsmod; + int dialnorm; + int dialnorm2; + int surmixlev; + int mixlevel; + int cmixlev; + int mixlevel2; + int fscod; + int lfeon; + int bsid; + int dsurmod; + int frmsizecod; + int langcod; + int langcod2; + int timecod; + int roomtyp; + int timecod2; + int roomtyp2; +}; + +struct AudioPCM { + int present; // 1: PCM audio stream present + int audio_frm_num; + int num_of_audio_ch; + int Fs; + int quantization; + int emphasis; + int mute_bit; +}; + +struct AudioParam { + int valid; + struct AudioMPEG mpeg; + struct AudioAC3 ac3; + struct AudioPCM pcm; +}; + +struct OSDPicture { // all u32 pointers are 21 bit word addresses + int open; // are the buffers initialized? + int width; // frame width + int height; // frame height + int bpp; // bit per pixel + int evenfirst; // first line is in even field + int aspectratio; // pixel aspect ratio: 11/aspectratio + int oddheight; // height of the odd field + u32 oddmem; // DRAM address of allocated memory + u32 odddata; // data (=header) pointer + u32 oddpalette; // pointer to palette inside data + u32 oddbitmap; // pointer to bitmap inside data + u32 oddterm; // pointer to termination header + int evenheight; // height of the even field + u32 evenmem; // DRAM address of allocated memory + u32 evendata; // data (=header) pointer + u32 evenpalette; // pointer to palette inside data + u32 evenbitmap; // pointer to bitmap inside data + u32 eventerm; // pointer to termination header +}; + +struct StreamInfo { + int valid; // 1: struct contains valid data + int MPEG2; // 0: MPEG1/ISO11172 1: MPEG2/ISO13818 + int hsize; // overall hsize (hsize&hsizeext) + int vsize; // overall vsize (vsize&vsizeext) + int bitrate; // overall bitrate (bitrate&bitrateext) + int vbvbuffersize; // overall... + struct GOPHeader gop; + struct SequenceHeader sh; + struct SequenceExtension se; + struct AudioParam audio; +}; + +struct StreamSetup { // user selected parameters for the stream playback + stream_type streamtype; // what is the type of our input stream? + audio_type audioselect; // 0=auto/unknown 1=MPEG 2=LPCM 3=AC3 + int videoID; // stream ID of the video ES, -1 for any + int audioID; // stream ID of the audio ES, -1 for any + int audioIDext; // stream ID of the audio extension ES, -1 for none + int SPDIFmode; // 0:MPEG/AC3 data on digital S/PDIF out 1:IEC956 data on digital S/PDIF out +}; + +#define MAX_PTS 256 + +typedef struct PTSRecord { + int begin; + int end; + int size; + u32 LastAddr; + u32 AddrB[MAX_PTS]; + u32 AddrE[MAX_PTS]; + u32 PTS[MAX_PTS]; +} PTSStorage; + +#define DVB_DEVS_MAX 9 + +typedef struct dvb_devs_s { + int num; + int tab[DVB_DEVS_MAX]; + int max_users[DVB_DEVS_MAX]; + int max_writers[DVB_DEVS_MAX]; +} dvb_devs_t; + +struct cvdv_cards { +#ifdef DVB + struct dvb_device dvb_dev; + dvb_demux_t demux; +#endif + struct cvdv_cards *next; + void *margi; + struct bus_operations *bus; + u_char scl; + u_char sda; + int i2c_addr; + u32 VideoESSize; + u32 AudioESSize; + u32 VideoPESSize; + u32 DataDumpSize; + u32 AudioPESSize; + u32 NaviBankSize; + int currentType; + ringbuffy rbufA; + ringbuffy rbufB; + int use_ringA; + int use_ringB; + int nonblock; + u8 *addr; + unsigned int size; + unsigned int minor; + struct DRAMBlock *DRAMFirstBlock; + u32 DRAMSize; + struct OSDPicture OSD; + int DMAABusy; // Is the DMA A currently in use? + int DMABBusy; // Is the DMA B currently in use? + int IntInstalled; // is the card interrupt routine installed? + int ChannelBuffersAllocated; // Are the channel buffers for the decoder allocated? + u32 VideoES; // 21 bit word address of the allocated channel + u32 AudioES; // 21 bit word address of the allocated channel + u32 VideoPES; // 21 bit word address of the allocated channel + u32 DataDump; // 21 bit word address of the allocated channel + u32 AudioPES; // 21 bit word address of the allocated channel + u32 NaviBank; // 21 bit word address of the allocated channel + int FrameBuffersAllocated; // Are the frame buffers for the decoder allocated? + u32 FrameStoreLuma1; // 21 bit word address of the allocated frame + u32 FrameStoreChroma1; // 21 bit word address of the allocated frame + u32 FrameStoreLuma2; // 21 bit word address of the allocated frame + u32 FrameStoreChroma2; // 21 bit word address of the allocated frame + u32 FrameStoreLumaB; // 21 bit word address of the allocated frame + u32 FrameStoreChromaB; // 21 bit word address of the allocated frame + int DecoderOpen; // Is the Decoder initialized? + u16 AuxFifo[FIFO_MASK + 1]; // Auxiliary Fifo Data + int AuxFifoHead; // Auxiliary Fifo Position + int AuxFifoTail; // Auxiliary Fifo Position + u16 DataFifo[FIFO_MASK + 1]; // Data Fifo Data + int DataFifoHead; // Data Fifo Position + int DataFifoTail; // Data Fifo Position + int FifoALast; // last used thread of FIFO A + int FifoBLast; // last used thread of FIFO B + videosystem videomode; // current video output mode, PAL or NTSC + struct StreamInfo stream; // header information of the current stream + struct StreamSetup setup; // should be filled bevor sending data, but default is OK + int AuxFifoExt; // used by Aux FIFO parser + int AuxFifoLayer; // " " " " " + int AudioInitialized; // Is the Audio set up? + int AudioOldMode; // remainder of the previous mode while trickmodes, or -1 + int open; // is the 64017 initialized and the video out active? + int closing; // 1 if char device closed, but DMA still running + int startingV; // 1 if card is waiting for the Video ES buffer to fill up, to start the decoder + int startingA; // 1 if card is waiting for the Audio ES buffer to fill up, to start the decoder + int startingDVDV; // 1 if card is waiting for the Video ES buffer to fill up, to start the decoder + int startingDVDA; // 1 if card is waiting for the Audio ES buffer to fill up, to start the decoder + int channelrun; // 1 if channel has been started by the host + int fields; // counter of video fields, debugging only + struct CSS css; // CSS data + u32 NaviPackAddress; // Read address of the Navi Pack Buffer + wait_queue_head_t wqA; + wait_queue_head_t wqB; + u8 navibuffer[NAVIBUFFERSIZE]; + int navihead; + int navitail; + int intdecodestatus; + int showvideo; + int videodelay; + int videodelay_last; + int videoskip; + int videoskip_last; + int videosync; + int videoslow; + int videoslow_last; + int videoffwd; + int videoffwd_last; + PTSStorage VideoPTSStore; + PTSStorage AudioPTSStore; + u32 LastAddr; + u32 VPTS; + u32 oldVPTS; + long VSCR; + u32 APTS; + u32 oldAPTS; + int scrset; + long ASCR; + long SyncTime; + int paused; + u16 lastvattr; + u16 lastaattr; + u8 reg07B; // mirrors of write-only register + u8 reg08F; + u8 reg090; + u8 reg091; + u8 reg092; + u8 reg093; + u8 highlight[10]; // content of registers 1C0 thru 1C0, to be written after next BAV int. + int highlight_valid; // if 1 + int do_flush; // if 1, send flush packet after last transfer done + int hasZV; +#ifdef NOINT + struct timer_list timer; + spinlock_t timelock; +#endif + +#ifdef DVB + dvb_devs_t *dvb_devs; + int users[DVB_DEVS_MAX]; + int writers[DVB_DEVS_MAX]; + + dmxdev_t dmxdev; + boolean video_blank; + struct videoStatus videostate; + struct audioStatus audiostate; + int dvb_registered; + char demux_id[16]; + dmx_frontend_t mem_frontend; + ipack tsa; + ipack tsv; +#endif + + int svhs; + int composite; +}; + +extern u8 FlushPacket[32]; + +extern struct cvdv_cards *first_card; +extern struct cvdv_cards *minorlist[MAXDEV]; + +void DecoderStreamReset(struct cvdv_cards *card); + +void DecoderSetupReset(struct cvdv_cards *card); + +void DecoderCSSReset(struct cvdv_cards *card); + +void card_init(struct cvdv_cards *card, unsigned int minor); + +#endif /* CARDBASE_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/crc.c linux.19pre5-ac1/drivers/media/video/margi/crc.c --- linux.19p5/drivers/media/video/margi/crc.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/crc.c Mon Feb 4 22:21:06 2002 @@ -0,0 +1,78 @@ +/* + crc.c + + Copyright (C) Christian Wolff for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the 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. +*/ + +/*--------------------------------------------------------- + +Cyclic Redundancy Check 16 and 32 Bit + +Christian Wolff, 19990122 + +---------------------------------------------------------*/ + +#define __NO_VERSION__ + +#include "crc.h" + +unsigned short crc_16_table[256]; +unsigned long crc_32_table[256]; + +// generate the tables of CRC-16 and CRC-32 remainders for all possible bytes +void gen_crc_table() +{ + register int i, j; + register unsigned short crc16; + register unsigned long crc32; + for (i = 0; i < 256; i++) { + crc16 = (unsigned short) i << 8; + crc32 = (unsigned long) i << 24; + for (j = 0; j < 8; j++) { + if (crc16 & 0x8000) + crc16 = (crc16 << 1) ^ POLYNOMIAL_16; + else + crc16 = (crc16 << 1); + if (crc32 & 0x80000000L) + crc32 = (crc32 << 1) ^ POLYNOMIAL_32; + else + crc32 = (crc32 << 1); + } + crc_16_table[i] = crc16; + crc_32_table[i] = crc32; + } +} + +// update the CRC on the data block one byte at a time +unsigned short update_crc_16_block(unsigned short crc, + char *data_block_ptr, + int data_block_size) +{ + register int i; + for (i = 0; i < data_block_size; i++) + crc = update_crc_16(crc, *data_block_ptr++); + return crc; +} + +unsigned long update_crc_32_block(unsigned long crc, char *data_block_ptr, + int data_block_size) +{ + register int i; + for (i = 0; i < data_block_size; i++) + crc = update_crc_32(crc, *data_block_ptr++); + return crc; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/crc.h linux.19pre5-ac1/drivers/media/video/margi/crc.h --- linux.19p5/drivers/media/video/margi/crc.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/crc.h Mon Feb 4 22:21:06 2002 @@ -0,0 +1,56 @@ +/* + crc.h + + Copyright (C) Christian Wolff for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the 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. +*/ + +/*--------------------------------------------------------- + +Cyclic Redundancy Check 16 and 32 Bit - Header File + +Christian Wolff, 19990122 + +---------------------------------------------------------*/ + +#ifndef _CRC_H_ +#define _CRC_H_ + +// 16 Bit CCITT standard polynomial x^16 + x^12 + x^5 + x^1 + x^0 +#define POLYNOMIAL_16 0x1021 +// 32 Bit standard polynomial x^32 + x^26 + x^23 + x^22 + x^16 + +// x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + x^0 +#define POLYNOMIAL_32 0x04C11DB7L + +#define CRC_INIT_16 0xFFFF +#define CRC_INIT_32 0xFFFFFFFFL + +#define update_crc_16(crc, data) ((crc << 8) ^ crc_16_table[((int)(crc >> 8 ) ^ (data)) & 0xFF]) +#define update_crc_32(crc, data) ((crc << 8) ^ crc_32_table[((int)(crc >> 24) ^ (data)) & 0xFF]) + +extern unsigned short crc_16_table[256]; +extern unsigned long crc_32_table[256]; + +extern void gen_crc_table(void); + +extern unsigned short update_crc_16_block(unsigned short crc, + char *data_block_ptr, + int data_block_size); +extern unsigned long update_crc_32_block(unsigned long crc, + char *data_block_ptr, + int data_block_size); + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/cvdv.c linux.19pre5-ac1/drivers/media/video/margi/cvdv.c --- linux.19p5/drivers/media/video/margi/cvdv.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/cvdv.c Mon Feb 4 23:50:49 2002 @@ -0,0 +1,1985 @@ +/* + cvdv.c + + Copyright (C) Christian Wolff + Marcus Metzler for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the 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. +*/ + + ///////////////////////////////////////////////////////////////////// + // // + // Driver for the Convergence Digital Video decoder card (pci) // + // with L64017, L64021, PCM1723, and Bt864/Bt865 chipset // + // (c) Christian Wolff 19990209 for convergence integrated media // + // // +///////////////////////////////////////////////////////////////////// + +// Convergence CV2300i +#define __NO_VERSION__ + +#include +#include "cvdv.h" +#include "ost/osd.h" +#include "i2c.h" + + ////////////////////// + // global variables // +////////////////////// + +// Our major device number +unsigned int major_device_number; + + +// my little random function for memory test +uint16_t rnd_seed; +uint16_t rnd(uint16_t range) +{ // returns random 0..(range-1) range<=872 + uint32_t b = 75 * (rnd_seed + 1) - 1; + rnd_seed = (uint16_t) (b & 0xFFFF); + return ((b * range) / 0xFFFF) - ((b / 0xFFFF) * range); +} +void rnd_omize(void) +{ + rnd_seed = (uint16_t) jiffies; +} + +static char *cimlogo[] = { +".............................................", +".............................................", +"......................###....................", +".....................#####...................", +".....................######..................", +"..............#......#####...................", +"...........#####....######...................", +".........########...######...................", +"........########....######...................", +".......#########...######....................", +"......########.....######...####.............", +".....#######.......#####...#####.............", +".....######.......######...######............", +"....#######.......######....######...........", +"....######........######....######...........", +"....#####........######......#####...........", +"...######........######......#####...........", +"...#####.........######......######..........", +"...#####.........#####.......######..........", +"...#####........######........#####..........", +"...#####........######.......######..........", +"...#####........#####.........#####..........", +"...#####.......######........######..........", +"...#####.......######........#####...........", +"...######.......####.........#####...........", +"....#####........##.........######...........", +"....######..................######...........", +"....######.................######............", +".....#######..............######.....#####...", +".....########............#######....#######..", +"......#########........########.....#######..", +".......#######################......########.", +"........#####################.......#######..", +"..........#################.........#######..", +"............#############............#####...", +"...............#.#####.................##....", +".............................................", +"............................................." +}; + + ///////////////////////////////////////////// + // // + // Controlling the L64021 MPEG-2 Decoder // + // // +///////////////////////////////////////////// + +int OSDTest(struct cvdv_cards *card) +{ + int i, j, col, x0, y0, x1, y1,aspx; + uint8_t b; + + + if (!card->OSD.open) + return -2; + + OSDQuery(card, &x0, &y0, &x1, &y1, &aspx); + OSDShow(card); + OSDSetColor(card, 0, 0, 0, 0, 0, 0, 0); + OSDSetColor(card, 1, 128, 255, 255, 0, 0, 0); + for ( i = 0; i < cimlogo_width; i++){ + for ( j = 0; j < cimlogo_height; j++){ + b = cimlogo[j][i]; + col = (b == '#') ? 1: 0; + OSDSetPixel(card, x0+i, y0+j, col); + } + } + + return 0; +} + + +void SetVideoSystem(struct cvdv_cards *card) +{ + uint8_t reg; + + // set the hsync and vsync generators in the L64017 according to the video standard + reg = read_indexed_register(card, IIO_VIDEO_CONTROL1); + reg &= ~0x03; + switch (card->videomode) { + case PAL: // 864*625*50Hz = 27MHz, 25fps + I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x41 | 0x0a); + I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04); + I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x15); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x96); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x15); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0x13); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x54); + reg |= VMS_PAL; + break; + case PALN: + I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0xa1 | 0x0a); + I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04); + I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x15); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x96); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x15); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0x13); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x54); + reg |= VMS_PAL; + break; + + case PALNc: + I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x81 | 0x0a); + I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04); + I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x15); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x8c); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x28); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xed); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43); + reg |= VMS_PAL; + break; + + case NTSC: // 858*525*59.94006Hz = 27MHz, 29.97fps + I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x01 | 0x0a); + I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04); + I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x1c); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x3e); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0xf8); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xe0); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43); + reg |= VMS_NTSC; + break; + + case PALM: + I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x01 | 0x0a); + I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04); + I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x15); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x4e); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x4a); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xe1); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43); + reg |= VMS_PAL; + break; + + case NTSC60: // 857*525*60.010002Hz = 27MHz, 30fps + I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x21 | 0x0a); + I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04); + I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x1c); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x3e); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0xf8); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xe0); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43); + reg |= VMS_NTSC; + break; + + case PALM60: + I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x61 | 0x0a); + I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04); + I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x15); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x4e); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x4a); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xe1); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43); + reg |= VMS_PAL; + break; + + case PAL60: + break; + } + write_indexed_register(card, IIO_VIDEO_CONTROL1, reg); + // set the pixel generators according to the video standard + L64021Setup(card); +} + +int SetVideoAttr(struct cvdv_cards *card, uint16_t vattr) +{ + uint8_t video_compression_mode; + uint8_t tv_system; + uint8_t aspect_ratio; + uint8_t display_mode; + uint8_t line_21_switch_1; + uint8_t line_21_switch_2; + uint8_t source_picture_resolution; + uint8_t source_picture_letterboxed; + uint8_t reserved; + uint8_t film_camera_mode; + uint16_t hsize, vsize; + if (vattr != card->lastvattr) { + video_compression_mode = (vattr >> 14) & 0x03; + tv_system = (vattr >> 12) & 0x03; + aspect_ratio = (vattr >> 10) & 0x03; + display_mode = (vattr >> 8) & 0x03; + line_21_switch_1 = (vattr >> 7) & 0x01; + line_21_switch_2 = (vattr >> 6) & 0x01; + source_picture_resolution = (vattr >> 3) & 0x07; + source_picture_letterboxed = (vattr >> 2) & 0x01; + reserved = (vattr >> 1) & 0x01; + film_camera_mode = (vattr >> 0) & 0x01; + card->videomode = + ((tv_system == 0) ? NTSC : ((tv_system == 1) ? + PAL : PAL)); + SetVideoSystem(card); + hsize = + ((source_picture_resolution == 0) ? 720 + : ((source_picture_resolution == 1) ? 702 : 352)); + vsize = ((source_picture_resolution == 3) + ? ((tv_system == 0) ? 240 : 288) + : ((tv_system == 0) ? 480 : 576)); + if (DecoderOpen + (card, hsize, vsize, ((aspect_ratio) ? 3 : 2), + ((video_compression_mode) ? 0 : 1), + source_picture_letterboxed, tv_system)) { + MDEBUG(0, + ": Video Decoder Open failed: On-card memory insufficient for frame stores\n"); + } + card->lastvattr = vattr; + } else { + MDEBUG(0, + ": Video attribute not set, equal to previous one.\n"); + } + return 0; +} + +int SetAudioAttr(struct cvdv_cards *card, uint16_t aattr) +{ + uint8_t audio_coding_mode; + uint8_t multichannel_extension; + uint8_t audio_type; + uint8_t audio_application_mode; + uint8_t quantization_drc; + uint8_t fs; + uint8_t reserved; + uint8_t num_audio_ch; + if (aattr) { + if (aattr != card->lastaattr) { + audio_coding_mode = (aattr >> 13) & 0x07; + multichannel_extension = (aattr >> 12) & 0x01; + audio_type = (aattr >> 10) & 0x03; + audio_application_mode = (aattr >> 8) & 0x03; + quantization_drc = (aattr >> 6) & 0x03; + fs = (aattr >> 4) & 0x03; + reserved = (aattr >> 3) & 0x01; + num_audio_ch = (aattr >> 0) & 0x07; + switch (audio_coding_mode) { + case 0: // AC-3 + card->setup.audioselect = audio_AC3; + break; + case 2: // MPEG Audio + card->setup.audioselect = audio_MPEG; + break; + case 3: // MPEG Audio with ext. + card->setup.audioselect = audio_MPEG_EXT; + break; + case 4: // Linear Pulse Code Modulation LPCM + card->setup.audioselect = audio_LPCM; + break; + case 6: // DTS + card->setup.audioselect = audio_DTS; + break; + case 7: // SDDS + card->setup.audioselect = audio_SDDS; + break; + } + DecoderPrepareAudio(card); + AudioInit(card, ((fs) ? 96 : 48), + ((audio_application_mode == 2) ? 1 : 0)); + } else { + MDEBUG(0, + ": Audio attribute not set, equal to previous one.\n"); + } + } else { + card->setup.audioselect = audio_none; + DecoderPrepareAudio(card); + } + card->lastaattr = aattr; + return 0; +} + +int Prepare(struct cvdv_cards *card) +{ + int err, h; + struct StreamSetup *setup = &card->setup; + + if (!card->ChannelBuffersAllocated) { + + DecoderStreamReset(card); + if (setup->streamtype == stream_none) { + setup->streamtype = stream_PS; + } + + if (setup->audioselect == audio_none) { + setup->audioselect = audio_MPEG; + } + + DecoderPrepareAudio(card); + AudioMute(card, 1); + DecoderPrepareVideo(card); + VideoSetBackground(card, 1, 0, 0, 0); // black + + switch (setup->streamtype) { + default: + case stream_none: // unknown stream! + MDEBUG(0, + ": Video Decoder Prepare failed: unknown stream type\n"); + return -ENODEV; // not an MPEG stream! + case stream_ES: // Elementary Stream + err = DecoderPrepareES(card); + break; + case stream_PES: // Packetized Elementary Stream + err = DecoderPreparePES(card); + break; + case stream_PS: // MPEG-1 System Stream / MPEG-2 Program Stream + err = DecoderPreparePS(card, -1, 0, 0, 0, 0, 0); + break; + case stream_DVD: // DVD Stream + err = DecoderPreparePS(card, 0, 0, 0, 0, 3, 1); + break; + } + if (err) { // insufficient memory + MDEBUG(0, + ": Video Decoder Prepare failed: no kernel memory, please reboot if possible\n"); + CloseCard(card); + return -ENODEV; + } + } + + // Set up the Video Decoder as we have the stream information + if ((!card->FrameBuffersAllocated) + && (card->ChannelBuffersAllocated) && (card->stream.sh.valid)) { + // Automatic PAL/NTSC-switch according to MPEG-Source + h = card->stream.vsize; + if (h < 480) + h *= 2; // catch quarter sized images + printk(KERN_INFO LOGNAME ": Video mode: %s\n", + ((h == 480) ? "NTSC" : "PAL")); + card->videomode = ((h == 480) ? NTSC : PAL); + SetVideoSystem(card); + // Open the Video Decoder with the parameters retreived from the stream + if ( + (err = + DecoderOpen(card, card->stream.hsize, + card->stream.vsize, + card->stream.sh.aspectratio, + !card->stream.MPEG2, 0, + (card->stream.hsize > 480)))) { // TODO: include vbvbuffersize + MDEBUG(0, + ": Video Decoder Open failed: %s\n", + ((err == 1) ? + "Picture size too big (>1440 pixel wide)" : + "On-card memory insufficient for frame stores")); + CloseCard(card); + return -ENODEV; // picture too big or insufficient memory + } + MDEBUG(1, ": Ready to go\n"); + card->startingV = 1; // tell the card to start playing as soon as ES-buffers are sufficiently full + card->startingA = 1; // tell the card to start playing as soon as ES-buffers are sufficiently full + } + + + return 0; +} + +int SetSCRstart(struct cvdv_cards *card, uint32_t SCR_base) +{ + uint32_t SCR_compare; + uint32_t SCR_compareA; + uint32_t SCR_compareV; + if (card->startingV) { + MDEBUG(0, ": SCR in DVD Pack: 0x%08X\n", + SCR_base); + card->startingV = 0; + card->startingA = 0; + DecoderMaskByte(card, 0x007, 0xD2, 0xD2); // Set 0x010, halt SCR counter + SCR_compare = SCR_base + 000; + if (SCR_base < 900) + SCR_base = 0; + else + SCR_base -= 900; + //DecoderWriteDWord(card,0x009,SCR_base); // Set SCR counter + DecoderWriteByte(card, 0x009, SCR_base & 0xFF); // Set SCR counter + DecoderWriteByte(card, 0x00A, (SCR_base >> 8) & 0xFF); + DecoderWriteByte(card, 0x00B, (SCR_base >> 16) & 0xFF); + DecoderWriteByte(card, 0x00C, (SCR_base >> 24) & 0xFF); + DecoderMaskByte(card, 0x011, 0x03, 0x02); // compare, not capture + MDEBUG(0, ": SCR compare value: 0x%08X\n", + SCR_compare); + //DecoderWriteDWord(card,0x00D,SCR_compare); // Set Compare register + DecoderWriteByte(card, 0x00D, SCR_compare & 0xFF); // Set Compare register + DecoderWriteByte(card, 0x00E, (SCR_compare >> 8) & 0xFF); + DecoderWriteByte(card, 0x00F, (SCR_compare >> 16) & 0xFF); + DecoderWriteByte(card, 0x010, (SCR_compare >> 24) & 0xFF); + //DecoderWriteDWord(card,0x014,SCR_compare); // Set audio compare reg. + DecoderWriteByte(card, 0x014, SCR_compare & 0xFF); // Set audio compare reg. + DecoderWriteByte(card, 0x015, (SCR_compare >> 8) & 0xFF); + DecoderWriteByte(card, 0x016, (SCR_compare >> 16) & 0xFF); + DecoderWriteByte(card, 0x017, (SCR_compare >> 24) & 0xFF); + DecoderSetByte(card, 0x013, 0x03); // Video and Audio start on cmp. + //DecoderSetVideoPanic(card,0,DecoderGetVideoESSize(card)/4); // video panic at 25 percent + VideoSetBackground(card, 1, 0, 0, 0); // black + SCR_base = DecoderReadByte(card, 0x009); + SCR_base = + SCR_base | ((uint32_t) DecoderReadByte(card, 0x00A) << 8); + SCR_base = + SCR_base | ((uint32_t) DecoderReadByte(card, 0x00B) << 16); + SCR_base = + SCR_base | ((uint32_t) DecoderReadByte(card, 0x00C) << 24); + SCR_compareA = DecoderReadByte(card, 0x014); + SCR_compareA = + SCR_compareA | ((uint32_t) DecoderReadByte(card, 0x015) << + 8); + SCR_compareA = + SCR_compareA | ((uint32_t) DecoderReadByte(card, 0x016) << + 16); + SCR_compareA = + SCR_compareA | ((uint32_t) DecoderReadByte(card, 0x017) << + 24); + SCR_compareV = DecoderReadByte(card, 0x00D); + SCR_compareV = + SCR_compareV | ((uint32_t) DecoderReadByte(card, 0x00E) << + 8); + SCR_compareV = + SCR_compareV | ((uint32_t) DecoderReadByte(card, 0x00F) << + 16); + SCR_compareV = + SCR_compareV | ((uint32_t) DecoderReadByte(card, 0x010) << + 24); + if (DecoderReadByte(card, 0x013) & 0x03) + MDEBUG(1,": SCR 0x%08X, videocmp=0x%08X, audiocmp=0x%08X %02X\n", + SCR_base, SCR_compareV, SCR_compareA, + DecoderReadByte(card, 0x013)); + DecoderMaskByte(card, 0x007, 0xD2, 0xC2); // Del 0x010, SCR counter run + } + return 0; +} + +int DecoderWriteBlock(struct cvdv_cards *card, uint8_t * data, int size, + int initial, int setSCR) +{ + //int a,v,as,vs,ap,vp; + int res; + uint32_t SCR_base; + int co = 0; + // uint32_t SCR_compare; + res = 0; + + Prepare(card); + + if (size > 0) { + + if (!card->use_ringA) + MargiSetBuffers(card, NBBUF*CHANNELBUFFERSIZE,0); + + if (card->startingDVDV || card->startingDVDA) + setSCR = 1; + + if (initial) { + DecoderStreamReset(card); + //TODO stop and start channel interface + setSCR = 1; + } + + if (setSCR) { + SCR_base = ParseSCR(data); + SetSCR(card, SCR_base); + } + card->DMAABusy = 0; + while (((res = MargiPushA(card, size, data)) < size) + && co < 1000) { + data+=res; + size-=res; + co++; + MDEBUG(2, + ": DecoderWriteBlock - buffers only filled with %d instead of %d bytes\n",res, size); + if (card->DMAABusy){ + interruptible_sleep_on(&card->wqA); + } + } + + if (card->startingDVDV) { + card->startingDVDV = 0; + card->startingV = 1; + DecoderStartDecode(card); + } + if (card->startingDVDA) { + card->startingDVDA = 0; + card->startingA = 1; + AudioSetPlayMode(card, MAUDIO_PLAY); + } + } + return 0; +} + + + + + + ////////////////////////////// + // // + // Char Device Procedures // + // // +////////////////////////////// +static long margi_write(struct cvdv_cards *card, const char *data, + unsigned long count, int nonblock) +{ + + int res; + long int out=0; + int free; + + free = ring_write_rest(&(card->rbufA)); + + if (card != NULL) { + card->nonblock = nonblock; + if (count > 0) { // Do we have data? + if ((res = Prepare(card))) + return res; + if (!card->use_ringA) + MargiSetBuffers(card, NBBUF*CHANNELBUFFERSIZE, + 0); + if (!nonblock && + !wait_event_interruptible( + card->wqA, + ring_write_rest(&(card->rbufA)) >count )){ + + out = MargiPushA(card, count, + data); + } else { + out = MargiPushA(card, count, data); + } + } + return out; + } else { + MDEBUG(0, + ": Video Decoder Prepare failed: device with this minor number not found\n"); + return -ENODEV; // device with this minor number not found + } +} + + +static long margi_write_audio(struct cvdv_cards *card, const char *data, + unsigned long count, int nonblock) +{ + struct StreamSetup *setup = &card->setup; + + int res; + long int out=0; + int free; + + free = ring_write_rest(&(card->rbufB)); + + if (card != NULL) { + card->nonblock = nonblock; + + if (count > 0) { // Do we have data? + if ((res = Prepare(card))) + return res; + if ((setup->streamtype == stream_ES) + || (setup->streamtype == stream_PES)){ + if (!card->use_ringB) + MargiSetBuffers(card, NBBUF* + CHANNELBUFFERSIZE,1); + if (!nonblock && + !wait_event_interruptible( + card->wqB, + ring_write_rest(&(card->rbufB)) + > count)){ + out = MargiPushB(card, count, + data); + } else { + out = MargiPushB(card, count, data); + } + } + } + return out; + } else { + MDEBUG(0, + ": Video Decoder Prepare failed: device with this minor number not found\n"); + return -ENODEV; // device with this minor number not found + } +} + +void pes_write(uint8_t *buf, int count, void *priv) +{ + struct cvdv_cards *card = (struct cvdv_cards *) priv; + + margi_write(card, buf, count, 0); +} + + +static ssize_t PSwrite(struct file *file, const char *data, size_t count, + loff_t * offset) +{ + struct cvdv_cards *card = + minorlist[MINOR(file->f_dentry->d_inode->i_rdev) % MAXDEV]; // minor number modulo 16 + return margi_write(card, data, count, file->f_flags&O_NONBLOCK); +} + +static unsigned int PSpoll(struct file *file, poll_table * table) +{ + struct cvdv_cards *card = + minorlist[MINOR(file->f_dentry->d_inode->i_rdev) % MAXDEV]; // minor number modulo 16 + if (card != NULL) { + poll_wait(file, &card->wqA , table); + if ( !card->rbufA.buffy || ring_write_rest(&(card->rbufA)) ) + return (POLLOUT | POLLWRNORM); + else { + return 0; + } + } else + return POLLERR; +} + +static unsigned int poll_audio(struct file *file, poll_table * table) +{ + struct cvdv_cards *card = + minorlist[MINOR(file->f_dentry->d_inode->i_rdev) % MAXDEV]; // minor number modulo 16 + if (card != NULL) { + poll_wait(file, &card->wqB, table); + if ( !card->rbufB.buffy || ring_write_rest(&(card->rbufB)) ) + return (POLLOUT | POLLWRNORM); + else { + return 0; + } + } else + return POLLERR; +} + +static int +OSD_DrawCommand(struct cvdv_cards *card,osd_cmd_t *dc) +{ + + switch (dc->cmd) { + case OSD_Close: + MDEBUG(1,": OSD Close\n"); + return OSDClose(card); + case OSD_Open: // Open(x0,y0,x1,y1,BitPerPixel(2/4/8),mix(0..15)) + return OSDOpen(card, dc->x0, + dc->y0, dc->x1, + dc->y1, + dc->color & 0x0F, + (dc->color >> 4) & + 0x0F); + case OSD_Show: + return OSDShow(card); + case OSD_Hide: + return OSDHide(card); + case OSD_Clear: + return OSDClear(card); + case OSD_Fill: // Fill(color) + return OSDFill(card, dc->color); + case OSD_SetColor: // SetColor(color,R(x0),G(y0),B(x1),opacity(y1)) + return (OSDSetColor + (card, dc->color, dc->x0, + dc->y0, dc->x1, 0, + (dc->y1 != 255), + (dc->y1 == 0)) >= 0); + case OSD_SetPalette:// SetPalette(firstcolor{color},lastcolor{x0},data) + return OSDSetPalette(card, + dc->color, + dc->x0, (uint8_t *) + dc->data); + case OSD_SetTrans: // SetTrans(transparency{color}) + return OSDSetTrans(card, + (dc->color >> 4) + & 0x0F); + case OSD_SetPixel: // SetPixel(x0,y0,color) + return OSDSetPixel(card, dc->x0, + dc->y0, + dc->color); + case OSD_GetPixel: // GetPixel(x0,y0); + return OSDGetPixel(card, dc->x0, + dc->y0); + case OSD_SetRow: // SetRow(x0,y0,x1,(uint8_t*)data) + return OSDSetRow(card, dc->x0, + dc->y0, dc->x1, + (uint8_t *) dc->data); + case OSD_SetBlock: // SetBlock(x0,y0,x1,y1,(uint8_t*)data) + return OSDSetBlock(card, dc->x0, + dc->y0, dc->x1, + dc->y1, + dc->color, + (uint8_t *) + dc->data); + case OSD_FillRow: // FillRow(x0,y0,x1,color) + return OSDFillRow(card, dc->x0, + dc->y0, dc->x1, + dc->color); + case OSD_FillBlock: // FillRow(x0,y0,x1,y1,color) + return OSDFillBlock(card, dc->x0, + dc->y0, dc->x1, + dc->y1, + dc->color); + case OSD_Line: // Line(x0,y0,x1,y1,color); + return OSDLine(card, dc->x0, + dc->y0, dc->x1, + dc->y1, dc->color); + case OSD_Query: // Query(x0,y0,x1,y1,aspect(color:11) + return OSDQuery(card, &dc->x0, + &dc->y0, &dc->x1, + &dc->y1, + &dc->color); + case OSD_Test: + return OSDTest(card); + default: + return -EINVAL; + } +} + + +static int PSioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct cvdv_cards *card = minorlist[MINOR(inode->i_rdev) % MAXDEV]; // minor number modulo 16 + osd_cmd_t *dc; + struct decodercmd *command; + uint16_t attr; + + if (card != NULL) { + if (_IOC_TYPE(cmd) == CVDV_IOCTL_MAGIC) + switch (_IOC_NR(cmd)) { + case IOCTL_DRAW: // Drawing commands + dc = (osd_cmd_t *) arg; + return OSD_DrawCommand(card,dc); + break; + case IOCTL_DECODER: + command = (struct decodercmd *) arg; + switch (command->cmd) { + + case Decoder_CSS: + /* + return DecoderCSS(card, + command->param1, + command->data1); + */ + break; + + case Decoder_Set_Videosystem: + MDEBUG(1,": -- Decoder_Set_Videosystem\n"); + card->videomode = + (videosystem) command->param1; + SetVideoSystem(card); + return 0; + break; + + case Decoder_Set_Streamtype: + MDEBUG(1,": -- Decoder_Set_Streamtype\n"); + card->setup.streamtype = + (stream_type) command->param1; + return 0; + break; + + case Decoder_Set_Audiotype: + MDEBUG(1,": -- Decoder_Set_Audiotype\n"); + card->setup.audioselect = + (audio_type) command->param1; + DecoderPrepareAudio(card); + return 0; + break; + + case Decoder_Set_VideoStreamID: + MDEBUG(1,": -- Decoder_Set_VideoStreamID\n"); + card->setup.videoID = + command->param1; + DecoderPrepareVideo(card); + return 0; + break; + + case Decoder_Set_AudioStreamID: + MDEBUG(1,": -- Decoder_Set_AudioStreamID 0x%02X 0x%02X\n", + command->param1,command->param2); + card->setup.audioID = + command->param1; + card->setup.audioIDext = + command->param2; + attr = card->lastaattr; + DecoderSelectAudioID(card); + card->lastaattr = attr; + return 0; + break; + + case Decoder_Still_Put: + return DecoderShowStill(card, + command-> + param1, + command-> + param2, + command-> + data1, + command-> + data2); + break; + + case Decoder_Still_Get: + return DecoderGetStill(card, + &command-> + param1, + &command-> + param2, + command-> + data1, + command-> + data2); + break; + + case Decoder_Pause: // pause{param1} 0=run 1=pause 2=toggle + if (command->param1 == 2) { + if (card->paused) + DecoderUnPause + (card); + else + DecoderPause(card); + } else { + if (!command->param1) + DecoderUnPause + (card); + else + DecoderPause(card); + } + return 0; + + /* Too buggy + case Decoder_FFWD: // pause{param1} =normal 1=ffwd 2=toggle + if (command->param1 == 2) { + if (card->videoffwd) + card->videoffwd = 0; + else + card->videoffwd = 3; + } else { + if (!command->param1) + card->videoffwd = 0; + else + card->videoffwd = 3; + } + return 0; + + case Decoder_Slow: // pause{param1} =normal 1=slow 2=toggle + if (command->param1 == 2) { + if (card->videoslow) + card->videoslow = 0; + else + card->videoslow = 4; + } else { + if (!command->param1) + card->videoslow = 0; + else + card->videoslow = 4; + } + return 0; + */ + case Decoder_Highlight: // active{param1}, color information(SL_COLI or AC_COLI){data1[4]}, button position(BTN_POSI){data2[6]} + return DecoderHighlight(card, + command-> + param1, + command-> + data1, + command-> + data2); + case Decoder_SPU: // stream{param1}, active{param2} + return DecoderSPUStream(card, + command-> + param1, + command-> + param2); + case Decoder_SPU_Palette: // length{param1}, palette{data1} + return DecoderSPUPalette(card, + command-> + param1, + command-> + data1); + case Decoder_GetNavi: // data1 will be filled with PCI or DSI pack, and 1024 will be returned + return DecoderGetNavi(card, + command-> + data1); + case Decoder_SetKaraoke: // Vocal1{param1}, Vocal2{param2}, Melody{param3} + return DecoderKaraoke(card, + command-> + param1, + command-> + param2, + command-> + param3); + case Decoder_Set_Videoattribute: + MDEBUG(1,": -- Decoder_Set_Videoattribute\n"); + if (!card->ChannelBuffersAllocated) { + DecoderStreamReset(card); + MargiFlush(card); + + card->setup.streamtype = + stream_DVD; + card->setup.videoID = 0; + DecoderPrepareVideo(card); + DecoderPreparePS(card, 0, + 0, 2, 2, + 3, 1); + } + + SetVideoAttr(card, + command->param1); + card->startingDVDV = 1; +// tell the card to start playing as soon as ES-buffers are sufficiently full + return 0; + case Decoder_Set_Audioattribute: + MDEBUG(1,": -- Decoder_Set_Audioattribute\n"); + SetAudioAttr(card, + command->param1); + card->startingDVDA = + ((card->setup.audioselect != + audio_none) + && (card->setup.audioselect != audio_disable)); // tell the card to start playing as soon as ES-buffers are sufficiently full + return 0; + case Decoder_WriteBlock: // DVD-Sector{data1}, sectorsize{param1{2048}}, initialsector{param2{bool}}, set_SCR{param3} + return DecoderWriteBlock(card, + command-> + data1, + command-> + param1, + command-> + param2, + command-> + param3); + default: + return -EINVAL; + } + default: + return -EINVAL; + } else + return -EINVAL; + } else { + MDEBUG(0, + ": Video Decoder Prepare failed: device with this minor number not found\n"); + return -ENODEV; // device with this minor number not found + } +} + + +static int PSmmap(struct file *file, struct vm_area_struct *vm) +{ + return -ENODEV; +} + + + +static int margi_open(struct cvdv_cards *card, int flags) +{ + int closed; + + printk("Open card = %p\n", card); + + if (card != NULL) { + MDEBUG(1, ": -- open \n"); + CloseCard(card); + OSDClose(card); + + printk("Card and OSD closed.\n"); +#ifdef NOINT + card->timer.function = Timerfunction; + card->timer.data=(unsigned long) card; + card->timer.expires=jiffies+1; + add_timer(&card->timer); +#endif + printk("Timer added.\n"); + + if (card->open) + MDEBUG(0,": PSopen - already open\n"); + closed = 1; + if (card->open) + closed = 0; + if (closed) { // first open() for this card? + printk("Freeing buffers.\n"); + MargiFreeBuffers(card); + printk("Fade to black.\n"); + VideoSetBackground(card, 1, 0, 0, 0); // black + } + printk("Go\n"); + card->open++; + return 0; + } else { + MDEBUG(0, + ": Video Decoder Prepare failed: device with this minor number not found\n"); + return -ENODEV; // device with this minor number not found + } + +} + + +static int PSopen(struct inode *inode, struct file *file) +{ + struct cvdv_cards *card = minorlist[MINOR(inode->i_rdev) % MAXDEV]; +#ifdef DVB + if(card) + card->audiostate.AVSyncState=true; +#endif + return margi_open(card, file->f_flags); +} + + +static int all_margi_close(struct cvdv_cards *card) +{ + + if (card != NULL) { + MDEBUG(1, ": -- PSrelease\n"); + if (card->open <= 0) + MDEBUG(1,": PSrelease - not open\n"); + card->open--; + + if (!card->open) { + MDEBUG(1,": PSrelease - last close\n"); + CloseCard(card); // close immediately + } + return 0; + } else { + MDEBUG(0,": Video Decoder Prepare failed:\n"); + return -ENODEV; // device with this minor number not found + } + +} + +static int PSrelease(struct inode *inode, struct file *file) +{ + struct cvdv_cards *card = minorlist[MINOR(inode->i_rdev) % MAXDEV]; // minor number modulo 16 + return all_margi_close(card); +} + + ////////////////////////// + // // + // Char Device Hookup // + // // +////////////////////////// + +// Hookups for a write-only device, that accepts MPEG-2 Program Stream +struct file_operations cvdv_fileops = { + owner: THIS_MODULE, + write: PSwrite, + poll: PSpoll, + ioctl: PSioctl, + mmap: PSmmap, + open: PSopen, + release: PSrelease, +}; + + +#ifdef DVB + +static inline int +num2type(struct cvdv_cards *card, int num) +{ + if (!card->dvb_devs) + return -2; + if (num>=card->dvb_devs->num) + return -2; + return card->dvb_devs->tab[num]; +} + +static int +dvbdev_open(struct dvb_device *dvbdev, int num, + struct inode *inode, struct file *file) +{ + struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv; + int type=num2type(card, num); + int ret=0; + + if (type<0) + return -EINVAL; + + if (card->users[num] >= card->dvb_devs->max_users[num]) + return -EBUSY; + + if ((file->f_flags&O_ACCMODE)!=O_RDONLY) + if (card->writers[num] >= card->dvb_devs->max_writers[num]) + return -EBUSY; + + switch (type) { + case DVB_DEVICE_VIDEO_0: + card->video_blank=true; + card->audiostate.AVSyncState=true; + card->videostate.streamSource=VIDEO_SOURCE_DEMUX; + margi_open(card, file->f_flags); + break; + + case DVB_DEVICE_AUDIO_0: + card->audiostate.AVSyncState=true; + card->audiostate.streamSource=AUDIO_SOURCE_DEMUX; + break; + + case DVB_DEVICE_DEMUX_0: + if ((file->f_flags&O_ACCMODE)!=O_RDWR) + return -EINVAL; + ret=DmxDevFilterAlloc(&card->dmxdev, file); + break; + + case DVB_DEVICE_DVR_0: + card->audiostate.AVSyncState=true; + card->setup.streamtype = stream_PES; + margi_open(card, file->f_flags); + ret=DmxDevDVROpen(&card->dmxdev, file); + break; + + case DVB_DEVICE_OSD_0: + break; + default: + return -EINVAL; + } + if (ret<0) + return ret; + if ((file->f_flags&O_ACCMODE)!=O_RDONLY) + card->writers[num]++; + card->users[num]++; + return ret; +} + +static int +dvbdev_close(struct dvb_device *dvbdev, int num, + struct inode *inode, struct file *file) +{ + struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv; + int type=num2type(card, num); + int ret=0; + + if (type<0) + return -EINVAL; + + switch (type) { + case DVB_DEVICE_VIDEO_0: + case DVB_DEVICE_AUDIO_0: + if (card->open) + all_margi_close(card); + break; + + case DVB_DEVICE_DEMUX_0: + ret=DmxDevFilterFree(&card->dmxdev, file); + break; + + case DVB_DEVICE_DVR_0: + ret=DmxDevDVRClose(&card->dmxdev, file); + if (card->open) + all_margi_close(card); + break; + case DVB_DEVICE_OSD_0: + break; + default: + return -EINVAL; + } + if (ret<0) + return ret; + if ((file->f_flags&O_ACCMODE)!=O_RDONLY) + card->writers[num]--; + card->users[num]--; + return ret; +} + + +static ssize_t +dvbdev_write(struct dvb_device *dvbdev, int num, + struct file *file, + const char *buf, size_t count, loff_t *ppos) +{ + struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv; + int type=num2type(card, num); + + switch (type) { + case DVB_DEVICE_VIDEO_0: + if (card->videostate.streamSource!=VIDEO_SOURCE_MEMORY) + return -EPERM; + return margi_write(card, buf, count, + file->f_flags&O_NONBLOCK); + + case DVB_DEVICE_AUDIO_0: + if (card->audiostate.streamSource!=AUDIO_SOURCE_MEMORY) + return -EPERM; + if ( card->setup.streamtype != stream_PES ) + return -EPERM; + + return margi_write_audio(card, buf, count, + file->f_flags&O_NONBLOCK); + + case DVB_DEVICE_DVR_0: + return DmxDevDVRWrite(&card->dmxdev, file, buf, count, ppos); + default: + return -EOPNOTSUPP; + } + return 0; +} + +static ssize_t +dvbdev_read(struct dvb_device *dvbdev, int num, + struct file *file, char *buf, size_t count, loff_t *ppos) +{ + struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv; + int type=num2type(card, num); + + switch (type) { + case DVB_DEVICE_VIDEO_0: + break; + case DVB_DEVICE_AUDIO_0: + break; + case DVB_DEVICE_DEMUX_0: + return DmxDevRead(&card->dmxdev, file, buf, count, ppos); + case DVB_DEVICE_DVR_0: + return DmxDevDVRRead(&card->dmxdev, file, buf, count, ppos); + case DVB_DEVICE_CA_0: + break; + default: + return -EOPNOTSUPP; + } + return 0; +} + + + + +static int +dvbdev_ioctl(struct dvb_device *dvbdev, int num, + struct file *file, unsigned int cmd, unsigned long arg) +{ + struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv; + void *parg=(void *)arg; + int type=num2type(card, num); + uint16_t attr; + + switch (type) { + case DVB_DEVICE_VIDEO_0: + if (((file->f_flags&O_ACCMODE)==O_RDONLY) && + (cmd!=VIDEO_GET_STATUS)) + return -EPERM; + + switch (cmd) { + + case VIDEO_STOP: + DecoderPause(card); + card->videostate.playState = VIDEO_STOPPED; + if (card->videostate.videoBlank) + VideoSetBackground(card, 1, 0, 0, 0); + + + return 0; + + case VIDEO_PLAY: + + if (card->videostate.streamSource== + VIDEO_SOURCE_MEMORY) { + if (card->videostate.playState==VIDEO_FREEZED){ + DecoderUnPause(card); + } else { + DecoderUnPause(card); + } + } + break; + + case VIDEO_FREEZE: + DecoderPause(card); + break; + + case VIDEO_CONTINUE: + if (card->videostate.playState==VIDEO_FREEZED) { + DecoderUnPause(card); + } + break; + + case VIDEO_SELECT_SOURCE: + card->videostate.streamSource=(videoStreamSource_t) arg; + break; + + case VIDEO_SET_BLANK: + card->videostate.videoBlank=(boolean) arg; + break; + + case VIDEO_GET_STATUS: + if(copy_to_user(parg, &card->videostate, + sizeof(struct videoStatus))) + return -EFAULT; + break; + + case VIDEO_GET_EVENT: + return -EOPNOTSUPP; + + case VIDEO_SET_DISPLAY_FORMAT: + { + videoDisplayFormat_t format=(videoDisplayFormat_t) arg; + uint16_t val=0; + + switch(format) { + case VIDEO_PAN_SCAN: + val=VID_PAN_SCAN_PREF; + break; + + case VIDEO_LETTER_BOX: + val=VID_VC_AND_PS_PREF; + break; + + case VIDEO_CENTER_CUT_OUT: + val=VID_CENTRE_CUT_PREF; + break; + + default: + return -EINVAL; + } + + card->videostate.videoFormat=format; + return 0; + } + + case VIDEO_STILLPICTURE: + { + struct videoDisplayStillPicture pic; + + if(copy_from_user(&pic, parg, + sizeof(struct videoDisplayStillPicture))) + return -EFAULT; + + break; + } + + case VIDEO_FAST_FORWARD: + if (card->videostate.streamSource != + VIDEO_SOURCE_MEMORY) + return -EPERM; + card->videoffwd = 3; + break; + + case VIDEO_SLOWMOTION: + if (card->videostate.streamSource!=VIDEO_SOURCE_MEMORY) + return -EPERM; + card->videoslow = arg; + + break; + + case VIDEO_GET_CAPABILITIES: + { + int cap=VIDEO_CAP_MPEG1| + VIDEO_CAP_MPEG2| + VIDEO_CAP_SYS| + VIDEO_CAP_PROG| + VIDEO_CAP_SPU| + VIDEO_CAP_NAVI| + VIDEO_CAP_CSS; + + + if (copy_to_user(parg, &cap, + sizeof(cap))) + return -EFAULT; + break; + } + + case VIDEO_SET_STREAMTYPE: + { + int f = -1; + switch(arg){ + case VIDEO_CAP_MPEG1: + case VIDEO_CAP_MPEG2: + f = stream_PES; + break; + + case VIDEO_CAP_SYS: + case VIDEO_CAP_PROG: + f = stream_PS; + break; + + case VIDEO_CAP_SPU: + case VIDEO_CAP_NAVI: + case VIDEO_CAP_CSS: + f = stream_DVD; + } + card->setup.streamtype = f; + + } + break; + + case VIDEO_SET_ID: + card->setup.videoID = arg; + DecoderPrepareVideo(card); + break; + + case VIDEO_SET_SYSTEM: + card->videomode = (videosystem) arg; + SetVideoSystem(card); + break; + + case VIDEO_SET_HIGHLIGHT: + { + uint8_t data1[4]; + uint8_t data2[6]; + videoHighlight_t vh; + + if(copy_from_user(&vh, parg, sizeof(videoHighlight_t))) + return -EFAULT; + + data1[0] = vh.contrast1; + data1[1] = vh.contrast2; + data1[2] = vh.color1; + data1[3] = vh.color2; + data2[0] = vh.ypos & 0xFF; + data2[1] = (uint8_t) ((vh.ypos >> 1) & 0xFF); + data2[2] = (uint8_t) ((vh.ypos >> 2) & 0xFF); + data2[3] = vh.xpos & 0xFF; + data2[4] = (uint8_t) ((vh.xpos >> 1) & 0xFF); + data2[5] = (uint8_t) ((vh.xpos >> 2) & 0xFF); + return DecoderHighlight(card, vh.active, data1, data2); + break; + } + + case VIDEO_SET_SPU: + { + videoSPU_t spu; + + if(copy_from_user(&spu, parg, sizeof(videoSPU_t))) + return -EFAULT; + + return DecoderSPUStream(card, spu.streamID, spu.active); + break; + } + + case VIDEO_SET_SPU_PALETTE: + { + videoSPUPalette_t spup; + + if(copy_from_user(&spup, parg, sizeof(videoSPUPalette_t))) + return -EFAULT; + + return DecoderSPUPalette(card, spup.length, spup.palette); + break; + } + + case VIDEO_GET_NAVI: + { + videoNaviPack_t navi; + + navi.length = DecoderGetNavi(card, (u8 *)&(navi.data)); + if(copy_to_user(parg, &navi, sizeof(videoNaviPack_t))) + return -EFAULT; + } + break; + + case VIDEO_SET_ATTRIBUTES: + { + if (!card->ChannelBuffersAllocated) { + DecoderStreamReset(card); + MargiFlush(card); + + card->setup.streamtype = stream_DVD; + card->setup.videoID = 0; + DecoderPrepareVideo(card); + DecoderPreparePS(card, 0, 0, 2, 2, 3, 1); + } + + SetVideoAttr(card, arg); + card->startingDVDV = 1; + } + break; + + default: + return -ENOIOCTLCMD; + } + return 0; + + case DVB_DEVICE_AUDIO_0: + if (((file->f_flags&O_ACCMODE)==O_RDONLY) && + (cmd!=AUDIO_GET_STATUS)) + return -EPERM; + + switch (cmd) { + + case AUDIO_STOP: + if (card->audiostate.streamSource!=AUDIO_SOURCE_MEMORY) + break; + AudioStopDecode(card); + card->audiostate.playState=AUDIO_STOPPED; + break; + + case AUDIO_PLAY: + if (card->audiostate.streamSource!=AUDIO_SOURCE_MEMORY) + break; + AudioSetPlayMode(card, MAUDIO_PLAY); + card->audiostate.playState=AUDIO_PLAYING; + break; + + case AUDIO_PAUSE: + card->audiostate.playState=AUDIO_PAUSED; + AudioSetPlayMode(card, MAUDIO_PAUSE); + break; + + case AUDIO_CONTINUE: + if (card->audiostate.playState==AUDIO_PAUSED) { + card->audiostate.playState=AUDIO_PLAYING; + AudioSetPlayMode(card, MAUDIO_PLAY); + } + break; + + case AUDIO_SELECT_SOURCE: + card->audiostate.streamSource= + (audioStreamSource_t) arg; + break; + + case AUDIO_SET_MUTE: + { + AudioMute(card, arg); + card->audiostate.muteState=(boolean) arg; + break; + } + + case AUDIO_SET_AV_SYNC: + card->videosync=(boolean) arg; + card->audiostate.AVSyncState=(boolean) arg; + break; + + case AUDIO_SET_BYPASS_MODE: + return -EINVAL; + + case AUDIO_CHANNEL_SELECT: + card->audiostate.channelSelect=(audioChannelSelect_t) arg; + + switch(card->audiostate.channelSelect) { + case AUDIO_STEREO: + break; + + case AUDIO_MONO_LEFT: + break; + + case AUDIO_MONO_RIGHT: + break; + + default: + return -EINVAL; + } + return 0; + + case AUDIO_GET_STATUS: + if(copy_to_user(parg, &card->audiostate, + sizeof(struct audioStatus))) + return -EFAULT; + break; + + case AUDIO_GET_CAPABILITIES: + { + int cap=AUDIO_CAP_LPCM| + AUDIO_CAP_MP1| + AUDIO_CAP_MP2| + AUDIO_CAP_AC3; + + if (copy_to_user(parg, &cap, + sizeof(cap))) + return -EFAULT; + } + break; + + + case AUDIO_SET_STREAMTYPE: + { + int f = -1; + + switch(arg){ + case AUDIO_CAP_DTS: + case AUDIO_CAP_MP3: + case AUDIO_CAP_AAC: + case AUDIO_CAP_SDDS: + case AUDIO_CAP_OGG: + f = audio_none; + break; + + case AUDIO_CAP_LPCM: + f = audio_LPCM; + break; + + case AUDIO_CAP_MP1: + case AUDIO_CAP_MP2: + f = audio_MPEG; + break; + + case AUDIO_CAP_AC3: + f = audio_AC3; + break; + } + + card->setup.audioselect = (audio_type) f; + DecoderPrepareAudio(card); + break; + } + + case AUDIO_SET_ID: + if (arg < 0 || arg >32) arg = 0; + card->setup.audioID = arg; + arg = 0; + case AUDIO_SET_EXT_ID: + if (arg < 0 || arg >32) arg = 0; + card->setup.audioIDext = arg; + + attr = card->lastaattr; + DecoderSelectAudioID(card); + card->lastaattr = attr; + break; + + case AUDIO_SET_MIXER: + return -EINVAL; + + case AUDIO_SET_ATTRIBUTES: + SetAudioAttr(card,arg); + card->startingDVDA = ((card->setup.audioselect != audio_none) + && (card->setup.audioselect != + audio_disable)); + break; + + + case AUDIO_SET_KARAOKE: + { + break; + } + + default: + return -ENOIOCTLCMD; + } + break; + + case DVB_DEVICE_DEMUX_0: + return DmxDevIoctl(&card->dmxdev, file, cmd, arg); + break; + + case DVB_DEVICE_OSD_0: + { + switch (cmd) { + case OSD_SEND_CMD: + { + osd_cmd_t doc; + + if(copy_from_user(&doc, parg, + sizeof(osd_cmd_t))) + return -EFAULT; + return OSD_DrawCommand(card, &doc); + } + default: + return -EINVAL; + } + break; + } + default: + return -EOPNOTSUPP; + } + return 0; +} + +static unsigned int +dvbdev_poll(struct dvb_device *dvbdev, int num, + struct file *file, poll_table * wait) +{ + struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv; + int type=num2type(card, num); + + switch (type) { + case DVB_DEVICE_DEMUX_0: + return DmxDevPoll(&card->dmxdev, file, wait); + + case DVB_DEVICE_VIDEO_0: + return PSpoll(file, wait); + + case DVB_DEVICE_AUDIO_0: + return poll_audio(file, wait); + + case DVB_DEVICE_CA_0: + break; + + default: + return -EOPNOTSUPP; + } + + return 0; +} + + +static int +dvbdev_device_type(struct dvb_device *dvbdev, unsigned int num) +{ + struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv; + + return num2type(card, num); +} +#endif + +/****************************************************************************** + * driver registration + ******************************************************************************/ + + +#ifdef DVB + +#define INFU 32768 + + + +static dvb_devs_t mdvb_devs = { + 9, + { + DVB_DEVICE_VIDEO_0, DVB_DEVICE_AUDIO_0, + -1, -1, + DVB_DEVICE_DEMUX_0, DVB_DEVICE_DVR_0, + -1, -1, + DVB_DEVICE_OSD_0, + }, + { INFU, INFU, INFU, INFU, INFU, 1, 1, INFU, 1 }, + { 1, 1, 1, 1, INFU, 1, 1, 1, 1} +}; + + +static int +dvb_start_feed(dvb_demux_feed_t *dvbdmxfeed) +{ + dvb_demux_t *dvbdmx=dvbdmxfeed->demux; + struct cvdv_cards * card = (struct cvdv_cards *)dvbdmx->priv; + + if (!dvbdmx->dmx.frontend || !card) + return -EINVAL; + + if (dvbdmxfeed->type == DMX_TYPE_TS) { + if ((dvbdmxfeed->ts_type & TS_DECODER) + && (dvbdmxfeed->pes_typedmx.frontend->source) { + case DMX_MEMORY_FE: + if (dvbdmxfeed->ts_type & TS_DECODER) + if (dvbdmxfeed->pes_type<2 && + dvbdmx->pids[0]!=0xffff && + dvbdmx->pids[1]!=0xffff) { + + setup_ts2pes( &card->tsa, + &card->tsv, + dvbdmx->pids, + dvbdmx->pids+1, + pes_write, + (void *)card); + + dvbdmx->playing=1; + } + break; + default: + return -EINVAL; + break; + } + } + } + + if (dvbdmxfeed->type == DMX_TYPE_SEC) { + int i; + + for (i=0; ifilternum; i++) { + if (dvbdmx->filter[i].state!=DMX_STATE_READY) + continue; + if (dvbdmx->filter[i].type!=DMX_TYPE_SEC) + continue; + if (dvbdmx->filter[i].filter.parent!= + &dvbdmxfeed->feed.sec) + continue; + + dvbdmxfeed->feed.sec.is_filtering=1; + dvbdmx->filter[i].state=DMX_STATE_GO; + } + } + + return 0; +} + + +static int +dvb_stop_feed(dvb_demux_feed_t *dvbdmxfeed) +{ + dvb_demux_t *dvbdmx=dvbdmxfeed->demux; + struct cvdv_cards * card = (struct cvdv_cards *)dvbdmx->priv; + if (!card) + return -EINVAL; + + if (dvbdmxfeed->type == DMX_TYPE_TS) { + if ((dvbdmxfeed->ts_type & TS_DECODER) + && (dvbdmxfeed->pes_type<=1)) { + if (dvbdmx->playing) { + free_ipack(&card->tsa); + free_ipack(&card->tsv); + DecoderPause(card); + dvbdmx->playing=0; + } + } + + } + if (dvbdmxfeed->type == DMX_TYPE_SEC) { + int i; + + for (i=0; ifilternum; i++) + if (dvbdmx->filter[i].state==DMX_STATE_GO && + dvbdmx->filter[i].filter.parent== + &dvbdmxfeed->feed.sec) { + dvbdmx->filter[i].state=DMX_STATE_READY; + } + + } + return 0; +} + +static uint16_t get_pid(uint8_t *pid) +{ + uint16_t pp = 0; + + pp = (pid[0] & PID_MASK_HI)<<8; + pp |= pid[1]; + + return pp; +} + + +static int +dvb_write_to_decoder(dvb_demux_feed_t *dvbdmxfeed, uint8_t *buf, size_t count) +{ + dvb_demux_t *dvbdmx=dvbdmxfeed->demux; + struct cvdv_cards * card = (struct cvdv_cards *)dvbdmx->priv; + uint16_t pid = 0; + int off = 0; + + ipack *p; + + if (!card) + return -EINVAL; + + pid = get_pid(buf+1); + + if (pid == *(card->tsa.pid)) p = &(card->tsa); + else if (pid == *(card->tsv.pid)) p = &(card->tsv); + else return 0; + + if (dvbdmxfeed->pes_type>1) + return -1; + if (!(buf[3]&0x10)) // no payload? + return -1; + + if (count != TS_SIZE) return -1; + + if ( buf[3] & ADAPT_FIELD) { // adaptation field? + off = buf[4] + 1; + } + + + if (pid == *(card->tsa.pid)){ + MDEBUG(0,"AUDIO count: %d off: %d\n",count,off); + margi_write_audio(card, buf+off+4, TS_SIZE-4-off, 0); + } else { + MDEBUG(0,"VIDEO count: %d off: %d\n",count,off); + margi_write(card, buf+off+4, TS_SIZE-4-off, 0); + } + +// ts_to_pes( p, buf); // don't need count (=188) + return 0; +} + +int dvb_register(struct cvdv_cards *card) +{ + int i,ret; + struct dvb_device *dvbd=&card->dvb_dev; + + dvb_demux_t *dvbdemux = (dvb_demux_t *)&card->demux; + + if (card->dvb_registered) + return -1; + card->dvb_registered=1; + + card->audiostate.AVSyncState=0; + card->audiostate.muteState=0; + card->audiostate.playState=AUDIO_STOPPED; + card->audiostate.streamSource=AUDIO_SOURCE_MEMORY; + card->audiostate.channelSelect=AUDIO_STEREO; + card->audiostate.bypassMode=0; + + card->videostate.videoBlank=0; + card->videostate.playState=VIDEO_STOPPED; + card->videostate.streamSource=VIDEO_SOURCE_MEMORY; + card->videostate.videoFormat=VIDEO_FORMAT_4_3; + card->videostate.displayFormat=VIDEO_CENTER_CUT_OUT; + + // init and register demuxes + memcpy(card->demux_id, "demux0_0", 9); + card->demux_id[7] = 1+0x30; + dvbdemux->priv = (void *) card; + dvbdemux->filternum = 32; + dvbdemux->feednum = 32; + dvbdemux->start_feed = dvb_start_feed; + dvbdemux->stop_feed = dvb_stop_feed; + dvbdemux->write_to_decoder = dvb_write_to_decoder; + + dvbdemux->dmx.vendor="CIM"; + dvbdemux->dmx.model="sw"; + dvbdemux->dmx.id=card->demux_id; + dvbdemux->dmx.capabilities=(DMX_TS_FILTERING| + DMX_SECTION_FILTERING| + DMX_MEMORY_BASED_FILTERING); + + DvbDmxInit(&card->demux); + + card->dmxdev.filternum=32; + card->dmxdev.demux=&dvbdemux->dmx; + card->dmxdev.capabilities=0; + + DmxDevInit(&card->dmxdev); + + card->mem_frontend.id="mem_frontend"; + card->mem_frontend.vendor="memory"; + card->mem_frontend.model="sw"; + card->mem_frontend.source=DMX_MEMORY_FE; + ret=dvbdemux->dmx.add_frontend(&dvbdemux->dmx, + &card->mem_frontend); + if (ret<0) + return ret; + ret=dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, + &card->mem_frontend); + if (ret<0) + return ret; + + // init and register dvb device structure + dvbd->priv=(void *) card; + dvbd->open=dvbdev_open; + dvbd->close=dvbdev_close; + dvbd->write=dvbdev_write; + dvbd->read=dvbdev_read; + dvbd->ioctl=dvbdev_ioctl; + dvbd->poll=dvbdev_poll; + dvbd->device_type=dvbdev_device_type; + + for (i=0; iusers[i]=card->writers[i]=0; + + card->dvb_devs=0; + card->dvb_devs=&mdvb_devs; + + return dvb_register_device(dvbd); +} + +void dvb_unregister(struct cvdv_cards *card) +{ + dvb_demux_t *dvbdemux=&card->demux; + + dvbdemux->dmx.close(&dvbdemux->dmx); + dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &card->mem_frontend); + DmxDevRelease(&card->dmxdev); + DvbDmxRelease(&card->demux); + dvb_unregister_device(&card->dvb_dev); +} +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/cvdv.h linux.19pre5-ac1/drivers/media/video/margi/cvdv.h --- linux.19p5/drivers/media/video/margi/cvdv.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/cvdv.h Thu Apr 4 15:55:29 2002 @@ -0,0 +1,58 @@ +/* + cvdv.h + + Copyright (C) Christian Wolff for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _CVDV_H_ +#define _CVDV_H_ + + ////////////////////////////////////////////////////////// + // // + // Convergence Digital Video Decoder Card // + // Definitions for the PCI-Card and the Char-Driver // + // // +////////////////////////////////////////////////////////// + + +#include "cardbase.h" +#include "dram.h" +#include "osd.h" +#include "crc.h" +#include "l64021.h" +#include "audio.h" +#include "video.h" +#include "streams.h" +#include "decoder.h" +#include "spu.h" + +void SetVideoSystem(struct cvdv_cards *card); +u16 rnd(u16 range); +// debugging of the card: 0=normal, 1=color bars, 2=sync out +#define USE_DEBUG 0 + +#define cimlogo_width 45 +#define cimlogo_height 38 + +#define CHANNELBUFFERSIZE 32768*8 + +int Prepare(struct cvdv_cards *card); +int OSDTest(struct cvdv_cards *card); +void v4l_init(struct cvdv_cards *card); +int dvb_register(struct cvdv_cards *card); +void dvb_unregister(struct cvdv_cards *card); +#endif // _CVDV_H_ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/cvdvext.h linux.19pre5-ac1/drivers/media/video/margi/cvdvext.h --- linux.19p5/drivers/media/video/margi/cvdvext.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/cvdvext.h Mon Feb 4 22:21:06 2002 @@ -0,0 +1,30 @@ +/* + cvdvtypes.h + + Copyright (C) Christian Wolff for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _CVDVEXT_H_ +#define _CVDVEXT_H_ + +#include +#include "cvdvtypes.h" + +#define OSD_Draw(file,cmd) ioctl(fileno(file),_IO(CVDV_IOCTL_MAGIC,IOCTL_DRAW),&cmd) +#define DecoderCommand(file,cmd) ioctl(fileno(file),_IO(CVDV_IOCTL_MAGIC,IOCTL_DECODER),&cmd) + +#endif // _CVDVEXT_H_ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/cvdvtypes.h linux.19pre5-ac1/drivers/media/video/margi/cvdvtypes.h --- linux.19p5/drivers/media/video/margi/cvdvtypes.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/cvdvtypes.h Mon Feb 4 23:50:05 2002 @@ -0,0 +1,281 @@ +/* + cvdvtypes.h + + Copyright (C) Christian Wolff for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the 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. +*/ + + ///////////////////////////////////////////////// + // // + // Convergence Digital Video Decoder Card // + // External Definitions for the Char-Driver // + // Copyright (c) 1999 Christian Wolff / // + // convergence integrated media GmbH Berlin // + // // +///////////////////////////////////////////////// + +// As of 1999-11-09 + +#ifndef _CVDVTYPE_H_ +#define _CVDVTYPE_H_ + +// our ioctl number: _IOC_TYPE() is 0xA2 (162) and the range of _IOC_NR() is 0x00 to 0x0F. +// submitted 99/10/15 to mec@shout.net +#define CVDV_IOCTL_MAGIC 0xA2 + +// command numbers _IOC_NR() for ioctl +typedef enum { + IOCTL_DRAW = 0x01, + IOCTL_DECODER = 0x02 +} IOCTL_Command; + + +// supported Videosystems +// everything but PAL and NTSC is untested and probably won't work. +typedef enum { + NTSC = 1, // NTSC 29.97 fps + NTSC60, // NTSC 30 fps + PAL, // PAL-B, D, G, H, I, 25 fps + PALM, // PAL-M 29.97 fps + PALM60, // PAL-M 30 fps + PALN, // PAL-N 25 fps + PALNc, // PAL-Nc 25 fps + PAL60 // PAL 30 fps (doesn't work, yet...) +} videosystem; + +typedef enum { + stream_none = 0, // unknown + stream_ES, + stream_PES, + stream_PS, + stream_DVD +} stream_type; + +typedef enum { + audio_disable = -1, + audio_none = 0, // unknown + audio_MPEG, + audio_MPEG_EXT, + audio_LPCM, + audio_AC3, + audio_DTS, + audio_SDDS +} audio_type; + +#if 0 +typedef enum { + // All functions return -2 on "not open" + OSD_Close = 1, // () + // Disables OSD and releases the buffers + // returns 0 on success + OSD_Open, // (x0,y0,x1,y1,BitPerPixel[2/4/8](color&0x0F),mix[0..15](color&0xF0)) + // Opens OSD with this size and bit depth + // returns 0 on success, -1 on DRAM allocation error, -2 on "already open" + OSD_Show, // () + // enables OSD mode + // returns 0 on success + OSD_Hide, // () + // disables OSD mode + // returns 0 on success + OSD_Clear, // () + // Sets all pixel to color 0 + // returns 0 on success + OSD_Fill, // (color) + // Sets all pixel to color + // returns 0 on success + OSD_SetColor, // (color,R{x0},G{y0},B{x1},opacity{y1}) + // set palette entry to , and apply + // R,G,B: 0..255 + // R=Red, G=Green, B=Blue + // opacity=0: pixel opacity 0% (only video pixel shows) + // opacity=1..254: pixel opacity as specified in header + // opacity=255: pixel opacity 100% (only OSD pixel shows) + // returns 0 on success, -1 on error + OSD_SetPalette, // (firstcolor{color},lastcolor{x0},data) + // Set a number of entries in the palette + // sets the entries "firstcolor" through "lastcolor" from the array "data" + // data has 4 byte for each color: + // R,G,B, and a opacity value: 0->transparent, 1..254->mix, 255->pixel + OSD_SetTrans, // (transparency{color}) + // Sets transparency of mixed pixel (0..15) + // returns 0 on success + OSD_SetPixel, // (x0,y0,color) + // sets pixel , to color number + // returns 0 on success, -1 on error + OSD_GetPixel, // (x0,y0) + // returns color number of pixel ,, or -1 + OSD_SetRow, // (x0,y0,x1,data) + // fills pixels x0,y through x1,y with the content of data[] + // returns 0 on success, -1 on clipping all pixel (no pixel drawn) + OSD_SetBlock, // (x0,y0,x1,y1,increment{color},data) + // fills pixels x0,y0 through x1,y1 with the content of data[] + // inc contains the width of one line in the data block, + // inc<=0 uses blockwidth as linewidth + // returns 0 on success, -1 on clipping all pixel + OSD_FillRow, // (x0,y0,x1,color) + // fills pixels x0,y through x1,y with the color + // returns 0 on success, -1 on clipping all pixel + OSD_FillBlock, // (x0,y0,x1,y1,color) + // fills pixels x0,y0 through x1,y1 with the color + // returns 0 on success, -1 on clipping all pixel + OSD_Line, // (x0,y0,x1,y1,color) + // draw a line from x0,y0 to x1,y1 with the color + // returns 0 on success + OSD_Query, // (x0,y0,x1,y1,xasp{color}}), yasp=11 + // fills parameters with the picture dimensions and the pixel aspect ratio + // returns 0 on success + OSD_Test // () + // draws a test picture. for debugging purposes only + // returns 0 on success +// TODO: remove "test" in final version +} OSD_Command; + +struct drawcmd { + OSD_Command cmd; + int x0; + int y0; + int x1; + int y1; + int color; + void *data; +}; +#endif + +typedef enum { + Decoder_Pause, // pause{param1} 0=run 1=pause 2=toggle + Decoder_Still_Put, // (width{param1}, height{param2}, luma{data1}, chroma{data2}) + // show still picture of specified size + // width; width of the image + // height; height of the image + // luma; Y values, one byte per pixel, width*height bytes + // chroma; 4:2:0 U and V values, interlaced, one byte each U, one byte each V, width*height/2 bytes + Decoder_Still_Get, // (width{param1}, height{param2}, luma{data1}, chroma{data2}) + // grab current showing image + // width and height will be set to current picture size + // if luma and croma are NULL, only width and height will be reported + // otherwise the pixel data is filled in there, same format as Still_put + Decoder_Set_Videosystem, // (videosystem{param1}) + // videosystem: see enum {} videosystem; + Decoder_Set_Streamtype, // (streamtype{param1}) + // streamtype: according to enum {} stream_type; + // This has to be set BEFORE you send data to the device + // For ES and PES streams, Audio has to go into the first device (e.g.minor 0) and video into the second (e.g.minor 16) + Decoder_Set_Audiotype, // (audiotype{param1}) + // audiotype: see enum {} audio_type, +16 for IEC956 on S/PDIF out + Decoder_Set_VideoStreamID, // (video stream ID {param1}) + // video stream ID: MPEG ID 0..15 of video stream to display (E0..EF), -1 for any/auto + Decoder_Set_AudioStreamID, // (audio stream ID {param1}, audio extension stream ID {param2}) + // audio stream ID: MPEG ID 0..31 of audio stream to display (C0..DF), -1 for any/auto + // audio extension stream ID: MPEG ID 0..31 of audio extension stream (C0..DF), -1 for none + Decoder_CSS, // Passes CSS information to and from the decoder + // action{param1}, + // data block{data1} MSB first + // execute 1 to 4 once for each disc, then 5 to 8 for each title + // returns 0 on success, <0 on error + // -1: timeout reading data from card + // -2: data pointer not initialized + // -3: invalid action number + // action=0 -> disable and bypass CSS + // Disk key: + // action=1 -> retreive drive challenge (10 byte) from card + // action=2 -> post drive response (5 byte) to card + // action=3 -> post card challenge (10 byte) and retreive card response (5 byte) + // action=4 -> post disk key (2048 byte) into the card + // Title key: + // action=5 -> retreive title challenge (10 byte) from card + // action=6 -> post title response (5 byte) to card + // action=7 -> post card challenge (10 byte) and retreive card response (5 byte) + // action=8 -> post encrypted title key (5 byte) into the card + Decoder_Highlight, // post SPU Highlight information, + // active{param1} + // 1=show highlight, 0=hide highlight + // color information(SL_COLI or AC_COLI){data1[4]} MSB first + // bits: descr. + // 31-28 Emphasis pixel-2 color + // 27-24 Emphasis pixel-1 color + // 23-20 Pattern pixel color + // 19-16 Background pixel color + // 15-12 Emphasis pixel-2 contrast + // 11- 8 Emphasis pixel-1 contrast + // 7- 4 Pattern pixel contrast + // 3- 0 Background pixel contrast + // button position(BTN_POSI){data2[6]} MSB first + // bits: descr. + // 47-46 button color number + // 45-36 start x + // 33-24 end x + // 23-22 auto action mode + // 21-12 start y + // 9- 0 end y + Decoder_SPU, // Activate SPU decoding and select SPU stream ID + // stream{param1} + // active{param2} + Decoder_SPU_Palette, // post SPU Palette information + // length{param1} + // palette{data1} + Decoder_GetNavi, // Retreives CSS-decrypted navigational information from the stream. + // data1 will be filled with PCI or DSI pack (private stream 2 stream_id), + // and the length of data1 (1024 or 0) will be returned + Decoder_SetKaraoke, // Vocal1{param1}, Vocal2{param2}, Melody{param3} + // if Vocal1 or Vocal2 are non-zero, they get mixed into left and right at 70% each + // if both, Vocal1 and Vocal2 are non-zero, Vocal1 gets mixed into the left channel and + // Vocal2 into the right channel at 100% each. + // if Melody is non-zero, the melody channel gets mixed into left and right + Decoder_Set_Videoattribute, // Set the video parameters + // attribute{param1} (2 byte V_ATR) + // bits: descr. + // 15-14 Video compression mode (0=MPEG-1, 1=MPEG-2) + // 13-12 TV system (0=525/60, 1=625/50) + // 11-10 Aspect ratio (0=4:3, 3=16:9) + // 9- 8 permitted display mode on 4:3 monitor (0=both, 1=only pan-scan, 2=only letterbox) + // 7 line 21-1 data present in GOP (1=yes, 0=no) + // 6 line 21-2 data present in GOP (1=yes, 0=no) + // 5- 3 source resolution (0=720x480/576, 1=704x480/576, 2=352x480/576, 3=352x240/288) + // 2 source letterboxed (1=yes, 0=no) + // 0 film/camera mode (0=camera, 1=film (625/50 only)) + Decoder_Set_Audioattribute, // Set the audio parameters + // attribute{param1} (2 most significan bytes of A_ATR (bit 63 through 48)) + // bits: descr. + // 15-13 audio coding mode (0=ac3, 2=mpeg1, 3=mpeg2ext, 4=LPCM, 6=DTS, 7=SDDS) + // 12 multichannel extension + // 11-10 audio type (0=not spec, 1=language included) + // 9- 8 audio application mode (0=not spec, 1=karaoke, 2=surround) + // 7- 6 Quantization / DRC (mpeg audio: 1=DRC exists)(lpcm: 0=16bit, 1=20bit, 2=24bit) + // 5- 4 Sample frequency fs (0=48kHz, 1=96kHz) + // 2- 0 number of audio channels (n+1 channels) + Decoder_WriteBlock, // Post one block of data, e.g. one DVD sector of 2048 byte, into the decoder queue + // sectordata{data1} + // length{param1} + // is_initial_block{param2} + // set_SCR{param3} + /* + Decoder_FFWD, // ffwd{param1} 0=normal 1=ffwd 2=toggle + Decoder_Slow // slow{param1} 0=normal 1=slow 2=toggle + */ +} Decoder_Command; + +struct decodercmd { + Decoder_Command cmd; + int param1; + int param2; + int param3; + int param4; + int param5; + void *data1; + void *data2; +}; + +#endif // _CVDVTYPE_H_ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/decoder.c linux.19pre5-ac1/drivers/media/video/margi/decoder.c --- linux.19p5/drivers/media/video/margi/decoder.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/decoder.c Mon Feb 4 22:21:07 2002 @@ -0,0 +1,1536 @@ +/* + decoder.c + + Copyright (C) Christian Wolff for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define __NO_VERSION__ + +#include "decoder.h" +#include "l64021.h" +#include "video.h" +#include "audio.h" +#include "streams.h" +#include "osd.h" +#include "dram.h" +#include "cvdv.h" + +int DecoderGetNavi(struct cvdv_cards *card, u8 *navidata) +{ + if (card->navihead == card->navitail) return 0; + MDEBUG(3, ": Retreiving NaviPack\n"); + memcpy(navidata, &card->navibuffer[card->navitail], NAVISIZE); + card->navitail += NAVISIZE; + if (card->navitail >= NAVIBUFFERSIZE) card->navitail = 0; + return NAVISIZE; +} + +// returns 1 on overrun, 0 on no error +int DecoderQueueNavi(struct cvdv_cards *card, u8 *navidata) +{ + memcpy(&card->navibuffer[card->navihead], navidata, NAVISIZE); + card->navihead += NAVISIZE; + if (card->navihead >= NAVIBUFFERSIZE) card->navihead = 0; + if (card->navihead == card->navitail) { + MDEBUG(3, ": NaviPack buffer overflow\n"); + card->navitail += NAVISIZE; + if (card->navitail >= NAVIBUFFERSIZE) card->navitail = 0; + return 1; + } + return 0; +} + +u32 ParseSCR(const u8 *data) +{ + u32 SCR_base=0; + u8 scrdata[9]; + copy_from_user (scrdata, data, 9); + + if ((!scrdata[0]) && (!scrdata[1]) && (scrdata[2]==1) + && (scrdata[3]==0xBA) && ((scrdata[4]&0xC0)==0x40)) { + SCR_base=((scrdata[4]>>3)&0x07); + SCR_base=(SCR_base<<2) | (scrdata[4]&0x03); + SCR_base=(SCR_base<<8) | scrdata[5]; + SCR_base=(SCR_base<<5) | ((scrdata[6]>>3)&0x1F); + SCR_base=(SCR_base<<2) | (scrdata[6]&0x03); + SCR_base=(SCR_base<<8) | scrdata[7]; + SCR_base=(SCR_base<<5) | ((scrdata[8]>>3)&0x1F); + } + return SCR_base; +} + +u32 SetSCR(struct cvdv_cards *card, u32 SCR_base) +{ + MDEBUG(3, ": SCR in DVD Pack: 0x%08X\n",SCR_base); + if (DecoderReadByte(card, 0x007) & 0x10) { // SCR already stopped + DecoderWriteByte(card,0x009,SCR_base&0xFF); // Set SCR counter + DecoderWriteByte(card,0x00A,(SCR_base>>8)&0xFF); + DecoderWriteByte(card,0x00B,(SCR_base>>16)&0xFF); + DecoderWriteByte(card,0x00C,(SCR_base>>24)&0xFF); + } else { + DecoderMaskByte(card,0x007,0xD2,0xD2); + // Set 0x10, halt SCR counter + DecoderWriteByte(card,0x009,SCR_base&0xFF); // Set SCR counter + DecoderWriteByte(card,0x00A,(SCR_base>>8)&0xFF); + DecoderWriteByte(card,0x00B,(SCR_base>>16)&0xFF); + DecoderWriteByte(card,0x00C,(SCR_base>>24)&0xFF); + DecoderMaskByte(card,0x007,0xD2,0xC2); + // Del 0x10, SCR counter run + } + return SCR_base; +} + +void DecoderPause(struct cvdv_cards *card) +{ + DecoderMaskByte(card, 0x007, 0xD2, 0xD2); + // Set 0x010, halt SCR counter + AudioSetPlayMode(card, MAUDIO_PAUSE); + DecoderStopDecode(card); +#ifdef DVB + card->videostate.playState=VIDEO_FREEZED; +#endif + card->videoffwd = 0; + card->videoslow = 0; +} + +void DecoderUnPause(struct cvdv_cards *card) +{ + DecoderStartDecode(card); + card->videoffwd = 0; + AudioSetPlayMode(card, MAUDIO_PLAY); + DecoderMaskByte(card, 0x007, 0xD2, 0xC2); + // Del 0x010, SCR counter run +#ifdef DVB + card->videostate.playState=VIDEO_PLAYING;; +#endif + card->videoslow = 0; +} + +void CloseCard(struct cvdv_cards *card) +{ +#ifdef NOINT + spin_lock(&card->timelock); + del_timer(&card->timer); + spin_unlock(&card->timelock); +#endif + MargiFlush(card); + MDEBUG(1, ": Closing card\n"); + card->DecoderOpen = 1; + DecoderClose(card); + DecoderUnPrepare(card); + DecoderStreamReset(card); + DecoderSetupReset(card); + VideoSetBackground(card, 1, 0, 0, 0); + + AudioClose(card); + OSDClose(card); + L64021Init(card); + MargiFreeBuffers(card); + + OSDOpen(card, 50, 50, 150, 150, 2, 1); + OSDTest(card); +} + + +void DecoderReadAudioInfo(struct cvdv_cards *card) +{ + u8 data; + static int bitrates[17] = {0, 32, 40, 48, 56, 64, 80, 96, 112, + 128, 160, 192, 224, 256, 320, 384, 0}; + struct AudioParam *audio = &card->stream.audio; + data = DecoderReadByte(card, 0x150); + audio->mpeg.present = data & 0x60; + // MPEG Layer Code 00 reserverd, we can assume valid MPEG params + if (audio->mpeg.present) { + audio->mpeg.MPEG2 = data & 0x80; + audio->mpeg.layer = 4 - ((data >> 5) & 0x03); + if (data & 0x0F) { + if ((data & 0x0F) == 1) audio->mpeg.bitrate = 32; + else switch (audio->mpeg.layer) { + case 1: + audio->mpeg.bitrate = 32 * (data & 0x0F); + break; // Layer I + case 2: + audio->mpeg.bitrate = bitrates[(data & 0x0F) + + 1]; + break; // Layer II + default: + audio->mpeg.bitrate = bitrates[data & 0x0F]; + // Layer III + } + } else audio->mpeg.bitrate = 0; + data = DecoderReadByte(card, 0x151); + switch ((data >> 6) & 0x03) { + case 0: + audio->mpeg.samplefreq = 44; + break; + case 1: + audio->mpeg.samplefreq = 48; + break; + case 2: + audio->mpeg.samplefreq = 32; + break; + default: + audio->mpeg.samplefreq = 0; // invalid + } + audio->mpeg.mode = (data >> 3) & 0x03; + audio->mpeg.modeext = (data >> 1) & 0x03; + audio->mpeg.copyright = data & 0x01; + data=DecoderReadByte(card, 0x152); + audio->mpeg.original = data & 0x80; + audio->mpeg.emphasis = (data >> 5) & 0x03; + } + data = DecoderReadByte(card, 0x153); + audio->ac3.present = (data != 0); + // value 0 for bits 0..5 forbidden, we can assume valid ac3 params + if (audio->ac3.present) { + audio->ac3.acmod = (data >> 5) & 0x07; + audio->ac3.dialnorm = data & 0x1F; + data = DecoderReadByte(card, 0x154); + audio->ac3.bsmod = (data >> 5) & 0x07; + audio->ac3.dialnorm2 = data > 0x1F; + data = DecoderReadByte(card, 0x155); + audio->ac3.surmixlev = (data >> 6) & 0x03; + audio->ac3.mixlevel = (data >> 1) & 0x1F; + data = DecoderReadByte(card, 0x156); + audio->ac3.cmixlev = (data >> 6) & 0x03; + audio->ac3.mixlevel2 = (data >> 1) & 0x1F; + data = DecoderReadByte(card, 0x157); + audio->ac3.fscod = (data >> 6) & 0x03; + audio->ac3.lfeon = (data >> 5) & 0x01; + audio->ac3.bsid = data & 0x1F; + data = DecoderReadByte(card, 0x158); + audio->ac3.dsurmod = (data >> 6) & 0x03; + audio->ac3.frmsizecod = data & 0x3F; + audio->ac3.langcod = DecoderReadByte(card, 0x159); + audio->ac3.langcod2 = DecoderReadByte(card, 0x15A); + audio->ac3.timecod = DecoderReadByte(card, 0x15B); + data = DecoderReadByte(card, 0x15C); + audio->ac3.timecod = (audio->ac3.timecod << 6) | + ((data >> 2) & 0x3F); + audio->ac3.roomtyp = data & 0x03; + audio->ac3.timecod2 = DecoderReadByte(card, 0x15D); + data = DecoderReadByte(card, 0x15E); + audio->ac3.timecod2 = (audio->ac3.timecod2 << 6) | + ((data >> 2) & 0x3F); + audio->ac3.roomtyp2 = data & 0x03; + } + audio->pcm.present =! (DecoderReadByte(card, 0x161) & 0x20); + // PCM FIFO not empty? Then, we can assume valid LPCM params + if (audio->pcm.present) { + data = DecoderReadByte(card, 0x15F); + audio->pcm.audio_frm_num = (data >> 3) & 0x1F; + audio->pcm.num_of_audio_ch = data & 0x07; + data = DecoderReadByte(card, 0x160); + audio->pcm.Fs = (data >> 6) & 0x03; + audio->pcm.quantization = (data >> 4) & 0x03; + audio->pcm.emphasis = (data >> 2) & 0x03; + audio->pcm.mute_bit = (data >> 1) & 0x01; + } + switch (card->setup.audioselect) { + case audio_disable: + audio->valid = 0; + break; + case audio_none: + case audio_DTS: + case audio_SDDS: + if ((audio->valid = (audio->ac3.present || + audio->pcm.present || + audio->mpeg.present))) { + if (audio->mpeg.present) { + card->setup.audioselect = audio_MPEG; + } else if (audio->pcm.present) { + card->setup.audioselect = audio_LPCM; + } else if (audio->ac3.present) { + card->setup.audioselect = audio_AC3; + } + } else { + audio->valid = 0; + card->setup.audioselect = audio_none; + } + break; + case audio_MPEG: // MPEG Audio + case audio_MPEG_EXT: // MPEG Audio with extension stream + audio->valid = audio->mpeg.present; + break; + case audio_LPCM: // Linear Pulse Code Modulation LPCM + audio->valid = audio->pcm.present; + break; + case audio_AC3: // AC-3 + audio->valid = audio->ac3.present; + break; + } + MDEBUG(1, ": -- DecoderReadAudioInfo - type/valid %d/%d:\n", card->setup.audioselect, audio->valid); + if (audio->mpeg.present || audio->ac3.present || audio->pcm.present) + MDEBUG(1, ": Audio - Decoded parameters:\n"); + if (audio->mpeg.present) MDEBUG(1, ": MPEG%s Layer %d, %d kHz, %d kbps, %s, %s%s, %s emphasis\n", + ((audio->mpeg.MPEG2) ? "2" : "1"), + audio->mpeg.layer, + audio->mpeg.samplefreq, + audio->mpeg.bitrate, + ((audio->mpeg.mode == 0) ? "stereo" : ((audio->mpeg.mode == 1) ? "joint stereo" : ((audio->mpeg.mode == 2) ? "dual channel" : "single channel"))), + ((audio->mpeg.copyright) ? "copyrighted " : ""), + ((audio->mpeg.original) ? "original" : "copy"), + ((audio->mpeg.emphasis == 0) ? "no" : ((audio->mpeg.emphasis == 1) ? "50/15 usec." : ((audio->mpeg.emphasis == 2) ? "invalid" : "J.17"))) + ); + if (audio->ac3.present) MDEBUG(1, ": AC3 acmod=%d bsmod=%d dialnorm=%d dialnorm2=%d surmixlev=%d mixlevel=%d cmixlev=%d mixlevel2=%d fscod=%d lfeon=%d bsid=%d dsurmod=%d frmsizecod=%d langcod=%d langcod2=%d timecod=%d roomtyp=%d timecod2=%d roomtyp2=%d\n", + audio->ac3.acmod, + audio->ac3.bsmod, + audio->ac3.dialnorm, + audio->ac3.dialnorm2, + audio->ac3.surmixlev, + audio->ac3.mixlevel, + audio->ac3.cmixlev, + audio->ac3.mixlevel2, + audio->ac3.fscod, + audio->ac3.lfeon, + audio->ac3.bsid, + audio->ac3.dsurmod, + audio->ac3.frmsizecod, + audio->ac3.langcod, + audio->ac3.langcod2, + audio->ac3.timecod, + audio->ac3.roomtyp, + audio->ac3.timecod2, + audio->ac3.roomtyp2); + if (audio->pcm.present) MDEBUG(1, ": LPCM audio_frm_num=%d num_of_audio_ch=%d Fs=%d quantization=%d emphasis=%d mute_bit=%d\n", + audio->pcm.audio_frm_num, + audio->pcm.num_of_audio_ch, + audio->pcm.Fs, + audio->pcm.quantization, + audio->pcm.emphasis, + audio->pcm.mute_bit); +} + +void DecoderReadAuxFifo(struct cvdv_cards *card) +{ + int i = 0; + u8 data; + int layer; + + struct StreamInfo *stream = &card->stream; + MDEBUG(3, ": AUX - %03X ", card->AuxFifo[card->AuxFifoTail]); + while (card->AuxFifoHead != card->AuxFifoTail) { + + layer = (card->AuxFifo[card->AuxFifoTail] >> 8) & 0x07; + data = card->AuxFifo[card->AuxFifoTail] & 0xFF; + card->AuxFifoTail = (card->AuxFifoTail + 1) & FIFO_MASK; + if (layer != card->AuxFifoLayer) { // start of a new layer? + i = 0; + card->AuxFifoLayer = layer; + } else i++; + switch (layer) { // layer code + case 0: // sequence header + if (! stream->sh.valid) switch (i) { + case 0: + stream->sh.hsize = data & 0x0F; + break; + case 1: + stream->sh.hsize = (stream->sh.hsize << 8) + | data; + stream->hsize = stream->sh.hsize; + break; + case 2: + stream->sh.vsize = data & 0x0F; + break; + case 3: + stream->sh.vsize = (stream->sh.vsize << 8) | + data; + stream->vsize = stream->sh.vsize; + break; + case 4: + stream->sh.aspectratio = data & 0x0F; + break; + case 5: + stream->sh.frameratecode = data & 0x0F; + break; + case 6: + stream->sh.bitrate = data & 0x03; + break; + case 7: + stream->sh.bitrate = (stream->sh.bitrate << 8) + | data; + break; + case 8: + stream->sh.bitrate = (stream->sh.bitrate << 8) + | data; + stream->bitrate = stream->sh.bitrate; + break; + case 9: + stream->sh.vbvbuffersize = data & 0x03; + break; + case 10: + stream->sh.vbvbuffersize = + (stream->sh.vbvbuffersize << 8) | + data; + stream->vbvbuffersize = + stream->sh.vbvbuffersize; + break; + case 11: + stream->sh.constrained = data & 0x01; + stream->sh.valid = 1; + MDEBUG(1, ": AUX - MPEG1 - %dx%d %s %s fps, %d bps, %d kByte vbv%s\n", stream->sh.hsize, stream->sh.vsize, + ((stream->sh.aspectratio == 1) ? "1:1" : + ((stream->sh.aspectratio == 2) ? "3:4" : + ((stream->sh.aspectratio == 3) ? "9:16" : + ((stream->sh.aspectratio == 4) ? "1:2.21" : + "?:?")))), + ((stream->sh.frameratecode == 1) ? "23.976" : + ((stream->sh.frameratecode == 2) ? "24" : + ((stream->sh.frameratecode == 3) ? "25" : + ((stream->sh.frameratecode == 4) ? "29.97" : + ((stream->sh.frameratecode == 5) ? "30" : + ((stream->sh.frameratecode == 6) ? "50" : + ((stream->sh.frameratecode == 7) ? "59.94" : + ((stream->sh.frameratecode == 8) ? "60" : + "?")))))))), + stream->sh.bitrate * 400, + stream->sh.vbvbuffersize * 16, + ((stream->sh.constrained) ? ", constrained" : "") + ); + break; + } + break; + case 1: // group of pictures + if (! stream->gop.valid) + switch (i) { + case 0: + stream->gop.timecode = data & 0x01; + break; + case 1: + stream->gop.timecode = + (stream->gop.timecode << 8) | + data; + break; + case 2: + stream->gop.timecode = + (stream->gop.timecode << 8) | + data; + break; + case 3: + stream->gop.timecode = + (stream->gop.timecode << 8) | + data; + break; + case 4: + stream->gop.closedgop = data & 0x01; + break; + case 5: + stream->gop.brokenlink = data & 0x01; + stream->gop.valid = 1; + break; + } + break; + case 2: // picture + if (0) + switch (i) { + case 0: + break; + } + break; + case 7: // extension layer + if (i == 0) card->AuxFifoExt = data; + else + switch (card->AuxFifoExt) { // extension code + case 1: // sequence extension + if ((stream->sh.valid) && + (! stream->se.valid)) + switch (i) { + case 1: + stream->se.profilelevel + = data; + break; + case 2: + stream->se.progressive + = data & 0x01; + break; + case 3: + stream->se.chroma = + (data >> 4) & + 0x03; + stream->se.hsizeext = + (data >> 2) & + 0x03; + stream->se.vsizeext = + data & 0x03; + stream->hsize |= + (stream->se.hsizeext << 12); + stream->vsize |= + (stream->se.vsizeext << 12); + break; + case 4: + stream->se.bitrateext = + data & 0x0F; + break; + case 5: + stream->se.bitrateext = + (stream->se.bitrateext << 8) | data; + stream->bitrate |= + (stream->se.bitrateext << 18); + break; + case 6: + stream->se.vbvbuffersizeext = data; + stream->vbvbuffersize |= (stream->se.vbvbuffersizeext << 10); + break; + case 7: + stream->se.lowdelay = + (data >> 7) & + 0x01; + stream->se.frextn = + (data >> 5) & + 0x03; + stream->se.frextd = + data & 0x1F; + stream->se.valid = 1; + stream->MPEG2 = 1; + MDEBUG(1, ": AUX - MPEG2 - %dx%d %s %s*%d/%d fps, %d bps, %d kByte vbv%s%s\n", stream->hsize, stream->vsize, + ((stream->sh.aspectratio == 1) ? "1:1" : + ((stream->sh.aspectratio == 2) ? "3:4" : + ((stream->sh.aspectratio == 3) ? "9:16" : + ((stream->sh.aspectratio == 4) ? "1:2.21" : + "?:?")))), + ((stream->sh.frameratecode == 1) ? "23.976" : + ((stream->sh.frameratecode == 2) ? "24" : + ((stream->sh.frameratecode == 3) ? "25" : + ((stream->sh.frameratecode == 4) ? "29.97" : + ((stream->sh.frameratecode == 5) ? "30" : + ((stream->sh.frameratecode == 6) ? "50" : + ((stream->sh.frameratecode == 7) ? "59.94" : + ((stream->sh.frameratecode == 8) ? "60" : + "?")))))))), + stream->se.frextn + 1, + stream->se.frextd + 1, + stream->bitrate * 400, + stream->vbvbuffersize * 16, + ((stream->sh.constrained) ? ", constrained" : ""), + ((stream->se.lowdelay) ? ", low delay" : "") + ); + break; + } + break; + case 2: // sequence display extension + if (0) + switch (i) { + case 0: + break; + } + break; + case 3: // quant matrix extension + if (0) + switch (i) { + case 0: + break; + } + break; + case 4: // copyright extension + if (0) + switch (i) { + case 0: + break; + } + break; + case 7: // picture display extension + if (0) switch (i) { + case 0: + break; + } + break; + case 8: // picture coding extension + if (0) + switch (i) { + case 0: + break; + } + break; + default: + break; + } + break; + default:break; + } + + } +} + +void DecoderReadDataFifo(struct cvdv_cards *card) +{ + MDEBUG(3, ": DATA - "); + while (card->DataFifoHead != card->DataFifoTail) { + MDEBUG(3,"%03X ", card->DataFifo[card->DataFifoTail]); + card->DataFifoTail = (card->DataFifoTail + 1) & FIFO_MASK; + } + MDEBUG(3,"\n"); +} + +int DecoderReadNavipack(struct cvdv_cards *card) +{ + u32 startaddr, endaddr, writeaddr; + u8 navipack[1024]; + u16 PacketLength; + u8 SubStreamID; + //struct Navi navi; + int i; + startaddr = (DecoderReadWord(card, 0x05C) & 0x3FFF) << 7; + // 21 bit word address + endaddr = (DecoderReadWord(card, 0x05E) & 0x3FFF) << 7; + // 21 bit word address + writeaddr = DecoderReadByte(card, 0x075) & 0xFF; + writeaddr |= (DecoderReadWord(card, 0x077) & 0x0FFF) << 8; + //writeaddr <<= 3; + MDEBUG(3, ": -- DecoderReadNavipack 0x%08X-0x%08X, ->0x%08X <-0x%08X\n", + startaddr, endaddr, writeaddr, card->NaviPackAddress); + + if (DecoderReadByte(card, 0x07B) & 0xC0) { // navi pack available? + DRAMReadByte(card, card->NaviPackAddress, 1024, navipack, 0); + card->reg07B |= 0x20; // decrement navi counter + DecoderWriteByte(card, 0x07B, card->reg07B); + card->reg07B &= ~0x20; + //DecoderSetByte(card, 0x07B, 0x20); // decrement navi counter + card->NaviPackAddress += 512; // increment in words + if (card->NaviPackAddress >= endaddr) + card->NaviPackAddress = startaddr; + MDEBUG(4, ": Navipack %02X %02X %02X %02X %02X %02X %02X %02X\n", + navipack[0], navipack[1], navipack[2], navipack[3], navipack[4], + navipack[5], navipack[6], navipack[7]); + if ((!navipack[0]) && (!navipack[1]) && (navipack[2] == 1) && + (navipack[3] == 0xBF)) { + PacketLength = (navipack[4] << 8) | navipack[5]; + SubStreamID = navipack[6]; + MDEBUG(4, ": Navipack Len=%d, ID=%d\n", PacketLength, SubStreamID); + i = 7; // start of payload data in navipack[] + switch (SubStreamID) { + case 0: // Presentation Control Information (PCI) + if (PacketLength < 980) return 1; // Packet too small + DecoderQueueNavi(card, navipack); + break; + case 1: // Data Search Information (DSI) + if (PacketLength < 1018) return 1; // Packet too small + DecoderQueueNavi(card, navipack); + break; + default: + break; + } + } else { + MDEBUG(4, "navipack format error:%02X %02X %02X %02X %02X %02X %02X %02X\n", + navipack[0], navipack[1], navipack[2], navipack[3], navipack[4], + navipack[5], navipack[6], navipack[7]); + } + } else { + MDEBUG(4, ": no navi pack avail.\n"); + } + return 0; +} + +int AudioStart(struct cvdv_cards *card) +{ + DecoderReadAudioInfo(card); // detect audio type + if (card->stream.audio.valid) { + MDEBUG(1, ": Audio Init in delayed decoder start\n"); + if (card->AudioInitialized) AudioClose(card); + switch (card->setup.audioselect) { + case audio_MPEG: // MPEG Audio + case audio_MPEG_EXT: // MPEG Audio with ext. + MDEBUG(1, ": Using MPEG Audio\n"); + AudioInit(card, card->stream.audio.mpeg.samplefreq, 0); + if (card->stream.audio.mpeg.mode == 3) AudioDualMono(card, 2); // left channel only + else AudioDualMono(card, 0); + break; + case audio_DTS: + case audio_LPCM: // Linear Pulse Code Modulation LPCM + MDEBUG(1, ": Using LPCM Audio\n"); + AudioInit(card, 48, 0); // or 96 + break; + case audio_AC3: // AC-3 + MDEBUG(1, ": Using AC-3 Audio\n"); + switch (card->stream.audio.ac3.fscod) { + case 0:AudioInit(card, 48, 0); break; + case 1:AudioInit(card, 44, 0); break; + case 2:AudioInit(card, 32, 0); break; + } + break; + case audio_none: + case audio_disable: + case audio_SDDS: + } + } else return 1; + return 0; +} + +u32 DecoderReadSCR(struct cvdv_cards *card, u16 address) +{ + u32 SCR; + SCR = DecoderReadByte(card, address); + SCR |= ((u32)DecoderReadByte(card, address+1) << 8); + SCR |= ((u32)DecoderReadByte(card, address+2) << 16); + SCR |= ((u32)DecoderReadByte(card, address+3) << 24); + return SCR; +} + +u32 DecoderReadRWAddr(struct cvdv_cards *card, u16 address) +{ + u32 addr; + addr = DecoderReadByte(card, address) & 0xFF; + addr |= (((u32)DecoderReadByte(card, address+1) & 0xFF) << 8); + addr |= (((u32)DecoderReadByte(card, address+2) & 0x0F) << 16); + return addr; +} + +int PTSGetFirstPTS(PTSStorage *store, u32 *PTS) +{ + if ( store->end == store->begin ) { + return 0; + } else { + *PTS = store->PTS[store->begin]; + return 1; + } +} + +void PTSStoreAdd(PTSStorage *store, u32 PTS, u32 AddrB, u32 AddrE) +{ + int new; + MDEBUG(3, ": PTSStoreAdd - store in [%d] %08X - %08X\n", store->end, AddrB, AddrE); + + // cheap fix: don't store if address rollover + if ((AddrB & 0x00080000) != (AddrE & 0x00080000)) return; + + new = store->end; + + store->end++; + if (store->end >= store->size) store->end = 0; + if (store->end == store->begin) { + store->begin++; + if (store->begin >= store->size) store->begin = 0; + } + + store->AddrB[new] = AddrB; + store->AddrE[new] = AddrE; + store->PTS[new] = PTS; +} + +int PTSGetPTS (PTSStorage *store, u32 Addr, u32 *PTS ) +{ + u32 AddrB; + u32 AddrE; + int i; + int found; + int search; + + MDEBUG(3, ": PTSGetPTS - search %08X\n", Addr); + + if (store->end == store->begin) { + store->LastAddr = Addr; + return 0; + } + + // Search for the PTS in the array + found = 0; + search = 1; + while (search && !found) { + // Get the first value + i = store->begin; + AddrB = store->AddrB[i]; + AddrE = store->AddrE[i]; + + MDEBUG(3, ": PTSGetPTS - search in [%d] %08X - %08X\n", i, AddrB, AddrE); + + //If in range, keep it + if ((Addr >= AddrB) && (Addr <= AddrE)) { + *PTS = store->PTS[i]; + found = 1; + } else { + if ((Addr & 0x00080000) == (AddrB & 0x00080000)) { + if (Addr < AddrB ) search = 0; + } else { + if ((store->LastAddr & 0x00080000) == (Addr & 0x00080000)) search = 0; + } + } + if (search) { + store->begin++; + if (store->begin >= store->size) store->begin = 0; + if (store->end == store->begin ) search = 0; + } + } + store->LastAddr = Addr; + return found; +} + + +u32 GetPTS(u8 *data, u32* MediaPointer, int mpeg, int hlength,int off) +{ + u32 PTS = 0xFFFFFFFFUL; + int p = 0; + + // Read PTS, if present + if ((mpeg == 2 && data[p + 7] & 0x80) || + (mpeg == 1 && off)) { + if (mpeg == 1) p = off-9; + PTS = (data[p + 9] >> 1) & 0x03UL; + PTS = (PTS << 8) | (data[p + 10] & 0xFFUL); + PTS = (PTS << 7) | ((data[p + 11] >> 1) & 0x7FUL); + PTS = (PTS << 8) | (data[p + 12] & 0xFFULL); + PTS = (PTS << 7) | ((data[p + 13] >> 1) & 0x7FUL); + } + // Now, skip rest of PES header and stuffing + if (mpeg == 2){ + p += (9 + (data[p + 8] & 0xFF)); + p = ((p + 7) / 8) * 8; + } else p = hlength+7; + if (!(data[p++] | data[p++] | data[p++] | data[p++])) { + *MediaPointer = (u32)data[p++] & 0xFF; + *MediaPointer = (*MediaPointer << 8) | ((u32)data[p++] & 0xFF); + *MediaPointer = (*MediaPointer << 8) | ((u32)data[p++] & 0xFF); + *MediaPointer = (*MediaPointer << 8) | ((u32)data[p++] & 0xFF); + } else { + *MediaPointer = 0xFFFFFFFFUL; + } + return PTS; +} + +int ReadPESChunk(struct cvdv_cards *card, u32 *addr, u8 *data, u32 start, u32 end) +{ + int i = 5, err = -1; + while (err && (i--)) err &= DRAMReadByte(card, *addr << 2, 8, &data[0], 0); + if (err) return 1; + (*addr)++; + if (*addr >= end) *addr = start; + return 0; +} + +void ReadPESHeaders(struct cvdv_cards *card) +{ + u8 startcode[] = {0x00, 0x00, 0x01}; + int LoopCount; + u32 LastVAddr; // Current Video Address + u32 LastAAddr; // Current Audio Address + u32 Addr; // Current Header Address + u32 PESAddr; // Pointer from Header Block + u32 PTS; // PTS from Header Block + u8 Data[32]; + u32 AudioPESStart; + u32 AudioPESEnd; + int i, j, p, fail; + u32 FailAddr; + int hlength=0; + int mpeg=0; + int check; + int mp=0; + int off=0; + + AudioPESStart = (DecoderReadWord(card, 0x058) & 0x3FFF) << 5; + AudioPESEnd = ((DecoderReadWord(card, 0x05A) & 0x3FFF) + 1) << 5; + + LastVAddr = DecoderReadRWAddr(card, 0x060); + LastAAddr = DecoderReadRWAddr(card, 0x063); + + if (card->LastAddr == 0) card->LastAddr = AudioPESStart; + + //Read the PES header buffer + Addr = DecoderReadRWAddr(card, 0x072) & 0x0007FFFF; + if (Addr >= AudioPESEnd) { + Addr = card->LastAddr = AudioPESStart; + } + + LoopCount = 0; + while ((card->LastAddr != Addr) && (LoopCount++ < 200)) { + FailAddr = card->LastAddr; + fail = 0; + p = 0; + + if (ReadPESChunk(card, &card->LastAddr, &Data[p], + AudioPESStart, AudioPESEnd)) continue; + p+=8; + j=1; + + if (memcmp(Data, startcode, 3)) continue; + if ((Data[3] == 0xE0) || (Data[3] == 0xBD) + || ((Data[3] & 0xE0) == 0xC0)) { + + fail |= ReadPESChunk(card, &card->LastAddr, + &Data[p], AudioPESStart, + AudioPESEnd); + + + p+=8; + j++; + if ( (Data[6] & 0xC0) == 0x80 ){ + hlength = 9+Data[8]; + mpeg = 2; + } else { + mpeg = 1; + mp = 6; + check = Data[mp]; + mp++; + while (check == 0xFF){ + if (!fail && mp == p) { + fail |= ReadPESChunk( + card, + &card->LastAddr, + &Data[p], + AudioPESStart, + AudioPESEnd); + p+=8; + j++; + } + check = Data[mp]; + mp++; + } + if (!fail && mp == p) { + fail |= ReadPESChunk( + card, + &card->LastAddr, + &Data[p], + AudioPESStart, + AudioPESEnd); + p+=8; + j++; + } + + if ( !fail && (check & 0xC0) == 0x40){ + check = Data[mp]; + mp++; + if (!fail && mp == p) { + fail |= ReadPESChunk( + card, + &card->LastAddr, + &Data[p], + AudioPESStart, + AudioPESEnd); + p+=8; + j++; + } + check = Data[mp]; + mp++; + } + if ( !fail && (check & 0x20)){ + if (check & 0x30) hlength = mp+10; + else hlength = mp+5; + off = mp-1; + } + } + + for (i = 1; (i < ((hlength+7) / 8)) && (!fail); + i++) { + fail |= ReadPESChunk(card, &card->LastAddr, + &Data[p], AudioPESStart, + AudioPESEnd); + p+=8; + j++; + } + + if (!fail) { + PTS = GetPTS(Data, &PESAddr, + mpeg, hlength,off); + if ((PTS != 0xFFFFFFFF) && + (PESAddr != 0xFFFFFFFF)) { + if (Data[3] == 0xE0) { // Video + PTSStoreAdd(&card->VideoPTSStore, PTS, PESAddr, LastVAddr); + } else { // Audio + PTSStoreAdd(&card->AudioPTSStore, PTS, PESAddr, LastAAddr); + } + } + } + } else { + //card->LastAddr = Addr; + } + // In case of error, rewind and try again + if (fail) card->LastAddr = FailAddr; + } +} + +void L64021Intr(struct cvdv_cards *card) +{ + u32 SCR_base, SCR_compareV, SCR_compareA; + u32 VideoAddr, AudioAddr, PTS; + int i, a, v, as, vs, ap, vp; + u8 intr[5]; + u8 layer; + long ISRTime, DeltaSyncTime, Offset; + + int used = 0; + u8 err; + + err = DecoderReadByte(card, 0x095); + if (err & 0x17) { + MDEBUG(0, ": Packet Error: 0x%02X\n", err); + } + + ISRTime = 0; // TODO system time + + for (i = 0; i < 5; i++) + if ((intr[i] = DecoderReadByte(card, i))) used = 1; + if (used) { + if (intr[0] & 0x80) { // new field + card->fields++; + + if (card->videoffwd){ + if (!card->videoffwd_last){ + AudioStopDecode(card); + card->videosync = 0; + card->videoskip = card->videoffwd; + card->videoskip = 0; + card->videoffwd_last = 1; + card->videoskip_last = 0; + } else { + if (card->videoskip_last == -1){ + card->videoskip = + card->videoffwd; + } + + if (!card->videoskip) + card->videoskip_last = -1; + else + card->videoffwd_last = + card->videoffwd; + } + } else if( card->videoffwd_last ){ + card->videoffwd_last = 0; +#ifdef DVB + if (card->audiostate.AVSyncState) +#endif + card->videosync = 1; + AudioStartDecode(card); + } + + + if (card->videoslow){ + if (!card->videoslow_last){ + AudioStopDecode(card); + card->videosync = 0; + card->videodelay = card->videoslow; + card->videoskip = 0; + card->videoslow_last = 1; + card->videodelay_last = 0; + } else { + if (card->videodelay_last == -1){ + card->videodelay = + card->videoslow; + } + + if (!card->videodelay) + card->videodelay_last = -1; + else + card->videodelay_last = + card->videodelay; + } + } else if( card->videoslow_last ){ + card->videoslow_last = 0; +#ifdef DVB + if (card->audiostate.AVSyncState) +#endif + card->videosync = 1; + AudioStartDecode(card); + } + + + if (card->videodelay > 0) { + if( (DecoderReadByte(card, 0x0ED) & 0x03) + == 0x00) { + card->videodelay--; + if(card->videodelay){ + DecoderWriteByte(card, 0x0ED, + 0x01); + } else { + DecoderWriteByte(card, 0x0ED, + 0x00); + } + } else { + card->videodelay--; + if(!card->videodelay){ + DecoderWriteByte(card, 0x0ED, + 0x00); + } + } + } else if (card->videoskip > 0) { + if ((DecoderReadByte(card, 0x0EC) & 0x03) + == 0x00) { + if (DecoderReadWord(card, 0x096) > 5){ + // pictures in video ES channel + card->videoskip--; + if(card->videoskip) { + DecoderWriteByte(card, + 0x0EC + ,0x03); + } else { + DecoderWriteByte(card, + 0x0EC + ,0x00); + } + } else { + card->videoskip = 0; + DecoderWriteByte (card, 0x0EC, + 0x00); + } + } + } + + + i = (DecoderReadByte(card, 0x113) & 0xFC) | + (DecoderReadByte(card, 0x114) & 0x01); + v = DecoderGetVideoESLevel(card); + if (card->startingV) { + vs = card->VideoESSize; + if (vs > 0) vp = (100 * v) / vs; + else vp = 0; + if (vp > 90) { + MDEBUG(0,": Delayed Video Decoder start\n"); + card->startingV = 0; + DecoderStartDecode(card); + //DecoderSetVideoPanic(card, 1, 3); + // video panic at 3 pictures + //DecoderSetVideoPanic(card, 0, DecoderGetVideoESSize(card) / 4); // video panic at 25 percent + } + } + a = DecoderGetAudioESLevel(card); + if (card->startingA) { + as = card->AudioESSize; + if (as > 0) ap = (100 * a) / as; + else ap = 0; + if (ap > 90) { + MDEBUG(0,": Delayed Audio Decoder start\n"); + AudioSetPlayMode(card, MAUDIO_PLAY); + if (!AudioStart(card)) { + card->startingA = 0; + } + } + } + if (card->fields >= 250) { // 5 seconds (PAL) + SCR_base = DecoderReadSCR(card, 0x009); + SCR_compareA = DecoderReadSCR(card, 0x014); + SCR_compareV = DecoderReadSCR(card, 0x00D); + if (DecoderReadByte(card, 0x013) & 0x03) + card->fields = 0; + } + } + + if (intr[0] & 0x04) { // First Slice Start Code + if (card->showvideo) { + // Unmute card video if first picture slice detected + VideoSetBackground(card, 0, 0, 0, 0); // Video on black + card->showvideo = 0; + } + } + + if (intr[0] & 0x02 ) { // Aux/User Data Fifo + used = 0; + while ( (used++ < 1000) && + (layer = DecoderReadByte(card, 0x040)) & 0x03){ + card->AuxFifo[card->AuxFifoHead] = + ((layer << 6) & 0x0700) | + DecoderReadByte(card, 0x043); + card->AuxFifoHead = (card->AuxFifoHead + 1) & + FIFO_MASK; + } + if (used < 1000) DecoderReadAuxFifo(card); + used = 0; + + while ( (used++ < 1000) && + (layer = DecoderReadByte(card, 0x041)) & 0x03){ + card->DataFifo[card->DataFifoHead] = + ((layer << 6) & 0x0300) | + DecoderReadByte(card, 0x043); + card->DataFifoHead = (card->DataFifoHead + 1) + & FIFO_MASK; + } + if (used < 1000 ) DecoderReadDataFifo(card); + } + + if ((intr[0] & 0x01) != card->intdecodestatus) { + // decode status + card->intdecodestatus = intr[0] & 0x01; + MDEBUG(0, ": Int - decode status now %s\n", + ((card->intdecodestatus) ? + "running" : "stopped")); + if (card->intdecodestatus) { // now running + //DecoderSetVideoPanic(card, 1, 3); + // video panic at 3 pictures + card->showvideo = 1; + } else { // now stopped + if (card->closing) { + card->closing = 0; + CloseCard(card); + } + } + + } + + if (intr[1] & 0x10) { // Begin Active Video + if (card->highlight_valid) { + for (i = 0; i < 10; i++) + DecoderWriteByte(card, 0x1C0 + i, + card->highlight[i]); + card->highlight_valid = 0; + } + } + if (intr[1] & 0x08) { // SPU Start Code Detected + MDEBUG(0, ": Int - SPU Start Code Detected\n"); + } + + if (intr[1] & 0x04) { // SCR compare audio + MDEBUG(0, ": Int - SCR compare audio\n"); + DecoderDelByte(card, 0x013, 0x01); + AudioStart(card); + } + + if (intr[2] & 0x20) { // DSI PES data ready + DecoderReadNavipack(card); + } + + if (intr[2] & 0x06) { // Audio / Video PES data ready + ReadPESHeaders(card); + } + + if (intr[3] & 0x40) { // CSS + card->css.status = DecoderReadByte(card, 0x0B0); + if (card->css.status&0x01) + card->css.ChallengeReady = 1; + // challenge ready + if (card->css.status&0x02) + card->css.ResponseReady = 1; + // response ready + if (card->css.status&0x04) + card->css.DiskKey = 1; + // Disk key ready + if (card->css.status&0x08) + card->css.Error = 1; + // Disk key error + if (card->css.status&0x10) + card->css.TitleKey = 1; + // Title key ready + if (card->css.status&0x20) + card->css.TitleKeyDiff = 1; + // Title key error + } + + + if (intr[3] & 0x30) { + // Audio/Video ES channel buffer underflow + MDEBUG(1,": Int - ES channel buffer underflow\n"); + if (card->closing) { + card->closing = 0; + CloseCard(card); + } + } + + if (intr[4] & 0x10 ) { // SPU decode error + MDEBUG(1,": Int - SPU decode error: (1CA)=0x%02X\n", + DecoderReadByte(card, 0x1CA)); + DecoderDelByte(card, 0x1A0, 0x01); // SPU decode stop + DecoderSetByte(card, 0x1A0, 0x01); // SPU decode start + } + + // Audio / Video Syncronisation + + if (card->videosync && !card->videoskip && !card->videodelay) { + SCR_base = DecoderReadSCR(card, 0x009); + SCR_compareV = DecoderReadSCR(card, 0x00D); + if (intr[1] & 0x02) { // picture start code detected + DecoderMaskByte(card, 0x011, 0x03, 0x01); + // Set SCR compare/capture mode to capture + DecoderSetByte(card, 0x11, 0x04); + // Set "capture on picture start" + if (intr[1] & 0x01) { + // audio sync code detected + DecoderSetByte(card, 0x11, 0x08); + // Set "capture on audio sync code" + } + VideoAddr = DecoderReadRWAddr(card,0x080); + if (PTSGetPTS(&card->VideoPTSStore, VideoAddr, + &PTS)) { + card->oldVPTS = card->VPTS; + card->VPTS = PTS; + card->VSCR = ((long)SCR_compareV + - (long)PTS) / 2; +// card->VideoTime = ISRTime; + } + } else if (intr[1] & 0x01) { + // audio sync code detected + DecoderMaskByte(card, 0x011, 0x03, 0x01); + // Set SCR compare/capture mode to capture + DecoderSetByte(card, 0x11, 0x08); + // Set "capture on audio sync code" + AudioAddr = DecoderReadRWAddr(card,0x083); + if (PTSGetPTS(&card->AudioPTSStore, AudioAddr, + &PTS)) { + card->oldAPTS = card->APTS; + card->APTS = PTS; + card->ASCR = ((long)SCR_compareV - + (long)PTS) / 2; + } else { + card->ASCR = 0x7FFFFFFF; + } + + if (card->VSCR != 0x7FFFFFFF) { + if (card->ASCR != 0x7FFFFFFF) { + DeltaSyncTime = ISRTime - + card->SyncTime; + card->SyncTime = ISRTime; + + // Calculate Audio and Video SCR difference + Offset = (card->ASCR - + card->VSCR - + (10 * 736)) / 736; + + // if the APTS and SCR are off update SCR to keep SubPic synced + if ((SCR_compareV > card->APTS) + || ((card->APTS - + SCR_compareV) > + 10000)) { + Offset = 0; + SetSCR(card, + card->APTS); + } + + // if more than 3 frames away + if ((Offset > 3) || + (Offset < -3)) { + if (Offset > 0 ) { + card->videodelay = 0; + if (Offset < 100) { + if (Offset < 10) { + card->videodelay = 1; + } else { + card->videodelay = Offset / 2; + if (card->videodelay > 20) { + card->videodelay = 20; + } + } + MDEBUG(0,": <<< Pausing %d\n", card->videodelay); + } else { + } + } else { + card->videoskip = 0; + if (Offset > -100) { + if (Offset < -10) { + card->videoskip = 10; + } else { + card->videoskip = 3; + } + MDEBUG(0, ": >>> FForward %d\n", card->videoskip); + } + } + } else { + } + card->VSCR = 0x7FFFFFFF; + } + } + } + } + } + DecoderWriteByte(card, 0x006, 0x01); // Clear Interrupt Pin +} + +// Enable the IRQ Masks +void L64021InstallIntr(struct cvdv_cards *card) { + u8 data; + + data=0; + data |= 0x80; // new field + data |= 0x40; // audio sync recovery + data |= 0x20; // SPU SCR compare + // data |= 0x10; // SDRAM Transfer Done + // data |= 0x08; // Sequence End Code Detect + data |= 0x04; // First Slice Start Code + data |= 0x02; // Aux/User Data Fifo + data |= 0x01; // decode status + DecoderWriteByte(card, 0x000, (~data) & 0xFF); + + data = 0; + // data |= 0x80; // SCR compare + // data |= 0x40; // SCR Overflow + // data |= 0x20; // Begin Vertical Blank + data |= 0x10; // Begin Active Video + data |= 0x08; // SPU Start Code Detected + data |= 0x04; // SCR compare audio + data |= 0x02; // picture start code detected + data |= 0x01; // audio sync code detected + DecoderWriteByte(card, 0x001, (~data) & 0xFF); + + data = 0; + // data |= 0x80; // DTS video event + // data |= 0x40; // DTS audio event + data |= 0x20; // DSI PES data ready + // data |= 0x10; // Seq end code in video channel + data |= 0x08; // SPU PES data ready + data |= 0x04; // Video PES data ready + data |= 0x02; // Audio PES data ready + // data |= 0x01; // Pack data ready + DecoderWriteByte(card, 0x002, (~data) & 0xFF); + + data = 0; + // data |= 0x80; // Reserved + data |= 0x40; // CSS + data |= 0x20; // Video ES channel buffer underflow + data |= 0x10; // Audio ES channel buffer underflow + // data |= 0x08; // Data Dump channel PES data ready + data |= 0x04; // SPU channel buffer overflow + //data |= 0x02; // Video ES channel buffer overflow + //data |= 0x01; // Audio ES channel buffer overflow + DecoderWriteByte(card, 0x003, (~data) & 0xFF); + + data = 0; +// data |= 0x80; // S/PDIF channel buffer underflow + // data |= 0x40; // packet error + // data |= 0x20; // reserved + data |= 0x10; // SPU decode error +// data |= 0x08; // Audio Sync error +// data |= 0x04; // Audio CRC or illegal bit error +// data |= 0x02; // context error +// data |= 0x01; // VLC or Run length error + DecoderWriteByte(card, 0x004, (~data) & 0xFF); + card->IntInstalled = 1; +} + +int L64021RemoveIntr(struct cvdv_cards *card) { + // Disable the IRQ Masks + DecoderWriteByte(card, 0x000, 0xFF); // No ints + DecoderWriteByte(card, 0x001, 0xFF); // No ints + DecoderWriteByte(card, 0x002, 0xFF); // No ints + DecoderWriteByte(card, 0x003, 0xFF); // No ints + DecoderWriteByte(card, 0x004, 0xFF); // No ints + card->IntInstalled = 0; + return 0; +} + +int L64021Reset(struct cvdv_cards *card) { + L64021RemoveIntr(card); // Stop interrupts + // Reset + MDEBUG(1, ": L64021 Software reset...\n"); + //DecoderSetByte(card, 0x007, 0x20); // reset on + DecoderMaskByte(card, 0x007, 0xE2, 0xE2); // reset on + while (!(DecoderReadByte(card, 0x007) & 0x02)) ; // wait until reset is done + //DecoderDelByte(card, 0x007, 0x20); // reset off + DecoderMaskByte(card, 0x007, 0xE2, 0xC2); // reset off + MDEBUG(1, ": L64021 Software reset done.\n"); + DecoderStopChannel(card); + DecoderStopDecode(card); + DecoderStreamReset(card); + DecoderSetupReset(card); + printk(KERN_INFO LOGNAME ": L64021 Rev. 0x%02X reset successfully.\n", +DecoderReadByte(card, 0x0F5)); + return 0; +} + +int L64021Setup(struct cvdv_cards *card) { + MDEBUG(1, ": -- L64021Setup\n"); + DecoderWriteByte(card, 0x0C1, 0x88); // + switch (card->videomode) { + case NTSC: // NTSC M, N. America, Taiwan, Japan + DecoderMaskByte(card, 0x122, 0x03, 0x01); // Television Standard: NTSC + /* Default values: + DecoderWriteByte(card, 0x116, 90); // Main Reads per Line + DecoderWriteByte(card, 0x11A, 4); // Vline Count Init + DecoderWriteByte(card, 0x11C, 0x13); // Pixel State Reset Value / BT.656 Mode / Sync Active Low + DecoderWriteByte(card, 0x129, 23); // Start- and End Row + DecoderWriteByte(card, 0x12A, 262 & 0xFF); + DecoderWriteByte(card, 0x12B, (262>>4)&0x70); + DecoderWriteByte(card, 0x12C, 244 & 0xFF); // Start- and End Column + DecoderWriteByte(card, 0x12D, 1683 & 0xFF); + DecoderWriteByte(card, 0x12E, ((1683>>4)&0x70)|((244>>8)&0x07)); + DecoderWriteByte(card, 0x132, 240 & 0xFF); // SAV Column + DecoderWriteByte(card, 0x133, 1684 & 0xFF); // EAV Column + DecoderWriteByte(card, 0x134, ((1684>>4)&0x70)|((240>>8)&0x07)); + DecoderWriteByte(card, 0x12F, (21&0x1F)|((262>>3)&0x20)|(1<<6)|((265>>1)&0x80)); // VCode Zero... + DecoderWriteByte(card, 0x130, 262&0xFF); // ... and VCode Even + DecoderWriteByte(card, 0x131, 265&0xFF); // ... and FCode + */ + break; + case PAL: // PAL-B, D, G, H, I, Europe, Asia + DecoderMaskByte(card, 0x122, 0x03, 0x02); // Television Standard: PAL + /* Default values: + DecoderWriteByte(card, 0x116, 90); // Main Reads per Line + DecoderWriteByte(card, 0x11A, 1); // Vline Count Init + DecoderWriteByte(card, 0x11C, 0x13); // Pixel State Reset Value / BT.656 Mode / Sync Active Low + DecoderWriteByte(card, 0x129, 23); // Start- and End Row + DecoderWriteByte(card, 0x12A, 310 & 0xFF); + DecoderWriteByte(card, 0x12B, (310>>4)&0x70); + DecoderWriteByte(card, 0x12C, 264 & 0xFF); // Start- and End Column + DecoderWriteByte(card, 0x12D, 1703 & 0xFF); + DecoderWriteByte(card, 0x12E, ((1703>>4)&0x70)|((264>>8)&0x07)); + DecoderWriteByte(card, 0x132, 260 & 0xFF); // SAV Column + DecoderWriteByte(card, 0x133, 1704 & 0xFF); // EAV Column + DecoderWriteByte(card, 0x134, ((1704>>4)&0x70)|((260>>8)&0x07)); + DecoderWriteByte(card, 0x12F, (21&0x1F)|((310>>3)&0x20)|(0<<6)|((312>>1)&0x80)); // VCode Zero... + DecoderWriteByte(card, 0x130, 310&0xFF); // ... and VCode Even + DecoderWriteByte(card, 0x131, 312&0xFF); // ... and FCode + */ + break; + case PAL60: // PAL 60Hz + case NTSC60: // NTSC 60Hz, USA HDTV + case PALM: // PAL-M normal, Brazil + case PALM60: // PAL-M HDTV, Brazil + case PALN: // PAL-N, Uruguay, Paraguay + case PALNc: // PAL-Nc, Argentinia + default: // TODO: set mode according to other standards + DecoderMaskByte(card, 0x122, 0x03, 0x00); // Television Standard: User programmed + DecoderWriteByte(card, 0x116, 90); // Main Reads per Line + DecoderWriteByte(card, 0x11A, 1); // Vline Count Init + DecoderWriteByte(card, 0x11C, 0x13); // Pixel State Reset Value / BT.656 Mode / Sync Active Low + DecoderWriteByte(card, 0x129, 23); // Start- and End Row + DecoderWriteByte(card, 0x12A, 310 & 0xFF); + DecoderWriteByte(card, 0x12B, (310>>4)&0x70); + DecoderWriteByte(card, 0x12C, 264 & 0xFF); // Start- and End Column + DecoderWriteByte(card, 0x12D, 1703 & 0xFF); + DecoderWriteByte(card, 0x12E, ((1703>>4)&0x70)|((264>>8)&0x07)); + DecoderWriteByte(card, 0x132, 260 & 0xFF); // SAV Column + DecoderWriteByte(card, 0x133, 1704 & 0xFF); // EAV Column + DecoderWriteByte(card, 0x134, ((1704>>4)&0x70)|((260>>8)&0x07)); + DecoderWriteByte(card, 0x12F, (21&0x1F)|((310>>3)&0x20)|(0<<6)|((312>>1)&0x80)); // VCode Zero... + DecoderWriteByte(card, 0x130, 310&0xFF); // ... and VCode Even + DecoderWriteByte(card, 0x131, 312&0xFF); // ... and FCode + break; + } + DecoderWriteByte(card, 0x045, 0x00); // disable compares and panic mode + DecoderWriteByte(card, 0x094, 0x00); // disable TOS Detect + DecoderMaskByte(card, 0x109, 0x30, 0x00); // Display Override off, don't change OSD, Background + DecoderWriteByte(card, 0x112, 0x00); // Disable Horizontal 2:1 Filter + DecoderWriteByte(card, 0x113, 0x14); // FreezeMode 1 / 3:2 Pulldown / Repeat First Field / Top Field First + DecoderWriteByte(card, 0x114, ( 5 <<3)|( 0 <<1)|( 0 <<2)|( 1 <<7)); // VideoMode/FilterEnable/FilterAB/FieldSyncEnable + DecoderWriteByte(card, 0x115, 0); // Horizontal Filter Scale + DecoderWriteByte(card, 0x117, 0x80); // Automatic Field Inversion Correction +// DecoderWriteByte(card, 0x117, 0x00); // no Automatic Field Inversion Correction + DecoderWriteByte(card, 0x118, 0); // Horizontal Pan and Scan Word Offset (signed) + DecoderWriteByte(card, 0x119, 0); // Vertical Pan and Scan Line Offset + DecoderWriteByte(card, 0x11B, 0x00); // Override Picture Width +// if (0) { // letterbox +// DecoderWriteByte(card, 0x114, (DecoderReadByte(card, 0x114) & ~0x78) | 0x40); // mode 8 +// DecoderWriteByte(card, 0x129, 0x35); +// DecoderWriteByte(card, 0x12A, 0xE7); +// DecoderWriteByte(card, 0x114, DecoderReadByte(card, 0x114) & ~0x77); // ??? +// } else { +// if (0) { // MPEG-1 +// DecoderWriteByte(card, 0x114, (DecoderReadByte(card, 0x114) & ~0x78) | 0x10); // mode 2 +// } else { // MPEG-2 +// DecoderWriteByte(card, 0x114, (DecoderReadByte(card, 0x114) & ~0x78) | 0x28); // mode 5 +// } +// } + L64021InstallIntr(card); // Set the interrupt masks, again + + return 0; +} + +int L64021Init(struct cvdv_cards *card) { +MDEBUG(1, ": -- L64021Init\n"); + L64021Reset(card); + L64021Setup(card); + VideoSetBackground(card, 1, 0, 0, 0); // black + DecoderWriteByte(card, 0x135, 0x01); // Enable Video Out, Disable SPU Mix + DecoderWriteByte(card,0x11C,0x13); // Pixel State Reset Value / BT.656 Mode / Sync Active Low + L64021InstallIntr(card); + return 0; +} + + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/decoder.h linux.19pre5-ac1/drivers/media/video/margi/decoder.h --- linux.19p5/drivers/media/video/margi/decoder.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/decoder.h Thu Apr 4 15:55:29 2002 @@ -0,0 +1,70 @@ +/* + decoder.h + + Copyright (C) Christian Wolff for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef CVDV_DECODER_H +#define CVDV_DECODER_H + +#include "cardbase.h" + + +int DecoderGetNavi(struct cvdv_cards *card, u8 * navidata); + +// returns 1 on overrun, 0 on no error +int DecoderQueueNavi(struct cvdv_cards *card, u8 * navidata); + +u32 ParseSCR(const u8 * scrdata); + +u32 SetSCR(struct cvdv_cards *card, u32 SCR_base); + +void DecoderPause(struct cvdv_cards *card); + +void DecoderUnPause(struct cvdv_cards *card); + +void CloseCard(struct cvdv_cards *card); + + +void DecoderReadAudioInfo(struct cvdv_cards *card); + +void DecoderReadAuxFifo(struct cvdv_cards *card); + +void DecoderReadDataFifo(struct cvdv_cards *card); + +int DecoderReadNavipack(struct cvdv_cards *card); + +int AudioStart(struct cvdv_cards *card); + +// Puts decoder in pause after so many fields +void StepsToPause(struct cvdv_cards *card, int steps); + +void L64021Intr(struct cvdv_cards *card); +//static void L64021Intr(struct cvdv_cards *card); + +// Enable the IRQ Masks +void L64021InstallIntr(struct cvdv_cards *card); + +int L64021RemoveIntr(struct cvdv_cards *card); + +int L64021Reset(struct cvdv_cards *card); + +int L64021Setup(struct cvdv_cards *card); + +int L64021Init(struct cvdv_cards *card); + +#endif /* CVDV_DECODER_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/dmxdev.c linux.19pre5-ac1/drivers/media/video/margi/dmxdev.c --- linux.19p5/drivers/media/video/margi/dmxdev.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/dmxdev.c Mon Feb 4 22:30:16 2002 @@ -0,0 +1,1065 @@ +/* + * dmxdev.c - DVB demultiplexer device + * + * Copyright (C) 2000 Ralph Metzler + * & Marcus Metzler + for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include + +#include "cardbase.h" +#include "dmxdev.h" + +#ifdef MODULE +MODULE_DESCRIPTION(""); +MODULE_AUTHOR("Ralph Metzler, Marcus Metzler"); +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif +MODULE_PARM(debug,"i"); +#endif +static int debug = 0; + +#define dprintk if (debug) printk + +inline dmxdev_filter_t * +DmxDevFile2Filter(dmxdev_t *dmxdev, struct file *file) +{ + return (dmxdev_filter_t *) file->private_data; +} + +inline dmxdev_dvr_t * +DmxDevFile2DVR(dmxdev_t *dmxdev, struct file *file) +{ + return (dmxdev_dvr_t *) file->private_data; +} + +static inline void +DmxDevBufferInit(dmxdev_buffer_t *buffer) +{ + buffer->data=0; + buffer->size=8192; + buffer->pread=0; + buffer->pwrite=0; + buffer->error=0; + init_waitqueue_head(&buffer->queue); +} + +static inline int +DmxDevBufferWrite(dmxdev_buffer_t *buf, uint8_t *src, int len) +{ + int split; + int free; + int todo; + + if (!len) + return 0; + if (!buf->data) + return 0; + + free=buf->pread-buf->pwrite; + split=0; + if (free<=0) { + free+=buf->size; + split=buf->size-buf->pwrite; + } + if (len>=free) { + dprintk("dmxdev: buffer overflow\n"); + return -1; + } + if (split>=len) + split=0; + todo=len; + if (split) { + memcpy(buf->data + buf->pwrite, src, split); + todo-=split; + buf->pwrite=0; + } + memcpy(buf->data + buf->pwrite, src+split, todo); + buf->pwrite=(buf->pwrite+todo)%buf->size; + return len; +} + +static ssize_t +DmxDevBufferRead(dmxdev_buffer_t *src, int non_blocking, + char *buf, size_t count, loff_t *ppos) +{ + unsigned long todo=count; + int split, avail, error; + + if (!src->data) + return 0; + if ((error=src->error)) { + src->error=0; + return error; + } + + if (non_blocking && (src->pwrite==src->pread)) + return -EWOULDBLOCK; + + while (todo>0) { + if (non_blocking && (src->pwrite==src->pread)) + return (count-todo) ? (count-todo) : -EWOULDBLOCK; + + if (wait_event_interruptible(src->queue, + (src->pread!=src->pwrite) || + (src->error))<0) + return count-todo; + + if ((error=src->error)) { + src->error=0; + return error; + } + + split=src->size; + avail=src->pwrite - src->pread; + if (avail<0) { + avail+=src->size; + split=src->size - src->pread; + } + if (avail>todo) + avail=todo; + if (splitdata+src->pread, split)) + return -EFAULT; + buf+=split; + src->pread=0; + todo-=split; + avail-=split; + } + if (avail) { + if (copy_to_user(buf, src->data+src->pread, avail)) + return -EFAULT; + src->pread = (src->pread + avail) % src->size; + todo-=avail; + buf+=avail; + } + } + return count; +} + +static dmx_frontend_t * +get_fe(dmx_demux_t *demux, int type) +{ + struct list_head *head, *pos; + + head=demux->get_frontends(demux); + if (!head) + return 0; + list_for_each(pos, head) + if (DMX_FE_ENTRY(pos)->source==type) + return DMX_FE_ENTRY(pos); + + return 0; +} + +static inline void +DmxDevDVRStateSet(dmxdev_dvr_t *dmxdevdvr, int state) +{ + spin_lock_irq(&dmxdevdvr->dev->lock); + dmxdevdvr->state=state; + spin_unlock_irq(&dmxdevdvr->dev->lock); +} + +int +DmxDevDVROpen(dmxdev_t *dmxdev, struct file *file) +{ + dmx_frontend_t *front; + + down(&dmxdev->mutex); + if ((file->f_flags&O_ACCMODE)==O_RDWR) { + if (!(dmxdev->capabilities&DMXDEV_CAP_DUPLEX)) { + up(&dmxdev->mutex); + return -EOPNOTSUPP; + } + } + + if ((file->f_flags&O_ACCMODE)==O_RDONLY) { + DmxDevBufferInit(&dmxdev->dvr_buffer); + dmxdev->dvr_buffer.size=DVR_BUFFER_SIZE; + dmxdev->dvr_buffer.data=vmalloc(DVR_BUFFER_SIZE); + if (!dmxdev->dvr_buffer.data) { + up(&dmxdev->mutex); + return -ENOMEM; + } + } + + if ((file->f_flags&O_ACCMODE)==O_WRONLY) { + dmxdev->dvr_orig_fe=dmxdev->demux->frontend; + + if (!dmxdev->demux->write) { + up(&dmxdev->mutex); + return -EOPNOTSUPP; + } + + front=get_fe(dmxdev->demux, DMX_MEMORY_FE); + + if (!front) { + up(&dmxdev->mutex); + return -EINVAL; + } + dmxdev->demux->disconnect_frontend(dmxdev->demux); + dmxdev->demux->connect_frontend(dmxdev->demux, front); + } + up(&dmxdev->mutex); + return 0; +} + +int +DmxDevDVRClose(dmxdev_t *dmxdev, struct file *file) +{ + down(&dmxdev->mutex); + if ((file->f_flags&O_ACCMODE)==O_WRONLY) { + dmxdev->demux->disconnect_frontend(dmxdev->demux); + dmxdev->demux->connect_frontend(dmxdev->demux, + dmxdev->dvr_orig_fe); + } + if ((file->f_flags&O_ACCMODE)==O_RDONLY) { + if (dmxdev->dvr_buffer.data) { + void *mem=dmxdev->dvr_buffer.data; + mb(); + spin_lock_irq(&dmxdev->lock); + dmxdev->dvr_buffer.data=0; + spin_unlock_irq(&dmxdev->lock); + vfree(mem); + } + } + up(&dmxdev->mutex); + return 0; +} + +ssize_t +DmxDevDVRWrite(dmxdev_t *dmxdev, struct file *file, + const char *buf, size_t count, loff_t *ppos) +{ + int ret; + + if (!dmxdev->demux->write) + return -EOPNOTSUPP; + if ((file->f_flags&O_ACCMODE)!=O_WRONLY) + return -EINVAL; + down(&dmxdev->mutex); + ret=dmxdev->demux->write(dmxdev->demux, buf, count); + up(&dmxdev->mutex); + return ret; +} + +ssize_t +DmxDevDVRRead(dmxdev_t *dmxdev, struct file *file, + char *buf, size_t count, loff_t *ppos) +{ + int ret; + + down(&dmxdev->mutex); + ret= DmxDevBufferRead(&dmxdev->dvr_buffer, + file->f_flags&O_NONBLOCK, + buf, count, ppos); + up(&dmxdev->mutex); + return ret; +} + +static inline void +DmxDevFilterStateSet(dmxdev_filter_t *dmxdevfilter, int state) +{ + spin_lock_irq(&dmxdevfilter->dev->lock); + dmxdevfilter->state=state; + spin_unlock_irq(&dmxdevfilter->dev->lock); +} + +static int +DmxDevSetBufferSize(dmxdev_filter_t *dmxdevfilter, unsigned long size) +{ + dmxdev_buffer_t *buf=&dmxdevfilter->buffer; + + if (buf->size==size) + return 0; + if (dmxdevfilter->state>=DMXDEV_STATE_GO) + return -EBUSY; + spin_lock_irq(&dmxdevfilter->dev->lock); + if (buf->data) + vfree(buf->data); + buf->data=0; + buf->size=size; + buf->pwrite=buf->pread=0; + spin_unlock_irq(&dmxdevfilter->dev->lock); + + if (buf->size) { + void *mem=vmalloc(dmxdevfilter->buffer.size); + + if (!mem) + return -ENOMEM; + spin_lock_irq(&dmxdevfilter->dev->lock); + buf->data=mem; + spin_unlock_irq(&dmxdevfilter->dev->lock); + } + return 0; +} + +static void +DmxDevFilterTimeout(unsigned long data) +{ + dmxdev_filter_t *dmxdevfilter=(dmxdev_filter_t *)data; + + dmxdevfilter->buffer.error=-ETIMEDOUT; + spin_lock_irq(&dmxdevfilter->dev->lock); + dmxdevfilter->state=DMXDEV_STATE_TIMEDOUT; + spin_unlock_irq(&dmxdevfilter->dev->lock); + wake_up(&dmxdevfilter->buffer.queue); +} + +static void +DmxDevFilterTimer(dmxdev_filter_t *dmxdevfilter) +{ + struct dmxSctFilterParams *para=&dmxdevfilter->params.sec; + + del_timer(&dmxdevfilter->timer); + if (para->timeout) { + dmxdevfilter->timer.function=DmxDevFilterTimeout; + dmxdevfilter->timer.data=(unsigned long) dmxdevfilter; + dmxdevfilter->timer.expires=jiffies+1+(HZ/2+HZ*para->timeout)/1000; + add_timer(&dmxdevfilter->timer); + } +} + +static int +DmxDevSectionCallback(u8 *buffer1, size_t buffer1_len, + u8 *buffer2, size_t buffer2_len, + dmx_section_filter_t *filter, + dmx_success_t success) +{ + dmxdev_filter_t *dmxdevfilter=(dmxdev_filter_t *) filter->priv; + int ret; + + if (dmxdevfilter->buffer.error) + return 0; + spin_lock(&dmxdevfilter->dev->lock); + if (dmxdevfilter->state!=DMXDEV_STATE_GO) { + spin_unlock(&dmxdevfilter->dev->lock); + return 0; + } + del_timer(&dmxdevfilter->timer); + dprintk("dmxdev: section callback %02x %02x %02x %02x %02x %02x\n", + buffer1[0], buffer1[1], + buffer1[2], buffer1[3], + buffer1[4], buffer1[5]); + ret=DmxDevBufferWrite(&dmxdevfilter->buffer, buffer1, buffer1_len); + if (ret==buffer1_len) { + ret=DmxDevBufferWrite(&dmxdevfilter->buffer, buffer2, buffer2_len); + } + if (ret<0) { + dmxdevfilter->buffer.pwrite=dmxdevfilter->buffer.pread; + dmxdevfilter->buffer.error=-EBUFFEROVERFLOW; + } + if (dmxdevfilter->params.sec.flags&DMX_ONESHOT) + dmxdevfilter->state=DMXDEV_STATE_DONE; + spin_unlock(&dmxdevfilter->dev->lock); + wake_up(&dmxdevfilter->buffer.queue); + return 0; +} + +static int +DmxDevTSCallback(u8 *buffer1, size_t buffer1_len, + u8 *buffer2, size_t buffer2_len, + dmx_ts_feed_t *feed, + dmx_success_t success) +{ + dmxdev_filter_t *dmxdevfilter=(dmxdev_filter_t *) feed->priv; + dmxdev_buffer_t *buffer; + int ret; + + if (dmxdevfilter->params.pes.output==DMX_OUT_DECODER) + return 0; + + if (dmxdevfilter->params.pes.output==DMX_OUT_TAP) + buffer=&dmxdevfilter->buffer; + else + buffer=&dmxdevfilter->dev->dvr_buffer; + if (buffer->error) { + wake_up(&buffer->queue); + return 0; + } + ret=DmxDevBufferWrite(buffer, buffer1, buffer1_len); + if (ret==buffer1_len) + ret=DmxDevBufferWrite(buffer, buffer2, buffer2_len); + if (ret<0) { + buffer->pwrite=buffer->pread; + buffer->error=-EBUFFEROVERFLOW; + } + wake_up(&buffer->queue); + return 0; +} + + +/* stop feed but only mark the specified filter as stopped (state set) */ + +static int +DmxDevFeedStop(dmxdev_filter_t *dmxdevfilter) +{ + DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_SET); + + switch (dmxdevfilter->type) { + case DMXDEV_TYPE_SEC: + del_timer(&dmxdevfilter->timer); + dmxdevfilter->feed.sec->stop_filtering(dmxdevfilter->feed.sec); + break; + case DMXDEV_TYPE_PES: + dmxdevfilter->feed.ts->stop_filtering(dmxdevfilter->feed.ts); + break; + default: + return -EINVAL; + } + return 0; +} + + +/* start feed associated with the specified filter */ + +static int +DmxDevFeedStart(dmxdev_filter_t *dmxdevfilter) +{ + DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_GO); + + switch (dmxdevfilter->type) { + case DMXDEV_TYPE_SEC: + dmxdevfilter->feed.sec->start_filtering(dmxdevfilter->feed.sec); + break; + case DMXDEV_TYPE_PES: + dmxdevfilter->feed.ts->start_filtering(dmxdevfilter->feed.ts); + break; + default: + return -EINVAL; + } + return 0; +} + + +/* restart section feed if it has filters left associated with it, + otherwise release the feed */ + +static int +DmxDevFeedRestart(dmxdev_filter_t *dmxdevfilter) +{ + int i; + dmxdev_t *dmxdev=dmxdevfilter->dev; + dvb_pid_t pid=dmxdevfilter->params.sec.pid; + + for (i=0; ifilternum; i++) + if (dmxdev->filter[i].state>=DMXDEV_STATE_GO && + dmxdev->filter[i].type==DMXDEV_TYPE_SEC && + dmxdev->filter[i].pid==pid) { + DmxDevFeedStart(&dmxdev->filter[i]); + return 0; + } + + dmxdevfilter->dev->demux-> + release_section_feed(dmxdev->demux, + dmxdevfilter->feed.sec); + + return 0; +} + +static int +DmxDevFilterStop(dmxdev_filter_t *dmxdevfilter) +{ + if (dmxdevfilter->statetype) { + case DMXDEV_TYPE_SEC: + if (!dmxdevfilter->feed.sec) + break; + DmxDevFeedStop(dmxdevfilter); + if (dmxdevfilter->filter.sec) + dmxdevfilter->feed.sec-> + release_filter(dmxdevfilter->feed.sec, + dmxdevfilter->filter.sec); + DmxDevFeedRestart(dmxdevfilter); + dmxdevfilter->feed.sec=0; + break; + case DMXDEV_TYPE_PES: + if (!dmxdevfilter->feed.ts) + break; + DmxDevFeedStop(dmxdevfilter); + dmxdevfilter->dev->demux-> + release_ts_feed(dmxdevfilter->dev->demux, + dmxdevfilter->feed.ts); + dmxdevfilter->feed.ts=0; + break; + default: + if (dmxdevfilter->state==DMXDEV_STATE_ALLOCATED) + return 0; + return -EINVAL; + } + dmxdevfilter->buffer.pwrite=dmxdevfilter->buffer.pread=0; + return 0; +} + +static inline int +DmxDevFilterReset(dmxdev_filter_t *dmxdevfilter) +{ + if (dmxdevfilter->statetype=DMXDEV_TYPE_NONE; + dmxdevfilter->pid=0xffff; + DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_ALLOCATED); + return 0; +} + +static int +DmxDevFilterStart(dmxdev_filter_t *dmxdevfilter) +{ + dmxdev_t *dmxdev=dmxdevfilter->dev; + void *mem; + int ret, i; + + if (dmxdevfilter->statestate>=DMXDEV_STATE_GO) + DmxDevFilterStop(dmxdevfilter); + + mem=dmxdevfilter->buffer.data; + if (!mem) { + mem=vmalloc(dmxdevfilter->buffer.size); + spin_lock_irq(&dmxdevfilter->dev->lock); + dmxdevfilter->buffer.data=mem; + spin_unlock_irq(&dmxdevfilter->dev->lock); + if (!dmxdevfilter->buffer.data) + return -ENOMEM; + } + + switch (dmxdevfilter->type) { + case DMXDEV_TYPE_SEC: + { + struct dmxSctFilterParams *para=&dmxdevfilter->params.sec; + dmx_section_filter_t **secfilter=&dmxdevfilter->filter.sec; + dmx_section_feed_t **secfeed=&dmxdevfilter->feed.sec; + + *secfilter=0; + *secfeed=0; + + /* find active filter/feed with same PID */ + for (i=0; ifilternum; i++) + if (dmxdev->filter[i].state>=DMXDEV_STATE_GO && + dmxdev->filter[i].pid==para->pid) { + if (dmxdev->filter[i].type!=DMXDEV_TYPE_SEC) + return -EBUSY; + *secfeed=dmxdev->filter[i].feed.sec; + break; + } + + /* if no feed found, try to allocate new one */ + if (!*secfeed) { + ret=dmxdev->demux-> + allocate_section_feed(dmxdev->demux, + secfeed, + DmxDevSectionCallback); + if (ret<0) { + printk ("could not alloc feed\n"); + return ret; + } + + ret=(*secfeed)->set(*secfeed, para->pid, 32768, 0, + (para->flags & DMX_CHECK_CRC) ? 1 : 0); + + if (ret<0) { + printk ("could not set feed\n"); + DmxDevFeedRestart(dmxdevfilter); + return ret; + } + } + else + DmxDevFeedStop(dmxdevfilter); + + ret=(*secfeed)->allocate_filter(*secfeed, secfilter); + if (ret<0) { + DmxDevFeedRestart(dmxdevfilter); + dmxdevfilter->feed.sec-> + start_filtering(*secfeed); + dprintk ("could not get filter\n"); + return ret; + } + + (*secfilter)->priv=(void *) dmxdevfilter; + memcpy(&((*secfilter)->filter_value[3]), + &(para->filter.filter[1]), DMX_FILTER_SIZE-1); + memcpy(&(*secfilter)->filter_mask[3], + ¶->filter.mask[1], DMX_FILTER_SIZE-1); + (*secfilter)->filter_value[0]=para->filter.filter[0]; + (*secfilter)->filter_mask[0]=para->filter.mask[0]; + (*secfilter)->filter_mask[1]=0; + (*secfilter)->filter_mask[2]=0; + + dmxdevfilter->todo=0; + dmxdevfilter->feed.sec-> + start_filtering(dmxdevfilter->feed.sec); + DmxDevFilterTimer(dmxdevfilter); + break; + } + + case DMXDEV_TYPE_PES: + { + struct timespec timeout = {0 }; + struct dmxPesFilterParams *para=&dmxdevfilter->params.pes; + dmxOutput_t otype; + int ret; + int ts_type; + dmx_ts_pes_t ts_pes; + dmx_ts_feed_t **tsfeed=&dmxdevfilter->feed.ts; + + dmxdevfilter->feed.ts=0; + otype=para->output; + + ts_pes=(dmx_ts_pes_t) para->pesType; + + if (ts_pesdemux->allocate_ts_feed(dmxdev->demux, + tsfeed, + DmxDevTSCallback); + if (ret<0) + return ret; + + (*tsfeed)->priv=(void *) dmxdevfilter; + ret=(*tsfeed)->set(*tsfeed, para->pid, 188, 32768, 0, timeout); + if (ret<0) { + dmxdev->demux-> + release_ts_feed(dmxdev->demux, *tsfeed); + return ret; + } + if ((*tsfeed)->set_type) + ret=(*tsfeed)->set_type(*tsfeed, ts_type, ts_pes); + if (ret<0) { + dmxdev->demux-> + release_ts_feed(dmxdev->demux, *tsfeed); + return ret; + } + dmxdevfilter->feed.ts-> + start_filtering(dmxdevfilter->feed.ts); + break; + } + default: + return -EINVAL; + } + DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_GO); + return 0; +} + +int +DmxDevFilterNum(dmxdev_t *dmxdev) +{ + int i, num; + + if (!dmxdev->filter) + return 0; + down(&dmxdev->mutex); + for (i=0, num=0; ifilternum; i++) + if (dmxdev->filter[i].state==DMXDEV_STATE_FREE) + num++; + up(&dmxdev->mutex); + return num; +} + +int +DmxDevFilterAlloc(dmxdev_t *dmxdev, struct file *file) +{ + int i; + dmxdev_filter_t *dmxdevfilter; + + if (!dmxdev->filter) + return -EINVAL; + down(&dmxdev->mutex); + for (i=0; ifilternum; i++) + if (dmxdev->filter[i].state==DMXDEV_STATE_FREE) + break; + if (i==dmxdev->filternum) { + up(&dmxdev->mutex); + return -EMFILE; + } + dmxdevfilter=&dmxdev->filter[i]; + file->private_data=dmxdevfilter; + + DmxDevBufferInit(&dmxdevfilter->buffer); + dmxdevfilter->type=DMXDEV_TYPE_NONE; + DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_ALLOCATED); + dmxdevfilter->feed.ts=0; + init_timer(&dmxdevfilter->timer); + + up(&dmxdev->mutex); + //printk("free filters = %d\n", DmxDevFilterNum(dmxdev)); + return 0; +} + +int +DmxDevFilterFree(dmxdev_t *dmxdev, struct file *file) +{ + dmxdev_filter_t *dmxdevfilter; + + down(&dmxdev->mutex); + + if (!(dmxdevfilter=DmxDevFile2Filter(dmxdev, file))) { + up(&dmxdev->mutex); + return -EINVAL; + } + + DmxDevFilterStop(dmxdevfilter); + DmxDevFilterReset(dmxdevfilter); + + if (dmxdevfilter->buffer.data) { + void *mem=dmxdevfilter->buffer.data; + + spin_lock_irq(&dmxdev->lock); + dmxdevfilter->buffer.data=0; + spin_unlock_irq(&dmxdev->lock); + vfree(mem); + } + DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_FREE); + wake_up(&dmxdevfilter->buffer.queue); + up(&dmxdev->mutex); + //printk("free filters = %d\n", DmxDevFilterNum(dmxdev)); + return 0; +} + + +static int +DmxDevFilterSet(dmxdev_t *dmxdev, + dmxdev_filter_t *dmxdevfilter, + struct dmxSctFilterParams *params) +{ + dprintk ("function : %s\n", __FUNCTION__); + + DmxDevFilterStop(dmxdevfilter); + + dmxdevfilter->type=DMXDEV_TYPE_SEC; + dmxdevfilter->pid=params->pid; + memcpy(&dmxdevfilter->params.sec, + params, sizeof(struct dmxSctFilterParams)); + + DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_SET); + + if (params->flags&DMX_IMMEDIATE_START) + return DmxDevFilterStart(dmxdevfilter); + + return 0; +} + +static int +DmxDevPesFilterSet(dmxdev_t *dmxdev, + dmxdev_filter_t *dmxdevfilter, + struct dmxPesFilterParams *params) +{ + DmxDevFilterStop(dmxdevfilter); + + if (params->pesType>DMX_PES_OTHER || params->pesType<0) + return -EINVAL; + + dmxdevfilter->type=DMXDEV_TYPE_PES; + dmxdevfilter->pid=params->pid; + memcpy(&dmxdevfilter->params, params, sizeof(struct dmxPesFilterParams)); + + DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_SET); + + if (params->flags&DMX_IMMEDIATE_START) + return DmxDevFilterStart(dmxdevfilter); + + return 0; +} + +int +DmxDevInit(dmxdev_t *dmxdev) +{ + int i; + + if (dmxdev->demux->open(dmxdev->demux)<0) + return -EUSERS; + + dmxdev->filter=vmalloc(dmxdev->filternum*sizeof(dmxdev_filter_t)); + if (!dmxdev->filter) + return -ENOMEM; + + dmxdev->dvr=vmalloc(dmxdev->filternum*sizeof(dmxdev_dvr_t)); + if (!dmxdev->dvr) { + vfree(dmxdev->filter); + dmxdev->filter=0; + return -ENOMEM; + } + sema_init(&dmxdev->mutex, 1); + spin_lock_init(&dmxdev->lock); + for (i=0; ifilternum; i++) { + dmxdev->filter[i].dev=dmxdev; + dmxdev->filter[i].buffer.data=0; + DmxDevFilterStateSet(&dmxdev->filter[i], DMXDEV_STATE_FREE); + dmxdev->dvr[i].dev=dmxdev; + dmxdev->dvr[i].buffer.data=0; + DmxDevFilterStateSet(&dmxdev->filter[i], DMXDEV_STATE_FREE); + DmxDevDVRStateSet(&dmxdev->dvr[i], DMXDEV_STATE_FREE); + } + DmxDevBufferInit(&dmxdev->dvr_buffer); + MOD_INC_USE_COUNT; + return 0; +} + +void +DmxDevRelease(dmxdev_t *dmxdev) +{ + if (dmxdev->filter) { + vfree(dmxdev->filter); + dmxdev->filter=0; + } + if (dmxdev->dvr) { + vfree(dmxdev->dvr); + dmxdev->dvr=0; + } + dmxdev->demux->close(dmxdev->demux); + MOD_DEC_USE_COUNT; +} + +static ssize_t +DmxDevReadSec(dmxdev_filter_t *dfil, struct file *file, + char *buf, size_t count, loff_t *ppos) +{ + int result, hcount; + int done=0; + + if (dfil->todo<=0) { + hcount=3+dfil->todo; + if (hcount>count) + hcount=count; + result=DmxDevBufferRead(&dfil->buffer, file->f_flags&O_NONBLOCK, + buf, hcount, ppos); + if (result<0) { + dfil->todo=0; + return result; + } + if (copy_from_user(dfil->secheader-dfil->todo, buf, result)) + return -EFAULT; + buf+=result; + done=result; + count-=result; + dfil->todo-=result; + if (dfil->todo>-3) + return done; + dfil->todo=((dfil->secheader[1]<<8)|dfil->secheader[2])&0xfff; + if (!count) + return done; + } + if (count>dfil->todo) + count=dfil->todo; + result=DmxDevBufferRead(&dfil->buffer, file->f_flags&O_NONBLOCK, + buf, count, ppos); + if (result<0) + return result; + dfil->todo-=result; + return (result+done); +} + + +ssize_t +DmxDevRead(dmxdev_t *dmxdev, struct file *file, + char *buf, size_t count, loff_t *ppos) +{ + dmxdev_filter_t *dmxdevfilter=DmxDevFile2Filter(dmxdev, file); + int ret=0; + + down(&dmxdev->mutex); + if (dmxdevfilter->type==DMXDEV_TYPE_SEC) + ret=DmxDevReadSec(dmxdevfilter, file, buf, count, ppos); + else + ret=DmxDevBufferRead(&dmxdevfilter->buffer, + file->f_flags&O_NONBLOCK, + buf, count, ppos); + up(&dmxdev->mutex); + return ret; +} + + +int DmxDevIoctl(dmxdev_t *dmxdev, struct file *file, + unsigned int cmd, unsigned long arg) +{ + void *parg=(void *)arg; + int ret=0; + + dmxdev_filter_t *dmxdevfilter=DmxDevFile2Filter(dmxdev, file); + + if (!dmxdevfilter) + return -EINVAL; + + down(&dmxdev->mutex); + switch (cmd) { + case DMX_START: + if (dmxdevfilter->statedemux->get_pes_pids) { + ret=-EINVAL; + break; + } + dmxdev->demux->get_pes_pids(dmxdev->demux, pids); + if (copy_to_user(parg, pids, 5*sizeof(dvb_pid_t))) + ret=-EFAULT; + break; + } + + default: + ret=-EINVAL; + } + up(&dmxdev->mutex); + return ret; +} + +unsigned int +DmxDevPoll(dmxdev_t *dmxdev, struct file *file, poll_table * wait) +{ + dmxdev_filter_t *dmxdevfilter=DmxDevFile2Filter(dmxdev, file); + + if (!dmxdevfilter) + return -EINVAL; + + if (dmxdevfilter->state==DMXDEV_STATE_FREE) + return 0; + + if (dmxdevfilter->buffer.pread!=dmxdevfilter->buffer.pwrite || + dmxdevfilter->buffer.error) + return (POLLIN | POLLRDNORM | POLLPRI); + + if (dmxdevfilter->state!=DMXDEV_STATE_GO) + return 0; + + poll_wait(file, &dmxdevfilter->buffer.queue, wait); + + if (dmxdevfilter->state==DMXDEV_STATE_FREE) + return 0; + + if (dmxdevfilter->buffer.pread!=dmxdevfilter->buffer.pwrite || + dmxdevfilter->buffer.error) + return (POLLIN | POLLRDNORM | POLLPRI); + + return 0; +} + +int DmxDevDVRIoctl(dmxdev_t *dmxdev, struct file *file, + unsigned int cmd, unsigned long arg) +{ + //void *parg=(void *)arg; + int ret=0; + + down(&dmxdev->mutex); + switch (cmd) { + case DMX_SET_BUFFER_SIZE: + // FIXME: implement + ret=0; + break; + + default: + ret=-EINVAL; + } + up(&dmxdev->mutex); + return ret; +} + +unsigned int +DmxDevDVRPoll(dmxdev_t *dmxdev, struct file *file, poll_table * wait) +{ + if ((file->f_flags&O_ACCMODE)==O_RDONLY) { + if (dmxdev->dvr_buffer.pread!=dmxdev->dvr_buffer.pwrite) + return (POLLIN | POLLRDNORM | POLLPRI); + + poll_wait(file, &dmxdev->dvr_buffer.queue, wait); + + if (dmxdev->dvr_buffer.pread!=dmxdev->dvr_buffer.pwrite) + return (POLLIN | POLLRDNORM | POLLPRI); + + return 0; + } else + return (POLLOUT | POLLWRNORM | POLLPRI); +} + + +#ifdef MODULE +#ifdef EXPORT_SYMTAB +EXPORT_SYMBOL(DmxDevInit); +EXPORT_SYMBOL(DmxDevRelease); + +EXPORT_SYMBOL(DmxDevDVROpen); +EXPORT_SYMBOL(DmxDevDVRClose); +EXPORT_SYMBOL(DmxDevDVRRead); +EXPORT_SYMBOL(DmxDevDVRWrite); +EXPORT_SYMBOL(DmxDevDVRIoctl); +EXPORT_SYMBOL(DmxDevDVRPoll); + +EXPORT_SYMBOL(DmxDevFilterAlloc); +EXPORT_SYMBOL(DmxDevFilterFree); +EXPORT_SYMBOL(DmxDevRead); +EXPORT_SYMBOL(DmxDevIoctl); +EXPORT_SYMBOL(DmxDevPoll); +#endif +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/dmxdev.h linux.19pre5-ac1/drivers/media/video/margi/dmxdev.h --- linux.19p5/drivers/media/video/margi/dmxdev.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/dmxdev.h Thu Apr 4 15:55:29 2002 @@ -0,0 +1,154 @@ +/* + * dmxdev.h + * + * Copyright (C) 2000 Ralph Metzler + * & Marcus Metzler + for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _DMXDEV_H_ +#define _DMXDEV_H_ + +#ifndef __KERNEL__ +#define __KERNEL__ +#endif + +#ifdef __DVB_PACK__ +#include "ost/demux.h" +#include "ost/dmx.h" +#else +#include +#include +#endif +#include +#include +#include +#include + +#if LINUX_VERSION_CODE < 0x020300 +#define WAIT_QUEUE struct wait_queue* +#define init_waitqueue_head(wq) *(wq) = NULL; +#define DECLARE_WAITQUEUE(wait, current) struct wait_queue wait = { current, NULL } +#define list_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); pos = pos->next) +#else +#define WAIT_QUEUE wait_queue_head_t +#endif + +typedef enum { + DMXDEV_TYPE_NONE, + DMXDEV_TYPE_SEC, + DMXDEV_TYPE_PES, +} dmxdev_type_t; + +typedef enum { + DMXDEV_STATE_FREE, + DMXDEV_STATE_ALLOCATED, + DMXDEV_STATE_SET, + DMXDEV_STATE_GO, + DMXDEV_STATE_DONE, + DMXDEV_STATE_TIMEDOUT +} dmxdev_state_t; + +typedef struct dmxdev_buffer_s { + uint8_t *data; + uint32_t size; + int32_t pread; + int32_t pwrite; + WAIT_QUEUE queue; + int error; +} dmxdev_buffer_t; + + +typedef struct dmxdev_filter_s { + union { + dmx_pes_filter_t *pes; + dmx_section_filter_t *sec; + } filter; + + union { + dmx_ts_feed_t *ts; + dmx_section_feed_t *sec; + } feed; + + union { + struct dmxSctFilterParams sec; + struct dmxPesFilterParams pes; + } params; + + int type; + dmxdev_state_t state; + struct dmxdev_s *dev; + dmxdev_buffer_t buffer; + + // only for sections + struct timer_list timer; + int todo; + uint8_t secheader[3]; + + u16 pid; +} dmxdev_filter_t; + + +typedef struct dmxdev_dvr_s { + int state; + struct dmxdev_s *dev; + dmxdev_buffer_t buffer; +} dmxdev_dvr_t; + + +typedef struct dmxdev_s { + dmxdev_filter_t *filter; + dmxdev_dvr_t *dvr; + dmx_demux_t *demux; + + int filternum; + int capabilities; +#define DMXDEV_CAP_DUPLEX 1 + dmx_frontend_t *dvr_orig_fe; + + dmxdev_buffer_t dvr_buffer; +#define DVR_BUFFER_SIZE (512*1024) + + struct semaphore mutex; + spinlock_t lock; +} dmxdev_t; + + +int DmxDevInit(dmxdev_t *dmxdev); +void DmxDevRelease(dmxdev_t *dmxdev); + +int DmxDevFilterAlloc(dmxdev_t *dmxdev, struct file *file); +int DmxDevFilterFree(dmxdev_t *dmxdev, struct file *file); +int DmxDevIoctl(dmxdev_t *dmxdev, struct file *file, + unsigned int cmd, unsigned long arg); +unsigned int DmxDevPoll(dmxdev_t *dmxdev, struct file *file, poll_table * wait); +ssize_t DmxDevRead(dmxdev_t *dmxdev, struct file *file, + char *buf, size_t count, loff_t *ppos); + +int DmxDevDVROpen(dmxdev_t *dmxdev, struct file *file); +int DmxDevDVRClose(dmxdev_t *dmxdev, struct file *file); +ssize_t DmxDevDVRWrite(dmxdev_t *dmxdev, struct file *file, + const char *buf, size_t count, loff_t *ppos); +ssize_t DmxDevDVRRead(dmxdev_t *dmxdev, struct file *file, + char *buf, size_t count, loff_t *ppos); +int DmxDevDVRIoctl(dmxdev_t *dmxdev, struct file *file, + unsigned int cmd, unsigned long arg); +unsigned int DmxDevDVRPoll(dmxdev_t *dmxdev, struct file *file, poll_table * wait); + +#endif /* _DMXDEV_H_ */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/dram.c linux.19pre5-ac1/drivers/media/video/margi/dram.c --- linux.19p5/drivers/media/video/margi/dram.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/dram.c Tue Feb 5 00:22:28 2002 @@ -0,0 +1,515 @@ +/* + dram.c + + Copyright (C) Christian Wolff for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the 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. +*/ + + ///////////////////////////////// + // // + // L64021 DRAM Memory Access // + // // +///////////////////////////////// + +#define __NO_VERSION__ + +#include "dram.h" +#include "l64021.h" + +#define EMERGENCYCOUNTER 5 + + // where: 21 bit DRAM Word-Address, 4 word aligned + // size: bytes (8 byte aligned, remainder will be filled with fill value) + // data: fill value +// returns 0 on success, -1 on collision with DMA transfer +int DRAMFillByte(struct cvdv_cards *card, u32 where, int size, u8 data) +{ + int i, j, k, n; + u8 volatile flag; + + size = (size >> 3) + ((size & 7) ? 1 : 0); // 8 bytes at a time, padding with garbage + where >>= 2; // 8 byte aligned data + DecoderSetByte(card, 0x0C1, 0x08); +//TODO: 0x80? + + DecoderWriteByte(card, 0x0C6, (u8) ((where >> 16) & 0x00000007L)); + DecoderWriteByte(card, 0x0C5, (u8) ((where >> 8) & 0x000000FFL)); + DecoderWriteByte(card, 0x0C4, (u8) (where & 0x000000FFL)); + i = 0; + for (j = 0; j < size; j++) { + for (k = 0; k < 8; k++) { + n = EMERGENCYCOUNTER; + do { // wait if FIFO full + flag = DecoderReadByte(card, 0x0C0); + } while ((flag & 0x08) && n--); + if (n<0) + return -1; + DecoderWriteByte(card, 0x0C3, data); + } + } + flag = DecoderReadByte(card, 0x0C0); + n = EMERGENCYCOUNTER; + do { // wait for FIFO empty + flag = DecoderReadByte(card, 0x0C0); + } while (!(flag & 0x04) && n--); + return ((n>=0) ? 0 : -1); +} + + // where: 21 bit DRAM Word-Address, 8 byte aligned + // size: bytes (8 byte aligned, remainder will be filled with garbage) + // swap: 0=normal mode, 1=write each 8 bytes on reverse order (7,6,5,4,3,2,1,0,15,14,13,etc.) +// returns 0 on success, -1 on collision with DMA transfer +int DRAMWriteByte(struct cvdv_cards *card, u32 where, int size, u8 * data, + int swapburst) +{ + int i, j, k, n; + u8 volatile flag; + + size = (size >> 3) + ((size & 7) ? 1 : 0); // 8 bytes at a time, padding with garbage + where >>= 2; // 8 byte aligned data + MDEBUG(4, ": Moving %d 64-bit-words to DRAM 0x%08X\n",size,where); + //if (swap) DecoderDelByte(card,0x0C1,0x08); // byte swapping of 8 byte bursts + //else DecoderSetByte(card,0x0C1,0x08); // no byte swapping + DecoderSetByte(card, 0x0C1, 0x08); // no byte swapping + + DecoderWriteByte(card, 0x0C6, (u8) ((where >> 16) & 0x00000007L)); + DecoderWriteByte(card, 0x0C5, (u8) ((where >> 8) & 0x000000FFL)); + DecoderWriteByte(card, 0x0C4, (u8) (where & 0x000000FFL)); + i = 0; + if (swapburst) { + for (j = 0; j < size; j++) { + for (k = 7; k >= 0; k--) { + n = EMERGENCYCOUNTER; + do { // wait if FIFO full + flag = + DecoderReadByte(card, 0x0C0); + } while ((flag & 0x08) && n--); + if (n<0) + return -1; + DecoderWriteByte(card, 0x0C3, data[i + k]); + } + i += 8; + } + } else { + for (j = 0; j < size; j++) { + for (k = 0; k < 8; k++) { + n = EMERGENCYCOUNTER; + do { // wait if FIFO full + flag = + DecoderReadByte(card, 0x0C0); + } while ((flag & 0x08) && n--); + if (n<0) + return -1; + DecoderWriteByte(card, 0x0C3, data[i++]); + } + } + } + flag = DecoderReadByte(card, 0x0C0); + n = EMERGENCYCOUNTER; + do { // wait for FIFO empty + flag = DecoderReadByte(card, 0x0C0); + } while (!(flag & 0x04) && n--); + return ((n>=0) ? 0 : -1); +} + + // where: 21 bit DRAM Word-Address, 4 word aligned + // size: words (4 word aligned, remainder will be filled with garbage) + // swap: 0=normal mode, 1=write each 8 bytes on reverse order (7,6,5,4,3,2,1,0,15,14,13,etc.) +// returns 0 on success, -1 on collision with DMA transfer +int DRAMWriteWord(struct cvdv_cards *card, u32 where, int size, u16 * data, + int swap) +{ + int i, j, k, n; + u8 volatile flag; + + size = (size >> 2) + ((size & 3) ? 1 : 0); // 4 words at a time, padding with garbage + where >>= 2; // 8 byte aligned data + MDEBUG(4, ": Moving %d 64-bit-words to DRAM 0x%08X\n",size,where); +//TODO: swap manually + if (swap) + DecoderDelByte(card, 0x0C1, 0x08); // byte swapping of 8 byte bursts + else + DecoderSetByte(card, 0x0C1, 0x08); // no byte swapping + + DecoderWriteByte(card, 0x0C6, (u8) ((where >> 16) & 0x00000007L)); + DecoderWriteByte(card, 0x0C5, (u8) ((where >> 8) & 0x000000FFL)); + DecoderWriteByte(card, 0x0C4, (u8) (where & 0x000000FFL)); + i = 0; + for (j = 0; j < size; j++) { + for (k = 0; k < 4; k++) { + n = EMERGENCYCOUNTER; + do { // wait if FIFO full + flag = DecoderReadByte(card, 0x0C0); + } while ((flag & 0x08) && n--); + if (n<0) + return -1; + DecoderWriteByte(card, 0x0C3, data[i] >> 8); + n = EMERGENCYCOUNTER; + do { // wait if FIFO full + flag = DecoderReadByte(card, 0x0C0); + } while ((flag & 0x08) && n--); + if (n<0) + return -1; + DecoderWriteByte(card, 0x0C3, data[i++]); + } + } + flag = DecoderReadByte(card, 0x0C0); + n = EMERGENCYCOUNTER; + do { // wait for FIFO empty + flag = DecoderReadByte(card, 0x0C0); + } while (!(flag & 0x04) && n--); + return ((n>=0) ? 0 : -1); +} + + // where: 21 bit DRAM Word-Address, 8 byte aligned + // size: bytes + // swap: 0=normal mode, 1=write each 8 bytes on reverse order (7,6,5,4,3,2,1,0,15,14,13,etc.) +// returns 0 on success, -1 on collision with DMA transfer +int DRAMReadByte(struct cvdv_cards *card, u32 where, int size, u8 * data, + int swap) +{ + int i, j, rsize, n; + u8 volatile flag; + + rsize = size & 7; // padding bytes + size = size >> 3; // 8 bytes at a time + where >>= 2; // 8 byte aligned data + MDEBUG(4, ": Moving %d 64-bit-words to DRAM 0x%08X\n",size,where); +//TODO: swap manually + if (swap) + DecoderDelByte(card, 0x0C1, 0x08); // byte swapping of 8 byte bursts + else + DecoderSetByte(card, 0x0C1, 0x08); // no byte swapping + + DecoderWriteByte(card, 0x0C9, (u8) ((where >> 16) & 0x00000007L)); + DecoderWriteByte(card, 0x0C8, (u8) ((where >> 8) & 0x000000FFL)); + DecoderWriteByte(card, 0x0C7, (u8) (where & 0x000000FFL)); + i = 0; + for (j = 0; j < size; j++) { + n = EMERGENCYCOUNTER; + do { // wait if FIFO empty + flag = DecoderReadByte(card, 0x0C0); + } while ((flag & 0x01) && n--); + if (n<0) // WARNING nicht if(!n) + return -1; + data[i++] = DecoderReadByte(card, 0x0C2); + data[i++] = DecoderReadByte(card, 0x0C2); + data[i++] = DecoderReadByte(card, 0x0C2); + data[i++] = DecoderReadByte(card, 0x0C2); + data[i++] = DecoderReadByte(card, 0x0C2); + data[i++] = DecoderReadByte(card, 0x0C2); + data[i++] = DecoderReadByte(card, 0x0C2); + data[i++] = DecoderReadByte(card, 0x0C2); + } + n = EMERGENCYCOUNTER; + do { // wait if FIFO empty + flag = DecoderReadByte(card, 0x0C0); + } while ((flag & 0x01) && n--); + if (n<0) + return -1; + for (j = 0; j < rsize; j++) + data[i++] = DecoderReadByte(card, 0x0C2); + flag = DecoderReadByte(card, 0x0C0); + n = EMERGENCYCOUNTER; + do { // wait for FIFO full + flag = DecoderReadByte(card, 0x0C0); + } while (!(flag & 0x02) && n--); + return ((n>=0) ? 0 : -1); +} + + + // where: 21 bit DRAM Word-Address, 4 word aligned + // size: words + // swap: 0=normal mode, 1=write each 8 bytes on reverse order (7,6,5,4,3,2,1,0,15,14,13,etc.) +// returns 0 on success, -1 on collision with DMA transfer +int DRAMReadWord(struct cvdv_cards *card, u32 where, int size, u16 * data, + int swap) +{ + int i, j, rsize, n; + u8 volatile flag; + u8 b; + + rsize = size & 3; // padding words + size >>= 2; // 4 words at a time + where >>= 2; // 8 byte aligned data + MDEBUG(4, ": Reading %d 64-bit-words and %d 16-bit-words from DRAM 0x%08X\n", + size,rsize,where); +//TODO: swap manually + if (swap) + DecoderDelByte(card, 0x0C1, 0x08); // byte swapping of 8 byte bursts + else + DecoderSetByte(card, 0x0C1, 0x08); // no byte swapping + + DecoderWriteByte(card, 0x0C9, (u8) ((where >> 16) & 0x00000007L)); + DecoderWriteByte(card, 0x0C8, (u8) ((where >> 8) & 0x000000FFL)); + DecoderWriteByte(card, 0x0C7, (u8) (where & 0x000000FFL)); + i = 0; + for (j = 0; j < size; j++) { + n = EMERGENCYCOUNTER; + do { // wait if FIFO empty + flag = DecoderReadByte(card, 0x0C0); + } while ((flag & 0x01) && n--); + if (n<0) + return -1; + b = DecoderReadByte(card, 0x0C2); + data[i++] = ((b << 8) | DecoderReadByte(card, 0x0C2)); + b = DecoderReadByte(card, 0x0C2); + data[i++] = ((b << 8) | DecoderReadByte(card, 0x0C2)); + b = DecoderReadByte(card, 0x0C2); + data[i++] = ((b << 8) | DecoderReadByte(card, 0x0C2)); + b = DecoderReadByte(card, 0x0C2); + data[i++] = ((b << 8) | DecoderReadByte(card, 0x0C2)); + } + n = EMERGENCYCOUNTER; + do { // wait if FIFO empty + flag = DecoderReadByte(card, 0x0C0); + } while ((flag & 0x01) && n--); + if (n<0) + return -1; + for (j = 0; j < rsize; j++) { + b = DecoderReadByte(card, 0x0C2); + data[i++] = ((b << 8) | DecoderReadByte(card, 0x0C2)); + } + flag = DecoderReadByte(card, 0x0C0); + n = EMERGENCYCOUNTER; + do { // wait for FIFO full + flag = DecoderReadByte(card, 0x0C0); + } while (!(flag & 0x02) && n--); + return ((n>=0) ? 0 : -1); +} + + // where: 21 bit DRAM Word-Address, 4 word aligned + // size: words + // swap: 0=normal mode, 1=write each 8 bytes on reverse order (7,6,5,4,3,2,1,0,15,14,13,etc.) + // returns -1 on success (equal content), + // word position on error (compare failure), +// -2 on collision with DMA transfer +int DRAMVerifyWord(struct cvdv_cards *card, u32 where, int size, + u16 * data, int swap) +{ + int i, j, rsize, n; + u8 volatile flag, b; + + rsize = size & 3; // padding words + size >>= 2; // 4 words at a time + where >>= 2; // 8 byte aligned data, now 19 bit 64-bit-word-address +//TODO: swap manually + if (swap) + DecoderDelByte(card, 0x0C1, 0x08); // byte swapping of 8 byte bursts + else + DecoderSetByte(card, 0x0C1, 0x08); // no byte swapping + + DecoderWriteByte(card, 0x0C9, (u8) ((where >> 16) & 0x00000007L)); + DecoderWriteByte(card, 0x0C8, (u8) ((where >> 8) & 0x000000FFL)); + DecoderWriteByte(card, 0x0C7, (u8) (where & 0x000000FFL)); + i = 0; + for (j = 0; j < size; j++) { + n = EMERGENCYCOUNTER; + do { // wait if FIFO empty + flag = DecoderReadByte(card, 0x0C0); + } while ((flag & 0x01) && n--); + b = DecoderReadByte(card, 0x0C2); + if (data[i++] != ((b << 8) | DecoderReadByte(card, 0x0C2))) + return i; + b = DecoderReadByte(card, 0x0C2); + if (data[i++] != ((b << 8) | DecoderReadByte(card, 0x0C2))) + return i; + b = DecoderReadByte(card, 0x0C2); + if (data[i++] != ((b << 8) | DecoderReadByte(card, 0x0C2))) + return i; + b = DecoderReadByte(card, 0x0C2); + if (data[i++] != ((b << 8) | DecoderReadByte(card, 0x0C2))) + return i; + } + n = EMERGENCYCOUNTER; + do { // wait if FIFO empty + flag = DecoderReadByte(card, 0x0C0); + } while ((flag & 0x01) && n--); + for (j = 0; j < rsize; j++) { + b = DecoderReadByte(card, 0x0C2); + if (data[i++] != ((b << 8) | DecoderReadByte(card, 0x0C2))) + return i; + } + flag = DecoderReadByte(card, 0x0C0); + n = EMERGENCYCOUNTER; + do { // wait for FIFO full + flag = DecoderReadByte(card, 0x0C0); + } while (!(flag & 0x02) && n--); + return -1; +} + + // WARNING: better not use this one. It can collide with normal DRAM access and other DMA transfers + // If you want to use it, implement card->DMAMoveBusy in all other DMA functions, initialisation, and header file + // source, destination: 21 bit DRAM Word-Address, 4 word aligned + // size: byte (8 byte aligned, hang over bytes will NOT be moved) + // returns 0 on success on success, + // -1 on collision with DMA transfer, +// -2 on interrupt handler not installed +int DRAMMove(struct cvdv_cards *card, u32 source, u32 destination, + int size) +{ + if (!card->IntInstalled) + return -2; + if (card->DMAABusy || card->DMABBusy) + return -1; + + size >>= 3; // 64-bit-words + source >>= 2; // 8 byte aligned data, + destination >>= 2; // now 19 bit 64-bit-word-address + + DecoderDelByte(card, 0x0C1, 0x06); // DMA idle + + DecoderWriteByte(card, 0x0DA, (u8) ((source >> 16) & 0x00000007L)); + DecoderWriteByte(card, 0x0D9, (u8) ((source >> 8) & 0x000000FFL)); + DecoderWriteByte(card, 0x0D8, (u8) (source & 0x000000FFL)); + DecoderWriteByte(card, 0x0D7, + (u8) ((destination >> 16) & 0x00000007L)); + DecoderWriteByte(card, 0x0D6, + (u8) ((destination >> 8) & 0x000000FFL)); + DecoderWriteByte(card, 0x0D5, (u8) (destination & 0x000000FFL)); + + //card->DMAMoveBusy=1; // would have to catch that in all the other DMA routines + DecoderSetByte(card, 0x0C1, 0x06); // DMA block move + + return 0; +} + + // size in words + // align: number of words on wich start of block will be aligned +// return value is 21 bit word address, or 0xFFFFFFFF on error +u32 DRAMAlloc(struct cvdv_cards * card, u32 size, int align) +{ + struct DRAMBlock *ptr, *ptr2; + u32 addr = 0; + u32 alignmask = align - 1; + int valid = 0; + + printk("DRAMAlloc %d bytes (from %d).\n", size, card->DRAMSize); + + if (size == 0) + { + printk("DRAMAlloc - 0 size.\n"); + return BLANK; + } + + if (size & 3) + size = (size & ~3) + 4; // increase size if not 64 bit aligned + + printk("DRAMAlloc %d bytes.\n", size); + if (card->DRAMFirstBlock == NULL) { // virgin territory? + valid = ((addr + size) <= card->DRAMSize); // does it fit at all? + } else { + addr = 0; + valid = ((addr + size) <= card->DRAMSize); // does it fit at all? + for (ptr2 = card->DRAMFirstBlock; + (ptr2 != NULL) && (valid); ptr2 = ptr2->next) { // check against all existing blocks + if ((ptr2->start >= addr) + && (ptr2->start < (addr + size))) + valid = 0; // existing block start inside new block? + else if (((ptr2->start + ptr2->length) > addr) + && ((ptr2->start + ptr2->length) <= + (addr + size))) + valid = 0; // existing block end inside new block? + else if ((ptr2->start < addr) + && ((ptr2->start + ptr2->length) > + (addr + size))) valid = 0; // new block inside existing block? + } + for (ptr = card->DRAMFirstBlock; (ptr != NULL) && (!valid); + ptr = ptr->next) { // check all existing blocks + addr = ptr->start + ptr->length; // assume, after this block is free space + if (addr & alignmask) + addr = (addr & ~alignmask) + align; // round up to alignation border + valid = ((addr + size) <= card->DRAMSize); // does it fit at all? + for (ptr2 = card->DRAMFirstBlock; + (ptr2 != NULL) && (valid); ptr2 = ptr2->next) { // check against all existing blocks + if ((ptr2->start >= addr) + && (ptr2->start < (addr + size))) + valid = 0; // existing block start inside new block? + else + if ( + ((ptr2->start + ptr2->length) > + addr) + && ((ptr2->start + ptr2->length) <= + (addr + size))) + valid = 0; // existing block end inside new block? + else if ((ptr2->start < addr) + && ((ptr2->start + ptr2->length) > + (addr + size))) + valid = 0; // new block inside existing block? + } + } + } + if (valid) { // The new block fits + ptr = (struct DRAMBlock *) kmalloc(sizeof(struct DRAMBlock), GFP_KERNEL); + if (ptr == NULL) { + printk(KERN_INFO LOGNAME ": ERROR: out of kernel memory for block info. Please reboot if possible.\n"); + return BLANK; // out of kernel mem + } + if (card->DRAMFirstBlock == NULL) { + card->DRAMFirstBlock = ptr; + } else { + ptr2 = card->DRAMFirstBlock; + while (ptr2->next != NULL) + ptr2 = ptr2->next; + ptr2->next = ptr; + } + ptr->next = NULL; + ptr->start = addr; + ptr->length = size; + MDEBUG(1,": DRAM Allocate 0x%08X-0x%08X\n", addr, + addr + size - 1); + + printk("DRAMAlloc ok\n"); + return addr; + } + printk(KERN_ERR "DRAMAlloc: No card memory.\n"); + return BLANK; +} + + // addr is the return value of that resp. DRAMAlloc call +// returns 0 on success (always) +int DRAMFree(struct cvdv_cards *card, u32 addr) +{ + struct DRAMBlock *ptr, *ptr2; + ptr2 = NULL; + for (ptr = card->DRAMFirstBlock; ptr != NULL; ptr = ptr->next) { // check all existent blocks + if (addr == ptr->start) { // this is our block to be removed + if (ptr2 == NULL) + card->DRAMFirstBlock = ptr->next; + else + ptr2->next = ptr->next; + kfree(ptr); + MDEBUG(1, ": DRAM Free 0x%08X\n", addr); + } else + ptr2 = ptr; + } + return 0; +} + + // free all blocks +// returns 0 on success (always) +int DRAMRelease(struct cvdv_cards *card) +{ + struct DRAMBlock *ptr, *ptr2; + MDEBUG(1, ": -- DRAMRelease\n"); + for (ptr = card->DRAMFirstBlock; ptr != NULL; ptr = ptr2) { // check all existent blocks + ptr2 = ptr->next; + MDEBUG(4, ": kfree(0x%08X)\n",(int)ptr); + kfree(ptr); + } + card->DRAMFirstBlock = NULL; + return 0; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/dram.h linux.19pre5-ac1/drivers/media/video/margi/dram.h --- linux.19p5/drivers/media/video/margi/dram.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/dram.h Thu Apr 4 15:55:29 2002 @@ -0,0 +1,99 @@ +/* + dram.h + + Copyright (C) Christian Wolff for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef DRAM_H +#define DRAM_H + + ///////////////////////////////// + // // + // L64021 DRAM Memory Access // + // // +///////////////////////////////// + +#include "cardbase.h" + + // where: 21 bit DRAM Word-Address, 4 word aligned + // size: bytes (8 byte aligned, remainder will be filled with fill value) + // data: fill value +// returns 0 on success, -1 on collision with DMA transfer +int DRAMFillByte(struct cvdv_cards *card, u32 where, int size, u8 data); + + // where: 21 bit DRAM Word-Address, 8 byte aligned + // size: bytes (8 byte aligned, remainder will be filled with garbage) + // swap: 0=normal mode, 1=write each 8 bytes on reverse order (7,6,5,4,3,2,1,0,15,14,13,etc.) +// returns 0 on success, -1 on collision with DMA transfer +int DRAMWriteByte(struct cvdv_cards *card, u32 where, int size, u8 * data, + int swapburst); + + // where: 21 bit DRAM Word-Address, 4 word aligned + // size: words (4 word aligned, remainder will be filled with garbage) + // swap: 0=normal mode, 1=write each 8 bytes on reverse order (7,6,5,4,3,2,1,0,15,14,13,etc.) +// returns 0 on success, -1 on collision with DMA transfer +int DRAMWriteWord(struct cvdv_cards *card, u32 where, int size, u16 * data, + int swap); + + // where: 21 bit DRAM Word-Address, 8 byte aligned + // size: bytes + // swap: 0=normal mode, 1=write each 8 bytes on reverse order (7,6,5,4,3,2,1,0,15,14,13,etc.) +// returns 0 on success, -1 on collision with DMA transfer +int DRAMReadByte(struct cvdv_cards *card, u32 where, int size, u8 * data, + int swap); + + + // where: 21 bit DRAM Word-Address, 4 word aligned + // size: words + // swap: 0=normal mode, 1=write each 8 bytes on reverse order (7,6,5,4,3,2,1,0,15,14,13,etc.) +// returns 0 on success, -1 on collision with DMA transfer +int DRAMReadWord(struct cvdv_cards *card, u32 where, int size, u16 * data, + int swap); + + // where: 21 bit DRAM Word-Address, 4 word aligned + // size: words + // swap: 0=normal mode, 1=write each 8 bytes on reverse order (7,6,5,4,3,2,1,0,15,14,13,etc.) + // returns -1 on success (equal content), + // word position on error (compare failure), +// -2 on collision with DMA transfer +int DRAMVerifyWord(struct cvdv_cards *card, u32 where, int size, + u16 * data, int swap); + + // WARNING: better not use this one. It can collide with normal DRAM access and other DMA transfers + // If you want to use it, implement card->DMAMoveBusy in all other DMA functions, initialisation, and header file + // source, destination: 21 bit DRAM Word-Address, 4 word aligned + // size: byte (8 byte aligned, hang over bytes will NOT be moved) + // returns 0 on success on success, + // -1 on collision with DMA transfer, +// -2 on interrupt handler not installed +int DRAMMove(struct cvdv_cards *card, u32 source, u32 destination, + int size); + + // size in words + // align: number of words on wich start of block will be aligned +// return value is 21 bit word address, or 0xFFFFFFFF on error +u32 DRAMAlloc(struct cvdv_cards *card, u32 size, int align); + + // addr is the return value of that resp. DRAMAlloc call +// returns 0 on success (always) +int DRAMFree(struct cvdv_cards *card, u32 addr); + + // free all blocks +// returns 0 on success (always) +int DRAMRelease(struct cvdv_cards *card); + +#endif /* DRAM_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/dvb_demux.c linux.19pre5-ac1/drivers/media/video/margi/dvb_demux.c --- linux.19p5/drivers/media/video/margi/dvb_demux.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/dvb_demux.c Mon Feb 4 22:21:08 2002 @@ -0,0 +1,1169 @@ +/* + * dvb_demux.c - DVB kernel demux API + * + * Copyright (C) 2000-2001 Ralph Metzler + * & Marcus Metzler + * for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include + +#include "dvb_demux.h" + +#ifdef MODULE +MODULE_DESCRIPTION(""); +MODULE_AUTHOR("Ralph Metzler, Marcus Metzler"); +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif +#endif + +#define NOBUFS + +LIST_HEAD(dmx_muxs); + +int dmx_register_demux(dmx_demux_t *demux) +{ + struct list_head *pos, *head=&dmx_muxs; + + if (!(demux->id && demux->vendor && demux->model)) + return -EINVAL; + list_for_each(pos, head) + { + if (!strcmp(DMX_DIR_ENTRY(pos)->id, demux->id)) + return -EEXIST; + } + demux->users=0; + list_add(&(demux->reg_list), head); + MOD_INC_USE_COUNT; + return 0; +} + +int dmx_unregister_demux(dmx_demux_t* demux) +{ + struct list_head *pos, *head=&dmx_muxs; + + list_for_each(pos, head) + { + if (DMX_DIR_ENTRY(pos)==demux) + { + if (demux->users>0) + return -EINVAL; + list_del(pos); + MOD_DEC_USE_COUNT; + return 0; + } + } + return -ENODEV; +} + + +struct list_head *dmx_get_demuxes(void) +{ + if (list_empty(&dmx_muxs)) + return NULL; + + return &dmx_muxs; +} + +/****************************************************************************** + * static inlined helper functions + ******************************************************************************/ + +static inline u16 +section_length(const u8 *buf) +{ + return 3+((buf[1]&0x0f)<<8)+buf[2]; +} + +static inline u16 +ts_pid(const u8 *buf) +{ + return ((buf[1]&0x1f)<<8)+buf[2]; +} + +static inline int +payload(const u8 *tsp) +{ + if (!(tsp[3]&0x10)) // no payload? + return 0; + if (tsp[3]&0x20) { // adaptation field? + if (tsp[4]>183) // corrupted data? + return 0; + else + return 184-1-tsp[4]; + } + return 184; +} + + +static u32 +dvb_crc_table[256] = { + 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, + 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, + 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, + 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, + 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, + 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, + 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, + 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, + 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, + 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, + 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, + 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, + 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, + 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, + 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, + 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, + 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, + 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, + 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, + 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, + 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, + 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, + 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, + 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, + 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, + 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, + 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, + 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, + 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, + 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, + 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, + 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, + 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, + 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, + 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, + 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, + 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, + 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, + 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, + 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, + 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, + 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, + 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4}; + +u32 dvb_crc32(u8 *data, int len) +{ + int i; + u32 crc = 0xffffffff; + + for (i=0; i> 24) ^ *data++) & 0xff]; + return crc; +} + +void dvb_set_crc32(u8 *data, int length) +{ + u32 crc; + + crc=dvb_crc32(data,length); + data[length] = (crc>>24)&0xff; + data[length+1] = (crc>>16)&0xff; + data[length+2] = (crc>>8)&0xff; + data[length+3] = (crc)&0xff; +} + + +/****************************************************************************** + * Software filter functions + ******************************************************************************/ + +static inline int +DvbDmxSWFilterPayload(dvb_demux_feed_t *dvbdmxfeed, const u8 *buf) +{ + int p, count; + //int ccok; + //u8 cc; + + if (!(count=payload(buf))) + return -1; + p=188-count; + /* + cc=buf[3]&0x0f; + ccok=((dvbdmxfeed->cc+1)&0x0f)==cc ? 1 : 0; + dvbdmxfeed->cc=cc; + if (!ccok) + printk("missed packet!\n"); + */ + if (buf[1]&0x40) // PUSI ? + dvbdmxfeed->peslen=0xfffa; + dvbdmxfeed->peslen+=count; + + return dvbdmxfeed->cb.ts((u8 *)&buf[p], count, 0, 0, + &dvbdmxfeed->feed.ts, DMX_OK); +} + + +static int +DvbDmxSWFilterSectionFilter(dvb_demux_feed_t *dvbdmxfeed, + dvb_demux_filter_t *dvbdmxfilter) +{ + dmx_section_filter_t *filter=&dvbdmxfilter->filter; +#if 1 + int i; + + for (i=0; ifilter_mask[i]& + (filter->filter_value[i]^dvbdmxfeed->secbuf[i])) + return 0; +#else + u32 res; + u32 *val=(u32 *)(filter->filter_value); + u32 *mask=(u32 *)(filter->filter_mask); + u32 *data=(u32 *)(dvbdmxfeed->secbuf); + + res=mask[0]&(val[0]^data[0]); + if (res) return 0; + + res=mask[1]&(val[1]^data[1]); + if (res) return 0; + + res=mask[2]&(val[2]^data[2]); + if (res) return 0; + + res=mask[3]&(val[3]^data[3]); + if (res) return 0; + + res=*(u16 *)(4+mask) & (*(u16 *)(4+val) ^ *(u16 *)(4+data)); + if (res) return 0; +#endif + + return dvbdmxfeed->cb.sec(dvbdmxfeed->secbuf, dvbdmxfeed->seclen, + 0, 0, filter, DMX_OK); +} + +static inline int +DvbDmxSWFilterSectionFeed(dvb_demux_feed_t *dvbdmxfeed) +{ + u8 *buf=dvbdmxfeed->secbuf; + dvb_demux_filter_t *f; + + if (dvbdmxfeed->secbufp!=dvbdmxfeed->seclen) + return -1; + if (!dvbdmxfeed->feed.sec.is_filtering) + return 0; + if (!(f=dvbdmxfeed->filter)) + return 0; + do + if (DvbDmxSWFilterSectionFilter(dvbdmxfeed, f)<0) + return -1; + while ((f=f->next) && dvbdmxfeed->feed.sec.is_filtering); + + dvbdmxfeed->secbufp=dvbdmxfeed->seclen=0; + memset(buf, 0, DVB_DEMUX_MASK_MAX); + return 0; +} + +static inline int +DvbDmxSWFilterSectionPacket(dvb_demux_feed_t *dvbdmxfeed, const u8 *buf) +{ + int p, count; + int ccok, rest; + u8 cc; + + if (!(count=payload(buf))) + return -1; + p=188-count; + + cc=buf[3]&0x0f; + ccok=((dvbdmxfeed->cc+1)&0x0f)==cc ? 1 : 0; + dvbdmxfeed->cc=cc; + + if (buf[1]&0x40) { // PUSI set + // offset to start of first section is in buf[p] + if (p+buf[p]>187) // trash if it points beyond packet + return -1; + if (buf[p] && ccok) { // rest of previous section? + // did we have enough data in last packet to calc length? + if (dvbdmxfeed->secbufp && dvbdmxfeed->secbufp<3) { + memcpy(dvbdmxfeed->secbuf+dvbdmxfeed->secbufp, + buf+p+1, + 3-dvbdmxfeed->secbufp); + dvbdmxfeed->seclen=section_length(dvbdmxfeed->secbuf); + if (dvbdmxfeed->seclen>4096) + return -1; + } + rest=dvbdmxfeed->seclen-dvbdmxfeed->secbufp; + if (rest==buf[p] && dvbdmxfeed->seclen) { + memcpy(dvbdmxfeed->secbuf+dvbdmxfeed->secbufp, + buf+p+1, buf[p]); + dvbdmxfeed->secbufp+=buf[p]; + DvbDmxSWFilterSectionFeed(dvbdmxfeed); + } + } + p+=buf[p]+1; // skip rest of last section + count=188-p; + while (count>0) { + if ((count>2) && // enough data to determine sec length? + ((dvbdmxfeed->seclen=section_length(buf+p))<=count)) { + if (dvbdmxfeed->seclen>4096) + return -1; + memcpy(dvbdmxfeed->secbuf, buf+p, + dvbdmxfeed->seclen); + dvbdmxfeed->secbufp=dvbdmxfeed->seclen; + p+=dvbdmxfeed->seclen; + count=188-p; + DvbDmxSWFilterSectionFeed(dvbdmxfeed); + + // filling bytes until packet end? + if (count && buf[p]==0xff) + count=0; + } else { // section continues to following TS packet + memcpy(dvbdmxfeed->secbuf, buf+p, count); + dvbdmxfeed->secbufp+=count; + count=0; + } + } + } else { // section continued below + if (!ccok) + return -1; + if (!dvbdmxfeed->secbufp) // any data in last ts packet? + return -1; + // did we have enough data in last packet to calc section length? + if (dvbdmxfeed->secbufp<3) { + memcpy(dvbdmxfeed->secbuf+dvbdmxfeed->secbufp, buf+p, + 3-dvbdmxfeed->secbufp); + dvbdmxfeed->seclen=section_length(dvbdmxfeed->secbuf); + if (dvbdmxfeed->seclen>4096) + return -1; + } + rest=dvbdmxfeed->seclen-dvbdmxfeed->secbufp; + if (rest<0) + return -1; + if (rest<=count) { // section completed in this TS packet + memcpy(dvbdmxfeed->secbuf+dvbdmxfeed->secbufp, buf+p, rest); + dvbdmxfeed->secbufp+=rest; + DvbDmxSWFilterSectionFeed(dvbdmxfeed); + } else { // section continues in following ts block + memcpy(dvbdmxfeed->secbuf+dvbdmxfeed->secbufp, buf+p, count); + dvbdmxfeed->secbufp+=count; + } + + } + return 0; +} + +static inline void +DvbDmxSWFilterPacketType(dvb_demux_feed_t *dvbdmxfeed, const u8 *buf) +{ + switch(dvbdmxfeed->type) { + case DMX_TYPE_TS: + if (!dvbdmxfeed->feed.ts.is_filtering) + break; + if (dvbdmxfeed->ts_type & TS_PACKET) { + if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY) + DvbDmxSWFilterPayload(dvbdmxfeed, buf); + else + dvbdmxfeed->cb.ts((u8 *)buf, 188, 0, 0, + &dvbdmxfeed->feed.ts, DMX_OK); + } + if (dvbdmxfeed->ts_type & TS_DECODER) + if (dvbdmxfeed->demux->write_to_decoder) + dvbdmxfeed->demux-> + write_to_decoder(dvbdmxfeed, (u8 *)buf, 188); + break; + + case DMX_TYPE_SEC: + if (!dvbdmxfeed->feed.sec.is_filtering) + break; + if (DvbDmxSWFilterSectionPacket(dvbdmxfeed, buf)<0) + dvbdmxfeed->seclen=dvbdmxfeed->secbufp=0; + break; + + default: + break; + } +} + +void inline +DvbDmxSWFilterPacket(dvb_demux_t *dvbdmx, const u8 *buf) +{ + dvb_demux_feed_t *dvbdmxfeed; + + if (!(dvbdmxfeed=dvbdmx->pid2feed[ts_pid(buf)])) + return; + DvbDmxSWFilterPacketType(dvbdmxfeed, buf); +} + +void +DvbDmxSWFilterPackets(dvb_demux_t *dvbdmx, const u8 *buf, int count) +{ + dvb_demux_feed_t *dvbdmxfeed; + + if ((dvbdmxfeed=dvbdmx->pid2feed[0x2000])) + dvbdmxfeed->cb.ts((u8 *)buf, count*188, 0, 0, + &dvbdmxfeed->feed.ts, DMX_OK); + while (count) { + DvbDmxSWFilterPacket(dvbdmx, buf); + count--; + buf+=188; + } +} + +static inline void +DvbDmxSWFilter(dvb_demux_t *dvbdmx, const u8 *buf, size_t count) +{ + int p=0,i, j; + + if ((i=dvbdmx->tsbufp)) { + if (count<(j=188-i)) { + memcpy(&dvbdmx->tsbuf[i], buf, count); + dvbdmx->tsbufp+=count; + return; + } + memcpy(&dvbdmx->tsbuf[i], buf, j); + DvbDmxSWFilterPacket(dvbdmx, dvbdmx->tsbuf); + dvbdmx->tsbufp=0; + p+=j; + } + + while (p=188) { + DvbDmxSWFilterPacket(dvbdmx, buf+p); + p+=188; + } else { + i=count-p; + memcpy(dvbdmx->tsbuf, buf+p, i); + dvbdmx->tsbufp=i; + return; + } + } else + p++; + } +} + + +/****************************************************************************** + ****************************************************************************** + * DVB DEMUX API LEVEL FUNCTIONS + ****************************************************************************** + ******************************************************************************/ + +static dvb_demux_filter_t * +DvbDmxFilterAlloc(dvb_demux_t *dvbdmx) +{ + int i; + + for (i=0; ifilternum; i++) + if (dvbdmx->filter[i].state==DMX_STATE_FREE) + break; + if (i==dvbdmx->filternum) + return 0; + dvbdmx->filter[i].state=DMX_STATE_ALLOCATED; + return &dvbdmx->filter[i]; +} + +static dvb_demux_feed_t * +DvbDmxFeedAlloc(dvb_demux_t *dvbdmx) +{ + int i; + + for (i=0; ifeednum; i++) + if (dvbdmx->feed[i].state==DMX_STATE_FREE) + break; + if (i==dvbdmx->feednum) + return 0; + dvbdmx->feed[i].state=DMX_STATE_ALLOCATED; + return &dvbdmx->feed[i]; +} + + +/****************************************************************************** + * dmx_ts_feed API calls + ******************************************************************************/ + +static int +dmx_ts_feed_set_type(dmx_ts_feed_t *feed, int type, dmx_ts_pes_t pes_type) +{ + dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed; + dvb_demux_t *dvbdmx=dvbdmxfeed->demux; + + down(&dvbdmx->mutex); + dvbdmxfeed->ts_type=type; + dvbdmxfeed->pes_type=pes_type; + + if (dvbdmxfeed->ts_type & TS_DECODER) { + if (pes_type >= DMX_TS_PES_OTHER) { + up(&dvbdmx->mutex); + return -EINVAL; + } + if (dvbdmx->pesfilter[pes_type] && + (dvbdmx->pesfilter[pes_type]!=dvbdmxfeed)) { + up(&dvbdmx->mutex); + return -EINVAL; + } + dvbdmx->pesfilter[pes_type]=dvbdmxfeed; + dvbdmx->pids[pes_type]=dvbdmxfeed->pid; + } + up(&dvbdmx->mutex); + return 0; +} + +static int +dmx_pid_set(u16 pid, dvb_demux_feed_t *dvbdmxfeed) +{ + dvb_demux_t *dvbdmx=dvbdmxfeed->demux; + dvb_demux_feed_t **pid2feed=dvbdmx->pid2feed; + + if (pid>DMX_MAX_PID) + return -EINVAL; + if (dvbdmxfeed->pid!=0xffff) { + if (dvbdmxfeed->pid<=DMX_MAX_PID) + pid2feed[dvbdmxfeed->pid]=0; + dvbdmxfeed->pid=0xffff; + } + if (pid2feed[pid]) { + return -EBUSY; + } + pid2feed[pid]=dvbdmxfeed; + dvbdmxfeed->pid=pid; + return 0; +} + + +static int +dmx_ts_feed_set(struct dmx_ts_feed_s* feed, + u16 pid, + size_t callback_length, + size_t circular_buffer_size, + int descramble, + struct timespec timeout + ) +{ + dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed; + dvb_demux_t *dvbdmx=dvbdmxfeed->demux; + int ret; + + down(&dvbdmx->mutex); + ret=dmx_pid_set(pid, dvbdmxfeed); + if (ret<0) { + up(&dvbdmx->mutex); + return ret; + } + dvbdmxfeed->buffer_size=circular_buffer_size; + dvbdmxfeed->descramble=descramble; + dvbdmxfeed->timeout=timeout; + dvbdmxfeed->cb_length=callback_length; + dvbdmxfeed->ts_type=TS_PACKET; + + if (dvbdmxfeed->descramble) { + up(&dvbdmx->mutex); + return -ENOSYS; + } + + if (dvbdmxfeed->buffer_size) { +#ifdef NOBUFS + dvbdmxfeed->buffer=0; +#else + dvbdmxfeed->buffer=vmalloc(dvbdmxfeed->buffer_size); + if (!dvbdmxfeed->buffer) { + up(&dvbdmx->mutex); + return -ENOMEM; + } +#endif + } + dvbdmxfeed->state=DMX_STATE_READY; + up(&dvbdmx->mutex); + return 0; +} + +static int +dmx_ts_feed_start_filtering(struct dmx_ts_feed_s* feed) +{ + dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed; + dvb_demux_t *dvbdmx=dvbdmxfeed->demux; + int ret; + + down(&dvbdmx->mutex); + if (dvbdmxfeed->state!=DMX_STATE_READY || + dvbdmxfeed->type!=DMX_TYPE_TS) { + up(&dvbdmx->mutex); + return -EINVAL; + } + if (!dvbdmx->start_feed) { + up(&dvbdmx->mutex); + return -1; + } + ret=dvbdmx->start_feed(dvbdmxfeed); + if (ret<0) { + up(&dvbdmx->mutex); + return ret; + } + feed->is_filtering=1; + dvbdmxfeed->state=DMX_STATE_GO; + up(&dvbdmx->mutex); + return 0; +} + +static int +dmx_ts_feed_stop_filtering(struct dmx_ts_feed_s* feed) +{ + dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed; + dvb_demux_t *dvbdmx=dvbdmxfeed->demux; + int ret; + + down(&dvbdmx->mutex); + if (dvbdmxfeed->statemutex); + return -EINVAL; + } + if (!dvbdmx->stop_feed) { + up(&dvbdmx->mutex); + return -1; + } + ret=dvbdmx->stop_feed(dvbdmxfeed); + feed->is_filtering=0; + dvbdmxfeed->state=DMX_STATE_ALLOCATED; + + up(&dvbdmx->mutex); + return ret; +} + +static int dvbdmx_allocate_ts_feed(dmx_demux_t *demux, + dmx_ts_feed_t **feed, + dmx_ts_cb callback) +{ + dvb_demux_t *dvbdmx=(dvb_demux_t *) demux; + dvb_demux_feed_t *dvbdmxfeed; + + down(&dvbdmx->mutex); + if (!(dvbdmxfeed=DvbDmxFeedAlloc(dvbdmx))) { + up(&dvbdmx->mutex); + return -EBUSY; + } + dvbdmxfeed->type=DMX_TYPE_TS; + dvbdmxfeed->cb.ts=callback; + dvbdmxfeed->demux=dvbdmx; + dvbdmxfeed->pid=0xffff; + dvbdmxfeed->peslen=0xfffa; + dvbdmxfeed->buffer=0; + + (*feed)=&dvbdmxfeed->feed.ts; + (*feed)->is_filtering=0; + (*feed)->parent=demux; + (*feed)->priv=0; + (*feed)->set=dmx_ts_feed_set; + (*feed)->set_type=dmx_ts_feed_set_type; + (*feed)->start_filtering=dmx_ts_feed_start_filtering; + (*feed)->stop_filtering=dmx_ts_feed_stop_filtering; + + + if (!(dvbdmxfeed->filter=DvbDmxFilterAlloc(dvbdmx))) { + dvbdmxfeed->state=DMX_STATE_FREE; + up(&dvbdmx->mutex); + return -EBUSY; + } + + dvbdmxfeed->filter->type=DMX_TYPE_TS; + dvbdmxfeed->filter->feed=dvbdmxfeed; + dvbdmxfeed->filter->state=DMX_STATE_READY; + + up(&dvbdmx->mutex); + return 0; +} + +static int dvbdmx_release_ts_feed(dmx_demux_t *demux, dmx_ts_feed_t *feed) +{ + dvb_demux_t *dvbdmx=(dvb_demux_t *) demux; + dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed; + + down(&dvbdmx->mutex); + if (dvbdmxfeed->state==DMX_STATE_FREE) { + up(&dvbdmx->mutex); + return -EINVAL; + } +#ifndef NOBUFS + if (dvbdmxfeed->buffer) { + vfree(dvbdmxfeed->buffer); + dvbdmxfeed->buffer=0; + } +#endif + dvbdmxfeed->state=DMX_STATE_FREE; + dvbdmxfeed->filter->state=DMX_STATE_FREE; + if (dvbdmxfeed->pid!=0xffff) { + if (dvbdmxfeed->pid<=DMX_MAX_PID) + dvbdmxfeed->demux->pid2feed[dvbdmxfeed->pid]=0; + dvbdmxfeed->pid=0xffff; + } + + up(&dvbdmx->mutex); + return 0; +} + + +/****************************************************************************** + * dmx_pes_feed API calls + ******************************************************************************/ +/* +static int +dmx_pes_feed_set(struct dmx_pes_feed_s* feed, + u16 pid, + size_t circular_buffer_size, + int descramble, + struct timespec timeout) +{ + return 0; +} + +static int +dmx_pes_feed_start_filtering(struct dmx_pes_feed_s* feed) +{ + return 0; +} + +static int +dmx_pes_feed_stop_filtering(struct dmx_pes_feed_s* feed) +{ + return 0; +} +*/ + +static int dvbdmx_allocate_pes_feed(dmx_demux_t *demux, + dmx_pes_feed_t **feed, + dmx_pes_cb callback) +{ + return 0; +} + +static int dvbdmx_release_pes_feed(dmx_demux_t *demux, + dmx_pes_feed_t *feed) +{ + return 0; +} + + +/****************************************************************************** + * dmx_section_feed API calls + ******************************************************************************/ + +static int +dmx_section_feed_allocate_filter(struct dmx_section_feed_s* feed, + dmx_section_filter_t** filter) +{ + dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed; + dvb_demux_t *dvbdemux=dvbdmxfeed->demux; + dvb_demux_filter_t *dvbdmxfilter; + + down(&dvbdemux->mutex); + dvbdmxfilter=DvbDmxFilterAlloc(dvbdemux); + if (!dvbdmxfilter) { + up(&dvbdemux->mutex); + return -ENOSPC; + } + *filter=&dvbdmxfilter->filter; + (*filter)->parent=feed; + (*filter)->priv=0; + dvbdmxfilter->feed=dvbdmxfeed; + dvbdmxfilter->pid=dvbdmxfeed->pid; + dvbdmxfilter->type=DMX_TYPE_SEC; + dvbdmxfilter->state=DMX_STATE_READY; + + dvbdmxfilter->next=dvbdmxfeed->filter; + dvbdmxfeed->filter=dvbdmxfilter; + up(&dvbdemux->mutex); + return 0; +} + +static int +dmx_section_feed_set(struct dmx_section_feed_s* feed, + u16 pid, size_t circular_buffer_size, + int descramble, int check_crc) +{ + dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed; + dvb_demux_t *dvbdmx=dvbdmxfeed->demux; + + if (pid>0x1fff) + return -EINVAL; + down(&dvbdmx->mutex); + if (dvbdmxfeed->pid!=0xffff) { + dvbdmx->pid2feed[dvbdmxfeed->pid]=0; + dvbdmxfeed->pid=0xffff; + } + if (dvbdmx->pid2feed[pid]) { + up(&dvbdmx->mutex); + return -EBUSY; + } + dvbdmx->pid2feed[pid]=dvbdmxfeed; + dvbdmxfeed->pid=pid; + + dvbdmxfeed->buffer_size=circular_buffer_size; + dvbdmxfeed->descramble=descramble; + if (dvbdmxfeed->descramble) { + up(&dvbdmx->mutex); + return -ENOSYS; + } + + dvbdmxfeed->check_crc=check_crc; +#ifdef NOBUFS + dvbdmxfeed->buffer=0; +#else + dvbdmxfeed->buffer=vmalloc(dvbdmxfeed->buffer_size); + if (!dvbdmxfeed->buffer) { + up(&dvbdmx->mutex); + return -ENOMEM; + } +#endif + dvbdmxfeed->state=DMX_STATE_READY; + up(&dvbdmx->mutex); + return 0; +} + +static int +dmx_section_feed_start_filtering(dmx_section_feed_t *feed) +{ + dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed; + dvb_demux_t *dvbdmx=dvbdmxfeed->demux; + int ret; + + down(&dvbdmx->mutex); + if (feed->is_filtering) { + up(&dvbdmx->mutex); + return -EBUSY; + } + if (!dvbdmxfeed->filter) { + up(&dvbdmx->mutex); + return -EINVAL; + } + dvbdmxfeed->secbufp=0; + dvbdmxfeed->seclen=0; + + if (!dvbdmx->start_feed) { + up(&dvbdmx->mutex); + return -1; + } + ret=dvbdmx->start_feed(dvbdmxfeed); + if (ret<0) { + up(&dvbdmx->mutex); + return ret; + } + feed->is_filtering=1; + dvbdmxfeed->state=DMX_STATE_GO; + up(&dvbdmx->mutex); + return 0; +} + +static int +dmx_section_feed_stop_filtering(struct dmx_section_feed_s* feed) +{ + dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed; + dvb_demux_t *dvbdmx=dvbdmxfeed->demux; + int ret; + + down(&dvbdmx->mutex); + if (!dvbdmx->stop_feed) { + up(&dvbdmx->mutex); + return -1; + } + ret=dvbdmx->stop_feed(dvbdmxfeed); + + dvbdmxfeed->state=DMX_STATE_READY; + feed->is_filtering=0; + up(&dvbdmx->mutex); + return ret; +} + +static int +dmx_section_feed_release_filter(dmx_section_feed_t *feed, + dmx_section_filter_t* filter) +{ + dvb_demux_filter_t *dvbdmxfilter=(dvb_demux_filter_t *) filter, *f; + dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed; + dvb_demux_t *dvbdmx=dvbdmxfeed->demux; + + down(&dvbdmx->mutex); + if (dvbdmxfilter->feed!=dvbdmxfeed) { + up(&dvbdmx->mutex); + return -EINVAL; + } + if (feed->is_filtering) + feed->stop_filtering(feed); + + f=dvbdmxfeed->filter; + if (f==dvbdmxfilter) + dvbdmxfeed->filter=dvbdmxfilter->next; + else { + while(f->next!=dvbdmxfilter) + f=f->next; + f->next=f->next->next; + } + dvbdmxfilter->state=DMX_STATE_FREE; + up(&dvbdmx->mutex); + return 0; +} + +static int dvbdmx_allocate_section_feed(dmx_demux_t *demux, + dmx_section_feed_t **feed, + dmx_section_cb callback) +{ + dvb_demux_t *dvbdmx=(dvb_demux_t *) demux; + dvb_demux_feed_t *dvbdmxfeed; + + down(&dvbdmx->mutex); + if (!(dvbdmxfeed=DvbDmxFeedAlloc(dvbdmx))) { + up(&dvbdmx->mutex); + return -EBUSY; + } + dvbdmxfeed->type=DMX_TYPE_SEC; + dvbdmxfeed->cb.sec=callback; + dvbdmxfeed->demux=dvbdmx; + dvbdmxfeed->pid=0xffff; + dvbdmxfeed->secbufp=0; + dvbdmxfeed->filter=0; + dvbdmxfeed->buffer=0; + + (*feed)=&dvbdmxfeed->feed.sec; + (*feed)->is_filtering=0; + (*feed)->parent=demux; + (*feed)->priv=0; + (*feed)->set=dmx_section_feed_set; + (*feed)->allocate_filter=dmx_section_feed_allocate_filter; + (*feed)->release_filter=dmx_section_feed_release_filter; + (*feed)->start_filtering=dmx_section_feed_start_filtering; + (*feed)->stop_filtering=dmx_section_feed_stop_filtering; + + up(&dvbdmx->mutex); + return 0; +} + +static int dvbdmx_release_section_feed(dmx_demux_t *demux, + dmx_section_feed_t *feed) +{ + dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed; + dvb_demux_t *dvbdmx=(dvb_demux_t *) demux; + + down(&dvbdmx->mutex); + if (dvbdmxfeed->state==DMX_STATE_FREE) { + up(&dvbdmx->mutex); + return -EINVAL; + } +#ifndef NOBUFS + if (dvbdmxfeed->buffer) { + vfree(dvbdmxfeed->buffer); + dvbdmxfeed->buffer=0; + } +#endif + dvbdmxfeed->state=DMX_STATE_FREE; + dvbdmxfeed->demux->pid2feed[dvbdmxfeed->pid]=0; + if (dvbdmxfeed->pid!=0xffff) + dvbdmxfeed->demux->pid2feed[dvbdmxfeed->pid]=0; + up(&dvbdmx->mutex); + return 0; +} + + +/****************************************************************************** + * dvb_demux kernel data API calls + ******************************************************************************/ + +static int dvbdmx_open(dmx_demux_t *demux) +{ + dvb_demux_t *dvbdemux=(dvb_demux_t *) demux; + + if (dvbdemux->users>=MAX_DVB_DEMUX_USERS) + return -EUSERS; + dvbdemux->users++; + return 0; +} + +static int dvbdmx_close(struct dmx_demux_s *demux) +{ + dvb_demux_t *dvbdemux=(dvb_demux_t *) demux; + + if (dvbdemux->users==0) + return -ENODEV; + dvbdemux->users--; + //FIXME: release any unneeded resources if users==0 + return 0; +} + +static int dvbdmx_write(dmx_demux_t *demux, const char *buf, size_t count) +{ + dvb_demux_t *dvbdemux=(dvb_demux_t *) demux; + + if ((!demux->frontend) || + (demux->frontend->source!=DMX_MEMORY_FE)) + return -EINVAL; + + down(&dvbdemux->mutex); + DvbDmxSWFilter(dvbdemux, buf, count); + up(&dvbdemux->mutex); + return count; +} + + +static int dvbdmx_add_frontend(dmx_demux_t *demux, + dmx_frontend_t *frontend) +{ + dvb_demux_t *dvbdemux=(dvb_demux_t *) demux; + struct list_head *pos, *head=&dvbdemux->frontend_list; + + //printk ("function : %s\n", __FUNCTION__); + + if (!(frontend->id && frontend->vendor && frontend->model)) + return -EINVAL; + list_for_each(pos, head) + { + if (!strcmp(DMX_FE_ENTRY(pos)->id, frontend->id)) + return -EEXIST; + } + + list_add(&(frontend->connectivity_list), head); + return 0; +} + +static int +dvbdmx_remove_frontend(dmx_demux_t *demux, + dmx_frontend_t *frontend) +{ + dvb_demux_t *dvbdemux=(dvb_demux_t *) demux; + struct list_head *pos, *head=&dvbdemux->frontend_list; + + list_for_each(pos, head) + { + if (DMX_FE_ENTRY(pos)==frontend) + { + list_del(pos); + return 0; + } + } + return -ENODEV; +} + +static struct list_head * +dvbdmx_get_frontends(dmx_demux_t *demux) +{ + dvb_demux_t *dvbdemux=(dvb_demux_t *) demux; + + if (list_empty(&dvbdemux->frontend_list)) + return NULL; + return &dvbdemux->frontend_list; +} + +static int dvbdmx_connect_frontend(dmx_demux_t *demux, + dmx_frontend_t *frontend) +{ + dvb_demux_t *dvbdemux=(dvb_demux_t *) demux; + + if (demux->frontend) + return -EINVAL; + + down(&dvbdemux->mutex); + demux->frontend=frontend; + up(&dvbdemux->mutex); + return 0; +} + +static int dvbdmx_disconnect_frontend(dmx_demux_t *demux) +{ + dvb_demux_t *dvbdemux=(dvb_demux_t *) demux; + + down(&dvbdemux->mutex); + demux->frontend=NULL; + up(&dvbdemux->mutex); + return 0; +} + +static int dvbdmx_get_pes_pids(dmx_demux_t *demux, u16 *pids) +{ + dvb_demux_t *dvbdemux=(dvb_demux_t *) demux; + + memcpy(pids, dvbdemux->pids, 5*sizeof(u16)); + return 0; +} + +int +DvbDmxInit(dvb_demux_t *dvbdemux) +{ + int i; + dmx_demux_t *dmx=&dvbdemux->dmx; + + dvbdemux->users=0; + dvbdemux->filter=vmalloc(dvbdemux->filternum*sizeof(dvb_demux_filter_t)); + if (!dvbdemux->filter) + return -ENOMEM; + + dvbdemux->feed=vmalloc(dvbdemux->feednum*sizeof(dvb_demux_feed_t)); + if (!dvbdemux->feed) { + vfree(dvbdemux->filter); + return -ENOMEM; + } + for (i=0; ifilternum; i++) { + dvbdemux->filter[i].state=DMX_STATE_FREE; + dvbdemux->filter[i].index=i; + } + for (i=0; ifeednum; i++) + dvbdemux->feed[i].state=DMX_STATE_FREE; + dvbdemux->frontend_list.next= + dvbdemux->frontend_list.prev= + &dvbdemux->frontend_list; + for (i=0; ipesfilter[i]=NULL; + dvbdemux->pids[i]=0xffff; + } + dvbdemux->playing=dvbdemux->recording=0; + memset(dvbdemux->pid2feed, 0, (DMX_MAX_PID+1)*sizeof(dvb_demux_feed_t *)); + dvbdemux->tsbufp=0; + + dmx->frontend=0; + dmx->reg_list.next=dmx->reg_list.prev=&dmx->reg_list; + dmx->priv=(void *) dvbdemux; + //dmx->users=0; // reset in dmx_register_demux() + dmx->open=dvbdmx_open; + dmx->close=dvbdmx_close; + dmx->write=dvbdmx_write; + dmx->allocate_ts_feed=dvbdmx_allocate_ts_feed; + dmx->release_ts_feed=dvbdmx_release_ts_feed; + dmx->allocate_pes_feed=dvbdmx_allocate_pes_feed; + dmx->release_pes_feed=dvbdmx_release_pes_feed; + dmx->allocate_section_feed=dvbdmx_allocate_section_feed; + dmx->release_section_feed=dvbdmx_release_section_feed; + + dmx->descramble_mac_address=NULL; + dmx->descramble_section_payload=NULL; + + dmx->add_frontend=dvbdmx_add_frontend; + dmx->remove_frontend=dvbdmx_remove_frontend; + dmx->get_frontends=dvbdmx_get_frontends; + dmx->connect_frontend=dvbdmx_connect_frontend; + dmx->disconnect_frontend=dvbdmx_disconnect_frontend; + dmx->get_pes_pids=dvbdmx_get_pes_pids; + sema_init(&dvbdemux->mutex, 1); + + if (dmx_register_demux(dmx)<0) + return -1; + + return 0; +} + +int +DvbDmxRelease(dvb_demux_t *dvbdemux) +{ + dmx_demux_t *dmx=&dvbdemux->dmx; + + dmx_unregister_demux(dmx); + if (dvbdemux->filter) + vfree(dvbdemux->filter); + if (dvbdemux->feed) + vfree(dvbdemux->feed); + return 0; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/dvb_demux.h linux.19pre5-ac1/drivers/media/video/margi/dvb_demux.h --- linux.19p5/drivers/media/video/margi/dvb_demux.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/dvb_demux.h Mon Feb 4 22:31:51 2002 @@ -0,0 +1,141 @@ +/* + * dvb_demux.h - DVB kernel demux API + * + * Copyright (C) 2000-2001 Marcus Metzler + * & Ralph Metzler + * for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _DVB_DEMUX_H_ +#define _DVB_DEMUX_H_ + +#if LINUX_VERSION_CODE < 0x020300 +#define WAIT_QUEUE struct wait_queue* +#define init_waitqueue_head(wq) *(wq) = NULL; +#define DECLARE_WAITQUEUE(wait, current) struct wait_queue wait = { current, NULL } +#define list_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); pos = pos->next) +#else +#define WAIT_QUEUE wait_queue_head_t +#endif + +#include "ost/demux.h" + +#define DMX_TYPE_TS 0 +#define DMX_TYPE_SEC 1 +#define DMX_TYPE_PES 2 + +#define DMX_STATE_FREE 0 +#define DMX_STATE_ALLOCATED 1 +#define DMX_STATE_SET 2 +#define DMX_STATE_READY 3 +#define DMX_STATE_GO 4 + +#define DVB_DEMUX_MASK_MAX 18 + +typedef struct dvb_demux_filter_s { + dmx_section_filter_t filter; + struct dvb_demux_filter_s *next; + struct dvb_demux_feed_s *feed; + int index; + int state; + int type; + int pesto; + + u32 flags; + u16 handle; + u16 hw_handle; + struct timer_list timer; + int ts_state; + + u16 pid; //to be removed +} dvb_demux_filter_t; + +typedef struct dvb_demux_feed_s { + union { + dmx_ts_feed_t ts; + dmx_section_feed_t sec; + dmx_pes_feed_t pes; + } feed; + + union { + dmx_ts_cb ts; + dmx_section_cb sec; + dmx_pes_cb pes; + } cb; + + struct dvb_demux_s *demux; + int type; + int state; + u16 pid; + u8 *buffer; + int buffer_size; + int descramble; + int check_crc; + + struct timespec timeout; + dvb_demux_filter_t *filter; + int cb_length; + + int ts_type; + dmx_ts_pes_t pes_type; + + u8 secbuf[4096]; + int secbufp; + int seclen; + int cc; + + u16 peslen; +} dvb_demux_feed_t; + +typedef struct dvb_demux_s { + dmx_demux_t dmx; + void *priv; + int filternum; + int feednum; + int (*start_feed)(dvb_demux_feed_t *); + int (*stop_feed)(dvb_demux_feed_t *); + int (*write_to_decoder)(dvb_demux_feed_t *, u8 *, size_t); + + + int users; +#define MAX_DVB_DEMUX_USERS 10 + dvb_demux_filter_t *filter; + dvb_demux_feed_t *feed; + + struct list_head frontend_list; + + dvb_demux_feed_t *pesfilter[DMX_TS_PES_OTHER]; + u16 pids[DMX_TS_PES_OTHER]; + int playing; + int recording; + +#define DMX_MAX_PID 0x2000 + dvb_demux_feed_t *pid2feed[DMX_MAX_PID+1]; + u8 tsbuf[188]; + int tsbufp; + + struct semaphore mutex; +} dvb_demux_t; + + +int DvbDmxInit(dvb_demux_t *dvbdemux); +int DvbDmxRelease(dvb_demux_t *dvbdemux); +void DvbDmxSWFilterPackets(dvb_demux_t *dvbdmx, const u8 *buf, int count); + +#endif /* _DVB_DEMUX_H_ */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/dvb_filter.c linux.19pre5-ac1/drivers/media/video/margi/dvb_filter.c --- linux.19p5/drivers/media/video/margi/dvb_filter.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/dvb_filter.c Mon Feb 4 22:41:02 2002 @@ -0,0 +1,769 @@ +#include +#include +#include "dvb_filter.h" +#if 0 +#ifdef MODULE +MODULE_DESCRIPTION(""); +MODULE_AUTHOR("Marcus Metzler, Ralph Metzler"); +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif +#endif +#endif + +unsigned int bitrates[3][16] = +{{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0}, + {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0}, + {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}}; + +uint32_t freq[4] = {441, 480, 320, 0}; + +unsigned int ac3_bitrates[32] = + {32,40,48,56,64,80,96,112,128,160,192,224,256,320,384,448,512,576,640, + 0,0,0,0,0,0,0,0,0,0,0,0,0}; + +uint32_t ac3_freq[4] = {480, 441, 320, 0}; +uint32_t ac3_frames[3][32] = + {{64,80,96,112,128,160,192,224,256,320,384,448,512,640,768,896,1024, + 1152,1280,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {69,87,104,121,139,174,208,243,278,348,417,487,557,696,835,975,1114, + 1253,1393,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {96,120,144,168,192,240,288,336,384,480,576,672,768,960,1152,1344, + 1536,1728,1920,0,0,0,0,0,0,0,0,0,0,0,0,0}}; + + + +void pes2ts_init(pes2ts_t *p2ts, unsigned short pid, + pes2ts_cb_t *cb, void *priv) +{ + unsigned char *buf=p2ts->buf; + + buf[0]=0x47; + buf[1]=(pid>>8); + buf[2]=pid&0xff; + p2ts->cc=0; + p2ts->cb=cb; + p2ts->priv=priv; +} + +int pes2ts(pes2ts_t *p2ts, unsigned char *pes, int len) +{ + unsigned char *buf=p2ts->buf; + int ret=0, rest; + + //len=6+((pes[4]<<8)|pes[5]); + + buf[1]|=0x40; + while (len>=184) { + buf[3]=0x10|((p2ts->cc++)&0x0f); + memcpy(buf+4, pes, 184); + if ((ret=p2ts->cb(p2ts->priv, buf))) + return ret; + len-=184; pes+=184; + buf[1]&=~0x40; + } + if (!len) + return 0; + buf[3]=0x30|((p2ts->cc++)&0x0f); + rest=183-len; + if (rest) { + buf[5]=0x00; + if (rest-1) + memset(buf+6, 0xff, rest-1); + } + buf[4]=rest; + memcpy(buf+5+rest, pes, len); + return p2ts->cb(p2ts->priv, buf); +} + +void reset_ipack(ipack *p) +{ + p->found = 0; + p->cid = 0; + p->plength = 0; + p->flag1 = 0; + p->flag2 = 0; + p->hlength = 0; + p->mpeg = 0; + p->check = 0; + p->which = 0; + p->done = 0; + p->count = 0; +} + +void init_ipack(ipack *p, int size, + void (*func)(u8 *buf, int size, void *priv)) +{ + if ( !(p->buf = vmalloc(size*sizeof(u8))) ){ + printk ("Couldn't allocate memory for ipack\n"); + } + p->size = size; + p->func = func; + p->repack_subids = 0; + reset_ipack(p); +} + +void free_ipack(ipack * p) +{ + if (p->buf) vfree(p->buf); +} + +void send_ipack(ipack *p) +{ + int off; + AudioInfo ai; + int ac3_off = 0; + int streamid=0; + int nframes= 0; + int f=0; + + switch ( p->mpeg ){ + case 2: + if (p->count < 10) return; + p->buf[3] = p->cid; + + p->buf[4] = (u8)(((p->count-6) & 0xFF00) >> 8); + p->buf[5] = (u8)((p->count-6) & 0x00FF); + if (p->repack_subids && p->cid == PRIVATE_STREAM1){ + + off = 9+p->buf[8]; + streamid = p->buf[off]; + if ((streamid & 0xF8) == 0x80){ + ai.off = 0; + ac3_off = ((p->buf[off+2] << 8)| + p->buf[off+3]); + if (ac3_off < p->count) + f=get_ac3info(p->buf+off+3+ac3_off, + p->count-ac3_off, &ai,0); + if ( !f ){ + nframes = (p->count-off-3-ac3_off)/ + ai.framesize + 1; + p->buf[off+2] = (ac3_off >> 8)& 0xFF; + p->buf[off+3] = (ac3_off)& 0xFF; + p->buf[off+1] = nframes; + + ac3_off += nframes * ai.framesize - + p->count; + } + } + } + p->func(p->buf, p->count, p->data); + + p->buf[6] = 0x80; + p->buf[7] = 0x00; + p->buf[8] = 0x00; + p->count = 9; + if (p->repack_subids && p->cid == PRIVATE_STREAM1 + && (streamid & 0xF8)==0x80 ){ + p->count += 4; + p->buf[9] = streamid; + p->buf[10] = (ac3_off >> 8)& 0xFF; + p->buf[11] = (ac3_off)& 0xFF; + p->buf[12] = 0; + } + + break; + case 1: + if (p->count < 8) return; + p->buf[3] = p->cid; + + p->buf[4] = (u8)(((p->count-6) & 0xFF00) >> 8); + p->buf[5] = (u8)((p->count-6) & 0x00FF); + p->func(p->buf, p->count, p->data); + + p->buf[6] = 0x0F; + p->count = 7; + break; + } +} + +void send_ipack_rest(ipack *p) +{ + if (p->plength != MMAX_PLENGTH-6 || p->found<=6) + return; + p->plength = p->found-6; + p->found = 0; + send_ipack(p); + reset_ipack(p); +} + +static void write_ipack(ipack *p, u8 *data, int count) +{ + u8 headr[3] = { 0x00, 0x00, 0x01} ; + + if (p->count < 6){ + memcpy(p->buf, headr, 3); + p->count = 6; + } + + if (p->count + count < p->size){ + memcpy(p->buf+p->count, data, count); + p->count += count; + } else { + int rest = p->size - p->count; + memcpy(p->buf+p->count, data, rest); + p->count += rest; + send_ipack(p); + if (count - rest > 0) + write_ipack(p, data+rest, count-rest); + } +} + +int instant_repack(u8 *buf, int count, ipack *p) +{ + int l; + int c=0; + + while (c < count && (p->mpeg == 0 || + (p->mpeg == 1 && p->found < 7) || + (p->mpeg == 2 && p->found < 9)) + && (p->found < 5 || !p->done)){ + switch ( p->found ){ + case 0: + case 1: + if (buf[c] == 0x00) p->found++; + else p->found = 0; + c++; + break; + case 2: + if (buf[c] == 0x01) p->found++; + else if (buf[c] == 0) { + p->found = 2; + } else p->found = 0; + c++; + break; + case 3: + p->cid = 0; + switch (buf[c]){ + case PROG_STREAM_MAP: + case PRIVATE_STREAM2: + case PROG_STREAM_DIR: + case ECM_STREAM : + case EMM_STREAM : + case PADDING_STREAM : + case DSM_CC_STREAM : + case ISO13522_STREAM: + p->done = 1; + case PRIVATE_STREAM1: + case VIDEO_STREAM_S ... VIDEO_STREAM_E: + case AUDIO_STREAM_S ... AUDIO_STREAM_E: + p->found++; + p->cid = buf[c]; + c++; + break; + default: + p->found = 0; + break; + } + break; + + case 4: + if (count-c > 1){ + p->plen[0] = buf[c]; + c++; + p->plen[1] = buf[c]; + c++; + p->found+=2; + p->plength=(p->plen[0]<<8)|p->plen[1]; + } else { + p->plen[0] = buf[c]; + p->found++; + return count; + } + break; + case 5: + p->plen[1] = buf[c]; + c++; + p->found++; + p->plength=(p->plen[0]<<8)|p->plen[1]; + break; + case 6: + if (!p->done){ + p->flag1 = buf[c]; + c++; + p->found++; + if ( (p->flag1 & 0xC0) == 0x80 ) p->mpeg = 2; + else { + p->hlength = 0; + p->which = 0; + p->mpeg = 1; + p->flag2 = 0; + } + } + break; + + case 7: + if ( !p->done && p->mpeg == 2) { + p->flag2 = buf[c]; + c++; + p->found++; + } + break; + + case 8: + if ( !p->done && p->mpeg == 2) { + p->hlength = buf[c]; + c++; + p->found++; + } + break; + + default: + + break; + } + } + + if (c == count) return count; + + if (!p->plength) p->plength = MMAX_PLENGTH-6; + + if ( p->done || ((p->mpeg == 2 && p->found >= 9) || + (p->mpeg == 1 && p->found >= 7)) ){ + switch (p->cid){ + + case AUDIO_STREAM_S ... AUDIO_STREAM_E: + case VIDEO_STREAM_S ... VIDEO_STREAM_E: + case PRIVATE_STREAM1: + + if (p->mpeg == 2 && p->found == 9) { + write_ipack(p, &p->flag1, 1); + write_ipack(p, &p->flag2, 1); + write_ipack(p, &p->hlength, 1); + } + + if (p->mpeg == 1 && p->found == 7) + write_ipack(p, &p->flag1, 1); + + if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) && + p->found < 14) { + while (c < count && p->found < 14) { + p->pts[p->found-9] = buf[c]; + write_ipack(p, buf+c, 1); + c++; + p->found++; + } + if (c == count) return count; + } + + if (p->mpeg == 1 && p->which < 2000) { + + if (p->found == 7) { + p->check = p->flag1; + p->hlength = 1; + } + + while (!p->which && c < count && + p->check == 0xFF){ + p->check = buf[c]; + write_ipack(p, buf+c, 1); + c++; + p->found++; + p->hlength++; + } + + if ( c == count) return count; + + if ( (p->check & 0xC0) == 0x40 && !p->which){ + p->check = buf[c]; + write_ipack(p, buf+c, 1); + c++; + p->found++; + p->hlength++; + + p->which = 1; + if ( c == count) return count; + p->check = buf[c]; + write_ipack(p, buf+c, 1); + c++; + p->found++; + p->hlength++; + p->which = 2; + if ( c == count) return count; + } + + if (p->which == 1){ + p->check = buf[c]; + write_ipack(p, buf+c, 1); + c++; + p->found++; + p->hlength++; + p->which = 2; + if ( c == count) return count; + } + + if ( (p->check & 0x30) && p->check != 0xFF){ + p->flag2 = (p->check & 0xF0) << 2; + p->pts[0] = p->check; + p->which = 3; + } + + if ( c == count) return count; + if (p->which > 2){ + if ((p->flag2 & PTS_DTS_FLAGS) + == PTS_ONLY){ + while (c < count && + p->which < 7){ + p->pts[p->which-2] = + buf[c]; + write_ipack(p,buf+c,1); + c++; + p->found++; + p->which++; + p->hlength++; + } + if ( c == count) return count; + } else if ((p->flag2 & PTS_DTS_FLAGS) + == PTS_DTS){ + while (c < count && + p->which< 12){ + if (p->which< 7) + p->pts[p->which + -2] = + buf[c]; + write_ipack(p,buf+c,1); + c++; + p->found++; + p->which++; + p->hlength++; + } + if ( c == count) return count; + } + p->which = 2000; + } + + } + + while (c < count && p->found < p->plength+6){ + l = count -c; + if (l+p->found > p->plength+6) + l = p->plength+6-p->found; + write_ipack(p, buf+c, l); + p->found += l; + c += l; + } + + break; + } + + + if ( p->done ){ + if( p->found + count - c < p->plength+6){ + p->found += count-c; + c = count; + } else { + c += p->plength+6 - p->found; + p->found = p->plength+6; + } + } + + if (p->plength && p->found == p->plength+6) { + send_ipack(p); + reset_ipack(p); + if (c < count) + instant_repack(buf+c, count-c, p); + } + } + return count; +} + + + +void setup_ts2pes(ipack *pa, ipack *pv, u16 *pida, u16 *pidv, + void (*pes_write)(u8 *buf, int count, void *data), + void *priv) +{ + init_ipack(pa, IPACKS, pes_write); + init_ipack(pv, IPACKS, pes_write); + pa->pid = pida; + pv->pid = pidv; + pa->data = priv; + pv->data = priv; +} + +void ts_to_pes(ipack *p, u8 *buf) // don't need count (=188) +{ + u8 off = 0; + + if (!buf || !p ){ + printk("NULL POINTER IDIOT\n"); + return; + } + if (buf[1]&PAY_START) { + if (p->plength == MMAX_PLENGTH-6 && p->found>6){ + p->plength = p->found-6; + p->found = 0; + send_ipack(p); + reset_ipack(p); + } + } + if (buf[3] & ADAPT_FIELD) { // adaptation field? + off = buf[4] + 1; + if (off+4 > 187) return; + } + instant_repack(buf+4+off, TS_SIZE-4-off, p); +} + +int get_vinfo(uint8_t *mbuf, int count, VideoInfo *vi, int pr) +{ + uint8_t *headr; + int found = 0; + int sw; + int form = -1; + int c = 0; + + while (found < 4 && c+4 < count){ + uint8_t *b; + + b = mbuf+c; + if ( b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01 + && b[3] == 0xb3) found = 4; + else { + c++; + } + } + + if (! found) return -1; + c += 4; + if (c+12 >= count) return -1; + headr = mbuf+c; + + vi->horizontal_size = ((headr[1] &0xF0) >> 4) | (headr[0] << 4); + vi->vertical_size = ((headr[1] &0x0F) << 8) | (headr[2]); + + sw = (int)((headr[3]&0xF0) >> 4) ; + + switch( sw ){ + case 1: + if (pr) + printk("Videostream: ASPECT: 1:1"); + vi->aspect_ratio = 100; + break; + case 2: + if (pr) + printk("Videostream: ASPECT: 4:3"); + vi->aspect_ratio = 133; + break; + case 3: + if (pr) + printk("Videostream: ASPECT: 16:9"); + vi->aspect_ratio = 177; + break; + case 4: + if (pr) + printk("Videostream: ASPECT: 2.21:1"); + vi->aspect_ratio = 221; + break; + + case 5 ... 15: + if (pr) + printk("Videostream: ASPECT: reserved"); + vi->aspect_ratio = 0; + break; + + default: + vi->aspect_ratio = 0; + return -1; + } + + if (pr) + printk(" Size = %dx%d",vi->horizontal_size,vi->vertical_size); + + sw = (int)(headr[3]&0x0F); + + switch ( sw ) { + case 1: + if (pr) + printk(" FRate: 23.976 fps"); + vi->framerate = 24000/1001.; + form = -1; + break; + case 2: + if (pr) + printk(" FRate: 24 fps"); + vi->framerate = 24; + form = -1; + break; + case 3: + if (pr) + printk(" FRate: 25 fps"); + vi->framerate = 25; + form = VIDEO_MODE_PAL; + break; + case 4: + if (pr) + printk(" FRate: 29.97 fps"); + vi->framerate = 30000/1001.; + form = VIDEO_MODE_NTSC; + break; + case 5: + if (pr) + printk(" FRate: 30 fps"); + vi->framerate = 30; + form = VIDEO_MODE_NTSC; + break; + case 6: + if (pr) + printk(" FRate: 50 fps"); + vi->framerate = 50; + form = VIDEO_MODE_PAL; + break; + case 7: + if (pr) + printk(" FRate: 60 fps"); + vi->framerate = 60; + form = VIDEO_MODE_NTSC; + break; + } + + vi->bit_rate = 400*(((headr[4] << 10) & 0x0003FC00UL) + | ((headr[5] << 2) & 0x000003FCUL) | + (((headr[6] & 0xC0) >> 6) & 0x00000003UL)); + + if (pr){ + printk(" BRate: %d Mbit/s",(vi->bit_rate)); + printk("\n"); + } + vi->video_format = form; + + vi->off = c-4; + return 0; +} + +int get_ainfo(uint8_t *mbuf, int count, AudioInfo *ai, int pr) +{ + uint8_t *headr; + int found = 0; + int c = 0; + int fr = 0; + + while (found < 2 && c < count){ + uint8_t b[2]; + memcpy( b, mbuf+c, 2); + + if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8) + found = 2; + else { + c++; + } + } + + if (!found) return -1; + + if (c+3 >= count) return -1; + headr = mbuf+c; + + ai->layer = (headr[1] & 0x06) >> 1; + + if (pr) + printk("Audiostream: Layer: %d", 4-ai->layer); + + + ai->bit_rate = bitrates[(3-ai->layer)][(headr[2] >> 4 )]*1000; + + if (pr){ + if (ai->bit_rate == 0) + printk(" Bit rate: free"); + else if (ai->bit_rate == 0xf) + printk(" BRate: reserved"); + else + printk(" BRate: %d kb/s", ai->bit_rate/1000); + } + + fr = (headr[2] & 0x0c ) >> 2; + ai->frequency = freq[fr]*100; + if (pr){ + if (ai->frequency == 3) + printk(" Freq: reserved\n"); + else + printk(" Freq: %d kHz\n",ai->frequency); + + } + ai->off = c; + return 0; +} + +int get_ac3info(uint8_t *mbuf, int count, AudioInfo *ai, int pr) +{ + uint8_t *headr; + int found = 0; + int c = 0; + uint8_t frame = 0; + int fr = 0; + + while ( !found && c < count){ + uint8_t *b = mbuf+c; + + if ( b[0] == 0x0b && b[1] == 0x77 ) + found = 1; + else { + c++; + } + } + + if (!found) return -1; + if (pr) + printk("Audiostream: AC3"); + + ai->off = c; + if (c+5 >= count) return -1; + + ai->layer = 0; // 0 for AC3 + headr = mbuf+c+2; + + frame = (headr[2]&0x3f); + ai->bit_rate = ac3_bitrates[frame >> 1]*1000; + + if (pr) + printk(" BRate: %d kb/s", ai->bit_rate/1000); + + ai->frequency = (headr[2] & 0xc0 ) >> 6; + fr = (headr[2] & 0xc0 ) >> 6; + ai->frequency = freq[fr]*100; + if (pr) printk (" Freq: %d Hz\n", ai->frequency); + + + ai->framesize = ac3_frames[fr][frame >> 1]; + if ((frame & 1) && (fr == 1)) ai->framesize++; + ai->framesize = ai->framesize << 1; + if (pr) printk (" Framesize %d\n", ai->framesize); + + + return 0; +} + +uint8_t *skip_pes_header(uint8_t **bufp) +{ + uint8_t *inbuf = *bufp; + uint8_t *buf = inbuf; + uint8_t *pts = NULL; + int skip = 0; + +int mpeg1_skip_table[16] = { + 1, 0xffff, 5, 10, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff +}; + + + if ((inbuf[6] & 0xc0) == 0x80){ /* mpeg2 */ + if (buf[7] & PTS_ONLY) + pts = buf+9; + else pts = NULL; + buf = inbuf + 9 + inbuf[8]; + } else { /* mpeg1 */ + for (buf = inbuf + 6; *buf == 0xff; buf++) + if (buf == inbuf + 6 + 16) { + break; + } + if ((*buf & 0xc0) == 0x40) + buf += 2; + skip = mpeg1_skip_table [*buf >> 4]; + if (skip == 5 || skip == 10) pts = buf; + else pts = NULL; + + buf += mpeg1_skip_table [*buf >> 4]; + } + + *bufp = buf; + return pts; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/dvb_filter.h linux.19pre5-ac1/drivers/media/video/margi/dvb_filter.h --- linux.19p5/drivers/media/video/margi/dvb_filter.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/dvb_filter.h Thu Apr 4 15:55:29 2002 @@ -0,0 +1,146 @@ +#ifndef _DVB_FILTER_H_ +#define _DVB_FILTER_H_ + +#include +#include + +#include "ost/demux.h" + +typedef int (pes2ts_cb_t) (void *, unsigned char *); + +typedef struct pes2ts_s { + unsigned char buf[188]; + unsigned char cc; + pes2ts_cb_t *cb; + void *priv; +} pes2ts_t; + +void pes2ts_init(pes2ts_t *p2ts, unsigned short pid, + pes2ts_cb_t *cb, void *priv); +int pes2ts(pes2ts_t *p2ts, unsigned char *pes, int len); + + +#define PROG_STREAM_MAP 0xBC +#define PRIVATE_STREAM1 0xBD +#define PADDING_STREAM 0xBE +#define PRIVATE_STREAM2 0xBF +#define AUDIO_STREAM_S 0xC0 +#define AUDIO_STREAM_E 0xDF +#define VIDEO_STREAM_S 0xE0 +#define VIDEO_STREAM_E 0xEF +#define ECM_STREAM 0xF0 +#define EMM_STREAM 0xF1 +#define DSM_CC_STREAM 0xF2 +#define ISO13522_STREAM 0xF3 +#define PROG_STREAM_DIR 0xFF + +//flags2 +#define PTS_DTS_FLAGS 0xC0 +#define ESCR_FLAG 0x20 +#define ES_RATE_FLAG 0x10 +#define DSM_TRICK_FLAG 0x08 +#define ADD_CPY_FLAG 0x04 +#define PES_CRC_FLAG 0x02 +#define PES_EXT_FLAG 0x01 + +//pts_dts flags +#define PTS_ONLY 0x80 +#define PTS_DTS 0xC0 + +#define TS_SIZE 188 +#define TRANS_ERROR 0x80 +#define PAY_START 0x40 +#define TRANS_PRIO 0x20 +#define PID_MASK_HI 0x1F +//flags +#define TRANS_SCRMBL1 0x80 +#define TRANS_SCRMBL2 0x40 +#define ADAPT_FIELD 0x20 +#define PAYLOAD 0x10 +#define COUNT_MASK 0x0F + +// adaptation flags +#define DISCON_IND 0x80 +#define RAND_ACC_IND 0x40 +#define ES_PRI_IND 0x20 +#define PCR_FLAG 0x10 +#define OPCR_FLAG 0x08 +#define SPLICE_FLAG 0x04 +#define TRANS_PRIV 0x02 +#define ADAP_EXT_FLAG 0x01 + +// adaptation extension flags +#define LTW_FLAG 0x80 +#define PIECE_RATE 0x40 +#define SEAM_SPLICE 0x20 + + +#define MAX_PLENGTH 0xFFFF +#define MMAX_PLENGTH (256*MAX_PLENGTH) + +#ifndef IPACKS +#define IPACKS 2048 +#endif + +typedef struct ipack_s { + int size; + int found; + u8 *buf; + u8 cid; + uint32_t plength; + u8 plen[2]; + u8 flag1; + u8 flag2; + u8 hlength; + u8 pts[5]; + u16 *pid; + int mpeg; + u8 check; + int which; + int done; + void *data; + void (*func)(u8 *buf, int size, void *priv); + int count; + int repack_subids; +} ipack; + +typedef struct video_i{ + u32 horizontal_size; + u32 vertical_size ; + u32 aspect_ratio ; + double framerate ; + u32 video_format; + u32 bit_rate ; + u32 comp_bit_rate ; + u32 vbv_buffer_size; + u32 CSPF ; + u32 off; +} VideoInfo; + +typedef struct audio_i{ + int layer ; + u32 bit_rate ; + u32 frequency ; + u32 mode ; + u32 mode_extension ; + u32 emphasis ; + u32 framesize; + u32 off; +} AudioInfo; + +void reset_ipack(ipack *p); +int instant_repack(u8 *buf, int count, ipack *p); +void init_ipack(ipack *p, int size, + void (*func)(u8 *buf, int size, void *priv)); +void free_ipack(ipack * p); +void setup_ts2pes(ipack *pa, ipack *pv, u16 *pida, u16 *pidv, + void (*pes_write)(u8 *buf, int count, void *data), + void *priv); +void ts_to_pes(ipack *p, u8 *buf); +void send_ipack(ipack *p); +void send_ipack_rest(ipack *p); +int get_ainfo(uint8_t *mbuf, int count, AudioInfo *ai, int pr); +int get_ac3info(uint8_t *mbuf, int count, AudioInfo *ai, int pr); +int get_vinfo(uint8_t *mbuf, int count, VideoInfo *vi, int pr); +uint8_t *skip_pes_header(uint8_t **bufp); +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/dvb_formats.h linux.19pre5-ac1/drivers/media/video/margi/dvb_formats.h --- linux.19p5/drivers/media/video/margi/dvb_formats.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/dvb_formats.h Mon Feb 4 22:23:23 2002 @@ -0,0 +1,152 @@ +/* + * + * Copyright (C) 2000, 2001 Marcus Metzler + * for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Or, point your browser to http://www.gnu.org/copyleft/gpl.html + * + + * The author can be reached at marcus@convergence.de, + + * the project's page is at http://linuxtv.org/dvb/ + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef _DVB_FORMATS_H_ +#define _DVB_FORMATS_H_ + + +#define PROG_STREAM_MAP 0xBC +#ifndef PRIVATE_STREAM1 +#define PRIVATE_STREAM1 0xBD +#endif +#define PADDING_STREAM 0xBE +#ifndef PRIVATE_STREAM2 +#define PRIVATE_STREAM2 0xBF +#endif +#define AUDIO_STREAM_S 0xC0 +#define AUDIO_STREAM_E 0xDF +#define VIDEO_STREAM_S 0xE0 +#define VIDEO_STREAM_E 0xEF +#define ECM_STREAM 0xF0 +#define EMM_STREAM 0xF1 +#define DSM_CC_STREAM 0xF2 +#define ISO13522_STREAM 0xF3 +#define PROG_STREAM_DIR 0xFF + +#define BUFFYSIZE 10*MAX_PLENGTH +//#define MAX_PTS 8192 +#define MAX_FRAME 8192 +#define MAX_PACK_L 4096 +#define PS_HEADER_L1 14 +#define PS_HEADER_L2 (PS_HEADER_L1+18) +#define MAX_H_SIZE (PES_H_MIN + PS_HEADER_L1 + 5) +#define PES_MIN 7 +#define PES_H_MIN 9 + +//flags2 +#define PTS_DTS_FLAGS 0xC0 +#define ESCR_FLAG 0x20 +#define ES_RATE_FLAG 0x10 +#define DSM_TRICK_FLAG 0x08 +#define ADD_CPY_FLAG 0x04 +#define PES_CRC_FLAG 0x02 +#define PES_EXT_FLAG 0x01 + +//pts_dts flags +#define PTS_ONLY 0x80 +#define PTS_DTS 0xC0 + +#define TS_SIZE 188 +#define TRANS_ERROR 0x80 +#define PAY_START 0x40 +#define TRANS_PRIO 0x20 +#define PID_MASK_HI 0x1F +//flags +#define TRANS_SCRMBL1 0x80 +#define TRANS_SCRMBL2 0x40 +#define ADAPT_FIELD 0x20 +#define PAYLOAD 0x10 +#define COUNT_MASK 0x0F + +// adaptation flags +#define DISCON_IND 0x80 +#define RAND_ACC_IND 0x40 +#define ES_PRI_IND 0x20 +#define PCR_FLAG 0x10 +#define OPCR_FLAG 0x08 +#define SPLICE_FLAG 0x04 +#define TRANS_PRIV 0x02 +#define ADAP_EXT_FLAG 0x01 + +// adaptation extension flags +#define LTW_FLAG 0x80 +#define PIECE_RATE 0x40 +#define SEAM_SPLICE 0x20 + + +#define MAX_PLENGTH 0xFFFF +#define MMAX_PLENGTH (4*MAX_PLENGTH) + +#define IPACKS 2048 + +typedef struct ipack_s { + int size; + int found; + uint8_t *buf; + uint8_t cid; + uint32_t plength; + uint8_t plen[2]; + uint8_t flag1; + uint8_t flag2; + uint8_t hlength; + uint8_t pts[5]; + uint16_t *pid; + int mpeg; + uint8_t check; + int which; + int done; + void *data; + void (*func)(uint8_t *buf, int size, void *priv); + int count; +} ipack; + +void instant_repack (uint8_t *buf, int count, ipack *p); +void init_ipack(ipack *p, int size, + void (*func)(uint8_t *buf, int size, void *priv)); +void free_ipack(ipack * p); +void setup_ts2pes( ipack *pa, ipack *pv, uint16_t *pida, uint16_t *pidv, + void (*pes_write)(uint8_t *buf, int count, void *data), + void *priv); +void ts_to_pes( ipack *p, uint8_t *buf); // don't need count (=188) +uint16_t get_pid(uint8_t *pid); + + +#endif /* _DVB_FORMATS_H_*/ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/dvbdev.c linux.19pre5-ac1/drivers/media/video/margi/dvbdev.c --- linux.19p5/drivers/media/video/margi/dvbdev.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/dvbdev.c Mon Feb 4 22:21:09 2002 @@ -0,0 +1,233 @@ +/* + * dvbdev.c + * + * Copyright (C) 2000 Ralph Metzler + * & Marcus Metzler + for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dvbdev.h" + +#ifdef MODULE +MODULE_DESCRIPTION("Device registrar for DVB drivers"); +MODULE_AUTHOR("Marcus Metzler, Ralph Metzler"); +#ifdef MODULE_LICENSE +MODULE_LICENSE("LGPL"); +#endif +#endif + +#define DVB_MAJOR 250 + +static struct dvb_device *dvb_device[DVB_NUM_DEVICES]; +static devfs_handle_t dvb_devfs_handle; + +static inline struct dvb_device * +inode2dev (struct inode *inode) +{ + int minor=(MINOR(inode->i_rdev)>>6); + + return dvb_device[minor]; +} + +static inline int +inode2num(struct inode *inode) +{ + return (0x3f&MINOR(inode->i_rdev)); +} + +static ssize_t +dvb_device_read(struct file *file, char *buf, size_t count, loff_t *ppos) +{ + struct inode *inode=file->f_dentry->d_inode; + struct dvb_device *dvbdev=inode2dev(inode); + + if (!dvbdev) + return -ENODEV; + return dvbdev->read(dvbdev, inode2num(inode), file, buf, count, ppos); +} + +static ssize_t +dvb_device_write(struct file *file, const char *buf, + size_t count, loff_t *ppos) +{ + struct inode *inode=file->f_dentry->d_inode; + struct dvb_device *dvbdev=inode2dev(inode); + + if (!dvbdev) + return -ENODEV; + return dvbdev->write(dvbdev, inode2num(inode), file, buf, count, ppos); +} + +static int +dvb_device_open(struct inode *inode, struct file *file) +{ + struct dvb_device *dvbdev=inode2dev(inode); + + if (!dvbdev) + return -ENODEV; + return dvbdev->open(dvbdev, inode2num(inode), inode, file); +} + +static int +dvb_device_release(struct inode *inode, struct file *file) +{ + struct dvb_device *dvbdev=inode2dev(inode); + + if (!dvbdev) + return -ENODEV; + return dvbdev->close(dvbdev, inode2num(inode), inode, file); +} + +static int +dvb_device_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct dvb_device *dvbdev=inode2dev(inode); + + if (!dvbdev) + return -ENODEV; + return dvbdev->ioctl(dvbdev, inode2num(inode), file, cmd, arg); +} + +static unsigned int +dvb_device_poll(struct file *file, poll_table *wait) +{ + struct inode *inode=file->f_dentry->d_inode; + struct dvb_device *dvbdev=inode2dev(inode); + + if (!dvbdev) + return -ENODEV; + return dvbdev->poll(dvbdev, inode2num(inode), file, wait); +} + + +static struct file_operations dvb_device_fops = +{ + owner: THIS_MODULE, + read: dvb_device_read, + write: dvb_device_write, + ioctl: dvb_device_ioctl, + open: dvb_device_open, + release: dvb_device_release, + poll: dvb_device_poll, +}; + + +static char *dnames[] = { + "video", "audio", "sec", "frontend", "demux", "dvr", "ca", + "net", "osd" +}; + + +static void dvb_init_device(dvb_device_t *dev) +{ + int i, type; + char name[64]; + + sprintf(name, "card%d", dev->minor); + dev->devfsh = devfs_mk_dir (dvb_devfs_handle, name, NULL); + + for (i=0; (type=dev->device_type(dev,i))>-2; i++) { + if (type==-1) + continue; + + sprintf(name, "%s%d", dnames[type>>2], type&3); + devfs_register(dev->devfsh, name, DEVFS_FL_DEFAULT, + DVB_MAJOR, (dev->minor<<6)+i, + S_IFCHR | S_IRUSR | S_IWUSR, + &dvb_device_fops, NULL); + } + +} + +int dvb_register_device(dvb_device_t *dev) +{ + int i=0; + + for (i=0; iminor=i; + dvb_init_device(dev); + MOD_INC_USE_COUNT; + return 0; + } + } + return -ENFILE; +} + +void dvb_unregister_device(dvb_device_t *dev) +{ + if (dvb_device[dev->minor]!=dev) { + printk("dvbdev: bad unregister\n"); + return; + } + devfs_unregister(dev->devfsh); + dvb_device[dev->minor]=NULL; + MOD_DEC_USE_COUNT; +} + +int __init dvbdev_init(void) +{ + int i=0; + + for(i=0; i + * & Marcus Metzler + for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Lesser Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _DVBDEV_H_ +#define _DVBDEV_H_ + +#include +#include +#include +#include + +#define DVB_NUM_DEVICES 16 + +struct dvb_device +{ + char name[32]; + int type; + int hardware; + + void *priv; + int minor; + devfs_handle_t devfs_handle; + + int (*open)(struct dvb_device *, int, struct inode *, struct file *); + int (*close)(struct dvb_device *, int, struct inode *, struct file *); + ssize_t (*read)(struct dvb_device *, int, struct file *, char *, + size_t, loff_t *); + ssize_t (*write)(struct dvb_device *, int, struct file *, const char *, + size_t, loff_t *); + int (*ioctl)(struct dvb_device *, int, struct file *, + unsigned int , unsigned long); + unsigned int (*poll)(struct dvb_device *, int type, + struct file *file, poll_table * wait); + + int (*device_type)(struct dvb_device *, unsigned int device_num); +#define DVB_DEVICE_VIDEO_0 0 +#define DVB_DEVICE_AUDIO_0 4 +#define DVB_DEVICE_SEC_0 8 +#define DVB_DEVICE_FRONTEND_0 12 +#define DVB_DEVICE_DEMUX_0 16 +#define DVB_DEVICE_DEMUX_1 17 +#define DVB_DEVICE_DEMUX_2 18 +#define DVB_DEVICE_DEMUX_3 19 +#define DVB_DEVICE_DVR_0 20 +#define DVB_DEVICE_CA_0 24 +#define DVB_DEVICE_NET_0 28 +#define DVB_DEVICE_OSD_0 32 + devfs_handle_t devfsh; +}; + +typedef struct dvb_device dvb_device_t; + +int dvb_register_device(struct dvb_device *); +void dvb_unregister_device(struct dvb_device *); + +#endif /* #ifndef __DVBDEV_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/i2c.c linux.19pre5-ac1/drivers/media/video/margi/i2c.c --- linux.19p5/drivers/media/video/margi/i2c.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/i2c.c Mon Feb 4 22:21:09 2002 @@ -0,0 +1,186 @@ +/* + i2c.h + + Copyright (C) Marcus Metzler for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define __NO_VERSION__ + +#include "i2c.h" + +void out(struct cvdv_cards *card) +{ + write_indexed_register(card, IIO_GPIO_PINS, + (card->scl ? SCL : 0) | + (card->sda ? SDA : 0) | 1); + udelay(10); +} + +void clkon(struct cvdv_cards *card) +{ + card->scl = 1; +} + +void clkoff(struct cvdv_cards *card) +{ + card->scl = 0; +} + +void dat(struct cvdv_cards *card, u_char data) +{ + card->sda = data; +} + +int rdat(struct cvdv_cards *card) +{ + return ((read_indexed_register(card, IIO_GPIO_PINS) & SDA) ? 1 : + 0); +} + + +void I2CStart(struct cvdv_cards *card) +{ + dat(card, 1); + out(card); + clkon(card); + out(card); + dat(card, 0); + out(card); + clkoff(card); + out(card); +} + +void I2CStop(struct cvdv_cards *card) +{ + dat(card, 0); + out(card); + clkon(card); + out(card); + dat(card, 1); + out(card); + clkoff(card); + out(card); +} + +int I2CAck(struct cvdv_cards *card, int ack) +{ + dat(card, ack); + out(card); + write_indexed_register(card, IIO_GPIO_CONTROL, (~SDA) & 0x07); + clkon(card); + out(card); + ack = rdat(card); + clkoff(card); + out(card); + write_indexed_register(card, IIO_GPIO_CONTROL, 0x07); + out(card); + return ack; +} + +u_char I2CReadByte(struct cvdv_cards * card, int ack) +{ + int i; + u_char data = 0; + + clkoff(card); + dat(card, 1); + out(card); + write_indexed_register(card, IIO_GPIO_CONTROL, (~SDA) & 0x07); + for (i = 7; i >= 0; i--) { + clkon(card); + out(card); + data |= (rdat(card) << i); + clkoff(card); + out(card); + } + write_indexed_register(card, IIO_GPIO_CONTROL, 0x07); + I2CAck(card, ack); + return data; +} + + +int I2CSendByte(struct cvdv_cards *card, u_char data) +{ + int i; + + for (i = 7; i >= 0; i--) { + dat(card, data & (1 << i)); + out(card); + clkon(card); + out(card); + clkoff(card); + out(card); + } + i = I2CAck(card, 1); + return i; +} + +void I2CWrite(struct cvdv_cards *card, int adr, int reg, int val) +{ + I2CStart(card); + I2CSendByte(card, adr); + I2CSendByte(card, reg); + I2CSendByte(card, val); + I2CStop(card); +} + + +u_char I2CRead(struct cvdv_cards *card, int adr, int reg) +{ + u_char c; + + I2CStart(card); + I2CSendByte(card, adr); + I2CSendByte(card, reg); + I2CStart(card); + I2CSendByte(card, adr | 1); + c = I2CReadByte(card, 1); + I2CStop(card); + return c; +} + + +int I2CScan(struct cvdv_cards *card, int adr) +{ + int result; + I2CStart(card); + result = I2CSendByte(card, adr); + I2CStop(card); + return result; +} + +void I2CScanBus(struct cvdv_cards *card) +{ + int i; + + for (i = 0; i < 0xff; i += 2) { + if (!I2CScan(card, i)) + MDEBUG(0,"Found i2c device at %d\n", i); + } +} + +void I2CSend(struct cvdv_cards *card, int adr, u_char * vals) +{ + int reg, val; + while (*vals != 0xff) { + reg = *vals; + vals++; + val = *vals; + vals++; + I2CWrite(card, adr, reg, val); + } +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/i2c.h linux.19pre5-ac1/drivers/media/video/margi/i2c.h --- linux.19p5/drivers/media/video/margi/i2c.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/i2c.h Thu Apr 4 15:55:29 2002 @@ -0,0 +1,43 @@ +/* + i2c.h + + Copyright (C) Marcus Metzler for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef I2C_H +#define I2C_H +#include "cardbase.h" +#include "l64014.h" +#include "margi.h" + +void out(struct cvdv_cards *card); +void clkon(struct cvdv_cards *card); +void clkoff(struct cvdv_cards *card); +void dat(struct cvdv_cards *card, u_char data); +int rdat(struct cvdv_cards *card); +void I2CStart(struct cvdv_cards *card); +void I2CStop(struct cvdv_cards *card); +int I2CAck(struct cvdv_cards *card, int ack); +u_char I2CReadByte(struct cvdv_cards *card, int ack); +int I2CSendByte(struct cvdv_cards *card, u_char data); +void I2CWrite(struct cvdv_cards *card, int adr, int reg, int val); +u_char I2CRead(struct cvdv_cards *card, int adr, int reg); +int I2CScan(struct cvdv_cards *card, int adr); +void I2CScanBus(struct cvdv_cards *card); +void I2CSend(struct cvdv_cards *card, int adr, u_char * vals); + +#endif /* I2C_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/l64014.h linux.19pre5-ac1/drivers/media/video/margi/l64014.h --- linux.19p5/drivers/media/video/margi/l64014.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/l64014.h Thu Apr 4 15:55:29 2002 @@ -0,0 +1,188 @@ +/* + l64014.h + + Copyright (C) Marcus Metzler for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef L64014_h +#define L64014_h + +#include +#include +#include + + +#define DIO_CONTROL_INDEX 0x00 +#define DIO_CONTROL_DATA 0x02 +#define DIO_LSI_STATUS 0x04 +#define DIO_LSI_CHANNEL_DATA 0x04 +#define DIO_LSI_INDEX_LOW 0x08 +#define DIO_LSI_DATA 0x0A +#define DIO_LSI_INDEX_HIGH 0x0C + +#define LSI_READY 0x08 +#define LSI_WAIT 0x04 +#define LSI_ARQ 0x02 +#define LSI_VRQ 0x01 + +#define IIO_ID 0x00 +#define IIO_MODE 0x01 +#define IIO_IRQ_CONTROL 0x02 +#define IIO_IRQ_STATUS 0x03 +#define IIO_LSI_CONTROL 0x06 +#define IIO_OSC_AUD 0x08 +#define IIO_VIDEO_CONTROL0 0x09 +#define IIO_VIDEO_CONTROL1 0x0A +#define IIO_VIDEO_LOOKUP 0x0B +#define IIO_EEPROM_CONTROL 0x0C +#define IIO_VIDEO_HOR_DELAY 0x0D +#define IIO_VIDEO_HOR_ACTIVE 0x0E +#define IIO_VIDEO_HOR_HIGH 0x0F +#define IIO_GPIO_CONTROL 0x10 +#define IIO_GPIO_PINS 0x11 +#define IIO_CSS_COMMAND 0x12 +#define IIO_CSS_STATUS 0x13 +#define IIO_CSS_KEY 0x14 + +#define SCL 0x02 +#define SDA 0x04 + +#define CS_CONTROL0 0x00 +#define CS_CONTROL1 0x01 +#define CS_CONTROL2 0x02 +#define CS_DAC 0x04 +#define CS_STATUS 0x07 +#define CS_BKG_COL 0x08 +#define CS_GPIO_CTRL 0x09 +#define CS_GPIO_DATA 0x0A +#define CS_C_AMP 0x0D +#define CS_Y_AMP 0x0E +#define CS_I2C_ADR 0x0F +#define CS_SC_AMP 0x10 +#define CS_SC_SYNTH0 0x11 +#define CS_SC_SYNTH1 0x12 +#define CS_SC_SYNTH2 0x13 +#define CS_SC_SYNTH3 0x14 +#define CS_HUE_LSB 0x15 +#define CS_HUE_MSB 0x16 +#define CS_CC_EN 0x18 +#define CS_CC_21_1 0x19 +#define CS_CC_21_2 0x1A +#define CS_CC_284_1 0x1B +#define CS_CC_284_2 0x1C +#define CS_INT_EN 0x3B +#define CS_INT_CLR 0x3C +#define CS_ID_REG 0x3D + + +#define CSS_COMMAND 0x12 +#define CSS_STATUS 0x13 +#define CSS_KEY 0x14 + +#define L14_CSS_NONE 0x00 +#define L14_CSS_PASSTHRU 0x01 +#define L14_CSS_DESCRAM 0x05 +#define L14_CSS_GEN_CH 0x08 +#define L14_CSS_RD_CH 0x09 +#define L14_CSS_WR_CH 0x0a +#define L14_CSS_WR_DRVREF 0x0b +#define L14_CSS_DRVAUTH 0x0c +#define L14_CSS_DECAUTH 0x0d +#define L14_CSS_DISCKEY 0x0e +#define L14_CSS_TITLEKEY 0x0f +#define L14_CSS_CMD_START 0x10 + +#define L14_CSS_BUSY 0x01 +#define L14_CSS_SUCCESS 0x02 + +#define DSVC 0x40 +#define RR 0x20 +#define DR 0x01 +#define AF1 0x20 +#define AF0 0x10 +#define SLEEP 0x08 +#define AFS2 0x04 +#define AFS1 0x02 +#define AFS0 0x01 + +#define ZVCLK13 0x04 +#define ZVCLKINV 0x08 +#define ZV16BIT 0x10 +#define ZVVREF_INVERT 0x08 +#define ZVHREF_INVERT 0x10 +#define HSYNC_INVERT 0x20 +#define ZV_OVERRIDE 0x40 +#define ZV_ENABLE 0x80 + + +#define IRQ_EN 0x04 +#define IRQ_MSK 0x08 +#define IRQ_POL 0x10 +#define DEC_EN 0x20 +#define DEC_INT 0x10 +#define VSYNC_EN 0x80 +#define VSYNC_INT 0x40 + +#define VMS_NOSY 0x00 +#define VMS_NTSC 0x01 +#define VMS_PAL 0x02 +#define VMS_PAL24 0x03 + +#define MAUDIO_PAUSE 0 +#define MAUDIO_PLAY 1 +#define MAUDIO_FAST 2 +#define MAUDIO_SLOW 3 + + +#define RegisterReadByte(card,where) read_indexed_register(&(card->link),(where)) +#define RegisterWriteByte(card,where,what) write_indexed_register(&(card->link),where,what) +#define RegisterMaskByte(card,where,mask,bits) RegisterWriteByte(card,where,(RegisterReadByte(card,where)&~(mask))|(bits)) +#define RegisterSetByte(card,where,bits) RegisterWriteByte(card,where,RegisterReadByte(card,where)|(bits)) +#define RegisterDelByte(card,where,mask) RegisterWriteByte(card,where,RegisterReadByte(card,where)&~(mask)) + +#define RegisterReadWord(card,where) (\ + (u16)RegisterReadByte(card,where)|\ + ((u16)RegisterReadByte(card,(where)+1)<<8)) +#define RegisterWriteWord(card,where,what) {\ + RegisterWriteByte(card,where,(what) & 0xFF);\ + RegisterWriteByte(card,(where)+1,((what)>>8) & 0xFF);} + +// 3-byte-wide (medium word, 24 Bit) access to the card's registers, LSB first +#define RegisterReadMWord(card,where) (\ + (u32)RegisterReadByte(card,where)|\ + ((u32)RegisterReadByte(card,(where)+1)<<8)|\ + ((u32)RegisterReadByte(card,(where)+2)<<16)) +#define RegisterWriteMWord(card,where,what) {\ + RegisterWriteByte(card,where,(what) & 0xFF);\ + RegisterWriteByte(card,(where)+1,((what)>>8) & 0xFF);\ + RegisterWriteByte(card,(where)+2,((what)>>16) & 0xFF);} + +// double-word-wide access to the card's registers, LSB first +//#define RegisterReadDWord(card,where) le32_to_cpu(readl(card->addr+(where))) +//#define RegisterWriteDWord(card,where,what) writel(cpu_to_le32(what),card->addr+(where)) +#define RegisterReadDWord(card,where) (\ + (u32)RegisterReadByte(card,where)|\ + ((u32)RegisterReadByte(card,(where)+1)<<8)|\ + ((u32)RegisterReadByte(card,(where)+2)<<16)|\ + ((u32)RegisterReadByte(card,(where)+3)<<24)) +#define RegisterWriteDWord(card,where,what) {\ + RegisterWriteByte(card,where,(what) & 0xFF);\ + RegisterWriteByte(card,(where)+1,((what)>>8) & 0xFF);\ + RegisterWriteByte(card,(where)+2,((what)>>16) & 0xFF);\ + RegisterWriteByte(card,(where)+3,((what)>>24) & 0xFF);} + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/l64021.h linux.19pre5-ac1/drivers/media/video/margi/l64021.h --- linux.19p5/drivers/media/video/margi/l64021.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/l64021.h Thu Apr 4 15:55:29 2002 @@ -0,0 +1,108 @@ +/* + l64021.h + + Copyright (C) Christian Wolff for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _L64021_H_ +#define _L64021_H_ + +#include "margi.h" +#include "l64014.h" +// L64021 DRAM definitions + +#define DRAMMaxSize 0x00200000 // 2 MWords of DRAM + +// definitions for the L64021 + +#define DECODER_OFFSET 0x400 + +#define L21INTR0 0x000 +#define L21INTR1 0x001 +#define L21INTR2 0x002 +#define L21INTR3 0x003 +#define L21INTR4 0x004 + + +// Host interface registers + +// Video Decoder Registers + +// CSS Regs + +// Memory Interface + +// Microcontroller + +// Video Interface + +// Audio Decoder + +// RAM Test + +// SPU Decoder + + + + + //////////////////////////////////////////////////// + // // + // Access to the L64021 registers (0x400-0x7FF) // + // // +//////////////////////////////////////////////////// + +#define DecoderWriteByte(card,where,what) WriteByte(card,where,what) +#define DecoderReadByte(card,where) ReadByte(card,where) +#define DecoderMaskByte(card,where,mask,bits) MaskByte(card,where,mask,bits) +#define DecoderSetByte(card,addr,bits) DecoderWriteByte(card,addr,DecoderReadByte(card,addr)|(bits)) +#define DecoderDelByte(card,addr,mask) DecoderWriteByte(card,addr,DecoderReadByte(card,addr)&~(mask)) + +#define DecoderReadWord(card,addr) ((u16)DecoderReadByte(card,addr)|\ + ((u16)DecoderReadByte(card,(addr)+1)<<8)) + +#define DecoderWriteWord(card,addr,data) {\ + DecoderWriteByte(card,addr,(data) & 0xFF);\ + DecoderWriteByte(card,(addr)+1,((data)>>8) & 0xFF);} + + +#define DecoderReadMWord(card, addr)(\ + (u32)DecoderReadByte(card,addr)|\ + ((u32)DecoderReadByte(card,(addr)+1)<<8)|\ + ((u32)DecoderReadByte(card,(addr)+2)<<16)) + +#define DecoderWriteMWord(card,addr,data) {\ + DecoderWriteByte(card,addr,(data) & 0xFF);\ + DecoderWriteByte(card,(addr)+1,((data)>>8) & 0xFF);\ + DecoderWriteByte(card,(addr)+2,((data)>>16) & 0xFF);} + +#define DecoderReadDWord(card,addr) (\ + (u32)DecoderReadByte(card,addr)|\ + ((u32)DecoderReadByte(card,(addr)+1)<<8)|\ + ((u32)DecoderReadByte(card,(addr)+2)<<16)|\ + ((u32)DecoderReadByte(card,(addr)+3)<<24)) + +#define DecoderWriteDWord(card,addr,data) {\ + DecoderWriteByte(card,addr,(data) & 0xFF);\ + DecoderWriteByte(card,(addr)+1,((data)>>8) & 0xFF);\ + DecoderWriteByte(card,(addr)+2,((data)>>16) & 0xFF);\ + DecoderWriteByte(card,(addr)+3,((data)>>24) & 0xFF);} + + +void l64020Reset(struct cvdv_cards *card); + + +#endif // _L64021_H_ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/makedev.napi linux.19pre5-ac1/drivers/media/video/margi/makedev.napi --- linux.19p5/drivers/media/video/margi/makedev.napi Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/makedev.napi Mon Feb 4 17:31:47 2002 @@ -0,0 +1,28 @@ +mkdir /dev/ost +chmod 755 /dev/ost +mknod -m 0666 /dev/ost/video0 c 250 0 +mknod -m 0666 /dev/ost/audio0 c 250 1 +mknod -m 0666 /dev/ost/sec0 c 250 2 +mknod -m 0666 /dev/ost/qpskfe0 c 250 3 +mknod -m 0666 /dev/ost/qamfe0 c 250 7 +mknod -m 0666 /dev/ost/demux0 c 250 4 +mknod -m 0666 /dev/ost/dvr0 c 250 5 +mknod -m 0666 /dev/ost/ca0 c 250 6 + +mknod -m 0666 /dev/ost/video1 c 250 64 +mknod -m 0666 /dev/ost/audio1 c 250 65 +mknod -m 0666 /dev/ost/sec1 c 250 66 +mknod -m 0666 /dev/ost/qpskfe1 c 250 67 +mknod -m 0666 /dev/ost/qamfe1 c 250 71 +mknod -m 0666 /dev/ost/demux1 c 250 68 +mknod -m 0666 /dev/ost/dvr1 c 250 69 +mknod -m 0666 /dev/ost/ca1 c 250 70 + +cd /dev/ost +ln -sf ca0 ca +ln -sf video0 video +ln -sf sec0 sec +ln -sf audio0 audio +ln -sf qpskfe0 qpskfe +ln -sf demux0 demux +ln -sf dvr0 dvr diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/margi linux.19pre5-ac1/drivers/media/video/margi/margi --- linux.19p5/drivers/media/video/margi/margi Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/margi Mon Feb 4 17:31:47 2002 @@ -0,0 +1,5 @@ +#!/bin/sh +# +# + +exit 0 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/margi.c linux.19pre5-ac1/drivers/media/video/margi/margi.c --- linux.19p5/drivers/media/video/margi/margi.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/margi.c Tue Feb 19 15:21:58 2002 @@ -0,0 +1,1493 @@ +/* + margi.c + + Copyright (C) Marcus Metzler for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "margi.h" + +#include +#include +#include +#include +#include +#include +#include + + + +#include "l64014.h" +#include "l64021.h" +#include "i2c.h" +#include "decoder.h" +#include "dram.h" +#include "video.h" +#include "cvdv.h" + + +static char *version = "margi_cs.c 0.6 02/04/2000 (Marcus Metzler)"; + +//#define USE_BH 1 +#ifdef USE_BH +#define MARGI_BH 31 +// shouldn't be a number, but then MARGI_BH must be entered into interrupt.h +#endif + +MODULE_AUTHOR(AUTHOR); +MODULE_DESCRIPTION(MEDDEVNAME " Driver V." DVERSION); +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif + +#define MAX_DEV 4 +#define DEVICE_NR(minor) ((minor)>>4) + +/*====================================================================*/ + +/* Parameters that can be set with 'insmod' */ +static int svhs = 1; +MODULE_PARM(svhs,"i"); +static int composite = 1; +MODULE_PARM(composite,"i"); +static int use_zv = 1; +MODULE_PARM(use_zv,"i"); + +/* Release IO ports after configuration? */ +static int free_ports = 0; + +/* The old way: bit map of interrupts to choose from */ +/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */ +static u_int irq_mask = 0xdeb8; +/* Newer, simpler way of listing specific interrupts */ +static int irq_list[4] = { -1 }; + +MODULE_PARM(free_ports, "i"); +MODULE_PARM(irq_mask, "i"); +MODULE_PARM(irq_list, "1-4i"); + +extern unsigned int major_device_number; +extern struct file_operations cvdv_fileops; + +typedef struct margi_info_t { + dev_link_t link; + dev_node_t node; + struct cvdv_cards card; + int stop; +} margi_info_t; + + + +/* + The event() function is this driver's Card Services event handler. + It will be called by Card Services when an appropriate card status + event is received. The config() and release() entry points are + used to configure or release a socket, in response to card + insertion and ejection events. They are invoked from the margi + event handler. +*/ + +static void margi_config(dev_link_t * link); +static void margi_release(u_long arg); +static int margi_event(event_t event, int priority, + event_callback_args_t * args); +/* + The attach() and detach() entry points are used to create and destroy + "instances" of the driver, where each instance represents everything + needed to manage one actual PCMCIA card. +*/ + +static dev_link_t *margi_attach(void); +static void margi_detach(dev_link_t *); +static u_char read_lsi_status(struct cvdv_cards *card); + +/* + You'll also need to prototype all the functions that will actually + be used to talk to your device. See 'memory_cs' for a good example + of a fully self-sufficient driver; the other drivers rely more or + less on other parts of the kernel. +*/ + +/* + The dev_info variable is the "key" that is used to match up this + device driver with appropriate cards, through the card configuration + database. +*/ + +static dev_link_t *dev_table[MAX_DEV] = { NULL, /* ... */ }; + +static dev_info_t dev_info = "margi_cs"; + +/* + A linked list of "instances" of the margi device. Each actual + PCMCIA card corresponds to one device instance, and is described + by one dev_link_t structure (defined in ds.h). + + You may not want to use a linked list for this -- for example, the + memory card driver uses an array of dev_link_t pointers, where minor + device numbers are used to derive the corresponding array index. +*/ + +static dev_link_t *dev_list = NULL; + +/* + A dev_link_t structure has fields for most things that are needed + to keep track of a socket, but there will usually be some device + specific information that also needs to be kept track of. The + 'priv' pointer in a dev_link_t structure can be used to point to + a device-specific private data structure, like this. + + To simplify the data structure handling, we actually include the + dev_link_t structure in the device's private data structure. + + A driver needs to provide a dev_node_t structure for each device + on a card. In some cases, there is only one device per card (for + example, ethernet cards, modems). In other cases, there may be + many actual or logical devices (SCSI adapters, memory cards with + multiple partitions). The dev_node_t structures need to be kept + in a linked list starting at the 'dev' field of a dev_link_t + structure. We allocate them in the card's private data structure, + because they generally shouldn't be allocated dynamically. + + In this case, we also provide a flag to indicate if a device is + "stopped" due to a power management event, or card ejection. The + device IO routines can use a flag like this to throttle IO to a + card that is not ready to accept it. + + The bus_operations pointer is used on platforms for which we need + to use special socket-specific versions of normal IO primitives + (inb, outb, readb, writeb, etc) for card IO. +*/ + +void DACSetFrequency(struct cvdv_cards *card, int khz, int multiple) { + uint8_t b = read_indexed_register(card, IIO_OSC_AUD); + + b &= 0xf8; + + switch (khz){ + case 32: + b |= 0x04; + break; + case 48: + b |= 0x00; + break; + case 44: + b |= 0x01; + break; + case 96: + b |= 0x02; + break; + default: + b |= 0x00; + break; + } + write_indexed_register(card, IIO_OSC_AUD, b); + +} + +int MargiFreeBuffers(struct cvdv_cards *card) +{ + MDEBUG(1, ": -- MargiFreeBuffers\n"); + + ring_destroy(&(card->rbufB)); + card->use_ringB = 0; + ring_destroy(&(card->rbufA)); + card->use_ringA = 0; + + return 0; +} + + +int MargiSetBuffers(struct cvdv_cards *card, uint32_t size, int isB) +{ + int err = 0; + + MDEBUG(0, ": -- MargiSetBuffers(%d) %d\n", + size, isB); + + if (isB){ + err = ring_init(&(card->rbufB),size); + if (!err) card->use_ringB = 1; + } else { + err = ring_init(&(card->rbufA),size); + if (!err) card->use_ringA = 1; + } + + MDEBUG(0,"set buffers: %d use_ringA: %d use_ringB: %d\n",err, +card->use_ringA,card->use_ringB); + return err; +} + + +int MargiFlush (struct cvdv_cards *card) +{ + int co = 0; + int i; + for (i=0;i<100;i++){ + MargiPushA(card, 32, FlushPacket); + MargiPushB(card, 32, FlushPacket); + } + while ( (ring_write_rest(&(card->rbufA))|| ring_write_rest(&(card->rbufB))) && co<100) + co++; + VideoSetBackground(card, 1, 0, 0, 0); // black + + if (card->use_ringA) ring_flush(&(card->rbufA)); + if (card->use_ringB) ring_flush(&(card->rbufB)); + card->DMAABusy = 0; + card->DMABBusy = 0; + + + DecoderStopChannel(card); + DecoderStreamReset(card); + DecoderSetupReset(card); + card->channelrun = 0; + + MDEBUG(1, ": Margi Flush \n"); + return 0; +} + + +int MargiPushA(struct cvdv_cards *card, int count, const char *data) +{ + int fill; + + fill = ring_read_rest(&(card->rbufA)); + + if (!card->use_ringA) + return 0; + if ((count>fill || fill > 3*card->rbufA.size/4) + && !card->channelrun){ + DecoderStartChannel(card); + card->DMAABusy = 1; + } + + count = ring_write(&(card->rbufA),data,count); + + return count; +} + +int MargiPushB(struct cvdv_cards *card, int count, const char *data) +{ + int fill; + + fill = ring_read_rest(&(card->rbufB)); + + if (!card->use_ringB) + return 0; + if ((count>fill || fill > 3*card->rbufB.size/4) + && !card->channelrun){ + DecoderStartChannel(card); + card->DMABBusy = 1; + } + + count = ring_write(&(card->rbufB),data,count); + + return count; +} + +int DecoderStartChannel(struct cvdv_cards *card) +{ + DecoderMaskByte(card, 0x007, 0xC3, 0xC3); // channel start + +#ifdef BYPASS + DecoderMaskByte(card,0x005,0x0F,0x08); +#else + DecoderMaskByte(card,0x005,0x0F,0x01); +#endif + card->channelrun = 1; + return 0; +} + +int DecoderStopChannel(struct cvdv_cards *card) +{ + DecoderMaskByte(card, 0x007, 0xC3, 0xC2); // channel reset + DecoderSetByte(card, 0x005, 0x04); // channel pause + card->channelrun = 0; + return 0; +} + +uint32_t DecoderGetAudioBufferSpace(struct cvdv_cards *card) +{ + + uint32_t MaxSize, Size; + + MaxSize = card->AudioESSize; + Size = DecoderGetAudioESLevel(card); + + if (Size>MaxSize) + return 0; + return (MaxSize - Size); + +} + +uint32_t DecoderGetVideoBufferSpace(struct cvdv_cards *card) +{ + + uint32_t MaxSize, Size; + + MaxSize = card->VideoESSize; + Size = DecoderGetVideoESLevel(card); + + if (Size>MaxSize) + return 0; + return (MaxSize - Size); + +} + +uint32_t DecoderGetBufferSpace(struct cvdv_cards *card) +{ + uint32_t audio,video; + + audio = DecoderGetAudioBufferSpace(card); + video = DecoderGetVideoBufferSpace(card); + + if (audio > 2048) audio -= 2048; + if (video > 2048) video -= 2048; + + if (audio < video) return audio; + return video; +} + + + +static int ringDMA (struct cvdv_cards *card){ + + uint32_t size = 0; + u_char stat; + dev_link_t *link = &(((margi_info_t *) card->margi)->link); + uint32_t acount=0; + uint32_t vcount=0; + uint8_t data; + ringbuffy *buffy; + int stype; + wait_queue_head_t *wq; + stat = read_lsi_status(card); + + + stype = card->setup.streamtype; + + if (stat & LSI_ARQ) { + stat = read_lsi_status(card); + } + + if (stat & LSI_READY){ + data = read_indexed_register(card, IIO_LSI_CONTROL); + data |= RR; + write_indexed_register(card, IIO_LSI_CONTROL, data); + return 0; + } + + if ((stat & LSI_ARQ) == 0) { + switch(stype){ + case stream_PES: + case stream_ES: + data = read_indexed_register(card, IIO_LSI_CONTROL); + data &= ~DSVC; + write_indexed_register(card, IIO_LSI_CONTROL, data); + buffy = &card->rbufB; + wq = &(card->wqB); + acount = ring_read_rest(buffy); + size = DecoderGetAudioBufferSpace(card); + if (size > 2048) size -= 2048; + break; + default: + buffy = &card->rbufA; + wq = &(card->wqA); + acount = ring_read_rest(buffy); + size = DecoderGetBufferSpace(card); + break; + } + if (acount > size) acount = size & 0xfffffffc; + if (acount>=2048) acount &=0xfffff800; + acount &=0xfffffffc; + + if (acount > size) acount = size & 0xfffffffc; + if (acount) { + ring_read_direct(buffy, + link->io.BasePort1+DIO_LSI_STATUS, + acount); + } else { + wake_up_interruptible(wq); + acount = 0; + } + } else { + acount = 0; + } + + if ((stat & LSI_VRQ) == 0 && + (stype == stream_PES || stype == stream_ES)) { + data = read_indexed_register(card, IIO_LSI_CONTROL); + data |= DSVC; + write_indexed_register(card, IIO_LSI_CONTROL, data); + buffy = &card->rbufA; + wq = &(card->wqA); + vcount = ring_read_rest(buffy); + + size = DecoderGetVideoBufferSpace(card); + if (size > 2048) size -= 2048; + if (vcount > size) vcount = size & 0xfffffffc; + if (vcount>=2048) vcount &=0xfffff800; + vcount &=0xfffffffc; + + if (vcount > size) vcount = size & 0xfffffffc; + if (vcount) { + ring_read_direct(buffy, + link->io.BasePort1+DIO_LSI_STATUS, + vcount); + } else { + wake_up_interruptible(wq); + vcount = 0; + } + } else { + vcount = 0; + } + + return vcount+acount; +} + + +u_char read_indexed_register(struct cvdv_cards * card, int addr) +{ + dev_link_t *link = &(((margi_info_t *) card->margi)->link); + u_char data; +#ifdef NOINT + spin_lock(&card->timelock); +#endif + outb(addr, link->io.BasePort1 + DIO_CONTROL_INDEX); + data = (inb(link->io.BasePort1 + DIO_CONTROL_DATA)); +#ifdef NOINT + spin_unlock(&card->timelock); +#endif + return data; +} + + +void write_indexed_register(struct cvdv_cards *card, int addr, u_char data) +{ + dev_link_t *link = &(((margi_info_t *) card->margi)->link); +#ifdef NOINT + spin_lock(&card->timelock); +#endif + outb(addr, link->io.BasePort1 + DIO_CONTROL_INDEX); + outb(data, link->io.BasePort1 + DIO_CONTROL_DATA); + +#ifdef NOINT + spin_unlock(&card->timelock); +#endif +} + +void WriteByte(struct cvdv_cards *card, int addr, u_char data) +{ + dev_link_t *link = &(((margi_info_t *) card->margi)->link); + +#ifdef NOINT + spin_lock(&card->timelock); +#endif + outb((u_char) (addr & 255), + link->io.BasePort1 + DIO_LSI_INDEX_LOW); + outb(((addr & 256) ? 1 : 0), + link->io.BasePort1 + DIO_LSI_INDEX_HIGH); + outb(data, link->io.BasePort1 + DIO_LSI_DATA); +#ifdef NOINT + spin_unlock(&card->timelock); +#endif +} + +u_char ReadByte(struct cvdv_cards *card, int addr) +{ + dev_link_t *link = &(((margi_info_t *) card->margi)->link); + u_char data; + +#ifdef NOINT + spin_lock(&card->timelock); +#endif + outb((u_char) (addr & 255), + link->io.BasePort1 + DIO_LSI_INDEX_LOW); + outb(((addr & 256) ? 1 : 0), + link->io.BasePort1 + DIO_LSI_INDEX_HIGH); + data = inb(link->io.BasePort1 + DIO_LSI_DATA); +#ifdef NOINT + spin_unlock(&card->timelock); +#endif + return data; +} + +void MaskByte(struct cvdv_cards *card, int addr, u_char mask, u_char bits) +{ + WriteByte(card, addr, (ReadByte(card, addr) & ~(mask)) | (bits)); +} + + + +#define MAXWRITE CHANNELBUFFERSIZE/2 +#define MAX_COUNT 400 + +#ifdef USE_BH +struct cvdv_cards *bh_card; + +static void do_margi_bh(void) +{ + struct cvdv_cards *card = bh_card; +#else + +static void do_margi(struct cvdv_cards *card) +{ + +#endif + int countA; + int try; + int stype = card->setup.streamtype; + + countA = 0; + + card->currentType = 0; + for ( try = 0; try < MAX_COUNT ;try++) + if (countA < MAXWRITE){ + int count = 0; + switch (stype){ + case stream_PES: + case stream_ES: + count = ringDMA(card); + countA += count; + if (!count) + try=MAX_COUNT; + break; + case stream_PS: + case stream_DVD: + count = ringDMA(card); + countA += count; + if (!count) + try=MAX_COUNT; + break; + } + } else break; + +} + + + + +void L64014Intr_function(struct cvdv_cards *card) +{ + uint8_t control,mask,stat; + int try; + + + control= read_indexed_register(card, IIO_IRQ_CONTROL); + if (control & IRQ_EN){ + mask = 0; + if ( control & DEC_EN ) mask |= DEC_INT; + if ( control & VSYNC_EN ) mask |= VSYNC_INT; + stat = read_indexed_register(card, IIO_IRQ_STATUS); + try = 0; + while ( (try++ < 100) && (stat & mask) ){ + + if (stat & VSYNC_INT) { + + write_indexed_register(card,IIO_IRQ_CONTROL, + control & (~VSYNC_EN)); + write_indexed_register(card,IIO_IRQ_CONTROL, + control); + + + if (card->DMAABusy || card->DMABBusy){ + +#ifdef USE_BH + bh_card = card; + mark_bh(MARGI_BH); +#else + do_margi(card); +#endif + if(card->use_ringA || card->use_ringB){ + L64021Intr(card); + } + } + } + + if (stat & DEC_INT) { + write_indexed_register(card,IIO_IRQ_CONTROL, + control & (~DEC_EN)); + write_indexed_register(card,IIO_IRQ_CONTROL, + control); + + if(card->use_ringA || card->use_ringB){ + L64021Intr(card); + } + } + + stat = read_indexed_register(card, IIO_IRQ_STATUS); + } + } + +} + + +#ifdef NOINT +void Timerfunction(unsigned long data) +{ + struct cvdv_cards *card = (struct cvdv_cards *) data; + + L64014Intr_function(card); + + card->timer.function = Timerfunction; + card->timer.data=(unsigned long) card; + card->timer.expires=jiffies+10; + if ( card->open) + add_timer(&card->timer); + +} +#endif + + +void L64014Intr(int irq, void *dev_id, struct pt_regs *regs) +{ + margi_info_t *margi = dev_id; + struct cvdv_cards *card = &(margi->card); + u_char dio_index, lsi_index_low, lsi_index_high; + +#ifdef NOINT + spin_lock(&card->timelock); +#endif + //save registers + dio_index = inb(margi->link.io.BasePort1 + DIO_CONTROL_INDEX); + lsi_index_low = inb(margi->link.io.BasePort1 + DIO_LSI_INDEX_LOW); + lsi_index_high = inb(margi->link.io.BasePort1 + DIO_LSI_INDEX_HIGH); + + + L64014Intr_function(card); + + //load registers + outb(dio_index, margi->link.io.BasePort1 + DIO_CONTROL_INDEX); + outb(lsi_index_low, margi->link.io.BasePort1 + DIO_LSI_INDEX_LOW); + outb(lsi_index_high,margi->link.io.BasePort1 + DIO_LSI_INDEX_HIGH); +#ifdef NOINT + spin_unlock(&card->timelock); +#endif +} + +int L64014RemoveIntr(struct cvdv_cards *card) +{ + MDEBUG(1, ": -- L64014RemoveIntr\n"); + // Disable the IRQ's + write_indexed_register(card, IIO_IRQ_CONTROL, 0x00); + if (!card->IntInstalled) + return 1; + L64021RemoveIntr(card); + return 0; +} + +void l64020Reset(struct cvdv_cards *card){ + uint8_t data; + + + data = read_indexed_register(card, IIO_LSI_CONTROL); + data &= ~(RR | DR); + write_indexed_register(card, IIO_LSI_CONTROL, data); + mdelay(100); + data = read_indexed_register(card, IIO_LSI_CONTROL); + data |= DR; + write_indexed_register(card, IIO_LSI_CONTROL, data); + + data = read_indexed_register(card,IIO_GPIO_PINS); + data &= ~0x01; + write_indexed_register(card,IIO_GPIO_PINS,data); + data |= 0x01; + write_indexed_register(card,IIO_GPIO_PINS,data); + + //write_indexed_register(card, IIO_LSI_CONTROL, DR); + + data = read_indexed_register(card, IIO_LSI_CONTROL); + data &= ~DSVC; + write_indexed_register(card, IIO_LSI_CONTROL, data); + +} + +void ZV_init(struct cvdv_cards *card) +{ + uint32_t delay, activel; + uint8_t reg; + delay = 235; + activel = delay + 1448; + + // init delay and active lines + write_indexed_register(card, IIO_VIDEO_HOR_DELAY, + (uint8_t)(delay & 0x00FF)); + write_indexed_register(card, IIO_VIDEO_HOR_ACTIVE, + (uint8_t)(activel & 0x00FF)); + reg = ((uint8_t)((activel >> 4) & 0x0070))|((uint8_t)((delay >> 8) & 0x0007)); + write_indexed_register(card, IIO_VIDEO_HOR_HIGH, reg); + + //init video + reg = read_indexed_register(card, IIO_VIDEO_CONTROL0); + reg |= (ZVCLK13 | ZV16BIT | ZVCLKINV); + write_indexed_register(card, IIO_VIDEO_CONTROL0, reg); + reg = read_indexed_register(card, IIO_VIDEO_CONTROL1); + reg |= (ZV_OVERRIDE | ZV_ENABLE); + write_indexed_register(card, IIO_VIDEO_CONTROL1, reg); +} + +void set_svhs(struct cvdv_cards *card, int onoff) +{ + uint8_t val; + + val = I2CRead(card, card->i2c_addr, CS_DAC)&0x0f; + MDEBUG(1, ": --svhs val 0x%02x\n",val); + + if (onoff){ + if (!card->svhs){ + I2CWrite(card, card->i2c_addr, CS_DAC, val|0x03); + card->svhs = 1; + } + } else { + if (!card->svhs){ + I2CWrite(card, card->i2c_addr, CS_DAC, val|0x30); + card->svhs = 1; + } + } + +} + +void set_composite(struct cvdv_cards *card, int onoff) +{ + uint8_t val; + + val = I2CRead(card, card->i2c_addr, CS_DAC)&0x0f; + MDEBUG(1, ": --composite val 0x%02x\n",val); + + + if (onoff){ + if (!card->composite){ + I2CWrite(card, card->i2c_addr, CS_DAC, val|0x84); + card->composite = 1; + } + } else { + if (!card->svhs){ + I2CWrite(card, card->i2c_addr, CS_DAC, val|0xE0); + card->composite = 1; + } + } + +} + + +int L64014Init(struct cvdv_cards *card) +{ + uint16_t testram[16]; + int i, err; + + MDEBUG(1, ": -- L64014Init\n"); + card->videomode = VIDEO_MODE; + + /* Reset 64020 */ + write_indexed_register(card, IIO_GPIO_CONTROL, 0x01); + l64020Reset(card); + /* init GPIO */ + write_indexed_register(card, IIO_GPIO_CONTROL, 0x01); + write_indexed_register(card, IIO_GPIO_PINS, 0xff); + + /* Set to PAL */ + write_indexed_register(card, IIO_VIDEO_CONTROL0, 0); + write_indexed_register(card, IIO_VIDEO_CONTROL1, VMS_PAL); + + /* Set Audio freq */ + write_indexed_register(card, IIO_OSC_AUD, 0x12); + + write_indexed_register(card, CSS_COMMAND, 0x01); + + + MDEBUG(0, "CSID: %02x\n", I2CRead(card, 0, 0x3d)); + card->i2c_addr = I2CRead(card, 0, 0x0f); + MDEBUG(0, "I2CADDR: %02x\n", card->i2c_addr); + + I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x4a); + I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04); + I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x15); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x96); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x15); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0x13); + I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x54); + +// I2CWrite(card, card->i2c_addr, CS_DAC, 0x87); + if (svhs) set_svhs(card, 1); + if (composite) set_composite(card, 1); + I2CWrite(card, card->i2c_addr, CS_BKG_COL, 0x03); + + MDEBUG(0,"Decoder Status: %d\n", read_lsi_status(card)); + MDEBUG(0,"lsi stat %d\n", DecoderReadByte(card, 0x005)); + + if (use_zv) ZV_init(card); + L64021Init(card); + + // Find out how much DRAM we have + card->DRAMSize = 0x00100000; // maximum size + do { + MDEBUG(0, + ": Probing DRAM Size: 0x%08X (%d kByte) ... ", + card->DRAMSize, card->DRAMSize / 512); + for (i = 0; i < 8; i++) + testram[i] = rnd(0x100) | (rnd(0x100) << 8); + if (DRAMWriteWord(card, 0, 4, &testram[0], 0)) + MDEBUG(0, ": DRAM Write error.\n"); + if (DRAMWriteWord + (card, card->DRAMSize - 4, 4, &testram[4], + 0)) MDEBUG(0, + ": DRAM Write error.\n"); + if (DRAMReadWord(card, 0, 4, &testram[8], 0)) + MDEBUG(0, ": DRAM Read error.\n"); + if (DRAMReadWord + (card, card->DRAMSize - 4, 4, &testram[12], + 0)) MDEBUG(0, ": DRAM Read error.\n"); + err = 0; + for (i = 0; (!err) && (i < 8); i++) + if (testram[i] != testram[i + 8]) + err = i + 1; + if (err) { + MDEBUG(0," failed\n"); + } else { + MDEBUG(0," ok\n"); + } + if (err) + MDEBUG(2,": DRAM compare error at cell %d: 0x%04X %04X %04X %04X->0x%04X %04X %04X %04X / 0x%04X %04X %04X %04X->0x%04X %04X %04X %04X\n", + err, testram[0], testram[1], testram[2], + testram[3], testram[8], testram[9], + testram[10], testram[11], testram[4], + testram[5], testram[6], testram[7], + testram[12], testram[13], testram[14], + testram[15]); + if (err) + card->DRAMSize >>= 1; + } while (err && (card->DRAMSize >= 0x00100000)); + printk(KERN_INFO LOGNAME ": DRAM Size: 0x%08X (%d kByte)\n", + card->DRAMSize, card->DRAMSize / 512); + if (card->DRAMSize < 0x00100000) { // minimum size + printk(KERN_INFO LOGNAME + ": DRAM ERROR: Not enough memory on card!\n"); + return 1; + } + return 0; +} + + +void CardDeInit(struct cvdv_cards *card) +{ + CloseCard(card); + MargiFlush(card); + MargiFreeBuffers(card); + + L64014RemoveIntr(card); + card_init(card, 0); +} + + +static u_char read_lsi_status(struct cvdv_cards *card) +{ + margi_info_t *margi = (margi_info_t *) card->margi; + return (inb(margi->link.io.BasePort1 + DIO_LSI_STATUS) & 15); + +} + +/*====================================================================*/ + +static void cs_error(client_handle_t handle, int func, int ret) +{ + error_info_t err = { func, ret }; + CardServices(ReportError, handle, &err); +} + +/*====================================================================== + + margi_attach() creates an "instance" of the driver, allocating + local data structures for one device. The device is registered + with Card Services. + + The dev_link structure is initialized, but we don't actually + configure the card at this point -- we wait until we receive a + card insertion event. + +======================================================================*/ + +static dev_link_t *margi_attach(void) +{ + margi_info_t *local; + dev_link_t *link; + client_reg_t client_reg; + int ret, i; + + MDEBUG(0, "margi_attach()\n"); + + for (i = 0; i < MAX_DEV; i++) + if (dev_table[i] == NULL) + break; + if (i == MAX_DEV) { + printk(KERN_NOTICE "margi_cs: no devices available\n"); + return NULL; + } + + /* Allocate space for private device-specific data */ + local = kmalloc(sizeof(margi_info_t), GFP_KERNEL); + if (!local) + return NULL; + memset(local, 0, sizeof(margi_info_t)); + link = &local->link; + link->priv = local; + local->card.margi = (void *) local; + dev_table[i] = link; + + /* Initialize the dev_link_t structure */ + link->release.function = &margi_release; + link->release.data = (u_long) link; + + /* Interrupt setup */ + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID; + if (irq_list[0] == -1) + link->irq.IRQInfo2 = irq_mask; + else + for (i = 0; i < 4; i++) + link->irq.IRQInfo2 |= 1 << irq_list[i]; + link->irq.Handler = NULL; + + /* + General socket configuration defaults can go here. In this + client, we assume very little, and rely on the CIS for almost + everything. In most clients, many details (i.e., number, sizes, + and attributes of IO windows) are fixed by the nature of the + device, and can be hard-wired here. + */ + link->conf.Attributes = 0; + link->conf.Vcc = 50; + + if(use_zv==0) + link->conf.IntType = INT_MEMORY_AND_IO; + else + link->conf.IntType = INT_ZOOMED_VIDEO; + + /* Register with Card Services */ + link->next = dev_list; + dev_list = link; + client_reg.dev_info = &dev_info; + client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; + client_reg.EventMask = + CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | + CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | + CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; + client_reg.event_handler = &margi_event; + client_reg.Version = 0x0210; + client_reg.event_callback_args.client_data = link; + ret = CardServices(RegisterClient, &link->handle, &client_reg); + if (ret != CS_SUCCESS) { + cs_error(link->handle, RegisterClient, ret); + margi_detach(link); + return NULL; + } + + return link; +} /* margi_attach */ + +/*====================================================================== + + This deletes a driver "instance". The device is de-registered + with Card Services. If it has been released, all local data + structures are freed. Otherwise, the structures will be freed + when the device is released. + +======================================================================*/ + +static void margi_detach(dev_link_t * link) +{ + dev_link_t **linkp; + + int nd; + + MDEBUG(0, "margi_detach(0x%p)\n", link); + + for (nd = 0; nd < MAX_DEV; nd++) + if (dev_table[nd] == link) + break; + if (nd == MAX_DEV) + return; + + /* Locate device structure */ + for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) + if (*linkp == link) + break; + if (*linkp == NULL) + return; + + /* + If the device is currently configured and active, we won't + actually delete it yet. Instead, it is marked so that when + the release() function is called, that will trigger a proper + detach(). + */ + if (link->state & DEV_CONFIG) { + MDEBUG(2, "margi_cs: detach postponed, '%s' " + "still locked\n", link->dev->dev_name); + link->state |= DEV_STALE_LINK; + return; + } + + /* Break the link with Card Services */ + if (link->handle) + CardServices(DeregisterClient, link->handle); + + /* Unlink device structure, and free it */ + *linkp = link->next; + /* This points to the parent struct cvdv_cards struct */ + dev_table[nd] = NULL; + + kfree(link->priv); + +} /* margi_detach */ + +/*====================================================================== + + margi_config() is scheduled to run after a CARD_INSERTION event + is received, to configure the PCMCIA socket, and to make the + device available to the system. + +======================================================================*/ + +#define CS_CHECK(fn, args...) \ +while ((last_ret=CardServices(last_fn=(fn),args))!=0) goto cs_failed + +#define CFG_CHECK(fn, args...) \ +if (CardServices(fn, args) != 0) goto next_entry + +static void margi_config(dev_link_t * link) +{ + client_handle_t handle = link->handle; + margi_info_t *dev = link->priv; + struct cvdv_cards *card = &(dev->card); + tuple_t tuple; + cisparse_t parse; + int last_fn, last_ret, i; + u_char buf[64]; + config_info_t conf; + win_req_t req; + memreq_t map; + int minor = 0; + + MDEBUG(0, "margi_config(0x%p)\n", link); + + /* + This reads the card's CONFIG tuple to find its configuration + registers. + */ + tuple.DesiredTuple = CISTPL_CONFIG; + tuple.Attributes = 0; + tuple.TupleData = buf; + tuple.TupleDataMax = sizeof(buf); + tuple.TupleOffset = 0; + CS_CHECK(GetFirstTuple, handle, &tuple); + CS_CHECK(GetTupleData, handle, &tuple); + CS_CHECK(ParseTuple, handle, &tuple, &parse); + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + + /* Configure card */ + link->state |= DEV_CONFIG; + + /* Look up the current Vcc */ + CS_CHECK(GetConfigurationInfo, handle, &conf); + link->conf.Vcc = conf.Vcc; + + /* + In this loop, we scan the CIS for configuration table entries, + each of which describes a valid card configuration, including + voltage, IO window, memory window, and interrupt settings. + + We make no assumptions about the card to be configured: we use + just the information available in the CIS. In an ideal world, + this would work for any PCMCIA card, but it requires a complete + and accurate CIS. In practice, a driver usually "knows" most of + these things without consulting the CIS, and most client drivers + will only use the CIS to fill in implementation-defined details. + */ + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + CS_CHECK(GetFirstTuple, handle, &tuple); + while (1) { + cistpl_cftable_entry_t dflt = { 0 }; + cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); + CFG_CHECK(GetTupleData, handle, &tuple); + CFG_CHECK(ParseTuple, handle, &tuple, &parse); + + if (cfg->flags & CISTPL_CFTABLE_DEFAULT) + dflt = *cfg; + if (cfg->index == 0) + goto next_entry; + link->conf.ConfigIndex = cfg->index; + + /* Does this card need audio output? */ + if (cfg->flags & CISTPL_CFTABLE_AUDIO) { + link->conf.Attributes |= CONF_ENABLE_SPKR; + link->conf.Status = CCSR_AUDIO_ENA; + } + + /* Use power settings for Vcc and Vpp if present */ + /* Note that the CIS values need to be rescaled */ + if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (conf.Vcc != + cfg->vcc.param[CISTPL_POWER_VNOM] / + 10000) goto next_entry; + } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (conf.Vcc != + dflt.vcc.param[CISTPL_POWER_VNOM] / + 10000) goto next_entry; + } + + if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) + link->conf.Vpp1 = link->conf.Vpp2 = + cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; + else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) + link->conf.Vpp1 = link->conf.Vpp2 = + dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; + + /* + Allocate an interrupt line. Note that this does not assign a + handler to the interrupt, unless the 'Handler' member of the + irq structure is initialized. + */ +#ifndef NOINT + link->irq.Attributes = + IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; + link->irq.Handler = &L64014Intr; + link->irq.Instance = link; + link->conf.Attributes |= CONF_ENABLE_IRQ; +#ifdef USE_BH + init_bh(MARGI_BH, do_margi_bh); +#endif + if (link->conf.Attributes & CONF_ENABLE_IRQ) + CS_CHECK(RequestIRQ, link->handle, &link->irq); +#endif + + /* IO window settings */ + link->io.NumPorts1 = link->io.NumPorts2 = 0; + if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { + cistpl_io_t *io = + (cfg->io.nwin) ? &cfg->io : &dflt.io; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + if (!(io->flags & CISTPL_IO_8BIT)) + link->io.Attributes1 = + IO_DATA_PATH_WIDTH_16; + if (!(io->flags & CISTPL_IO_16BIT)) + link->io.Attributes1 = + IO_DATA_PATH_WIDTH_8; + link->io.IOAddrLines = + io->flags & CISTPL_IO_LINES_MASK; + link->io.BasePort1 = io->win[0].base; + link->io.NumPorts1 = io->win[0].len; + if (io->nwin > 1) { + link->io.Attributes2 = + link->io.Attributes1; + link->io.BasePort2 = io->win[1].base; + link->io.NumPorts2 = io->win[1].len; + } + } + + /* This reserves IO space but doesn't actually enable it */ + CFG_CHECK(RequestIO, link->handle, &link->io); + + /* + Now set up a common memory window, if needed. There is room + in the dev_link_t structure for one memory window handle, + but if the base addresses need to be saved, or if multiple + windows are needed, the info should go in the private data + structure for this device. + + Note that the memory window base is a physical address, and + needs to be mapped to virtual space with ioremap() before it + is used. + */ + if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) { + cistpl_mem_t *mem = + (cfg->mem.nwin) ? &cfg->mem : &dflt.mem; + req.Attributes = + WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM; + req.Attributes |= WIN_ENABLE; + req.Base = mem->win[0].host_addr; + req.Size = mem->win[0].len; + req.AccessSpeed = 0; + link->win = (window_handle_t) link->handle; + CFG_CHECK(RequestWindow, &link->win, &req); + map.Page = 0; + map.CardOffset = mem->win[0].card_addr; + CFG_CHECK(MapMemPage, link->win, &map); + } + /* If we got this far, we're cool! */ + break; + + next_entry: + CS_CHECK(GetNextTuple, handle, &tuple); + } + + /* + This actually configures the PCMCIA socket -- setting up + the I/O windows and the interrupt mapping, and putting the + card and host interface into "Memory and IO" mode. + */ + CS_CHECK(RequestConfiguration, link->handle, &link->conf); + + /* + We can release the IO port allocations here, if some other + driver for the card is going to loaded, and will expect the + ports to be available. + */ + if (free_ports) { + if (link->io.BasePort1) + release_region(link->io.BasePort1, + link->io.NumPorts1); + if (link->io.BasePort2) + release_region(link->io.BasePort2, + link->io.NumPorts2); + } + + /* + At this point, the dev_node_t structure(s) need to be + initialized and arranged in a linked list at link->dev. + */ + + first_card = card; + minor=0; + card->next = NULL; + card_init(card, minor); + if ((i = register_chrdev(CVDV_MAJOR, CVDV_PROCNAME, &cvdv_fileops)) + >= 0) { + major_device_number = ((i) ? i : CVDV_MAJOR); + printk(KERN_INFO LOGNAME + ": Char-device with major number %d installed\n", + major_device_number); + } else { + printk(KERN_ERR LOGNAME + ": ERROR: Failed to install Char-device %d, error %d\n", + CVDV_MAJOR, i); + } + + + sprintf(dev->node.dev_name, "margi"); + dev->node.major = major_device_number; + dev->node.minor = minor; + link->dev = &dev->node; +#ifdef DVB + dvb_register(card); +#endif + /* Finally, report what we've done */ + printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", + dev->node.dev_name, link->conf.ConfigIndex, + link->conf.Vcc / 10, link->conf.Vcc % 10); + if (link->conf.Vpp1) + printk(", Vpp %d.%d", link->conf.Vpp1 / 10, + link->conf.Vpp1 % 10); + if (link->conf.Attributes & CONF_ENABLE_IRQ) + printk(", irq %d", link->irq.AssignedIRQ); + if (link->io.NumPorts1) + printk(", io 0x%04x-0x%04x", link->io.BasePort1, + link->io.BasePort1 + link->io.NumPorts1 - 1); + if (link->io.NumPorts2) + printk(" & 0x%04x-0x%04x", link->io.BasePort2, + link->io.BasePort2 + link->io.NumPorts2 - 1); + if (link->win) + printk(", mem 0x%06lx-0x%06lx", req.Base, + req.Base + req.Size - 1); + printk("\n"); + + link->state &= ~DEV_CONFIG_PENDING; + if (0xdd == read_indexed_register(card, IIO_ID)) { + printk("L64014 Version %d in mode %d detected\n", + (read_indexed_register(card, IIO_MODE) & 248) >> 3, + read_indexed_register(card, IIO_MODE) & 7); + write_indexed_register(card, IIO_GPIO_CONTROL, 0x07); + + L64014Init(card); + + // default: color bars + VideoSetBackground(card, 1, 0, 0, 0); // black + SetVideoSystem(card); + minorlist[minor] = card; // fast access for the char driver + + + /*enable L64014 IRQ */ + write_indexed_register(card, IIO_IRQ_CONTROL, + IRQ_POL | IRQ_EN | VSYNC_EN); +// write_indexed_register(card, IIO_IRQ_CONTROL, 0x24); + + OSDOpen(card, 50, 50, 150, 150, 2, 1); + OSDTest(card); + } + return; + + cs_failed: + cs_error(link->handle, last_fn, last_ret); + margi_release((u_long) link); + +} /* margi_config */ + +/*====================================================================== + + After a card is removed, margi_release() will unregister the + device, and release the PCMCIA configuration. If the device is + still open, this will be postponed until it is closed. + +======================================================================*/ + +static void margi_release(u_long arg) +{ + dev_link_t *link = (dev_link_t *) arg; + margi_info_t *dev = link->priv; + struct cvdv_cards *card = &(dev->card); + + MDEBUG(0, "margi_release(0x%p)\n", link); + /* + If the device is currently in use, we won't release until it + is actually closed, because until then, we can't be sure that + no one will try to access the device or its data structures. + */ + if (link->open) { + MDEBUG(1, "margi_cs: release postponed, '%s' still open\n", + link->dev->dev_name); + link->state |= DEV_STALE_CONFIG; + return; + } + + /* Unlink the device chain */ + link->dev = NULL; + + /* + In a normal driver, additional code may be needed to release + other kernel data structures associated with this device. + */ + + MDEBUG(1,": Unloading device driver\n"); + if (major_device_number) + unregister_chrdev(major_device_number, CVDV_PROCNAME); + CardDeInit(card); + +#ifndef NOINT +#ifdef USE_BH + remove_bh(MARGI_BH); +#endif + mdelay(100); +#endif + CloseCard(card); +#ifdef DVB + dvb_unregister(card); +#endif + /* Don't bother checking to see if these succeed or not */ + if (link->win) + CardServices(ReleaseWindow, link->win); + CardServices(ReleaseConfiguration, link->handle); + if (link->io.NumPorts1) + CardServices(ReleaseIO, link->handle, &link->io); +#ifndef NOINT + if (link->irq.AssignedIRQ) + CardServices(ReleaseIRQ, link->handle, &link->irq); +#endif + link->state &= ~DEV_CONFIG; + + if (link->state & DEV_STALE_LINK) + margi_detach(link); + +} /* margi_release */ + +/*====================================================================== + + The card status event handler. Mostly, this schedules other + stuff to run after an event is received. + + When a CARD_REMOVAL event is received, we immediately set a + private flag to block future accesses to this device. All the + functions that actually access the device should check this flag + to make sure the card is still present. + +======================================================================*/ + +static int margi_event(event_t event, int priority, + event_callback_args_t * args) +{ + dev_link_t *link = args->client_data; + margi_info_t *dev = link->priv; + + MDEBUG(1, "margi_event(0x%06x)\n", event); + + switch (event) { + case CS_EVENT_CARD_REMOVAL: + link->state &= ~DEV_PRESENT; + if (link->state & DEV_CONFIG) { + ((margi_info_t *) link->priv)->stop = 1; + link->release.expires = jiffies + HZ / 20; + add_timer(&link->release); + } + break; + case CS_EVENT_CARD_INSERTION: + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + dev->card.bus = args->bus; + margi_config(link); + break; + case CS_EVENT_PM_SUSPEND: + link->state |= DEV_SUSPEND; + /* Fall through... */ + case CS_EVENT_RESET_PHYSICAL: + /* Mark the device as stopped, to block IO until later */ + dev->stop = 1; + if (link->state & DEV_CONFIG) + CardServices(ReleaseConfiguration, link->handle); + break; + case CS_EVENT_PM_RESUME: + link->state &= ~DEV_SUSPEND; + /* Fall through... */ + case CS_EVENT_CARD_RESET: + if (link->state & DEV_CONFIG) + CardServices(RequestConfiguration, link->handle, + &link->conf); + dev->stop = 0; + /* + In a normal driver, additional code may go here to restore + the device state and restart IO. + */ + break; + } + return 0; +} /* margi_event */ + +/*====================================================================*/ + +static int __init init_margi_cs(void) +{ + servinfo_t serv; + MDEBUG(0, "%s\n", version); + CardServices(GetCardServicesInfo, &serv); + if (serv.Revision != CS_RELEASE_CODE) { + printk(KERN_NOTICE "margi_cs: Card Services release " + "does not match!\n"); + return -1; + } + register_pccard_driver(&dev_info, &margi_attach, &margi_detach); + return 0; +} + +static void __exit exit_margi_cs(void) +{ + MDEBUG(0, "margi_cs: unloading\n"); + unregister_pccard_driver(&dev_info); + while (dev_list != NULL) { + if (dev_list->state & DEV_CONFIG) + margi_release((u_long) dev_list); + margi_detach(dev_list); + } +} + +module_init(init_margi_cs); +module_exit(exit_margi_cs); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/margi.conf linux.19pre5-ac1/drivers/media/video/margi/margi.conf --- linux.19p5/drivers/media/video/margi/margi.conf Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/margi.conf Mon Feb 4 17:31:47 2002 @@ -0,0 +1,9 @@ +device "margi_cs" + class "margi" module "margi_cs" + +# Margi +card "MARGI-Billionton" +manfid 0x01d8, 0x1000 +bind "margi_cs" + + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/margi.h linux.19pre5-ac1/drivers/media/video/margi/margi.h --- linux.19p5/drivers/media/video/margi/margi.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/margi.h Thu Apr 4 15:55:29 2002 @@ -0,0 +1,62 @@ +/* + margi.h + + Copyright (C) Marcus Metzler for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef margi_cs_h +#define margi_cs_h + +#include "cardbase.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define PBUFFER 100 + +u_char read_indexed_register(struct cvdv_cards *card, int addr); +void write_indexed_register(struct cvdv_cards *card, int addr, + u_char data); +void WriteByte(struct cvdv_cards *card, int addr, u_char data); +u_char ReadByte(struct cvdv_cards *card, int addr); +void MaskByte(struct cvdv_cards *card, int addr, u_char mask, u_char bits); +int MargiFreeBuffers(struct cvdv_cards *card); +int MargiSetBuffers(struct cvdv_cards *card, uint32_t size, int isB); +int MargiFlush (struct cvdv_cards *card); +int MargiPushA(struct cvdv_cards *card, int count, const char *data); +int MargiPushB(struct cvdv_cards *card, int count, const char *data); +int DecoderStartChannel(struct cvdv_cards *card); +int DecoderStopChannel(struct cvdv_cards *card); +void DACSetFrequency(struct cvdv_cards *card, int khz, int multiple); +stream_type get_stream_type(struct cvdv_cards *card); +audio_type get_audio_type(struct cvdv_cards *card); + +#ifdef NOINT +void Timerfunction(unsigned long data); +#endif + + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/margi.opts linux.19pre5-ac1/drivers/media/video/margi/margi.opts --- linux.19p5/drivers/media/video/margi/margi.opts Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/margi.opts Mon Feb 4 17:31:47 2002 @@ -0,0 +1,4 @@ +# +# Option for margi +# + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/margi_cs.4 linux.19pre5-ac1/drivers/media/video/margi/margi_cs.4 --- linux.19p5/drivers/media/video/margi/margi_cs.4 Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/margi_cs.4 Mon Feb 4 17:31:47 2002 @@ -0,0 +1,34 @@ +.\" Copyright (c) 1997,1998,1999 Koji OKAMURA +.\" +.TH ISCC_CS 4 "1997/09/28" "" +.SH NAME +iscc_cs \- IBM Smart Capture Card device driver +.SH SYNOPSIS +.B insmod iscc_cs.o +.RB [ pc_debug=n ] +.RB [ mem_speed=n ] +.SH DESCRIPTION +.B Iscc_cs +is the low-level Card Services driver for the IBM Smart Capture Card +PCMCIA Video Capture adapter. When this driver is attached to a card, it +allocates the next available Video Capture Card device +.RB ( iscc0 .. iscc# ). +This +device name will be reported in the kernel log file, and passed on to +.BR cardmgr (8). +.SH PARAMETERS +.TP +.B pc_debug=n +Selects the PCMCIA debugging level. This parameter is only available +if the module is compiled with debugging enabled. A non-zero value +enables debugging. +.TP +.B mem_speed=n +Sets the access speed of the shared memory window, in nanoseconds. +The default is 0 (i.e., no extra wait states). Values of up to 1000 +are legal. +.SH AUTHOR +Koji OKAMURA \- Kyushu University + +.SH "SEE ALSO" +cardmgr(8), pcmcia(5). diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/margi_cs.mk linux.19pre5-ac1/drivers/media/video/margi/margi_cs.mk --- linux.19p5/drivers/media/video/margi/margi_cs.mk Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/margi_cs.mk Mon Feb 4 17:31:47 2002 @@ -0,0 +1,113 @@ +# +# Makefile for margi_cs +# Marcus Metzler +# + +include ../config.mk + +CC = $(KCC) $(AFLAGS) $(KFLAGS) + +CFLAGS += -g -O2 -Wall -Wstrict-prototypes -pipe -Wall -D__DVB_PACK__ -DUSE_OSD -DNOINT -DDVB -DUSE_ZV + +CPPFLAGS += $(PCDEBUG) -D__KERNEL__ -DMODULE -DMODVERSIONS -I../include \ + -I$(LINUX)/include -I$(LINUX) -Iinclude + +CC_MODULE = $(CC) -c $(CFLAGS) $(CPPFLAGS) + +ETC = $(PREFIX)/etc/pcmcia +MANDIR = $(PREFIX)/usr/man +MX_OBJS = dmxdev.o dvb_demux.o dvbdev.o + +all: margi_cs.o $(MX_OBJS) + +install-modules: $(MODULES) $(MX_OBJS) + mkdir -p $(PREFIX)/$(MODDIR)/pcmcia + cp $(MODULES) $(PREFIX)/$(MODDIR)/pcmcia + su -c "mkdir -p $(MODDIR)/misc; cp -v $(MX_OBJS) $(MX_OBJS) $(MODDIR)/misc" + +install-clients: + for f in $(CLIENTS) ; do \ + [ -r $$f.conf ] && cp $$f.conf $(ETC)/$$f.conf ; \ + cmp -s $$f $(ETC)/$$f && continue ; \ + [ -r $(ETC)/$$f ] && mv $(ETC)/$$f $(ETC)/$$f.O ; \ + cp $$f $(ETC)/$$f ; \ + OPTS=$(ETC)/$$f.opts ; \ + test -r $$OPTS || cp $$f.opts $$OPTS ; \ + done + cp cvdvext.h cvdvtypes.h /usr/include/linux + mkdir -p /usr/include/ost/ + cp include/ost/*.h /usr/include/ost + rm -rf /dev/ost + makedev.napi + depmod -a + +install-man4: $(MAN4) + mkdir -p $(MANDIR)/man4 + cp $(MAN4) $(MANDIR)/man4 + + +MMODULES = margi.o cvdv.o cardbase.o i2c.o dram.o osd.o audio.o video.o streams.o decoder.o spu.o crc.o ringbuffy.o dvb_formats.o + +margi_cs.o: $(MMODULES) + $(LD) -r -o margi_cs.o $(MMODULES) + chmod -x margi_cs.o + + +margi.o: margi.h cardbase.h l64014.h l64021.h i2c.h decoder.h dram.h\ + video.h cvdv.h margi.c + $(CC_MODULE) margi.c + +cvdv.o: cvdv.c cvdv.h cardbase.h cvdvtypes.h l64021.h l64014.h dram.h\ + osd.h audio.h video.h streams.h decoder.h spu.h \ + crc.h + $(CC_MODULE) cvdv.c + +cardbase.o: cardbase.c cardbase.h cvdvtypes.h + $(CC_MODULE) cardbase.c + +i2c.o: i2c.c i2c.h cardbase.h cvdvtypes.h l64014.h + $(CC_MODULE) i2c.c + +dram.o: dram.c dram.h cardbase.h cvdvtypes.h l64021.h l64014.h + $(CC_MODULE) dram.c + +osd.o: osd.c osd.h cardbase.h cvdvtypes.h dram.h l64021.h l64014.h + $(CC_MODULE) osd.c + +audio.o: audio.c audio.h cardbase.h cvdvtypes.h l64021.h l64014.h + $(CC_MODULE) audio.c + +video.o: video.c video.h cardbase.h cvdvtypes.h dram.h l64021.h l64014.h + $(CC_MODULE) video.c + +streams.o: streams.c streams.h cardbase.h cvdvtypes.h dram.h l64021.h l64014.h \ +video.h dram.h audio.h + $(CC_MODULE) streams.c + +decoder.o: decoder.c decoder.h cardbase.h cvdvtypes.h dram.h l64021.h l64014.h \ +video.h dram.h audio.h streams.h i2c.h osd.h dram.h + $(CC_MODULE) decoder.c + +spu.o: spu.c spu.h cardbase.h cvdvtypes.h l64021.h l64014.h + $(CC_MODULE) spu.c + +crc.o: crc.c crc.h + $(CC_MODULE) crc.c + +ringbuffy.o: ringbuffy.h ringbuffy.c + $(CC_MODULE) ringbuffy.c + +dvb_formats.o: dvb_formats.h dvb_formats.c + $(CC_MODULE) dvb_formats.c + +dmxdev.o: dmxdev.h dvb_demux.h + $(CC_MODULE) -include $(LINUX)/include/linux/modversions.h dmxdev.c + +dvb_demux.o: dvb_demux.h dmxdev.h dvbdev.h + $(CC_MODULE) -include $(LINUX)/include/linux/modversions.h dvb_demux.c + +dvbdev.o: dvbdev.h + $(CC_MODULE) -include $(LINUX)/include/linux/modversions.h -DEXPORT_SYMTAB -c dvbdev.c + +clean: + rm -f core core.* *.o .*.o *.s *.a *~ .depend .depfiles/*.d diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/margi_cs.mk.MAIN linux.19pre5-ac1/drivers/media/video/margi/margi_cs.mk.MAIN --- linux.19p5/drivers/media/video/margi/margi_cs.mk.MAIN Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/margi_cs.mk.MAIN Mon Feb 4 17:31:47 2002 @@ -0,0 +1,43 @@ +# +# Makefile for margi_cs +# Marcus Metzler +# + +VER = 0.5.0 + +FILES = margi_cs.mk margi2/margi_cs.mk \ + margi2/margi margi2/margi.opts margi2/margi.conf margi2/margi_cs.4\ + margi2/audio.c margi2/audio.h margi2/cardbase.c margi2/cardbase.h\ + margi2/crc.c margi2/crc.h margi2/cvdv.c\ + margi2/cvdv.h margi2/cvdvtypes.h margi2/decoder.c margi2/decoder.h\ + margi2/dram.c margi2/dram.h margi2/i2c.c margi2/i2c.h margi2/l64014.h\ + margi2/l64021.h margi2/margi.c margi2/margi.h margi2/video.c \ + margi2/video.h \ + margi2/osd.c margi2/osd.h margi2/spu.c margi2/spu.h margi2/streams.c\ + margi2/streams.h margi2/ringbuffy.c margi2/ringbuffy.h \ + margi2/README margi2/COPYING margi2/AUTHORS margi2/CHANGES\ + margi2/cvdvext.h\ + margi2/testsuite/Makefile margi2/testsuite/cvdvutil.c \ + margi2/testsuite/cvdvutil.h margi2/testsuite/osdtest.c \ + margi2/testsuite/osdwrap.c margi2/testsuite/osdwrap.h \ + margi2/testsuite/showpic.c margi2/testsuite/showpicmovie.c\ + margi2/testsuite/showstill.c margi2/testsuite/testpattern.c\ + margi2/testsuite/showstill.c margi2/testsuite/playfile.c\ + margi2/include/ost/audio.h margi2/include/ost/video.h \ + margi2/include/ost/ca.h margi2/include/ost/demux.h\ + margi2/include/ost/dmx.h margi2/include/ost/frontend.h\ + margi2/dvb_demux.h margi2/dvb_demux.c margi2/dvbdev.h margi2/dvbdev.c\ + margi2/include/ost/sec.h margi2/dmxdev.h margi2/dmxdev.c \ + margi2/include/ost/osd.h margi2/dvb_formats.h margi2/dvb_formats.c + +all: + $(MAKE) -C margi2 -f margi_cs.mk + +install: + $(MAKE) -C margi2 install-modules MODULES="margi_cs.o" -f margi_cs.mk + $(MAKE) -C margi2 install-clients CLIENTS=margi -f margi_cs.mk + $(MAKE) -C margi2 install-man4 MAN4=margi_cs.4 -f margi_cs.mk + +dist: + tar czvf margi_cs-$(VER).tar.gz $(FILES) + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/osd.c linux.19pre5-ac1/drivers/media/video/margi/osd.c --- linux.19p5/drivers/media/video/margi/osd.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/osd.c Mon Feb 4 22:21:10 2002 @@ -0,0 +1,947 @@ +/* + osd.c + + Copyright (C) Christian Wolff for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the 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. +*/ + + //////////////////////////////////////////////////////////////// + // // + // Functions to Draw on the On Screen Display of the L64021 // + // CLUT-Mode with 2, 4, or 8 bit per pixel, up to 720*576 // + // // +//////////////////////////////////////////////////////////////// +// OSD Pixel Aspect Ratio: +// CCIR601 525 Lines (NTSC,PAL-M): 11/10 (100*100 appears as 100*110) +// CCIR601 625 Lines (PAL): 11/12 (100*100 appears as 100*91.6) +// +// OSD functions for external use: +// int OSDOpen(struct cvdv_cards *card); +// int OSDClose(struct cvdv_cards *card); +// int OSDQuery(struct cvdv_cards *card, int *x0, int *y0, int *x1, int *y1, int *aspx, int *aspy); +// int OSDStartPicture(struct cvdv_cards *card, int left, int top, int width, int height, int bit, int mix); +// void OSDShow(struct cvdv_cards *card); +// void OSDHide(struct cvdv_cards *card); +// void OSDClear(struct cvdv_cards *card); +// void OSDFill(struct cvdv_cards *card, int col); +// int OSDSetColor(struct cvdv_cards *card, int num, int R, int G, int B, int mix, int trans); +// int OSDSetPixel(struct cvdv_cards *card, int x, int y, int col); +// int OSDGetPixel(struct cvdv_cards *card, int x, int y); +// int OSDSetRow(struct cvdv_cards *card, int x0, int y, int x1, u8 *data); +// int OSDFillRow(struct cvdv_cards *card, int x0, int y, int x1, int col); +// void OSDLine(struct cvdv_cards *card, int x0, int y0, int x1, int y1, int col); +// +// Return codes: (unless otherwise specified) +// 0: OK +// -1: Range error +// -2: OSD not open +// + +#define __NO_VERSION__ + +#include "osd.h" +#include "dram.h" +#include "l64021.h" + + // Builds a 4-word picture header in buf +// returns number of words in pixel field on success, -1 on error +int OSDHeader(u16 * buf, // 4 words + int *bit, // bit per pixel: 2, 4, or 8 + int *startrow, // position of our block, + int *stoprow, // row: 0..313 + int *startcol, // col: 0..864 + int *stopcol, // + int *mix, // opacity for mixed pixel, 0..15 (0%..94% resp.) + int nopal) +{ // 1: use previous palette + int count; + if (buf != NULL) { + if (*bit == 8) + *bit = 1; + else if (*bit == 2) + *bit = 0; + else + *bit = 2; + if (*startrow < 0) + *startrow = 0; + if (*startrow > 312) + *startrow = 312; + if (*stoprow <= *startrow) + *stoprow = *startrow + 1; + if (*stoprow > 313) + *stoprow = 313; + if (*startcol < 0) + *startcol = 0; + if (*startcol > 863) + *startcol = 863; + if (*stopcol <= *startcol) + *stopcol = *startcol + 2; + if (*stopcol > 864) + *stopcol = 864; + if ((*stopcol - *startcol + 1) & 1) + (*stopcol)--; + if (*mix < 0) + *mix = 0; + if (*mix > 15) + *mix = 15; + buf[0] = ((*bit << 14) & 0x8000) | (*startrow & 0x01FF); + buf[1] = + ((*mix << 12) & 0xF000) | ((*bit << 11) & 0x0800) | + ((nopal) ? 0x0400 : 0x0000) | (*stoprow & 0x01FF); + buf[2] = *startcol & 0x03FF; + buf[3] = *stopcol & 0x03FF; + count = + (*stoprow - *startrow + 1) * (*stopcol - *startcol + + 1); + if (*bit == 1) { + count = + ((count >> 3) + ((count & 0x07) ? 1 : 0)) << 2; + *bit = 8; + } else if (*bit == 0) { + count = + ((count >> 5) + ((count & 0x1F) ? 1 : 0)) << 2; + *bit = 2; + } else if (*bit == 2) { + count = + ((count >> 4) + ((count & 0x0F) ? 1 : 0)) << 2; + *bit = 4; + } + return count; // word count of pixel data + } else + return -1; +} + +// enables OSD mode +int OSDShow(struct cvdv_cards *card) +{ + if (card->OSD.open) { + DecoderMaskByte(card, 0x109, 0x03, 0x01); + DecoderDelByte(card, 0x112, 0x10); // no filter + return 0; + } else + return -2; +} + +// disables OSD mode +int OSDHide(struct cvdv_cards *card) +{ + if (card->OSD.open) { + DecoderMaskByte(card, 0x109, 0x03, 0x00); + return 0; + } else + return -2; +} + +// creates an empty picture in the memory of the card +// ONLY ONE PICTURE PER CARD! +// maximum sizes: NTSC: 720*525 PAL: 720*576 +// maximum positions: NTSC: 858*525 PAL: 864*625 +// returns 0 on success, -1 on DRAM allocation error +int OSDStartPicture(struct cvdv_cards *card, int left, int top, int width, + int height, int bit, int mix) +{ + u16 TermHeader[] = { 0x01FF, 0x05FF, 0x0000, 0x0000 }; + u16 header[4]; + int size, pixelsize, palsize, frametop, startrow, stoprow, + startcol, stopcol; + + if (card->OSD.open) + return -2; + if (top & 1) { + card->OSD.evenfirst = 0; + card->OSD.evenheight = height / 2; + card->OSD.oddheight = height - card->OSD.evenheight; + } else { + card->OSD.evenfirst = 1; + card->OSD.oddheight = height / 2; + card->OSD.evenheight = height - card->OSD.oddheight; + } + + // Setting the picture for the lines in the even field + frametop = top / 2; + startrow = frametop; + stoprow = frametop + card->OSD.evenheight - 1; + startcol = left; + stopcol = left + width - 1; + pixelsize = + OSDHeader(header, &bit, &startrow, &stoprow, &startcol, + &stopcol, &mix, 0); + card->OSD.evenheight = stoprow - startrow + 1; + card->OSD.bpp = bit; + if (bit == 8) + palsize = 256; + else if (bit == 2) + palsize = 4; + else + palsize = 16; + size = 8 + palsize + pixelsize; + card->OSD.evenmem = DRAMAlloc(card, size, 32); + if (card->OSD.evenmem == BLANK) + return -1; + card->OSD.evendata = card->OSD.evenmem; + card->OSD.evenpalette = card->OSD.evendata + 4; + card->OSD.evenbitmap = card->OSD.evenpalette + palsize; + card->OSD.eventerm = card->OSD.evenbitmap + pixelsize; + DecoderWriteWord(card, 0x110, (u16) (card->OSD.evendata >> 5)); + DRAMWriteWord(card, card->OSD.evendata, 4, header, 0); + DRAMFillByte(card, card->OSD.evenpalette, + (palsize + pixelsize) * 2, 0x00); + DRAMWriteWord(card, card->OSD.eventerm, 4, TermHeader, 0); + + // Setting the picture for the lines in the odd frame + frametop += card->OSD.evenfirst; + startrow = frametop; + stoprow = frametop + card->OSD.oddheight - 1; + pixelsize = + OSDHeader(header, &bit, &startrow, &stoprow, &startcol, + &stopcol, &mix, 0); + card->OSD.oddheight = stoprow - startrow + 1; + size = 8 + palsize + pixelsize; + card->OSD.oddmem = DRAMAlloc(card, size, 32); + if (card->OSD.oddmem == BLANK) + return -1; + card->OSD.odddata = card->OSD.oddmem; + card->OSD.oddpalette = card->OSD.odddata + 4; + card->OSD.oddbitmap = card->OSD.oddpalette + palsize; + card->OSD.oddterm = card->OSD.oddbitmap + pixelsize; + DecoderWriteWord(card, 0x10E, (u16) (card->OSD.odddata >> 5)); + DRAMWriteWord(card, card->OSD.odddata, 4, header, 0); + DRAMFillByte(card, card->OSD.oddpalette, (palsize + pixelsize) * 2, + 0x00); + DRAMWriteWord(card, card->OSD.oddterm, 4, TermHeader, 0); + + // Update of the picture dimensions + card->OSD.width = stopcol - startcol + 1; + card->OSD.height = card->OSD.evenheight + card->OSD.oddheight; + card->OSD.open = 1; + + MDEBUG(1,": OSD Open %dX%d, %d bit, mem 0x%08X/0x%08X\n", + card->OSD.width, card->OSD.height, card->OSD.bpp, + card->OSD.evendata, card->OSD.odddata); + return 0; +} + +// Disables OSD and releases the buffers +// returns 0 on success, 1 on "not open" +int OSDClose(struct cvdv_cards *card) +{ + if (card->OSD.open) { + OSDHide(card); + DRAMFree(card, card->OSD.evenmem); + DRAMFree(card, card->OSD.oddmem); + card->OSD.open = 0; + return 0; + } else + return -2; +} + +// Opens OSD with this size and bit depth +// returns 0 on success, 1 on DRAM allocation error, 2 on "already open" +int OSDOpen(struct cvdv_cards *card, int x0, int y0, int x1, int y1, + int bit, int mix) +{ + int ret; + if (card->OSD.open) + OSDClose(card); + if (bit < 0) + bit = 8; + else if (bit < 2) + bit = 2; + else if (bit < 4) + bit = 4; + else + bit = 8; + if (x0 < 0) + x0 = 0; + if (x1 < 0) + x1 = 720 - 1; + if (x1 < x0) + x1 = x0; + if (y0 < 0) + y0 = 0; + if (y1 < 0) + y1 = 576 - 1; + if (y1 < y0) + y1 = y0; + if ((x1 + 1) > 720) + x1 = 720 - 1; + if (x0 > x1) + x0 = x1; + if (CCIR601Lines(card->videomode) == 625) { // PAL + if ((y1 + 1) > 576) + y1 = 576 - 1; + if (y0 > y1) + y0 = y1; + if (! + (ret = + OSDStartPicture(card, 134 + x0, 48 + y0, x1 - x0 + 1, + y1 - y0 + 1, bit, mix))) + card->OSD.aspectratio = 12; // pixel aspect ratio 12/11 + } else { // NTSC + if ((y1 + 1) > 484) + y1 = 484 - 1; + if (y0 > y1) + y0 = y1; + if (! + (ret = + OSDStartPicture(card, 126 + x0, 44 + y0, x1 - x0 + 1, + y1 - y0 + 1, bit, mix))) + card->OSD.aspectratio = 10; // pixel aspect ratio 10/11 + } + return ret; +} + +// fills parameters with the picture dimensions and the pixel aspect ratio (aspy=11) +int OSDQuery(struct cvdv_cards *card, int *x0, int *y0, int *x1, int *y1, + int *aspx) +{ + if (!card->OSD.open) + return -2; + *x0 = 0; + *x1 = card->OSD.width - 1; + *y0 = 0; + *y1 = card->OSD.height - 1; + *aspx = card->OSD.aspectratio; + return 0; +} + +// Sets all pixel to color 0 +int OSDClear(struct cvdv_cards *card) +{ + if (!card->OSD.open) + return -2; + DRAMFillByte(card, card->OSD.oddbitmap, + (int) (card->OSD.oddterm - card->OSD.oddbitmap) * 2, + 0x00); + DRAMFillByte(card, card->OSD.evenbitmap, + (int) (card->OSD.eventerm - card->OSD.evenbitmap) * 2, + 0x00); + return 0; +} + +// Sets all pixel to color +int OSDFill(struct cvdv_cards *card, int col) +{ + u8 color; + if (!card->OSD.open) + return -2; + if (card->OSD.bpp == 8) { + color = col & 0xFF; + } else if (card->OSD.bpp == 4) { + color = (col & 0xF); + color |= (color << 4); + } else if (card->OSD.bpp == 2) { + color = (col & 0x03); + for (col = 1; col <= 3; col++) + color |= (color << 2); + } else + color = 0x00; + DRAMFillByte(card, card->OSD.oddbitmap, + (int) (card->OSD.oddterm - card->OSD.oddbitmap) * 2, + color); + DRAMFillByte(card, card->OSD.evenbitmap, + (int) (card->OSD.eventerm - card->OSD.evenbitmap) * 2, + color); + return 0; +} + +// converts RGB(8 bit) to YCrCb(OSD format) +// mix: 0=opacity 100% 1=opacity at mix value +// trans: 0=mix bit applies 1=opacity 0% +// returns word in OSD palette format +u16 OSDColor(u8 R, u8 G, u8 B, int mix, int trans) +{ + u16 Y, Cr, Cb; + Y = R * 77 + G * 150 + B * 29; // Luma=0.299R+0.587G+0.114B 0..65535 + Cb = 2048 + B * 8 - (Y >> 5); // Cr 0..4095 + Cr = 2048 + R * 10 - (Y >> 5); // Cb 0..4095 + return ((trans) ? 0 : // transparent pixel + (Y & 0xFC00) | // Luma 0..63 + ((mix) ? 0x0100 : 0x0000) | // Opacity applies + ((Cb >> 4) & 0x00F0) | // Cb 0..15 + ((Cr >> 8) & 0x000F) // Cr 0..15 + ); +} + +// set palette entry to , and apply +// R,G,B: 0..255 +// RGB=1: R=Red, G=Green, B=Blue RGB=0: R=Y G=Cb B=Cr +// mix=0, trans=0: pixel opacity 100% (only OSD pixel shows) +// mix=1, trans=0: pixel opacity as specified in header +// trans=1: pixel opacity 0% (only video pixel shows) +// returns 0 on success, 1 on error +int OSDSetColor(struct cvdv_cards *card, int num, int R, int G, int B, + int YUV, int mix, int trans) +{ + u16 burst[4]; // minimal memory unit + u32 addr; + u16 color; + if (!card->OSD.open) + return -2; + if (R < 0) + R = 0; + if (R > 255) + R = 255; + if (G < 0) + G = 0; + if (G > 255) + G = 255; + if (B < 0) + B = 0; + if (B > 255) + B = 255; + if ((num >= 0) && (num < (1 << card->OSD.bpp))) { + if (num==0) MDEBUG(4,"OSD SetColor num=%d, R=%d, G=%d, B=%d, YUV=%d, mix=%d, trans=%d\n", + num,R,G,B,YUV,mix,trans); + color = ((YUV) + ? ((trans) ? 0 : ((R << 8) & 0xFC00) | + ((mix) ? 0x0100 : 0x0000) | (G & 0x00F0) | + ((B >> 4) & 0x000F)) : OSDColor(R, G, B, mix, + trans)); + + addr = card->OSD.oddpalette + num; + DRAMReadWord(card, addr & ~3, 4, burst, 0); + burst[addr & 3] = color; + DRAMWriteWord(card, addr & ~3, 4, burst, 0); + + addr = card->OSD.evenpalette + num; + DRAMReadWord(card, addr & ~3, 4, burst, 0); + burst[addr & 3] = color; + DRAMWriteWord(card, addr & ~3, 4, burst, 0); + + return 0; + } else + return -1; +} + +// Set a number of entries in the palette +// sets the entries "firstcolor" through "lastcolor" from the array "data" +// data has 4 byte for each color: +// R,G,B, and a transparency value: 0->tranparent, 1..254->mix, 255->no mix +int OSDSetPalette(struct cvdv_cards *card, int firstcolor, int lastcolor, + u8 * data) +{ + u16 burst[4]; // minimal memory unit + u32 addr; + u16 color; + int num, i = 0; + if (!card->OSD.open) + return -2; + for (num = firstcolor; num <= lastcolor; num++) + if ((num >= 0) && (num < (1 << card->OSD.bpp))) { + color = + OSDColor(data[i], data[i + 1], data[i + 2], + ((data[i + 3] < 255) ? 1 : 0), + ((data[i + 3] == 0) ? 1 : 0)); + i += 4; + + addr = card->OSD.oddpalette + num; + DRAMReadWord(card, addr & ~3, 4, burst, 0); + burst[addr & 3] = color; + DRAMWriteWord(card, addr & ~3, 4, burst, 0); + + addr = card->OSD.evenpalette + num; + DRAMReadWord(card, addr & ~3, 4, burst, 0); + burst[addr & 3] = color; + DRAMWriteWord(card, addr & ~3, 4, burst, 0); + } + return 0; +} + +// Sets transparency of mixed pixel (0..15) +int OSDSetTrans(struct cvdv_cards *card, int trans) +{ + u16 burst[4]; // minimal memory unit + if (!card->OSD.open) + return -2; + trans &= 0x000F; + DRAMReadWord(card, card->OSD.evendata, 4, burst, 0); + burst[1] = (burst[1] & 0x0FFF) | (trans << 12); + DRAMWriteWord(card, card->OSD.evendata, 4, burst, 0); + + DRAMReadWord(card, card->OSD.odddata, 4, burst, 0); + burst[1] = (burst[1] & 0x0FFF) | (trans << 12); + DRAMWriteWord(card, card->OSD.odddata, 4, burst, 0); + return 0; +} + +// sets pixel , to color number +// returns 0 on success, 1 on error +int OSDSetPixel(struct cvdv_cards *card, int x, int y, int col) +{ + u16 burst[4]; // minimal memory unit od DRAM + u32 addr; + int offset, ppw, pos, shift, height, posmask; + u16 mask; + + if (!card->OSD.open) + return -2; + if ((y & 1) == card->OSD.evenfirst) { // even or odd frame? + addr = card->OSD.oddbitmap; + height = card->OSD.oddheight; + } else { + addr = card->OSD.evenbitmap; + height = card->OSD.evenheight; + } + y >>= 1; + if ((x >= 0) && (x < card->OSD.width) && (y >= 0) && (y < height)) { // clipping + ppw = + ((card->OSD.bpp == 4) ? 2 : ((card->OSD.bpp == 8) ? 1 : 3)); // OK, 4-(ln(bpp)/ln(2)) would have worked, too... + pos = x + y * card->OSD.width; // pixel number in bitfield + addr += (pos >> ppw); // 21 bit address of word with our pixel + offset = addr & 3; // offset in burst + addr &= ~3; // 21 bit burst address + posmask = (1 << ppw) - 1; // mask for position inside word + shift = ((posmask - (pos & posmask)) << (4 - ppw)); // pixel shift inside word + mask = (1 << (1 << (4 - ppw))) - 1; // pixel mask + DRAMReadWord(card, addr, 4, burst, 0); // get the burst with our pixel... + burst[offset] = + (burst[offset] & ~(mask << shift)) | ((col & mask) << + shift); + DRAMWriteWord(card, addr, 4, burst, 0); // ...and write it back + return 0; + } else + return -1; +} + +// returns color number of pixel ,, or -1 +int OSDGetPixel(struct cvdv_cards *card, int x, int y) +{ + u16 burst[4]; // minimal memory unit + u32 addr; + int offset, ppw, pos, shift, height, posmask; + u16 mask; + + if (!card->OSD.open) + return -2; + if ((y & 1) == card->OSD.evenfirst) { // even or odd frame? + addr = card->OSD.oddbitmap; + height = card->OSD.oddheight; + } else { + addr = card->OSD.evenbitmap; + height = card->OSD.evenheight; + } + y >>= 1; + if ((x >= 0) && (x < card->OSD.width) && (y >= 0) && (y < height)) { // clipping + ppw = + ((card->OSD.bpp == 4) ? 2 : ((card->OSD.bpp == 8) ? 1 : 3)); // OK, 4-(ln(bpp)/ln(2)) would have worked, too... + pos = x + y * card->OSD.width; // pixel number in bitfield + addr += (pos >> ppw); // 21 bit address of word with our pixel + offset = addr & 3; // offset in burst + addr &= ~3; // 21 bit burst address + posmask = (1 << ppw) - 1; // mask for position inside word + shift = ((posmask - (pos & posmask)) << (4 - ppw)); // pixel shift inside word + mask = (1 << (1 << (4 - ppw))) - 1; // pixel mask + DRAMReadWord(card, addr, 4, burst, 0); // get the burst with our pixel... + return (burst[offset] >> shift) & mask; // ...and return it's value + } else + return -1; +} + +// fills pixels x0,y through x1,y with the content of data[] +// returns 0 on success, -1 on clipping all pixel +int OSDSetRow(struct cvdv_cards *card, int x0, int y, int x1, u8 * data) +{ + u16 burst[4]; // minimal memory unit + u32 addr, addr1, bitmap; + int offset, offset1, ppw, pos, pos1, shift, shift0, shift1, + shiftstep, height, bpp, x, i, endburst, endword; + u16 mask, posmask; + + if (!card->OSD.open) + return -2; + if ((y & 1) == card->OSD.evenfirst) { + bitmap = card->OSD.oddbitmap; + height = card->OSD.oddheight; + } else { + bitmap = card->OSD.evenbitmap; + height = card->OSD.evenheight; + } + y >>= 1; + if ((y >= 0) && (y < height)) { + i = 0; + if (x0 > x1) { + x = x1; + x1 = x0; + x0 = x; + } + if ((x0 >= card->OSD.width) || (x1 < 0)) + return -1; + if (x0 < 0) { + i -= x0; + x0 = 0; + } + if (x1 >= card->OSD.width) + x1 = card->OSD.width - 1; + bpp = card->OSD.bpp; // bits per pixel + ppw = ((bpp == 4) ? 2 : ((bpp == 8) ? 1 : 3)); // positional parameter + mask = (1 << bpp) - 1; // mask for one pixel + posmask = (1 << ppw) - 1; // mask for position inside word + + pos = x0 + (y * card->OSD.width); // pixel number of first pixel + pos1 = pos + x1 - x0; // pixel number of last pixel + shift0 = ((posmask - (pos & posmask)) << (4 - ppw)); + shift1 = ((posmask - (pos1 & posmask)) << (4 - ppw)); + shiftstep = 1 << (4 - ppw); + + addr = bitmap + (pos >> ppw); // DRAM address of word with first pixel + addr1 = bitmap + (pos1 >> ppw); // " " " " " last " + offset = (int) (addr & 3); // word position inside burst + offset1 = (int) (addr1 & 3); // number of last word in the last burst + addr &= ~3; // burst address + addr1 &= ~3; // burst address of last pixel + + endburst = (addr1 != addr); // end in other burst + endword = (offset1 != offset); // end in other word + + // read old content of first burst if the row start after the beginning or + // end before the end of the first burst + if (offset || (pos & posmask) || + (!endburst + && ((offset1 != 3) + || ((pos1 & posmask) != posmask)))) { + DRAMReadWord(card, addr, 4, burst, 0); + } + // End beyond or at the end of this word? + if (endburst || endword || ((pos1 & posmask) == posmask)) { + // Fill first word + for (shift = shift0; shift >= 0; shift -= shiftstep) { // bit position inside word + burst[offset] = + (burst[offset] & ~(mask << shift)) | + ((data[i++] & mask) << shift); + } + if (endburst || endword) { // Any more words to fill? + shift0 = posmask << (4 - ppw); // from here on, we start at the beginning of each word + offset++; // fill the rest of the burst + if (endburst) { // end not in this burst? + while (offset <= 3) { // fill remaining words + burst[offset] = 0x0000; // clear first + for (shift = shift0; + shift >= 0; + shift -= shiftstep) { + burst[offset] |= + ((data + [i++] & mask) + << shift); + } + offset++; + } + DRAMWriteWord(card, addr, 4, burst, 0); // write first burst + addr += 4; // go on to the next burst + while (addr < addr1) { // all bursts between start and end burst + for (offset = 0; + offset <= 3; offset++) { // 4 words per burst + burst[offset] = 0x0000; // clear first + for (shift = + shift0; + shift >= 0; + shift -= + shiftstep) { + burst + [offset] + |= + ((data + [i++] + & + mask) + << + shift); + } + } + DRAMWriteWord(card, addr, + 4, burst, 0); // write full burst + addr += 4; // next burst + } + offset = 0; + if ((offset1 < 3) || shift1) { // does the row ends before the end of the burst? + DRAMReadWord(card, addr, 4, + burst, 0); // then we have to read the old content + } + } + while (offset < offset1) { // end not in this word + burst[offset] = 0x0000; // clear first + for (shift = shift0; shift >= 0; + shift -= shiftstep) { + burst[offset] |= + ((data[i++] & mask) << + shift); + } + offset++; + } + for (shift = shift0; shift >= shift1; + shift -= shiftstep) { // last word + burst[offset] = + (burst[offset] & + ~(mask << shift)) | + ((data[i++] & mask) << shift); + } + } + } else { // row starts and ends in one word + for (shift = shift0; shift >= shift1; shift -= shiftstep) { // bit position inside word + burst[offset] = + (burst[offset] & ~(mask << shift)) | + ((data[i++] & mask) << shift); + } + } + DRAMWriteWord(card, addr, 4, burst, 0); // write only/last burst + return 0; + } else + return -1; +} + +// fills pixels x0,y0 through x1,y1 with the content of data[] +// inc contains the width of one line in the data block, +// inc<=0 uses blockwidth as linewidth +// returns 0 on success, -1 on clipping all pixel +int OSDSetBlock(struct cvdv_cards *card, int x0, int y0, int x1, int y1, + int inc, u8 * data) +{ + int i, w = x1 - x0 + 1, ret = 0; + if (inc > 0) + w = inc; + for (i = y0; i <= y1; i++) { + ret |= OSDSetRow(card, x0, i, x1, data); + data += w; + } + return ret; +} + +// fills pixels x0,y through x1,y with the color +// returns 0 on success, -1 on clipping all pixel +int OSDFillRow(struct cvdv_cards *card, int x0, int y, int x1, int col) +{ + u16 burst[4]; // minimal memory unit + u32 addr, addr1, bitmap; + int offset, offset1, ppw, pos, pos1, shift, shift0, shift1, + shiftstep, height, bpp, x, i, endburst, endword; + u16 mask, posmask; + + if (!card->OSD.open) + return -2; + if ((y & 1) == card->OSD.evenfirst) { + bitmap = card->OSD.oddbitmap; + height = card->OSD.oddheight; + } else { + bitmap = card->OSD.evenbitmap; + height = card->OSD.evenheight; + } + y >>= 1; + if ((y >= 0) && (y < height)) { + i = 0; + if (x0 > x1) { + x = x1; + x1 = x0; + x0 = x; + } + if ((x0 >= card->OSD.width) || (x1 < 0)) + return -1; + if (x0 < 0) { + i -= x0; + x0 = 0; + } + if (x1 >= card->OSD.width) + x1 = card->OSD.width - 1; + bpp = card->OSD.bpp; // bits per pixel + ppw = ((bpp == 4) ? 2 : ((bpp == 8) ? 1 : 3)); // positional parameter + mask = (1 << bpp) - 1; // mask for one pixel + posmask = (1 << ppw) - 1; // mask for position inside word + + pos = x0 + (y * card->OSD.width); // pixel number of first pixel + pos1 = pos + x1 - x0; // pixel number of last pixel + shift0 = ((posmask - (pos & posmask)) << (4 - ppw)); + shift1 = ((posmask - (pos1 & posmask)) << (4 - ppw)); + shiftstep = 1 << (4 - ppw); + + addr = bitmap + (pos >> ppw); // DRAM address of word with first pixel + addr1 = bitmap + (pos1 >> ppw); // " " " " " last " + offset = (int) (addr & 3); // word position inside burst + offset1 = (int) (addr1 & 3); // number of last word in the last burst + addr &= ~3; // burst address + addr1 &= ~3; // burst address of last pixel + + endburst = (addr1 != addr); // end in other burst + endword = (offset1 != offset); // end in other word + + // read old content of first burst if the row start after the beginning or + // end before the end of the first burst + if (offset || (pos & posmask) || + (!endburst + && ((offset1 != 3) + || ((pos1 & posmask) != posmask)))) { + DRAMReadWord(card, addr, 4, burst, 0); + } + if (endburst || endword || ((pos1 & posmask) == posmask)) { // end beyond or at the end of this word? + for (shift = shift0; shift >= 0; shift -= shiftstep) { // bit position inside word + burst[offset] = + (burst[offset] & ~(mask << shift)) | + ((col & mask) << shift); + } + if (endburst || endword) { + shift0 = posmask << (4 - ppw); // from here on, we start at the beginning of each word + offset++; // fill the rest of the burst + if (endburst) { // end not in this burst? + while (offset <= 3) { // fill remaining words + burst[offset] = 0x0000; // clear first + for (shift = shift0; + shift >= 0; + shift -= shiftstep) { + burst[offset] |= + ((col & mask) + << shift); + } + offset++; + } + DRAMWriteWord(card, addr, 4, burst, 0); // write first burst + addr += 4; // next burst + while (addr < addr1) { // write all the bursts between start and end burst + for (offset = 0; + offset <= 3; offset++) { + burst[offset] = + 0x0000; + for (shift = + shift0; + shift >= 0; + shift -= + shiftstep) { + burst + [offset] + |= + ((col + & + mask) + << + shift); + } + } + DRAMWriteWord(card, addr, + 4, burst, 0); + addr += 4; + } + offset = 0; + if ((offset1 < 3) || shift1) { // does the row ends before the end of the burst? + DRAMReadWord(card, addr, 4, + burst, 0); // then we have to read the old content + } + } + while (offset < offset1) { // end not in this word + burst[offset] = 0x0000; + for (shift = shift0; shift >= 0; + shift -= shiftstep) { + burst[offset] |= + ((col & mask) << + shift); + } + offset++; + } + for (shift = shift0; shift >= shift1; + shift -= shiftstep) { + burst[offset] = + (burst[offset] & + ~(mask << shift)) | ((col & + mask) << + shift); + } + } + } else { // row starts and ends in one word + for (shift = shift0; shift >= shift1; shift -= shiftstep) { // bit position inside word + burst[offset] = + (burst[offset] & ~(mask << shift)) | + ((col & mask) << shift); + } + } + DRAMWriteWord(card, addr, 4, burst, 0); + return 0; + } else + return -1; +} + +// fills pixels x0,y0 through x1,y1 with the color +// returns 0 on success, -1 on clipping all pixel +int OSDFillBlock(struct cvdv_cards *card, int x0, int y0, int x1, int y1, + int col) +{ + int i, ret = 0; + for (i = y0; i <= y1; i++) + ret |= OSDFillRow(card, x0, i, x1, col); + return ret; +} + +// draw a line from x0,y0 to x1,y1 with the color +int OSDLine(struct cvdv_cards *card, int x0, int y0, int x1, int y1, + int col) +{ + int ct, ix, iy, ax, ay, dx, dy, off; +#define sgn(a) ((a)?(((a)>0)?1:-1):0) + if (!card->OSD.open) + return -2; + dx = x1 - x0; + dy = y1 - y0; + if (dx == 0) { + if (dy < 0) + for (iy = y1; iy <= y0; iy++) + OSDSetPixel(card, x0, iy, col); + else + for (iy = y0; iy <= y1; iy++) + OSDSetPixel(card, x0, iy, col); + } else if (dy == 0) { + OSDFillRow(card, x0, y0, x1, col); + } else { + ay = 0; + ax = 0; + ix = sgn(dx); + dx = abs(dx); + iy = sgn(dy); + dy = abs(dy); + if (dx < dy) { + off = dx; + dx = dy; + dy = off; + ay = ix; + ax = iy; + ix = 0; + iy = 0; + } + off = dx >> 1; + ct = 1; + OSDSetPixel(card, x0, y0, col); + x1 = x0; + y1 = y0; + while (dx >= ct) { + x0 += ix; + y0 += ax; + ct++; + off += dy; + if (off > dx) { + off -= dx; + x0 += ay; + y0 += iy; + } + if (ax) { + OSDSetPixel(card, x0, y0, col); + } else { + if (y0 != y1) { + OSDFillRow(card, x1, y1, x0 - ay, + col); + x1 = x0; + y1 = y0; + } + } + } + if (!ax) + OSDFillRow(card, x1, y0, x0, col); + } + return 0; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/osd.h linux.19pre5-ac1/drivers/media/video/margi/osd.h --- linux.19p5/drivers/media/video/margi/osd.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/osd.h Thu Apr 4 15:55:29 2002 @@ -0,0 +1,148 @@ +/* + osd.h + + Copyright (C) Christian Wolff for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef CVDV_OSD_H +#define CVDV_OSD_H + + //////////////////////////////////////////////////////////////// + // // + // Functions to Draw on the On Screen Display of the L64021 // + // CLUT-Mode with 2, 4, or 8 bit per pixel, up to 720*576 // + // // +//////////////////////////////////////////////////////////////// +// OSD Pixel Aspect Ratio: +// CCIR601 525 Lines (NTSC,PAL-M): 11/10 (100*100 appears as 100*110) +// CCIR601 625 Lines (PAL): 11/12 (100*100 appears as 100*91.6) +// +// OSD functions for external use: +// int OSDOpen(struct cvdv_cards *card); +// int OSDClose(struct cvdv_cards *card); +// int OSDQuery(struct cvdv_cards *card, int *x0, int *y0, int *x1, int *y1, int *aspx, int *aspy); +// int OSDStartPicture(struct cvdv_cards *card, int left, int top, int width, int height, int bit, int mix); +// void OSDShow(struct cvdv_cards *card); +// void OSDHide(struct cvdv_cards *card); +// void OSDClear(struct cvdv_cards *card); +// void OSDFill(struct cvdv_cards *card, int col); +// int OSDSetColor(struct cvdv_cards *card, int num, int R, int G, int B, int mix, int trans); +// int OSDSetPixel(struct cvdv_cards *card, int x, int y, int col); +// int OSDGetPixel(struct cvdv_cards *card, int x, int y); +// int OSDSetRow(struct cvdv_cards *card, int x0, int y, int x1, u8 *data); +// int OSDFillRow(struct cvdv_cards *card, int x0, int y, int x1, int col); +// void OSDLine(struct cvdv_cards *card, int x0, int y0, int x1, int y1, int col); +// +// Return codes: (unless otherwise specified) +// 0: OK +// -1: Range error +// -2: OSD not open +// + +#include "cardbase.h" + +// enables OSD mode +int OSDShow(struct cvdv_cards *card); + +// disables OSD mode +int OSDHide(struct cvdv_cards *card); + +// creates an empty picture in the memory of the card +// ONLY ONE PICTURE PER CARD! ( might be changed in the future, if i find time...) +// maximum sizes: NTSC: 720*525 PAL: 720*576 +// maximum positions: NTSC: 858*525 PAL: 864*625 +// returns 0 on success, -1 on DRAM allocation error +int OSDStartPicture(struct cvdv_cards *card, int left, int top, int width, + int height, int bit, int mix); + +// Disables OSD and releases the buffers +// returns 0 on success, 1 on "not open" +int OSDClose(struct cvdv_cards *card); + +// Opens OSD with this size and bit depth +// returns 0 on success, 1 on DRAM allocation error, 2 on "already open" +int OSDOpen(struct cvdv_cards *card, int x0, int y0, int x1, int y1, + int bit, int mix); + +// fills parameters with the picture dimensions and the pixel aspect ratio (aspy=11) +int OSDQuery(struct cvdv_cards *card, int *x0, int *y0, int *x1, int *y1, + int *aspx); + +// Sets all pixel to color 0 +int OSDClear(struct cvdv_cards *card); + +// Sets all pixel to color +int OSDFill(struct cvdv_cards *card, int col); + +// converts RGB(8 bit) to YCrCb(OSD format) +// mix: 0=opacity 100% 1=opacity at mix value +// trans: 0=mix bit applies 1=opacity 0% +// returns word in OSD palette format +u16 OSDColor(u8 R, u8 G, u8 B, int mix, int trans); + +// set palette entry to , and apply +// R,G,B: 0..255 +// RGB=1: R=Red, G=Green, B=Blue RGB=0: R=Y G=Cb B=Cr +// mix=0, trans=0: pixel opacity 100% (only OSD pixel shows) +// mix=1, trans=0: pixel opacity as specified in header +// trans=1: pixel opacity 0% (only video pixel shows) +// returns 0 on success, 1 on error +int OSDSetColor(struct cvdv_cards *card, int num, int R, int G, int B, + int YUV, int mix, int trans); + +// Set a number of entries in the palette +// sets the entries "firstcolor" through "lastcolor" from the array "data" +// data has 4 byte for each color: +// R,G,B, and a transparency value: 0->tranparent, 1..254->mix, 255->no mix +int OSDSetPalette(struct cvdv_cards *card, int firstcolor, int lastcolor, + u8 * data); + +// Sets transparency of mixed pixel (0..15) +int OSDSetTrans(struct cvdv_cards *card, int trans); + +// sets pixel , to color number +// returns 0 on success, 1 on error +int OSDSetPixel(struct cvdv_cards *card, int x, int y, int col); + +// returns color number of pixel ,, or -1 +int OSDGetPixel(struct cvdv_cards *card, int x, int y); + +// fills pixels x0,y through x1,y with the content of data[] +// returns 0 on success, -1 on clipping all pixel +int OSDSetRow(struct cvdv_cards *card, int x0, int y, int x1, u8 * data); + +// fills pixels x0,y0 through x1,y1 with the content of data[] +// inc contains the width of one line in the data block, +// inc<=0 uses blockwidth as linewidth +// returns 0 on success, -1 on clipping all pixel +int OSDSetBlock(struct cvdv_cards *card, int x0, int y0, int x1, int y1, + int inc, u8 * data); + +// fills pixels x0,y through x1,y with the color +// returns 0 on success, -1 on clipping all pixel +int OSDFillRow(struct cvdv_cards *card, int x0, int y, int x1, int col); + +// fills pixels x0,y0 through x1,y1 with the color +// returns 0 on success, -1 on clipping all pixel +int OSDFillBlock(struct cvdv_cards *card, int x0, int y0, int x1, int y1, + int col); + +// draw a line from x0,y0 to x1,y1 with the color +int OSDLine(struct cvdv_cards *card, int x0, int y0, int x1, int y1, + int col); + +#endif /* CVDV_OSD_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/ost/audio.h linux.19pre5-ac1/drivers/media/video/margi/ost/audio.h --- linux.19p5/drivers/media/video/margi/ost/audio.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/ost/audio.h Mon Feb 4 22:25:59 2002 @@ -0,0 +1,120 @@ +/* + * audio.h + * + * Copyright (C) 2000 Ralph Metzler + * & Marcus Metzler + for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Lesser Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _OST_AUDIO_H_ +#define _OST_AUDIO_H_ + +#ifdef __KERNEL__ +#include +#else +#include +#endif + +#define boolean int +#define true 1 +#define false 0 + +typedef enum { + AUDIO_SOURCE_DEMUX, /* Select the demux as the main source */ + AUDIO_SOURCE_MEMORY /* Select internal memory as the main source */ +} audioStreamSource_t; + +typedef enum { + AUDIO_STOPPED, /* Device is stopped */ + AUDIO_PLAYING, /* Device is currently playing */ + AUDIO_PAUSED /* Device is paused */ +} audioPlayState_t; + +typedef enum { + AUDIO_STEREO, + AUDIO_MONO_LEFT, + AUDIO_MONO_RIGHT, +} audioChannelSelect_t; + +typedef struct audioStatus { + boolean AVSyncState; /* sync audio and video? */ + boolean muteState; /* audio is muted */ + audioPlayState_t playState; /* current playback state */ + audioStreamSource_t streamSource; /* current stream source */ + audioChannelSelect_t channelSelect; /* currently selected channel */ + boolean bypassMode; /* pass on audio data to separate + decoder hardware */ +} audioStatus_t; + +typedef struct audioMixer { + unsigned int volume_left; + unsigned int volume_right; + // what else do we need? bass, pass-through, ... +} audioMixer_t; + +typedef +struct audioKaraoke{ /* if Vocal1 or Vocal2 are non-zero, they get mixed */ + int vocal1; /* into left and right t at 70% each */ + int vocal2; /* if both, Vocal1 and Vocal2 are non-zero, Vocal1 gets */ + int melody; /* mixed into the left channel and */ + /* Vocal2 into the right channel at 100% each. */ + /* if Melody is non-zero, the melody channel gets mixed */ /* into left and right */ +} audioKaraoke_t; + +typedef uint16_t audioAttributes_t; +/* bits: descr. */ +/* 15-13 audio coding mode (0=ac3, 2=mpeg1, 3=mpeg2ext, 4=LPCM, 6=DTS, */ +/* 12 multichannel extension */ +/* 11-10 audio type (0=not spec, 1=language included) */ +/* 9- 8 audio application mode (0=not spec, 1=karaoke, 2=surround) */ +/* 7- 6 Quantization / DRC (mpeg audio: 1=DRC exists)(lpcm: 0=16bit, */ +/* 5- 4 Sample frequency fs (0=48kHz, 1=96kHz) */ +/* 2- 0 number of audio channels (n+1 channels) */ + + +/* for GET_CAPABILITIES and SET_FORMAT, the latter should only set one bit */ +#define AUDIO_CAP_DTS 1 +#define AUDIO_CAP_LPCM 2 +#define AUDIO_CAP_MP1 4 +#define AUDIO_CAP_MP2 8 +#define AUDIO_CAP_MP3 16 +#define AUDIO_CAP_AAC 32 +#define AUDIO_CAP_OGG 64 +#define AUDIO_CAP_SDDS 128 +#define AUDIO_CAP_AC3 256 + +#define AUDIO_STOP _IO('o', 1) +#define AUDIO_PLAY _IO('o', 2) +#define AUDIO_PAUSE _IO('o', 3) +#define AUDIO_CONTINUE _IO('o', 4) +#define AUDIO_SELECT_SOURCE _IOW('o', 5, audioStreamSource_t) +#define AUDIO_SET_MUTE _IOW('o', 6, boolean) +#define AUDIO_SET_AV_SYNC _IOW('o', 7, boolean) +#define AUDIO_SET_BYPASS_MODE _IOW('o', 8, boolean) +#define AUDIO_CHANNEL_SELECT _IOW('o', 9, audioChannelSelect_t) +#define AUDIO_GET_STATUS _IOR('o', 10, audioStatus_t *) + +#define AUDIO_GET_CAPABILITIES _IOR('o', 11, unsigned int *) +#define AUDIO_CLEAR_BUFFER _IO('o', 12) +#define AUDIO_SET_ID _IOW('o', 13, int) +#define AUDIO_SET_MIXER _IOW('o', 14, audioMixer_t *) +#define AUDIO_SET_STREAMTYPE _IOW('o', 15, unsigned int) +#define AUDIO_SET_EXT_ID _IOW('o', 16, int) +#define AUDIO_SET_ATTRIBUTES _IOW('o', 17, audioAttributes_t) +#define AUDIO_SET_KARAOKE _IOW('o', 18, audioKaraoke_t *) +#endif /* _OST_AUDIO_H_ */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/ost/ca.h linux.19pre5-ac1/drivers/media/video/margi/ost/ca.h --- linux.19p5/drivers/media/video/margi/ost/ca.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/ost/ca.h Mon Feb 4 22:25:59 2002 @@ -0,0 +1,85 @@ +/* + * ca.h + * + * Copyright (C) 2000 Ralph Metzler + * & Marcus Metzler + for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Lesser Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _OST_CA_H_ +#define _OST_CA_H_ + +/* slot interface types and info */ + +typedef struct ca_slot_info_s { + int num; /* slot number */ + + int type; /* CA interface this slot supports */ +#define CA_CI 1 /* CI high level interface */ +#define CA_CI_LINK 2 /* CI link layer level interface */ +#define CA_CI_PHYS 4 /* CI physical layer level interface */ +#define CA_SC 128 /* simple smart card interface */ + + unsigned int flags; +#define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */ +#define CA_CI_MODULE_READY 2 +} ca_slot_info_t; + + +/* descrambler types and info */ + +typedef struct ca_descr_info_s { + unsigned int num; /* number of available descramblers (keys) */ + unsigned int type; /* type of supported scrambling system */ +#define CA_ECD 1 +#define CA_NDS 2 +#define CA_DSS 4 +} ca_descr_info_t; + +typedef struct ca_cap_s { + unsigned int slot_num; /* total number of CA card and module slots */ + unsigned int slot_type; /* OR of all supported types */ + unsigned int descr_num; /* total number of descrambler slots (keys) */ + unsigned int descr_type; /* OR of all supported types */ +} ca_cap_t; + +/* a message to/from a CI-CAM */ +typedef struct ca_msg_s { + unsigned int index; + unsigned int type; + unsigned int length; + unsigned char msg[256]; +} ca_msg_t; + +typedef struct ca_descr_s { + unsigned int index; + unsigned int parity; + unsigned char cw[8]; +} ca_descr_t; + +#define CA_RESET _IOW('o', 128, int) +#define CA_GET_CAP _IOR('o', 129, ca_cap_t *) +#define CA_GET_SLOT_INFO _IOR('o', 130, ca_slot_info_t *) +#define CA_GET_DESCR_INFO _IOR('o', 131, ca_descr_info_t *) +#define CA_GET_MSG _IOR('o', 132, ca_msg_t *) +#define CA_SEND_MSG _IOW('o', 133, ca_msg_t *) +#define CA_SET_DESCR _IOW('o', 134, ca_descr_t *) +#define CA_SELECT_SLOT _IOW('o', 135, int) + +#endif + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/ost/demux.h linux.19pre5-ac1/drivers/media/video/margi/ost/demux.h --- linux.19p5/drivers/media/video/margi/ost/demux.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/ost/demux.h Mon Feb 4 22:26:00 2002 @@ -0,0 +1,346 @@ +/* * demux.h * * Copyright (c) 2000 Nokia Research Center + * Tampere, FINLAND + * + * Project: + * Universal Broadcast Access + * + * Contains: + * Type definitions of a Linux kernel-level API for filtering MPEG-2 TS + * packets and MPEG-2 sections. Support for PES packet filtering will be + * added later. + * + * History: + * 12.01.2000/JPL File created - Initial version. + * 18.02.2000/JPL Minor corrections. + * 21.02.2000/JPL DMX_NAME_SIZE and dmx_in_use() removed, typos fixed, + * some names changed. + * 23.02.2000/JPL Added a parameter indicating the callback source in + * the callback functions. + * 10.03.2000/JPL Added the macros DMX_DIR_ENTRY() and DMX_FE_ENTRY(). + * 15.03.2000/JPL Added the capabilities field to dmx_demux_t. + * 22.03.2000/JPL Corrected the callback parameter in the + * allocate_x_feed() functions. + * 03.04.2000/JPL Added support for optional resource conflict resolution + * and scarce resource handling. + * 05.04.2000/JPL Changed the dmx_resolve_conflict() to use resource + * type as a parameter. + * 12.04.2000/JPL Added a second buffer parameter for dmx_x_callback() + * functions to better handle buffer wrapping. + * 26.04.2000/JPL Added functions for section-level descrambling. + * 03.09.2000/JPL Removed support for conflict resolution and scarce + * resource handling. Otherwise only minor changes to + * data structures and function prototypes. + * + * + * Author: + * Juha-Pekka Luoma (JPL) + * Nokia Research Center + * + * Notes: + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ +/* $Id: demux.h,v 1.14 2002/02/03 11:38:56 mocm Exp $ */ + +#ifndef __DEMUX_H +#define __DEMUX_H + +#ifndef __KERNEL__ +#define __KERNEL__ +#endif + +#include /* __u8, __u16, ... */ +#include /* list_entry(), struct list_head */ +#include /* struct timespec */ +#include /* Function return values */ + +/*--------------------------------------------------------------------------*/ +/* Common definitions */ +/*--------------------------------------------------------------------------*/ + +/* + * DMX_MAX_FILTER_SIZE: Maximum length (in bytes) of a section/PES filter. + */ + +#ifndef DMX_MAX_FILTER_SIZE +#define DMX_MAX_FILTER_SIZE 18 +#endif +/* + * dmx_success_t: Success codes for the Demux Callback API. + */ + +typedef enum { + DMX_OK = 0, /* Received Ok */ + DMX_LENGTH_ERROR, /* Incorrect length */ + DMX_OVERRUN_ERROR, /* Receiver ring buffer overrun */ + DMX_CRC_ERROR, /* Incorrect CRC */ + DMX_FRAME_ERROR, /* Frame alignment error */ + DMX_FIFO_ERROR, /* Receiver FIFO overrun */ + DMX_MISSED_ERROR /* Receiver missed packet */ +} dmx_success_t; + +/*--------------------------------------------------------------------------*/ +/* TS packet reception */ +/*--------------------------------------------------------------------------*/ + +/* TS filter type for set_type() */ + +#define TS_PACKET 1 /* send TS packets (188 bytes) to callback (default) */ +#define TS_PAYLOAD_ONLY 2 /* in case TS_PACKET is set, only send the TS + payload (<=184 bytes per packet) to callback */ +#define TS_DECODER 4 /* send stream to built-in decoder (if present) */ + +/* PES type for filters which write to built-in decoder */ +/* these should be kept identical to the types in dmx.h */ + +typedef enum +{ + DMX_TS_PES_AUDIO, /* also send packets to audio decoder (if it exists) */ + DMX_TS_PES_VIDEO, /* ... */ + DMX_TS_PES_TELETEXT, + DMX_TS_PES_SUBTITLE, + DMX_TS_PES_PCR, + DMX_TS_PES_OTHER, +} dmx_ts_pes_t; + + +struct dmx_ts_feed_s { + int is_filtering; /* Set to non-zero when filtering in progress */ + struct dmx_demux_s* parent; /* Back-pointer */ + void* priv; /* Pointer to private data of the API client */ + int (*set) (struct dmx_ts_feed_s* feed, + __u16 pid, + size_t callback_length, + size_t circular_buffer_size, + int descramble, + struct timespec timeout); + int (*start_filtering) (struct dmx_ts_feed_s* feed); + int (*stop_filtering) (struct dmx_ts_feed_s* feed); + int (*set_type) (struct dmx_ts_feed_s* feed, + int type, + dmx_ts_pes_t pes_type); +}; + +typedef struct dmx_ts_feed_s dmx_ts_feed_t; + +/*--------------------------------------------------------------------------*/ +/* PES packet reception (not supported yet) */ +/*--------------------------------------------------------------------------*/ + +typedef struct dmx_pes_filter_s { + struct dmx_pes_s* parent; /* Back-pointer */ + void* priv; /* Pointer to private data of the API client */ +} dmx_pes_filter_t; + +typedef struct dmx_pes_feed_s { + int is_filtering; /* Set to non-zero when filtering in progress */ + struct dmx_demux_s* parent; /* Back-pointer */ + void* priv; /* Pointer to private data of the API client */ + int (*set) (struct dmx_pes_feed_s* feed, + __u16 pid, + size_t circular_buffer_size, + int descramble, + struct timespec timeout); + int (*start_filtering) (struct dmx_pes_feed_s* feed); + int (*stop_filtering) (struct dmx_pes_feed_s* feed); + int (*allocate_filter) (struct dmx_pes_feed_s* feed, + dmx_pes_filter_t** filter); + int (*release_filter) (struct dmx_pes_feed_s* feed, + dmx_pes_filter_t* filter); +} dmx_pes_feed_t; + +/*--------------------------------------------------------------------------*/ +/* Section reception */ +/*--------------------------------------------------------------------------*/ + +typedef struct { + __u8 filter_value [DMX_MAX_FILTER_SIZE]; + __u8 filter_mask [DMX_MAX_FILTER_SIZE]; + struct dmx_section_feed_s* parent; /* Back-pointer */ + void* priv; /* Pointer to private data of the API client */ +} dmx_section_filter_t; + +struct dmx_section_feed_s { + int is_filtering; /* Set to non-zero when filtering in progress */ + struct dmx_demux_s* parent; /* Back-pointer */ + void* priv; /* Pointer to private data of the API client */ + int (*set) (struct dmx_section_feed_s* feed, + __u16 pid, + size_t circular_buffer_size, + int descramble, + int check_crc); + int (*allocate_filter) (struct dmx_section_feed_s* feed, + dmx_section_filter_t** filter); + int (*release_filter) (struct dmx_section_feed_s* feed, + dmx_section_filter_t* filter); + int (*start_filtering) (struct dmx_section_feed_s* feed); + int (*stop_filtering) (struct dmx_section_feed_s* feed); +}; +typedef struct dmx_section_feed_s dmx_section_feed_t; + +/*--------------------------------------------------------------------------*/ +/* Callback functions */ +/*--------------------------------------------------------------------------*/ + +typedef int (*dmx_ts_cb) ( __u8 * buffer1, + size_t buffer1_length, + __u8 * buffer2, + size_t buffer2_length, + dmx_ts_feed_t* source, + dmx_success_t success); + +typedef int (*dmx_section_cb) ( __u8 * buffer1, + size_t buffer1_len, + __u8 * buffer2, + size_t buffer2_len, + dmx_section_filter_t * source, + dmx_success_t success); + +typedef int (*dmx_pes_cb) ( __u8 * buffer1, + size_t buffer1_len, + __u8 * buffer2, + size_t buffer2_len, + dmx_pes_filter_t* source, + dmx_success_t success); + +/*--------------------------------------------------------------------------*/ +/* DVB Front-End */ +/*--------------------------------------------------------------------------*/ + +typedef enum { + DMX_OTHER_FE = 0, + DMX_SATELLITE_FE, + DMX_CABLE_FE, + DMX_TERRESTRIAL_FE, + DMX_LVDS_FE, + DMX_ASI_FE, /* DVB-ASI interface */ + DMX_MEMORY_FE +} dmx_frontend_source_t; + +typedef struct { + /* The following char* fields point to NULL terminated strings */ + char* id; /* Unique front-end identifier */ + char* vendor; /* Name of the front-end vendor */ + char* model; /* Name of the front-end model */ + struct list_head connectivity_list; /* List of front-ends that can + be connected to a particular + demux */ + void* priv; /* Pointer to private data of the API client */ + dmx_frontend_source_t source; +} dmx_frontend_t; + +/*--------------------------------------------------------------------------*/ +/* MPEG-2 TS Demux */ +/*--------------------------------------------------------------------------*/ + +/* + * Flags OR'ed in the capabilites field of struct dmx_demux_s. + */ + +#define DMX_TS_FILTERING 1 +#define DMX_PES_FILTERING 2 +#define DMX_SECTION_FILTERING 4 +#define DMX_MEMORY_BASED_FILTERING 8 /* write() available */ +#define DMX_CRC_CHECKING 16 +#define DMX_TS_DESCRAMBLING 32 +#define DMX_SECTION_PAYLOAD_DESCRAMBLING 64 +#define DMX_MAC_ADDRESS_DESCRAMBLING 128 + +/* + * Demux resource type identifier. +*/ + +/* + * DMX_FE_ENTRY(): Casts elements in the list of registered + * front-ends from the generic type struct list_head + * to the type * dmx_frontend_t + *. +*/ + +#define DMX_FE_ENTRY(list) list_entry(list, dmx_frontend_t, connectivity_list) + +struct dmx_demux_s { + /* The following char* fields point to NULL terminated strings */ + char* id; /* Unique demux identifier */ + char* vendor; /* Name of the demux vendor */ + char* model; /* Name of the demux model */ + __u32 capabilities; /* Bitfield of capability flags */ + dmx_frontend_t* frontend; /* Front-end connected to the demux */ + struct list_head reg_list; /* List of registered demuxes */ + void* priv; /* Pointer to private data of the API client */ + int users; /* Number of users */ + int (*open) (struct dmx_demux_s* demux); + int (*close) (struct dmx_demux_s* demux); + int (*write) (struct dmx_demux_s* demux, const char* buf, size_t count); + int (*allocate_ts_feed) (struct dmx_demux_s* demux, + dmx_ts_feed_t** feed, + dmx_ts_cb callback); + int (*release_ts_feed) (struct dmx_demux_s* demux, + dmx_ts_feed_t* feed); + int (*allocate_pes_feed) (struct dmx_demux_s* demux, + dmx_pes_feed_t** feed, + dmx_pes_cb callback); + int (*release_pes_feed) (struct dmx_demux_s* demux, + dmx_pes_feed_t* feed); + int (*allocate_section_feed) (struct dmx_demux_s* demux, + dmx_section_feed_t** feed, + dmx_section_cb callback); + int (*release_section_feed) (struct dmx_demux_s* demux, + dmx_section_feed_t* feed); + int (*descramble_mac_address) (struct dmx_demux_s* demux, + __u8* buffer1, + size_t buffer1_length, + __u8* buffer2, + size_t buffer2_length, + __u16 pid); + int (*descramble_section_payload) (struct dmx_demux_s* demux, + __u8* buffer1, + size_t buffer1_length, + __u8* buffer2, size_t buffer2_length, + __u16 pid); + int (*add_frontend) (struct dmx_demux_s* demux, + dmx_frontend_t* frontend); + int (*remove_frontend) (struct dmx_demux_s* demux, + dmx_frontend_t* frontend); + struct list_head* (*get_frontends) (struct dmx_demux_s* demux); + int (*connect_frontend) (struct dmx_demux_s* demux, + dmx_frontend_t* frontend); + int (*disconnect_frontend) (struct dmx_demux_s* demux); + + + /* added because js cannot keep track of these himself */ + int (*get_pes_pids) (struct dmx_demux_s* demux, __u16 *pids); +}; +typedef struct dmx_demux_s dmx_demux_t; + +/*--------------------------------------------------------------------------*/ +/* Demux directory */ +/*--------------------------------------------------------------------------*/ + +/* + * DMX_DIR_ENTRY(): Casts elements in the list of registered + * demuxes from the generic type struct list_head* to the type dmx_demux_t + *. + */ + +#define DMX_DIR_ENTRY(list) list_entry(list, dmx_demux_t, reg_list) + +int dmx_register_demux (dmx_demux_t* demux); +int dmx_unregister_demux (dmx_demux_t* demux); +struct list_head* dmx_get_demuxes (void); + +#endif /* #ifndef __DEMUX_H */ + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/ost/dmx.h linux.19pre5-ac1/drivers/media/video/margi/ost/dmx.h --- linux.19p5/drivers/media/video/margi/ost/dmx.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/ost/dmx.h Mon Feb 4 22:26:00 2002 @@ -0,0 +1,147 @@ +/* + * dmx.h + * + * Copyright (C) 2000 Marcus Metzler + * & Ralph Metzler + for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _OST_DMX_H_ +#define _OST_DMX_H_ + +#ifdef __KERNEL__ +#include +#else +#include +#endif + +#ifndef EBUFFEROVERFLOW +#define EBUFFEROVERFLOW 769 +#endif + +typedef uint16_t dvb_pid_t; + +#define DMX_FILTER_SIZE 16 + +typedef enum +{ + DMX_OUT_DECODER, /* Streaming directly to decoder. */ + DMX_OUT_TAP, /* Output going to a memory buffer */ + /* (to be retrieved via the read command).*/ + DMX_OUT_TS_TAP /* Output multiplexed into a new TS */ + /* (to be retrieved by reading from the */ + /* logical DVR device). */ +} dmxOutput_t; + + +typedef enum +{ + DMX_IN_FRONTEND, /* Input from a front-end device. */ + DMX_IN_DVR /* Input from the logical DVR device. */ +} dmxInput_t; + + +typedef enum +{ + DMX_PES_AUDIO, + DMX_PES_VIDEO, + DMX_PES_TELETEXT, + DMX_PES_SUBTITLE, + DMX_PES_PCR, + DMX_PES_OTHER +} dmxPesType_t; + + +typedef enum +{ + DMX_SCRAMBLING_EV, + DMX_FRONTEND_EV +} dmxEvent_t; + + +typedef enum +{ + DMX_SCRAMBLING_OFF, + DMX_SCRAMBLING_ON +} dmxScramblingStatus_t; + + +typedef struct dmxFilter +{ + uint8_t filter[DMX_FILTER_SIZE]; + uint8_t mask[DMX_FILTER_SIZE]; +} dmxFilter_t; + + +struct dmxFrontEnd +{ + +}; + + +struct dmxSctFilterParams +{ + dvb_pid_t pid; + dmxFilter_t filter; + uint32_t timeout; + uint32_t flags; +#define DMX_CHECK_CRC 1 +#define DMX_ONESHOT 2 +#define DMX_IMMEDIATE_START 4 +#define DMX_KERNEL_CLIENT 0x8000 +}; + + +struct dmxPesFilterParams +{ + dvb_pid_t pid; + dmxInput_t input; + dmxOutput_t output; + dmxPesType_t pesType; + uint32_t flags; +}; + + +struct dmxEvent +{ + dmxEvent_t event; + time_t timeStamp; + union + { + dmxScramblingStatus_t scrambling; + } u; +}; + + +typedef struct dmxCaps_s +{ + uint32_t caps; /* */ + int num_decoders; +} dmxCaps_t; + + +#define DMX_START _IOW('o',41,int) +#define DMX_STOP _IOW('o',42,int) +#define DMX_SET_FILTER _IOW('o',43,struct dmxSctFilterParams *) +#define DMX_SET_PES_FILTER _IOW('o',44,struct dmxPesFilterParams *) +#define DMX_SET_BUFFER_SIZE _IOW('o',45,unsigned long) +#define DMX_GET_EVENT _IOR('o',46,struct dmxEvent *) +#define DMX_GET_PES_PIDS _IOR('o',47,dvb_pid_t *) +#define DMX_GET_CAPS _IOR('o',48,dmxCaps_t *) + +#endif /*_OST_DMX_H_*/ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/ost/frontend.h linux.19pre5-ac1/drivers/media/video/margi/ost/frontend.h --- linux.19p5/drivers/media/video/margi/ost/frontend.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/ost/frontend.h Mon Feb 4 22:26:00 2002 @@ -0,0 +1,208 @@ +/* + * frontend.h + * + * Copyright (C) 2000 Marcus Metzler + * & Ralph Metzler + * for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _FRONTEND_H_ +#define _FRONTEND_H_ + +#include + + +#define ENOSIGNAL 768 +#ifndef EBUFFEROVERFLOW +#define EBUFFEROVERFLOW 769 +#endif + + +typedef __u32 FrontendStatus; + +/* bit definitions for FrontendStatus */ +#define FE_HAS_POWER 1 +#define FE_HAS_SIGNAL 2 +#define FE_SPECTRUM_INV 4 +#define FE_HAS_LOCK 8 +#define FE_HAS_CARRIER 16 +#define FE_HAS_VITERBI 32 +#define FE_HAS_SYNC 64 +#define FE_TUNER_HAS_LOCK 128 + + +/* possible values for spectral inversion */ +typedef enum { + INVERSION_OFF, + INVERSION_ON, + INVERSION_AUTO +} SpectralInversion; + +/* possible values for FEC_inner/FEC_outer */ +typedef enum { + FEC_AUTO, + FEC_1_2, + FEC_2_3, + FEC_3_4, + FEC_5_6, + FEC_7_8, + FEC_NONE +} CodeRate; + + +typedef enum { + QPSK, + QAM_16, + QAM_32, + QAM_64, + QAM_128, + QAM_256 +} Modulation; + + +typedef enum { + TRANSMISSION_MODE_2K, + TRANSMISSION_MODE_8K +} TransmitMode; + +typedef enum { + BANDWIDTH_8_MHZ, + BANDWIDTH_7_MHZ, + BANDWIDTH_6_MHZ +} BandWidth; + + +typedef enum { + GUARD_INTERVAL_1_32, + GUARD_INTERVAL_1_16, + GUARD_INTERVAL_1_8, + GUARD_INTERVAL_1_4 +} GuardInterval; + + +typedef enum { + HIERARCHY_NONE, + HIERARCHY_1, + HIERARCHY_2, + HIERARCHY_4 +} Hierarchy; + + +typedef struct { + __u32 SymbolRate; /* symbol rate in Symbols per second */ + CodeRate FEC_inner; /* forward error correction (see above) */ +} QPSKParameters; + + +typedef struct { + __u32 SymbolRate; /* symbol rate in Symbols per second */ + CodeRate FEC_inner; /* forward error correction (see above) */ + Modulation QAM; /* modulation type (see above) */ +} QAMParameters; + + +typedef struct { + BandWidth bandWidth; + CodeRate HP_CodeRate; /* high priority stream code rate */ + CodeRate LP_CodeRate; /* low priority stream code rate */ + Modulation Constellation; /* modulation type (see above) */ + TransmitMode TransmissionMode; + GuardInterval guardInterval; + Hierarchy HierarchyInformation; +} OFDMParameters; + + +typedef enum { + FE_QPSK, + FE_QAM, + FE_OFDM +} FrontendType; + + +typedef struct { + __u32 Frequency; /* (absolute) frequency in Hz for QAM/OFDM */ + /* intermediate frequency in kHz for QPSK */ + SpectralInversion Inversion; /* spectral inversion */ + union { + QPSKParameters qpsk; + QAMParameters qam; + OFDMParameters ofdm; + } u; +} FrontendParameters; + + +typedef enum { + FE_UNEXPECTED_EV, /* unexpected event (e.g. loss of lock) */ + FE_COMPLETION_EV, /* completion event, tuning succeeded */ + FE_FAILURE_EV /* failure event, we couldn't tune */ +} EventType; + + +typedef struct { + EventType type; /* type of event, FE_UNEXPECTED_EV, ... */ + + long timestamp; /* time in seconds since 1970-01-01 */ + + union { + struct { + FrontendStatus previousStatus; /* status before event */ + FrontendStatus currentStatus; /* status during event */ + } unexpectedEvent; + FrontendParameters completionEvent; /* parameters for which the + tuning succeeded */ + FrontendStatus failureEvent; /* status at failure (e.g. no lock) */ + } u; +} FrontendEvent; + +typedef struct { + FrontendType type; + __u32 minFrequency; + __u32 maxFrequency; + __u32 maxSymbolRate; + __u32 minSymbolRate; + __u32 hwType; + __u32 hwVersion; +} FrontendInfo; + + +typedef enum { + FE_POWER_ON, + FE_POWER_STANDBY, + FE_POWER_SUSPEND, + FE_POWER_OFF +} FrontendPowerState; + + +#define FE_SELFTEST _IO('o', 61) +#define FE_SET_POWER_STATE _IOW('o', 62, FrontendPowerState) +#define FE_GET_POWER_STATE _IOR('o', 63, FrontendPowerState*) +#define FE_READ_STATUS _IOR('o', 64, FrontendStatus*) +#define FE_READ_BER _IOW('o', 65, __u32*) +#define FE_READ_SIGNAL_STRENGTH _IOR('o', 66, __s32*) +#define FE_READ_SNR _IOR('o', 67, __s32*) +#define FE_READ_UNCORRECTED_BLOCKS _IOW('o', 68, __u32*) +#define FE_GET_NEXT_FREQUENCY _IOW('o', 69, __u32*) +#define FE_GET_NEXT_SYMBOL_RATE _IOW('o', 70, __u32*) + +#define FE_SET_FRONTEND _IOW('o', 71, FrontendParameters*) +#define FE_GET_FRONTEND _IOR('o', 72, FrontendParameters*) +#define FE_GET_INFO _IOR('o', 73, FrontendInfo*) +#define FE_GET_EVENT _IOR('o', 74, FrontendEvent*) + +#endif /*_FRONTEND_H_*/ + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/ost/net.h linux.19pre5-ac1/drivers/media/video/margi/ost/net.h --- linux.19p5/drivers/media/video/margi/ost/net.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/ost/net.h Mon Feb 4 22:26:00 2002 @@ -0,0 +1,40 @@ +/* + * net.h + * + * Copyright (C) 2000 Marcus Metzler + * & Ralph Metzler + for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _OST_NET_H_ +#define _OST_NET_H_ + +#ifdef __KERNEL__ +#include +#else +#include +#endif + +struct dvb_net_if { + uint16_t pid; + uint16_t if_num; +}; + +#define NET_ADD_IF _IOWR('o', 52, struct dvb_net_if *) +#define NET_REMOVE_IF _IOW('o', 53, uint16_t) +#endif /*_OST_VIDEO_H_*/ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/ost/osd.h linux.19pre5-ac1/drivers/media/video/margi/ost/osd.h --- linux.19p5/drivers/media/video/margi/ost/osd.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/ost/osd.h Mon Feb 4 22:26:01 2002 @@ -0,0 +1,111 @@ +/* + * osd.h + * + * Copyright (C) 2001 Ralph Metzler + * & Marcus Metzler + for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Lesser Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _OST_OSD_H_ +#define _OST_OSD_H_ + +typedef enum { + // All functions return -2 on "not open" + OSD_Close=1, // () + // Disables OSD and releases the buffers + // returns 0 on success + OSD_Open, // (x0,y0,x1,y1,BitPerPixel[2/4/8](color&0x0F),mix[0..15](color&0xF0)) + // Opens OSD with this size and bit depth + // returns 0 on success, -1 on DRAM allocation error, -2 on "already open" + OSD_Show, // () + // enables OSD mode + // returns 0 on success + OSD_Hide, // () + // disables OSD mode + // returns 0 on success + OSD_Clear, // () + // Sets all pixel to color 0 + // returns 0 on success + OSD_Fill, // (color) + // Sets all pixel to color + // returns 0 on success + OSD_SetColor, // (color,R{x0},G{y0},B{x1},opacity{y1}) + // set palette entry to , and apply + // R,G,B: 0..255 + // R=Red, G=Green, B=Blue + // opacity=0: pixel opacity 0% (only video pixel shows) + // opacity=1..254: pixel opacity as specified in header + // opacity=255: pixel opacity 100% (only OSD pixel shows) + // returns 0 on success, -1 on error + OSD_SetPalette, // (firstcolor{color},lastcolor{x0},data) + // Set a number of entries in the palette + // sets the entries "firstcolor" through "lastcolor" from the array "data" + // data has 4 byte for each color: + // R,G,B, and a opacity value: 0->transparent, 1..254->mix, 255->pixel + OSD_SetTrans, // (transparency{color}) + // Sets transparency of mixed pixel (0..15) + // returns 0 on success + OSD_SetPixel, // (x0,y0,color) + // sets pixel , to color number + // returns 0 on success, -1 on error + OSD_GetPixel, // (x0,y0) + // returns color number of pixel ,, or -1 + OSD_SetRow, // (x0,y0,x1,data) + // fills pixels x0,y through x1,y with the content of data[] + // returns 0 on success, -1 on clipping all pixel (no pixel drawn) + OSD_SetBlock, // (x0,y0,x1,y1,increment{color},data) + // fills pixels x0,y0 through x1,y1 with the content of data[] + // inc contains the width of one line in the data block, + // inc<=0 uses blockwidth as linewidth + // returns 0 on success, -1 on clipping all pixel + OSD_FillRow, // (x0,y0,x1,color) + // fills pixels x0,y through x1,y with the color + // returns 0 on success, -1 on clipping all pixel + OSD_FillBlock, // (x0,y0,x1,y1,color) + // fills pixels x0,y0 through x1,y1 with the color + // returns 0 on success, -1 on clipping all pixel + OSD_Line, // (x0,y0,x1,y1,color) + // draw a line from x0,y0 to x1,y1 with the color + // returns 0 on success + OSD_Query, // (x0,y0,x1,y1,xasp{color}}), yasp=11 + // fills parameters with the picture dimensions and the pixel aspect ratio + // returns 0 on success + OSD_Test, // () + // draws a test picture. for debugging purposes only + // returns 0 on success +// TODO: remove "test" in final version + OSD_Text, // (x0,y0,size,color,text) + OSD_SetWindow, // (x0) set window with number 0 + * & Marcus Metzler + for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _OST_SEC_H_ +#define _OST_SEC_H_ + +#define SEC_MAX_DISEQC_PARAMS 3 + +struct secDiseqcCmd { + uint8_t addr; + uint8_t cmd; + uint8_t numParams; + uint8_t params[SEC_MAX_DISEQC_PARAMS]; +}; + +typedef uint32_t secVoltage; + +enum { + SEC_VOLTAGE_OFF, + SEC_VOLTAGE_LT, + SEC_VOLTAGE_13, + SEC_VOLTAGE_13_5, + SEC_VOLTAGE_18, + SEC_VOLTAGE_18_5 +}; + +#define SEC_VOLTAGE_HORIZONTAL SEC_VOLTAGE_18 +#define SEC_VOLTAGE_VERTICAL SEC_VOLTAGE_13 + +typedef uint32_t secToneMode; + +typedef enum { + SEC_TONE_ON, + SEC_TONE_OFF +} secToneMode_t; + + +typedef uint32_t secMiniCmd; + +typedef enum { + SEC_MINI_NONE, + SEC_MINI_A, + SEC_MINI_B +} secMiniCmd_t; + +struct secStatus { + int32_t busMode; + secVoltage selVolt; + secToneMode contTone; +}; + +enum { + SEC_BUS_IDLE, + SEC_BUS_BUSY, + SEC_BUS_OFF, + SEC_BUS_OVERLOAD +}; + +struct secCommand { + int32_t type; + union { + struct secDiseqcCmd diseqc; + uint8_t vsec; + uint32_t pause; + } u; +}; + +struct secCmdSequence { + secVoltage voltage; + secMiniCmd miniCommand; + secToneMode continuousTone; + + uint32_t numCommands; + struct secCommand* commands; +}; + +enum { + SEC_CMDTYPE_DISEQC, + SEC_CMDTYPE_VSEC, + SEC_CMDTYPE_PAUSE +}; + + +#define SEC_GET_STATUS _IOR('o',91,struct secStatus *) +#define SEC_RESET_OVERLOAD _IOW('o',92,void) +#define SEC_SEND_SEQUENCE _IOW('o',93,struct secCmdSequence *) +#define SEC_SET_TONE _IOW('o',94,secToneMode) +#define SEC_SET_VOLTAGE _IOW('o',95,secVoltage) + +typedef enum { + SEC_DISEQC_SENT, + SEC_VSEC_SENT, + SEC_PAUSE_COMPLETE, + SEC_CALLBACK_ERROR +} secCallback_t; + + +#endif /*_OST_SEC_H_*/ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/ost/video.h linux.19pre5-ac1/drivers/media/video/margi/ost/video.h --- linux.19p5/drivers/media/video/margi/ost/video.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/ost/video.h Mon Feb 4 22:26:01 2002 @@ -0,0 +1,186 @@ +/* + * video.h + * + * Copyright (C) 2000 Marcus Metzler + * & Ralph Metzler + for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _OST_VIDEO_H_ +#define _OST_VIDEO_H_ + +#ifdef __KERNEL__ +#include +#else +#include +#endif + +#define boolean int +#define true 1 +#define false 0 + +typedef enum { + VIDEO_FORMAT_4_3, /* Select 4:3 format */ + VIDEO_FORMAT_16_9 /* Select 16:9 format. */ +} videoFormat_t; + +typedef enum { + VIDEO_SYSTEM_PAL, + VIDEO_SYSTEM_NTSC, + VIDEO_SYSTEM_PALN, + VIDEO_SYSTEM_PALNc, + VIDEO_SYSTEM_PALM, + VIDEO_SYSTEM_NTSC60, + VIDEO_SYSTEM_PAL60, + VIDEO_SYSTEM_PALM60 +} videoSystem_t; + +typedef enum { + VIDEO_PAN_SCAN, /* use pan and scan format */ + VIDEO_LETTER_BOX, /* use letterbox format */ + VIDEO_CENTER_CUT_OUT /* use center cut out format */ +} videoDisplayFormat_t; + +typedef enum { + VIDEO_SOURCE_DEMUX, /* Select the demux as the main source */ + VIDEO_SOURCE_MEMORY /* If this source is selected, the stream + comes from the user through the write + system call */ +} videoStreamSource_t; + +typedef enum { + VIDEO_STOPPED, /* Video is stopped */ + VIDEO_PLAYING, /* Video is currently playing */ + VIDEO_FREEZED /* Video is freezed */ +} videoPlayState_t; + +struct videoEvent { + int32_t type; + time_t timestamp; + union { + videoFormat_t videoFormat; + } u; +}; + +struct videoStatus { + boolean videoBlank; /* blank video on freeze? */ + videoPlayState_t playState; /* current state of playback */ + videoStreamSource_t streamSource; /* current source (demux/memory) */ + videoFormat_t videoFormat; /* current aspect ratio of stream */ + videoDisplayFormat_t displayFormat; /* selected cropping mode */ +}; + +/* pointer to and size of a single iframe in memory */ +struct videoDisplayStillPicture { + char *iFrame; + int32_t size; +}; + + +typedef +struct videoHighlight { + boolean active; /* 1=show highlight, 0=hide highlight */ + uint8_t contrast1; /* 7- 4 Pattern pixel contrast */ + /* 3- 0 Background pixel contrast */ + uint8_t contrast2; /* 7- 4 Emphasis pixel-2 contrast */ + /* 3- 0 Emphasis pixel-1 contrast */ + uint8_t color1; /* 7- 4 Pattern pixel color */ + /* 3- 0 Background pixel color */ + uint8_t color2; /* 7- 4 Emphasis pixel-2 color */ + /* 3- 0 Emphasis pixel-1 color */ + uint32_t ypos; /* 23-22 auto action mode */ + /* 21-12 start y */ + /* 9- 0 end y */ + uint32_t xpos; /* 23-22 button color number */ + /* 21-12 start x */ + /* 9- 0 end x */ +} videoHighlight_t; + + +typedef +struct videoSPU { + boolean active; + int streamID; +} videoSPU_t; + +typedef +struct videoSPUPalette{ /* SPU Palette information */ + int length; + uint8_t *palette; +} videoSPUPalette_t; + +typedef +struct videoNaviPack{ + int length; /* 0 ... 1024 */ + uint8_t data[1024]; +} videoNaviPack_t; + + +typedef uint16_t videoAttributes_t; +/* bits: descr. */ +/* 15-14 Video compression mode (0=MPEG-1, 1=MPEG-2) */ +/* 13-12 TV system (0=525/60, 1=625/50) */ +/* 11-10 Aspect ratio (0=4:3, 3=16:9) */ +/* 9- 8 permitted display mode on 4:3 monitor (0=both, 1=only pan-sca */ +/* 7 line 21-1 data present in GOP (1=yes, 0=no) */ +/* 6 line 21-2 data present in GOP (1=yes, 0=no) */ +/* 5- 3 source resolution (0=720x480/576, 1=704x480/576, 2=352x480/57 */ +/* 2 source letterboxed (1=yes, 0=no) */ +/* 0 film/camera mode (0=camera, 1=film (625/50 only)) */ + + +/* bit definitions for capabilities: */ +/* can the hardware decode MPEG1 and/or MPEG2? */ +#define VIDEO_CAP_MPEG1 1 +#define VIDEO_CAP_MPEG2 2 +/* can you send a system and/or program stream to video device? + (you still have to open the video and the audio device but only + send the stream to the video device) */ +#define VIDEO_CAP_SYS 4 +#define VIDEO_CAP_PROG 8 +/* can the driver also handle SPU, NAVI and CSS encoded data? + (CSS API is not present yet) */ +#define VIDEO_CAP_SPU 16 +#define VIDEO_CAP_NAVI 32 +#define VIDEO_CAP_CSS 64 + + +#define VIDEO_STOP _IOW('o', 21, boolean) +#define VIDEO_PLAY _IO('o', 22) +#define VIDEO_FREEZE _IO('o', 23) +#define VIDEO_CONTINUE _IO('o', 24) +#define VIDEO_SELECT_SOURCE _IOW('o', 25, videoStreamSource_t) +#define VIDEO_SET_BLANK _IOW('o', 26, boolean) +#define VIDEO_GET_STATUS _IOR('o', 27, struct videoStatus *) +#define VIDEO_GET_EVENT _IOR('o', 28, struct videoEvent *) +#define VIDEO_SET_DISPLAY_FORMAT _IOW('o', 29, videoDisplayFormat_t) +#define VIDEO_STILLPICTURE _IOW('o', 30, struct videoDisplayStillPicture *) +#define VIDEO_FAST_FORWARD _IOW('o', 31, int) +#define VIDEO_SLOWMOTION _IOW('o', 32, int) +#define VIDEO_GET_CAPABILITIES _IOR('o', 33, unsigned int *) +#define VIDEO_CLEAR_BUFFER _IO('o', 34) +#define VIDEO_SET_ID _IOW('o', 35, unsigned char) +#define VIDEO_SET_STREAMTYPE _IOW('o', 36, int) +#define VIDEO_SET_FORMAT _IOW('o', 37, videoFormat_t) +#define VIDEO_SET_SYSTEM _IOW('o', 38, videoSystem_t) +#define VIDEO_SET_HIGHLIGHT _IOW('o', 39, videoHighlight_t *) +#define VIDEO_SET_SPU _IOW('o', 50, videoSPU_t *) +#define VIDEO_SET_SPU_PALETTE _IOW('o', 51, videoSPUPalette_t *) +#define VIDEO_GET_NAVI _IOR('o', 52, videoNaviPack_t *) +#define VIDEO_SET_ATTRIBUTES _IOW('o', 53, videoAttributes_t) +#endif /*_OST_VIDEO_H_*/ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/ringbuffy.c linux.19pre5-ac1/drivers/media/video/margi/ringbuffy.c --- linux.19p5/drivers/media/video/margi/ringbuffy.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/ringbuffy.c Mon Feb 4 22:32:52 2002 @@ -0,0 +1,212 @@ +/* + ringbuffy.c + + Copyright (C) Marcus Metzler for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define __NO_VERSION__ + +#include "margi.h" +#include "ringbuffy.h" + +#ifndef outsl_ns +#define outsl_ns outsl +#endif + +int ring_init (ringbuffy *rbuf, long size) +{ + rbuf->size = 0; + rbuf->read_pos = 0; + rbuf->write_pos = 0; + + if (size > 0){ + if( !(rbuf->buffy = (char *) vmalloc(sizeof(char)*size)) ){ + MDEBUG(0, + "Not enough memory for ringbuffy\n"); + return -1; + } + } else { + MDEBUG(0, "Wrong size for ringbuffy\n"); + return -1; + } + + rbuf->size = size; + return 0; +} + + +void ring_destroy(ringbuffy *rbuf) +{ + if (rbuf->size){ + vfree(rbuf->buffy); + rbuf->buffy = NULL; + } + rbuf->size = 0; + rbuf->read_pos = 0; + rbuf->write_pos = 0; +} + + +int ring_write(ringbuffy *rbuf, const char *data, int count) +{ + + long diff, free, pos, rest; + + + if (count <=0 || !rbuf->buffy) return 0; + pos = rbuf->write_pos; + rest = rbuf->size - pos; + diff = rbuf->read_pos - pos; + free = (diff > 0) ? diff-4 : rbuf->size+diff-4; + + if ( free <= 0 ) return 0; + if ( free < count ) count = free; + + if (count >= rest){ + if(copy_from_user (rbuf->buffy+pos, data, rest)) + return -EFAULT; + if (count - rest) + if(copy_from_user(rbuf->buffy, data+rest, + count - rest)) + return -EFAULT; + rbuf->write_pos = count - rest; + } else { + copy_from_user (rbuf->buffy+pos, data, count); + rbuf->write_pos += count; + } + + return count; +} + + +int ring_writek(ringbuffy *rbuf, const char *data, int count) +{ + + long diff, free, pos, rest; + + + if (count <=0 || !rbuf->buffy) return 0; + pos = rbuf->write_pos; + rest = rbuf->size - pos; + diff = rbuf->read_pos - pos; + free = (diff > 0) ? diff-4 : rbuf->size+diff-4; + + if ( free <= 0 ) return 0; + if ( free < count ) count = free; + + if (count >= rest){ + if(memcpy(rbuf->buffy+pos, data, rest)) + return -EFAULT; + if (count - rest) + if(memcpy(rbuf->buffy, data+rest, + count - rest)) + return -EFAULT; + rbuf->write_pos = count - rest; + } else { + memcpy(rbuf->buffy+pos, data, count); + rbuf->write_pos += count; + } + + return count; +} + + + + +int ring_read(ringbuffy *rbuf, char *data, int count) +{ + + long diff, free, pos, rest; + + + if (count <=0 || !rbuf->buffy) return 0; + pos = rbuf->read_pos; + rest = rbuf->size - pos; + diff = rbuf->write_pos - pos; + free = (diff >= 0) ? diff : rbuf->size+diff; + + if ( free <= 0 ) return 0; + if ( free < count ) count = free; + + if ( count >= rest ){ + memcpy(data,rbuf->buffy+pos,rest); + if ( count - rest) + memcpy(data+rest,rbuf->buffy,count-rest); + rbuf->read_pos = count - rest; + } else { + memcpy(data,rbuf->buffy+pos,count); + rbuf->read_pos += count; + } + + return count; +} + +int ring_read_direct(ringbuffy *rbuf, int addr, int count) +{ + + long diff, free, pos, rest; + + + if (count <=0 || !rbuf->buffy) return 0; + pos = rbuf->read_pos; + rest = rbuf->size - pos; + diff = rbuf->write_pos - pos; + free = (diff >= 0) ? diff : rbuf->size+diff; + + if ( free <= 0 ) return 0; + if ( free < count ) count = free; + + if ( count >= rest ){ + outsl_ns(addr,rbuf->buffy+pos,rest/4); + if ( count - rest) + outsl_ns(addr,rbuf->buffy,(count-rest)/4); + rbuf->read_pos = count - rest; + } else { + outsl_ns(addr,rbuf->buffy+pos,count/4); + rbuf->read_pos += count; + } + + return count; +} + + +long ring_read_rest(ringbuffy *rbuf){ + long diff, free, pos; + + if (!rbuf->buffy) return 0; + pos = rbuf->read_pos; + diff = rbuf->write_pos - pos; + free = (diff >= 0) ? diff : rbuf->size+diff; + + return free; +} + +long ring_write_rest(ringbuffy *rbuf){ + long diff, free, pos; + + if (!rbuf->buffy) return 0; + pos = rbuf->write_pos; + diff = rbuf->read_pos - pos; + free = (diff > 0) ? diff-4 : rbuf->size+diff-4; + + return free; +} + +void ring_flush(ringbuffy *rbuf){ + rbuf->read_pos = 0; + rbuf->write_pos = 0; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/ringbuffy.h linux.19pre5-ac1/drivers/media/video/margi/ringbuffy.h --- linux.19p5/drivers/media/video/margi/ringbuffy.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/ringbuffy.h Mon Feb 4 22:21:11 2002 @@ -0,0 +1,43 @@ +/* + cvdv.h + + Copyright (C) Marcus Metzler for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef RINGBUFFY_H +#define RINGBUFFY_H + + +#define FULL_BUFFER -1000 +typedef struct ringbuffy{ + long read_pos; + long write_pos; + long size; + char *buffy; +} ringbuffy; + +int ring_init (ringbuffy *rbuf, long size); +void ring_destroy(ringbuffy *rbuf); +int ring_write(ringbuffy *rbuf, const char *data, int count); +int ring_writek(ringbuffy *rbuf, const char *data, int count); +int ring_read(ringbuffy *rbuf, char *data, int count); +long ring_read_rest(ringbuffy *rbuf); +long ring_write_rest(ringbuffy *rbuf); +void ring_flush(ringbuffy *rbuf); +int ring_read_direct(ringbuffy *rbuf, int addr, int count); + +#endif /* RINGBUFFY_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/spu.c linux.19pre5-ac1/drivers/media/video/margi/spu.c --- linux.19p5/drivers/media/video/margi/spu.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/spu.c Mon Feb 4 22:21:11 2002 @@ -0,0 +1,103 @@ +/* + spu.c + + Copyright (C) Christian Wolff for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define __NO_VERSION__ + +#include "spu.h" +#include "l64021.h" + +int DecoderHighlight(struct cvdv_cards *card, int active, u8 * coli, + u8 * btn_posi) +{ + int i; + if ((coli == NULL) || (btn_posi == NULL)) + return 1; + MDEBUG(0,": -- DecoderHighlight: col 0x%02X%02X, contr 0x%02X%02X, act %d, %d,%d - %d,%d\n", + coli[0], coli[1], coli[2], coli[3], active, + (((int) btn_posi[0] & 0x3F) << 4) | (btn_posi[1] >> 4), + (((int) btn_posi[3] & 0x3F) << 4) | (btn_posi[4] >> 4), + (((int) btn_posi[1] & 0x03) << 8) | btn_posi[2], + (((int) btn_posi[4] & 0x03) << 8) | btn_posi[5]); + //for (i=0; i<4; i++) DecoderWriteByte(card,0x1C0+i,coli[i]); +// DecoderWriteByte(card,0x1C0,coli[1]); +// DecoderWriteByte(card,0x1C1,coli[0]); +// DecoderWriteByte(card,0x1C2,coli[3]); +// DecoderWriteByte(card,0x1C3,coli[2]); + //for (i=0; i<6; i++) DecoderWriteByte(card,0x1C4+i,btn_posi[i]); +// for (i=0; i<6; i++) DecoderWriteByte(card,0x1C4+i,btn_posi[5-i]); + //if (active) DecoderSetByte(card,0x1BF,0x01); + //else DecoderDelByte(card,0x1BF,0x01); + + //for (i=0; i<4; i++) card->highlight[i]=coli[3-i]; + card->highlight[0] = coli[1]; + card->highlight[1] = coli[0]; + card->highlight[2] = coli[3]; + card->highlight[3] = coli[2]; + for (i = 0; i < 6; i++) + card->highlight[4 + i] = btn_posi[5 - i]; + card->highlight_valid = 1; + if (active) + DecoderWriteByte(card, 0x1BF, 0x01); + else + DecoderWriteByte(card, 0x1BF, 0x00); +//DecoderSetByte(card,0x135,0x02); // Enable SPU Mix +//DecoderWriteByte(card,0x1A0,0x01); // decode start, display on + return 0; +} + +int DecoderSPUPalette(struct cvdv_cards *card, int length, u8 * palette) +{ + int i; + MDEBUG(1,": -- DecoderSPUPalette: setting up %d bytes of SPU palette(Y,Cr,Cb):", length); + for (i = 0; i < (length / 3); i++) + MDEBUG(1," %d=(%d,%d,%d)", i, palette[i * 3],palette[i * 3 + 1], + palette[i * 3 + 2]); + MDEBUG(1,"\n"); + DecoderDelByte(card, 0x1A0, 0x01); // SPU decode stop + DecoderSetByte(card, 0x1A0, 0x10); + for (i = 0; i < length; i++) + DecoderWriteByte(card, 0x1BE, palette[i]); + DecoderSetByte(card, 0x1A0, 0x01); // SPU decode start + return 0; +} + +int DecoderSPUStream(struct cvdv_cards *card, int stream, int active) +{ + MDEBUG(1,": -- DecoderSPUStream: stream %d, active %d\n", stream, + active); + if (stream < 32) { + card->reg092 |= (0x20 | (stream & 0x1F)); // stream ID and select + DecoderWriteByte(card, 0x092, card->reg092); + DecoderMaskByte(card, 0x112, 0x20, 0x20); // chroma filter enable + DecoderMaskByte(card, 0x1A1, 0x0F, 0x00); // SPU timeout + DecoderWriteByte(card, 0x1BF, 0x00); // HighLight off + DecoderSetByte(card, 0x135, 0x02); // Enable SPU Mix + if (active) + DecoderWriteByte(card, 0x1A0, 0x01); // decode start, display on + else + DecoderWriteByte(card, 0x1A0, 0x05); // decode start, display off + } else { + DecoderWriteByte(card, 0x1A0, 0x04); // decode stop, display off + card->reg092 &= (~0x20); // stream select off + DecoderWriteByte(card, 0x092, card->reg092); + DecoderDelByte(card, 0x135, 0x02); // Disable SPU Mix + } + return 0; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/spu.h linux.19pre5-ac1/drivers/media/video/margi/spu.h --- linux.19p5/drivers/media/video/margi/spu.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/spu.h Thu Apr 4 15:55:29 2002 @@ -0,0 +1,33 @@ +/* + spu.h + + Copyright (C) Christian Wolff for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef CVDV_SPU_H +#define CVDV_SPU_H + +#include "cardbase.h" + +int DecoderHighlight(struct cvdv_cards *card, int active, u8 * coli, + u8 * btn_posi); + +int DecoderSPUPalette(struct cvdv_cards *card, int length, u8 * palette); + +int DecoderSPUStream(struct cvdv_cards *card, int stream, int active); + +#endif /* CVDV_SPU_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/streams.c linux.19pre5-ac1/drivers/media/video/margi/streams.c --- linux.19p5/drivers/media/video/margi/streams.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/streams.c Tue Feb 5 00:20:10 2002 @@ -0,0 +1,444 @@ +/* + streams.c + + Copyright (C) Christian Wolff for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define __NO_VERSION__ + +#include "streams.h" +#include "dram.h" +#include "l64021.h" +#include "video.h" +#include "audio.h" + +// Frees allocated channel buffers +int DecoderKillChannelBuffers(struct cvdv_cards *card) +{ + MDEBUG(1, ": -- DecoderKillChannelBuffers\n"); + DecoderStopDecode(card); + DRAMFree(card, card->VideoES); + card->VideoES = BLANK; + DRAMFree(card, card->AudioES); + card->AudioES = BLANK; + DRAMFree(card, card->VideoPES); + card->VideoPES = BLANK; + DRAMFree(card, card->DataDump); + card->DataDump = BLANK; + DRAMFree(card, card->AudioPES); + card->AudioPES = BLANK; + DRAMFree(card, card->NaviBank); + card->NaviBank = BLANK; + card->ChannelBuffersAllocated = 0; +// DecoderWriteWord( + return 0; +} + +// Allocates channel buffers +// All sizes in bytes, preferably multiple of 256 (will be rounded up otherwise) +int DecoderSetChannelBuffers(struct cvdv_cards *card, int VideoES, // Video ES Channel Buffer size, e.g. 229376 byte for NTSC + int AudioES, // Audio ES Channel Buffer size, 4096 byte + int VideoPES, // Video PES Header / SPU Channel Buffer size, 512 byte + int DataDump, // Data Dump Channel Buffer size, e.g. 80896 byte + int AudioPES, // Audio PES Header / System Channel Buffer size, 512 byte + int NaviBank) +{ // Navi Bank Channel Buffer size, 2048 byte +#define BUFFERSET(buf, id, adr,align) if (buf>0) {\ + if (buf&((1<buf=addr;\ + addr>>=align;\ + DecoderWriteByte(card,adr,addr&0xFF);\ + DecoderWriteByte(card,adr+1,(addr>>8)&(0x003F));\ + addr+=(buf>>align);\ + DecoderWriteByte(card,adr+2,(addr-1)&0xFF);\ + DecoderWriteByte(card,adr+3,((addr-1)>>8)&0x003F);\ +} + u32 addr; + MDEBUG(1, ": -- DecoderSetChannelBuffers\n"); + //DecoderStopDecode(card); + DecoderStopChannel(card); + VideoES >>= 1; // change to word sizes + AudioES >>= 1; + VideoPES >>= 1; + DataDump >>= 1; + AudioPES >>= 1; + NaviBank >>= 1; + if (card->ChannelBuffersAllocated) + DecoderKillChannelBuffers(card); + BUFFERSET(VideoES, "VideoES", 0x048, 7); + BUFFERSET(AudioES, "AudioES", 0x04C, 7); + BUFFERSET(VideoPES, "VideoPES", 0x050, 7); + BUFFERSET(DataDump, "DataDump", 0x054, 7); + BUFFERSET(AudioPES, "AudioPES", 0x058, 7); + BUFFERSET(NaviBank, "NaviBank", 0x05C, 7); + + card->VideoESSize = VideoES; + card->AudioESSize = AudioES; + card->VideoPESSize = VideoPES; + card->DataDumpSize = DataDump; + card->AudioPESSize = AudioPES; + card->NaviBankSize = NaviBank; + + DecoderWriteByte(card, 0x044, 0x7F); + DecoderWriteByte(card, 0x044, 0x01); + if (NaviBank) { + card->reg07B |= 0x10; // navi pack counter enable + DecoderWriteByte(card, 0x07B, card->reg07B); + //DecoderSetByte(card,0x07B,0x10); // navi pack counter enable + card->NaviPackAddress = + (DecoderReadWord(card, 0x05C) & 0x3FFF) << 7; + MDEBUG(4, ": navi bank init'ed: 0x%08X\n",card->NaviPackAddress); + } else { + card->reg07B &= ~0x10; // navi pack counter disable + DecoderWriteByte(card, 0x07B, card->reg07B); + //DecoderDelByte(card,0x07B,0x10); // navi pack counter disable + card->NaviPackAddress = 0; + } + card->ChannelBuffersAllocated = 1; +#undef BUFFERSET + return 0; +} + +//int DecoderReadFifo + +int DecoderUnPrepare(struct cvdv_cards *card) +{ + MDEBUG(0, ": -- DecoderUnPrepare\n"); + //DecoderStopDecode(card); + DecoderStopChannel(card); + DecoderKillChannelBuffers(card); + return 0; +} + +void DecoderPrepare(struct cvdv_cards *card) +{ + //VideoSetBackground(card,0,0,0,0); // Video on black + VideoSetBackground(card, 1, 0, 0, 0); // black + //VideoSetBackground(card,2,83,90,249); // Red + //VideoSetBackground(card,2,155,53,53); // Green + //VideoSetBackground(card,2,35,212,114); // Blue + //VideoSetBackground(card,2,4,128,128); // Black + //VideoSetBackground(card,3,155,53,53); // Video on Green + + //DecoderWriteByte(card,0x044,0x00); // Reset channel buffers on error +// DecoderWriteByte(card,0x044,0x01); // don't Reset channel buffers on error + + DecoderWriteByte(card, 0x040, 0x01); // Reset Aux FIFO + DecoderWriteByte(card, 0x041, 0x01); // Reset Data FIFO + //DecoderWriteByte(card,0x044,0x7E); // Reset channel buffers, Reset channel buffers on error + DecoderWriteByte(card, 0x044, 0x7F); // Reset channel buffers, don't Reset channel buffers on error +// udelay(100); +// DecoderWriteByte(card,0x040,0x00); // Reset Aux FIFO +// DecoderWriteByte(card,0x041,0x00); // Reset Data FIFO +// DecoderDelByte(card,0x044,0x7E); // Reset channel buffers +} + +// Selects audio type MPEG and sets stream ID's +// AID: -1=all MPEG, Audio Stream ID: 0..31 +// AExt: -1=unused, Audio Stream Extension ID: 0..31, only used if AType=5 +void DecoderSelectAudioID(struct cvdv_cards *card) +{ + int AID = card->setup.audioID; + int AExt = card->setup.audioIDext; + MDEBUG(1, ": -- SelectAudio %d %d\n", AID, AExt); + DecoderWriteByte(card, 0x07C, AExt & 0x1F); // Audio Stream Extension ID + card->reg08F = (card->reg08F & ~0x1F) | (AID & 0x1F); + DecoderWriteByte(card, 0x08F, card->reg08F); + //DecoderMaskByte(card,0x08F,0x1F,AID&0x1F); // Set Stream ID +} + +// AHeader: 0=No Headers, 1=first PTS/DTS header, 2=all headers, 3=All with PTS/DTS +// AType: 0=disable audio, 1=MPEG ID (MPEG 1), 2=Lin.PCM ID, 3=AC3 ID, 4=all MPEG (use only, if just one MPEG audio stream), 5=MPEG multichannel ID (MPEG 2) +// AID: -1=all MPEG, Audio Stream ID: 0..31 +// AExt: -1=unused, Audio Stream Extension ID: 0..31, only used if AType=5 +// IEC956: 0:MPEG/AC3 data on digital out 1:IEC956 data on digital S/PDIF out +void DecoderPrepareAudio(struct cvdv_cards *card) +{ + int AHeader = 2; + int AType = 3; + int AID = card->setup.audioID; + int AExt = card->setup.audioIDext; + int IEC956 = card->setup.SPDIFmode; + MDEBUG(1, ": -- PrepAudio %d %d %d %d %d\n", + AHeader, card->setup.audioselect, AID, AExt, IEC956); + switch (card->setup.audioselect) { + case audio_disable: + case audio_none: + case audio_SDDS: + AType = 0; + break; + case audio_MPEG: // MPEG Audio + AType = 1; + break; + case audio_MPEG_EXT: // MPEG Audio with extension stream + AType = 5; + break; + case audio_LPCM: // Linear Pulse Code Modulation LPCM + AType = 2; + break; + case audio_AC3: // AC-3 + AType = 3; + break; + case audio_DTS: // DTS + AType = 8; + break; + } + if (AType <= 0) { + card->reg08F = 0x00; // disable audio and discard all packets + DecoderWriteByte(card, 0x08F, card->reg08F); + //DecoderWriteByte(card,0x08F,0x00); // disable audio and discard all packets + //DecoderMaskByte(card,0x093,0xC3,0xC0); // write no headers + card->reg093 = (card->reg093 & ~0x03); // write no headers + DecoderWriteByte(card, 0x093, card->reg093); + } else { + AudioOpen(card); + DecoderMaskByte(card, 0x165, 0x1F, 0x00); // reset the register + if (AType == 8) { // DTS + card->reg090 |= 0x01; // DTS in Transport Private 1 Stream stored in AudioES channel buffer + DecoderWriteByte(card, 0x090, card->reg090); + //DecoderSetByte(card,0x090,0x01); // DTS in Transport Private 1 Stream stored in AudioES channel buffer + AudioSetMode(card, 0); + DecoderSetByte(card, 0x165, 0x01); + AudioStartFormat(card); + } else if (AType == 3) { // AC3 + card->reg090 |= 0x01; // AC3 in Transport Private 1 Stream stored in AudioES channel buffer + DecoderWriteByte(card, 0x090, card->reg090); + //DecoderSetByte(card,0x090,0x01); // AC3 in Transport Private 1 Stream stored in AudioES channel buffer + AudioSetMode(card, ((IEC956) ? 1 : 3)); + } else if (AType == 2) { // PCM + card->reg090 |= 0x01; // PCM in Transport Private 1 Stream stored in AudioES channel buffer + DecoderWriteByte(card, 0x090, card->reg090); + //DecoderSetByte(card,0x090,0x01); // PCM in Transport Private 1 Stream stored in AudioES channel buffer + AudioSetMode(card, 4); + } else { // MPEG + card->reg090 &= ~0x01; // MPEG Audio stored in AudioES channel buffer + DecoderWriteByte(card, 0x090, card->reg090); + //DecoderDelByte(card,0x090,0x01); // MPEG Audio stored in AudioES channel buffer + if (AID < 0) + AType = 4; + if (AExt >= 0) + AType = 5; + else + AExt = -1; + AudioSetMode(card, ((IEC956) ? 0 : 2)); + } + card->setup.audioID = AID; + card->setup.audioIDext = AExt; + DecoderSelectAudioID(card); + card->reg08F = (card->reg08F & ~0xE0) | ((AType & 0x07) << 5); // Set Stream Type + DecoderWriteByte(card, 0x08F, card->reg08F); + //DecoderMaskByte(card,0x08F,0xE0,(AType&0x07)<<5); // Set Stream Type + AudioSetVolume(card, 0xFF); // Set PCM scale to full volume + //DecoderMaskByte(card,0x093,0xC3,(AHeader&0x03)|0xC0); // write header select + card->reg093 = (card->reg093 & ~0x03) | (AHeader & 0x03); // write header select + DecoderWriteByte(card, 0x093, card->reg093); + // Mute the card and put it in play mode, then wait for the parameters to be parsed and un-mute if successful + //AudioMute(card,1); + if (AType > 0) { + AudioStartDecode(card); + //AudioSetPlayMode(card,MAUDIO_PLAY); + AudioSetPlayMode(card, MAUDIO_PAUSE); + } + //card->startingA=1; + } + card->lastaattr = 0; +} + +// VHeader: -1=disable Video, 0=No Headers, 1=first PTS/DTS header, 2=all headers, 3=All with PTS/DTS +// VID: -1=all MPEG, 0..15=Video Stream ID +void DecoderPrepareVideo(struct cvdv_cards *card) +{ + int VHeader = 3; + int VID = card->setup.videoID; + if (VHeader < 0) { + card->reg091 = 0x00; + DecoderWriteByte(card, 0x091, card->reg091); + //DecoderWriteByte(card,0x091,0x00); + } else { + if (VID < 0) { + card->reg091 = ((VHeader & 0x03) << 6) | (2 << 4); + DecoderWriteByte(card, 0x091, card->reg091); + //DecoderWriteByte(card,0x091,((VHeader&0x03)<<6)|(2<<4)); + } else { + card->reg091 = + ((VHeader & 0x03) << 6) | (1 << 4) | (VID & + 0x0F); + DecoderWriteByte(card, 0x091, card->reg091); + //DecoderWriteByte(card,0x091,((VHeader&0x03)<<6)|(1<<4)|(VID&0x0F)); + } + } +} + +// Prepare Decoder for Elementary Streams, Disable Preparser +int DecoderPrepareES(struct cvdv_cards *card) +{ + int i; + MDEBUG(1, ": -- PrepareES\n"); + //DecoderStopDecode(card); + +// DecoderWriteByte(card,0x05,0x00); + + DecoderMaskByte(card, 0x007, 0xCE, 0xC2 | (3 << 2)); // Stream Select: A/V Elementary Stream + MDEBUG(3, ": Int - A VideoES w/r addr: %08X %08X\n", + (DecoderReadByte(card,0x060)|(DecoderReadByte(card,0x061)<<8)| + (DecoderReadByte(card,0x062)<<16))<<2, + (DecoderReadByte(card,0x06C)|(DecoderReadByte(card,0x06D)<<8)| + (DecoderReadByte(card,0x06E)<<16))<<2); + // set the decoding buffers + card->reg093 = (card->reg093 & ~0xFC); // write no header + DecoderWriteByte(card, 0x093, card->reg093); + if ((i = DecoderSetChannelBuffers(card, 256000, 4096, 0, 0, 0, 0))) { + MDEBUG(0, ": SetDecoderBuffers failed for buffer at 0x%03X\n", i); + DecoderKillChannelBuffers(card); + return 1; + } + MDEBUG(3, ": Int - B VideoES w/r addr: %08X %08X\n", + (DecoderReadByte(card,0x060)|(DecoderReadByte(card,0x061)<<8)| + (DecoderReadByte(card,0x062)<<16))<<2, + (DecoderReadByte(card,0x06C)|(DecoderReadByte(card,0x06D)<<8)| + (DecoderReadByte(card,0x06E)<<16))<<2); + + MDEBUG(3, ": Int - C VideoES w/r addr: %08X %08X\n", + (DecoderReadByte(card,0x060)|(DecoderReadByte(card,0x061)<<8)| + (DecoderReadByte(card,0x062)<<16))<<2, + (DecoderReadByte(card,0x06C)|(DecoderReadByte(card,0x06D)<<8)| + (DecoderReadByte(card,0x06E)<<16))<<2); + +// DecoderStartChannel(card); +// DecoderStartDecode(card); + + MDEBUG(3, ": Int - D VideoES w/r addr: %08X %08X\n", + (DecoderReadByte(card,0x060)|(DecoderReadByte(card,0x061)<<8)| + (DecoderReadByte(card,0x062)<<16))<<2, + (DecoderReadByte(card,0x06C)|(DecoderReadByte(card,0x06D)<<8)| + (DecoderReadByte(card,0x06E)<<16))<<2); + + DecoderPrepare(card); + + return 0; +} + +// Prepare Decoder for Packetised Elementary Streams, set parameters of Preparser +int DecoderPreparePES(struct cvdv_cards *card) +{ + + // SPUID: -1=No SPU, 0..31=Display SPU of this ID + // DataDump: 0=disable DataDump, 1=process DataDump Substreams + // PackHeader: 0=write no headers, 1=write one header, 2=write all headers + // SysHeader: 0=write no headers, 1=write one header, 2=write all headers + // DSIHeader: 0=write no headers, 3=write PCI and DSI headers and packets + int i; + int SPUID = -1; + int DataDump = 0; + int PackHeader = 0; + int SysHeader = 0; + int DSIHeader = 0; + + MDEBUG(1, ": -- PreparePES\n"); + DecoderMaskByte(card, 0x007, 0xCE, 0xC2 | (0 << 2)); // Stream Select: A/V PES Packets + + if (SPUID < 0) + card->reg092 = 0; // Do we use SPU? + else + card->reg092 = 0x20 | (SPUID & 0x1F); + if (DataDump) + card->reg092 |= 0x40; // Do we use DataDump? + DecoderWriteByte(card, 0x092, card->reg092); + //DecoderMaskByte(card,0x093,0xFC,((DSIHeader&0x03)<<6)|((PackHeader&0x03)<<4)|((SysHeader&0x03)<<2)); + card->reg093 = + (card->reg093 & ~0xFC) | (((DSIHeader & 0x03) << 6) | + ((PackHeader & 0x03) << 4) | + ((SysHeader & 0x03) << 2)); + DecoderWriteByte(card, 0x093, card->reg093); + // set the decoding buffers + if ( + (i = + DecoderSetChannelBuffers(card, 256000, 4096, 512, 0, 512, + 0))) { + MDEBUG(0,": SetDecoderBuffers failed for buffer at 0x%03X\n", i); + DecoderKillChannelBuffers(card); + return 1; + } + + DecoderPrepare(card); + + return 0; +} + + +// Prepare Decoder for MPEG 1 Systems Streams or MPEG 2 Program Streams +// SPUID: -1:ignore, 0...15 SPU Substream ID +// DataDump: 0:disable data dump stream, 1:enable data dump stream +// PackHeader: 0:write no headers, 1:write one header, 2:write all headers, 3:always discard +// SysHeader: 0:always discard, 1:write one header, 2:write all headers, 3:always discard +// DSIHeader: 0:write no DSI or PCI headers, 3:write DSI and PCI headers + packets +// DVD: 0: normal MPEG-2 data, 1: DVD stream with navi pack data +int DecoderPreparePS(struct cvdv_cards *card, + int SPUID, int DataDump, + int PackHeader, int SysHeader, int DSIHeader, int DVD) +{ + int i=0; + MDEBUG(1, ": -- PreparePS %s\n", ((DVD) ? "DVD" : "")); + //DecoderStopDecode(card); + DecoderMaskByte(card, 0x007, 0xCE, 0xC2 | (1 << 2)); // Stream Select: MPEG1 System / MPEG2 Program Stream + + if (SPUID < 0) + card->reg092 = 0; // Do we use SPU? + else + card->reg092 = 0x20 | (SPUID & 0x1F); + if (DataDump) + card->reg092 |= 0x40; // Do we use DataDump? + DecoderWriteByte(card, 0x092, card->reg092); + //DecoderMaskByte(card,0x093,0xFC,((DSIHeader&0x03)<<6)|((PackHeader&0x03)<<4)|((SysHeader&0x03)<<2)); + card->reg093 = + (card->reg093 & ~0xFC) | (((DSIHeader & 0x03) << 6) | + ((PackHeader & 0x03) << 4) | + ((SysHeader & 0x03) << 2)); + DecoderWriteByte(card, 0x093, card->reg093); + // set the decoding buffers + if (DVD) { // do we need SPU-, navi- and datadump-buffers? + + // if(card->videomode == NTSC) + i = DecoderSetChannelBuffers(card, 340000, 32768, 32768, 0, + 512,4096) ; + //else + // i = DecoderSetChannelBuffers(card, 291878, 16384, 512, 0, + // 512,0) ; + + if (i) { + MDEBUG(0,": SetDecoderBuffers failed for buffer at 0x%03X\n", i); + DecoderKillChannelBuffers(card); + return 1; + } + + } else { // normal PS + if ( + (i = + DecoderSetChannelBuffers(card, 340000, 32768, 512, + 0, 512, 0))) { + MDEBUG(0,": SetDecoderBuffers failed for buffer at 0x%03X\n", i); + DecoderKillChannelBuffers(card); + return 1; + } + } + + DecoderPrepare(card); + + return 0; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/streams.h linux.19pre5-ac1/drivers/media/video/margi/streams.h --- linux.19p5/drivers/media/video/margi/streams.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/streams.h Thu Apr 4 15:55:29 2002 @@ -0,0 +1,79 @@ +/* + streams.h + + Copyright (C) Christian Wolff for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef CVDV_STREAMS_H +#define CVDV_STREAMS_H + +#include "cardbase.h" + +// Frees allocated channel buffers +int DecoderKillChannelBuffers(struct cvdv_cards *card); + +// Allocates channel buffers +// All sizes in bytes, preferably multiple of 256 (will be rounded up otherwise) +int DecoderSetChannelBuffers(struct cvdv_cards *card, int VideoES, // Video ES Channel Buffer size, e.g. 229376 byte for NTSC + int AudioES, // Audio ES Channel Buffer size, 4096 byte + int VideoPES, // Video PES Header / SPU Channel Buffer size, 512 byte + int DataDump, // Data Dump Channel Buffer size, e.g. 80896 byte + int AudioPES, // Audio PES Header / System Channel Buffer size, 512 byte + int NaviBank); // Navi Bank Channel Buffer size, 2048 byte + +//int DecoderReadFifo + +int DecoderUnPrepare(struct cvdv_cards *card); + +void DecoderPrepare(struct cvdv_cards *card); + +// Selects audio type MPEG and sets stream ID's +// AID: -1=all MPEG, Audio Stream ID: 0..31 +// AExt: -1=unused, Audio Stream Extension ID: 0..31, only used if AType=5 +void DecoderSelectAudioID(struct cvdv_cards *card); + +// AHeader: 0=No Headers, 1=first PTS/DTS header, 2=all headers, 3=All with PTS/DTS +// AType: 0=disable audio, 1=MPEG ID (MPEG 1), 2=Lin.PCM ID, 3=AC3 ID, 4=all MPEG (use only, if just one MPEG audio stream), 5=MPEG multichannel ID (MPEG 2) +// AID: -1=all MPEG, Audio Stream ID: 0..31 +// AExt: -1=unused, Audio Stream Extension ID: 0..31, only used if AType=5 +// IEC956: 0:MPEG/AC3 data on digital out 1:IEC956 data on digital S/PDIF out +void DecoderPrepareAudio(struct cvdv_cards *card); + +// VHeader: -1=disable Video, 0=No Headers, 1=first PTS/DTS header, 2=all headers, 3=All with PTS/DTS +// VID: -1=all MPEG, 0..15=Video Stream ID +void DecoderPrepareVideo(struct cvdv_cards *card); + +// Prepare Decoder for Elementary Streams, Disable Preparser +int DecoderPrepareES(struct cvdv_cards *card); + +// Prepare Decoder for Packetised Elementary Streams, set parameters of Preparser +int DecoderPreparePES(struct cvdv_cards *card); + + +// Prepare Decoder for MPEG 1 Systems Streams or MPEG 2 Program Streams +// SPUID: -1:ignore, 0...15 SPU Substream ID +// DataDump: 0:disable data dump stream, 1:enable data dump stream +// PackHeader: 0:write no headers, 1:write one header, 2:write all headers, 3:always discard +// SysHeaader: 0:always discard, 1:write one header, 2:write all headers, 3:always discard +// DSIHeader: 0:write no DSI or PCI headers, 3:write DSI and PCI headers + packets +// DVD: 0: normal MPEG-2 data, 1: DVD stream with navi pack data +int DecoderPreparePS(struct cvdv_cards *card, + int SPUID, int DataDump, + int PackHeader, int SysHeader, int DSIHeader, + int DVD); + +#endif /* CVDV_STREAMS_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/video.c linux.19pre5-ac1/drivers/media/video/margi/video.c --- linux.19p5/drivers/media/video/margi/video.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/video.c Tue Feb 5 00:14:01 2002 @@ -0,0 +1,525 @@ +/* + video.c + + Copyright (C) Christian Wolff for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the 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. +*/ + +// +// Video Decoder +// +#define __NO_VERSION__ + +#include "video.h" +#include "l64021.h" +#include "dram.h" + +// Set the background of the OSD and SPU and it's color +// mode=0: Video on Black +// mode=1: Black +// mode=2: Selected Color +// mode=3: Video on Selected Color +void VideoSetBackground(struct cvdv_cards *card, int mode, u8 Y, u8 Cb, + u8 Cr) +{ + DecoderWriteByte(card, 0x10A, Y); + DecoderWriteByte(card, 0x10B, Cb); + DecoderWriteByte(card, 0x10C, Cr); + DecoderMaskByte(card, 0x109, 0xC0, mode << 6); +} + + +int DecoderStartDecode(struct cvdv_cards *card) +{ + DecoderSetByte(card, 0x0F6, 0x01); +#ifdef DVB + if (card->audiostate.AVSyncState) +#endif + card->videosync = 1; + return 0; +} + +int DecoderStopDecode(struct cvdv_cards *card) +{ + DecoderDelByte(card, 0x0F6, 0x01); + card->videosync = 0; + return 0; +} + +// Sets Display Override (Still Image Display) to Frame Buffer at specified addresses, +// addresses are 16 bit, in 64 byte resolution +// mode: 0=off, 1=Frame, 2=Field +// width: width of the still picture in 8 pixel units +int DecoderStillImageDisplay(struct cvdv_cards *card, int mode, int width, + u16 LumaAddr, u16 ChromaAddr) +{ + DecoderStopDecode(card); + DecoderWriteWord(card, 0x11D, LumaAddr); + DecoderWriteWord(card, 0x11F, ChromaAddr); + DecoderWriteByte(card, 0x11B, width & 0x7F); + DecoderMaskByte(card, 0x109, 0x30, (mode & 3) << 4); // Display Override Mode + return 0; +} + +// Frees allocated frame buffers +int DecoderKillFrameBuffers(struct cvdv_cards *card) +{ + MDEBUG(1, ": -- DecoderKillFrameBuffers\n"); + DecoderStopDecode(card); + DRAMFree(card, card->FrameStoreLuma1); + card->FrameStoreLuma1 = BLANK; + DRAMFree(card, card->FrameStoreChroma1); + card->FrameStoreChroma1 = BLANK; + DRAMFree(card, card->FrameStoreLuma2); + card->FrameStoreLuma2 = BLANK; + DRAMFree(card, card->FrameStoreChroma2); + card->FrameStoreChroma2 = BLANK; + DRAMFree(card, card->FrameStoreLumaB); + card->FrameStoreLumaB = BLANK; + DRAMFree(card, card->FrameStoreChromaB); + card->FrameStoreChromaB = BLANK; + card->FrameBuffersAllocated = 0; +// DecoderWriteWord( + return 0; +} + +int DecoderSetFrameBuffers(struct cvdv_cards *card, int lines, // number of lines of the decoded MPEG + int TwoFrames, // 1 if no B-Frames are present in the video stream, thus allowing only 2 framestores + int RMM) // 1 if RMM +{ +#define SEGMENTS 44 // 40..54 for PAL, 44 recommended +#define BUFFERSET(buf,adr,align) if (buf>0) {\ + if (buf&((1<buf=addr;\ + addr>>=align;\ + DecoderWriteByte(card,adr,addr&0xFF);\ + DecoderWriteByte(card,adr+1,(addr>>8)&(0x00FF));\ +} + u32 addr; + int pixel, byteperline; // visible pixel per video line, same for PAL and NTSC + int FrameStoreLuma1, FrameStoreChroma1, + FrameStoreLuma2, FrameStoreChroma2, + FrameStoreLumaB, FrameStoreChromaB; + MDEBUG(1, ": -- DecoderSetFrameBuffers\n"); + DecoderStopDecode(card); + //DecoderStopChannel(card); + //lines=((CCIR601Lines(card->videomode)==625)?576:480); + byteperline = (DecoderReadByte(card, 0x116) & 0x7F) * 8; // main 64-bit reads per line + pixel = byteperline * lines; + FrameStoreLuma1 = FrameStoreLuma2 = FrameStoreLumaB = pixel >> 1; // 8 bit luma per pixel in words + FrameStoreChroma1 = FrameStoreChroma2 = FrameStoreChromaB = + pixel >> 2; // 8+8 bit chroma every 2nd pixel every 2nd line + if (card->FrameBuffersAllocated) + DecoderKillFrameBuffers(card); + BUFFERSET(FrameStoreLuma1, 0x0E0, 5); // Anchor Frame Store 1 + BUFFERSET(FrameStoreChroma1, 0x0E2, 5); + BUFFERSET(FrameStoreLuma2, 0x0E4, 5); // Anchor Frame Store 2 + BUFFERSET(FrameStoreChroma2, 0x0E6, 5); + if (TwoFrames) { + DecoderDelByte(card, 0x0F8, 0x01); + } else { +// if (CCIR601Lines(card->videomode)==525) { // Normal Mode, NTSC + if (!RMM) { // Normal Mode, NTSC + BUFFERSET(FrameStoreLumaB, 0x0E8, 5); // B Frame Store + BUFFERSET(FrameStoreChromaB, 0x0EA, 5); + DecoderDelByte(card, 0x0F8, 0x01); + } else { // Reduced Memory Mode, PAL + // 44 segments with 8 lines each (8 bit luma + 4 bit chroma) + // only display modes 4-8, 10, and 11 are allowed + FrameStoreLumaB = + (8 * byteperline * SEGMENTS) >> 1; + FrameStoreChromaB = + (4 * byteperline * SEGMENTS) >> 1; + BUFFERSET(FrameStoreLumaB, 0x0E8, 5); // B Frame Store + BUFFERSET(FrameStoreChromaB, 0x0EA, 5); + DecoderWriteByte(card, 0x121, SEGMENTS << 1); // Number of segments + DecoderSetByte(card, 0x0F8, 0x01); + } + } + card->FrameBuffersAllocated = 1; +#undef SEGMENTS +#undef BUFFERSET + return 0; +} + +// returns size of the Video ES Buffer in bytes or 0=error +u32 DecoderGetVideoESSize(struct cvdv_cards * card) +{ + if (!card->ChannelBuffersAllocated) + return 0; // buffer not initialised + return (u32) ((DecoderReadWord(card, 0x04A) & 0x3FFF) - + (DecoderReadWord(card, 0x048) & 0x3FFF)) * 256; // bytes +} + +// returns level of fullness in bytes +u32 DecoderGetVideoESLevel(struct cvdv_cards * card) +{ + u32 items; + items = DecoderReadByte(card, 0x086); + items |= ((DecoderReadWord(card, 0x087) & 0x07FF) << 8); + items *= 8; // 64 bit per item + return items; +} + +// pics=0 --> items=bytes +// pics=1 --> items=pictures +void DecoderSetVideoPanic(struct cvdv_cards *card, int pics, int items) +{ + if (pics < 0) { + DecoderMaskByte(card, 0x045, 0x18, 0x00 << 3); // disable panic mode + } else { + if (pics) { + DecoderWriteMWord(card, 0x086, items & 0x0003FFFF); + DecoderMaskByte(card, 0x045, 0x18, 0x02 << 3); // set panic mode to "number of pictures" in VideoES + } else { + DecoderWriteMWord(card, 0x086, + (items / 8) & 0x0003FFFF); + DecoderMaskByte(card, 0x045, 0x18, 0x01 << 3); // set panic mode to "number of 8-byte-frames" in VideoES + } + } +} + +int DecoderClose(struct cvdv_cards *card) +{ + if (card->DecoderOpen) { + MDEBUG(1, ": -- DecoderClose\n"); + DecoderStopDecode(card); + DecoderKillFrameBuffers(card); + card->DecoderOpen = 0; + card->lastvattr = 0; + return 0; + } else + return 1; +} + +// returns 0 on success, 1 on "picture size too big", 2 on "out of DRAM memory" +int DecoderOpen(struct cvdv_cards *card, int x, int y, // size of the decoded MPEG picture + int aspect, // pixel or picture aspect ratio of the MPEG picture: 1=square pixel 2=3:4 3=9:16 4=1:2.21 + int Field, // 0:Frame (interlaced, MPEG-2) , 1:Field (non-interlaced, MPEG-1) structure + int Letterbox, // 0:PanScan (4:3), 1:letterbox (16:9, 8:3) picture ratio + int RMM) // 1:use ReducedMemoryMode +{ + int mode, // Display Mode + i, factor, // zoom factor + top, bottom, left, right, width, height, newwidth, newheight, // screen size + vaspx, vaspy, // output video pixel aspect ratio + paspx, paspy, // input picture pixel aspect ratio + SIF; // 0:Full (480/576 lines, MPEG-2), 1:SIF (half, 240/288 lines, MPEG-1) resolution + + MDEBUG(1, ": -- DecoderOpen x:%d y:%d asp:%d field:%d lt:%d rmm:%d\n", + x, y, aspect, Field, Letterbox, RMM); + if ((x <= 0) || (y <= 0)) + return 4; // picture too small +//if (card->DecoderOpen) return 3; + DecoderStopDecode(card); + DecoderClose(card); // closes only, if already open + vaspy = 11; + vaspx = ((CCIR601Lines(card->videomode) == 525) ? 10 : 12); // screen pixel aspect ratio + // note: this aspect ratio applies to 704 pixel width, but the card's default is 720, wich is not 3:4 picture aspect ratio anymore!? + i = ((x == 720) ? 704 : x); // 720 wide is overscan of 704 wide + switch (aspect) { // MPEG data pixel aspect ratio + case 1: + paspx = 1; + paspy = 1; + break; + default: + case 2: + paspx = 4 * y; + paspy = 3 * i; + break; + case 3: + paspx = 16 * y; + paspy = 9 * i; + break; + case 4: + paspx = 221 * y; + paspy = 100 * i; + break; + } + top = + DecoderReadByte(card, + 0x129) | ((DecoderReadByte(card, 0x12B) & 0x07) + << 8); // current Start- and End Column + bottom = + DecoderReadByte(card, + 0x12A) | ((DecoderReadByte(card, 0x12B) & 0x70) + << 4); + height = (bottom - top + 1) * 2; // screen (frame) height + left = + DecoderReadByte(card, + 0x12C) | ((DecoderReadByte(card, 0x12E) & 0x07) + << 8); // current Start- and End Row + right = + DecoderReadByte(card, + 0x12D) | ((DecoderReadByte(card, 0x12E) & 0x70) + << 4); + width = (right - left + 1) / 2; // screen width, 2 clocks = 1 pixel + + if (RMM) + DecoderSetByte(card, 0x0F8, 0x01); + else + DecoderDelByte(card, 0x0F8, 0x01); + + DecoderWriteByte(card, 0x0EF, 0x08); + + //if (x>width) { // Is the picture too wide for the screen? + // DecoderSetByte(card,0x112,0x40); // Horiz. 2:1 Filter enable + // x/=2; + //} else { + DecoderDelByte(card, 0x112, 0x40); // Horiz. 2:1 Filter disable + //} + + + + + if (1 /*Letterbox */ ) { // Fit to width, reduce height + newwidth = (x * vaspy * paspx / (paspy * vaspx)); // width in right aspect ratio + if (newwidth <= 360) { // less then about half the screen size? + SIF = 1; + newwidth *= 2; + } else { + SIF = 0; + } + if ((newwidth == 704) || (newwidth == 720)) + width = newwidth; // standard sizes? + newheight = + (y * vaspx * paspy / (paspx * vaspy)) * width / x; + factor = newheight * 100 / y; + printk(KERN_INFO LOGNAME + ": Decoder Open: Display size %d x %d, Picture size %d x %d, Demanded size: %d x %d, factor %d\n", + width, height, x, y, newwidth, newheight, factor); + // 16:9 Letterbox + if ((aspect == 3) + || ((aspect == 0) + && (((factor >= 65) && (factor <= 80)) + || ((factor >= 140) && (factor <= 160))))) { + if (SIF) { // height * 1.5, SIF Letterbox + if (RMM) + return 1; // not supported! + height = (y * 3) / 2 - 2; + mode = 3; + } else { // height * 0.75, 16:9 Letterbox + height = (y * 3) / 4 - 2; + mode = 8; + } + // 2.21:1 Letterbox + } else if ((aspect == 4) + || ((aspect == 0) + && (((factor >= 45) && (factor <= 60)) + || (SIF && ((factor >= 90) + && (factor <= 110)))))) { + if (SIF) { // height * 1 + height = y; + mode = 5; + } else { // height / 2 + height = y / 2; + mode = 11; + } + // 3:4 aspect ratio + } else { + if (SIF) { + height = y * 2; + mode = ((Field && ~RMM) ? 9 : 10); + } else if (newwidth > 720) { // picture too wide, scale down to 3/4 + height = (y * 3) / 4; + mode = 8; + } else { + height = y; + mode = ((Field) ? 7 : 5); +// mode=((Field)?5:7); + } + } + width = (x * vaspy * paspx / (paspy * vaspx)) * height / y; + if (x < width) { // does the picture needs a horizontal blow-up? + DecoderWriteByte(card, 0x115, + ((x * 256 + width - 1) / width) & 0xFF); // Horiz.Filter scale, x/width*256, rounded up + DecoderSetByte(card, 0x114, 0x02); // Horiz.Filter enable + } else if (x == width) { + DecoderWriteByte(card, 0x115, 0); // 1:1 scale + DecoderDelByte(card, 0x114, 0x02); // Horiz.Filter disable + } else if (x <= 720) { + width = x; + DecoderWriteByte(card, 0x115, 0); // 1:1 scale + DecoderDelByte(card, 0x114, 0x02); // Horiz.Filter disable + } else { // picture is more than twice the screen width. sigh. + return 1; + } + } else { // Pan-Scan, fit height to maximum + DecoderSetByte(card, 0x117, 0x40); // pan-scan from bitstream +//TODO + newwidth = (x * vaspy * paspx / (paspy * vaspx)); // width in right aspect ratio + newheight = y; + if (newheight <= 288) { // less then about half the screen size? + SIF = 1; + newheight *= 2; + } else { + SIF = 0; + } + if ((newwidth == 704) || (newwidth == 720)) + width = newwidth; // standard sizes? + //newheight=(y*vaspx*paspy/(paspx*vaspy))*width/x; + factor = newheight * 100 / y; + printk(KERN_INFO LOGNAME + ": Decoder Open: Display size %d x %d, Picture size %d x %d, Demanded size: %d x %d, factor %d\n", + width, height, x, y, newwidth, newheight, factor); + if (aspect == 3) { // 16:9 Letterbox + if (SIF) { // height * 1.5, SIF Letterbox + if (RMM) + return 1; // not supported! + height = (y * 3) / 2; + mode = 3; + } else { // height * 0.75, 16:9 Letterbox + height = (y * 3) / 4; + mode = 8; + } + } else if (aspect == 4) { // 2.21:1 Letterbox + if (SIF) { // height * 1 + height = y; + mode = 5; + } else { // height / 2 + height = y / 2; + mode = 11; + } + } else if (aspect == 2) { // 3:4 aspect ratio + if (SIF) { + height = y * 2; + mode = ((Field && ~RMM) ? 9 : 10); + } else if (newwidth > 720) { // picture too wide, scale down to 3/4 + height = (y * 3) / 4; + mode = 8; + } else { + height = y; + mode = ((Field) ? 7 : 5); +// mode=((Field)?5:7); + } + } + width = (x * vaspy * paspx / (paspy * vaspx)) * height / y; + if (x < width) { // does the picture needs a horizontal blow-up? + DecoderWriteByte(card, 0x115, + ((x * 256 + width - 1) / width) & 0xFF); // Horiz.Filter scale, x/width*256, rounded up + DecoderSetByte(card, 0x114, 0x02); // Horiz.Filter enable + } else if (x == width) { + DecoderWriteByte(card, 0x115, 0); // 1:1 scale + DecoderDelByte(card, 0x114, 0x02); // Horiz.Filter disable + } else if (x <= 720) { + width = x; + DecoderWriteByte(card, 0x115, 0); // 1:1 scale + DecoderDelByte(card, 0x114, 0x02); // Horiz.Filter disable + } else { // picture is more than twice the screen width. sigh. + return 1; + } + } + printk(KERN_INFO LOGNAME + ": Decoder Open: Display size %d x %d, Picture size %d x %d Mode: %d\n", + width, height, x, y, mode); + + // calculate new picture start- and end rows and columns + height /= 2; // convert back to field height + top += ((bottom - top + 1 - height) / 2); + if (top < 0) + top = 0; + bottom = top + height - 1; + width *= 2; // convert back to clocks + left += ((right - left + 1 - width) / 2); + if (left < 0) + left = 0; + right = left + width - 1; + DecoderWriteByte(card, 0x12C, left & 0xFF); // Start- and End Column + DecoderWriteByte(card, 0x12D, right & 0xFF); + DecoderWriteByte(card, 0x12E, + ((right >> 4) & 0x70) | ((left >> 8) & 0x07)); + DecoderWriteByte(card, 0x129, top & 0xFF); // Start- and End Row + DecoderWriteByte(card, 0x12A, bottom & 0xFF); + DecoderWriteByte(card, 0x12b, + ((bottom >> 4) & 0x70) | ((top >> 8) & 0x07)); + + DecoderWriteByte(card, 0x116, ((x + 7) / 8) & 0x7F); // Main Reads per Line + + // set the new mode + DecoderMaskByte(card, 0x114, 0x78, (mode & 0x0F) << 3); + + MDEBUG(3,": Decoder Open: top/bottom/width / left/right/height / main reads %d/%d/%d / %d/%d/%d / %d\n",top,bottom,width,left,right,height,((x+7)/8)&0x7F); + + // set the frame store buffers + if ((i = DecoderSetFrameBuffers(card, y, 0, RMM))) { + MDEBUG(0,": SetFrameBuffers failed for buffer at 0x%03X\n",i); + DecoderKillFrameBuffers(card); + return 2; + } + + card->lastvattr = 0; + card->DecoderOpen = 1; + return 0; +} + +// displays a still image, whose pixel data is in luma and chroma +int DecoderShowStill(struct cvdv_cards *card, int width, int height, + u8 * luma, u8 * chroma) +{ + u16 addr; + DecoderOpen(card, width, height, + (((width == 320) || (width == 640) || (width == 384) + || (width == 768)) ? 1 : 2), + ((height < 313) ? 1 : 0), 1, 0); + addr = + ((DecoderReadWord(card, 0x11D) == DecoderReadWord(card, 0x0E0)) + ? 0x0E4 : 0x0E0); // choose invisible frame + DRAMWriteByte(card, DecoderReadWord(card, addr) << 5, + width * height, luma, 1); + DRAMWriteByte(card, DecoderReadWord(card, addr + 2) << 5, + width * height / 2, chroma, 1); + DecoderStillImageDisplay(card, ((height < 313) ? 2 : 1), + DecoderReadByte(card, 0x116) & 0x7F, + DecoderReadWord(card, addr), + DecoderReadWord(card, addr + 2)); + VideoSetBackground(card, 0, 0, 0, 0); // video on black + return 0; +} + +// TODO: untested, probably won't work (have to use "main reads per line" instead of width on SIF) +int DecoderGetStill(struct cvdv_cards *card, int *width, int *height, + u8 * luma, u8 * chroma) +{ + int framebuffer; + if (card->DecoderOpen) { + //*width=((DecoderReadByte(card,0x12D)|((DecoderReadByte(card,0x12E)&0x70)<<4))-(DecoderReadByte(card,0x12C)|((DecoderReadByte(card,0x12E)&0x07)<<8))+1)/2; // screen width, 2 clocks = 1 pixel + *width = DecoderReadByte(card, 0x116) * 8; + *height = + ((DecoderReadByte + (card, + 0x12A) | ((DecoderReadByte(card, 0x12B) & 0x70) << + 4)) - + (DecoderReadByte(card, 0x129) | + ((DecoderReadByte(card, 0x12B) & 0x07) << 8)) + 1) * 2; // screen (frame) height + if ((luma != NULL) && (chroma != NULL)) { + framebuffer = + (((DecoderReadByte(card, 0x0EE) & 0x0C) == 1) ? + 0x0E4 : 0x0E0); + DRAMReadByte(card, + DecoderReadWord(card, + framebuffer) << 5, + (*width) * (*height), luma, 1); + DRAMReadByte(card, + DecoderReadWord(card, + framebuffer + 2) << 5, + (*width) * (*height) / 2, chroma, 1); + } + return 0; + } else + return 1; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/video.h linux.19pre5-ac1/drivers/media/video/margi/video.h --- linux.19p5/drivers/media/video/margi/video.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/media/video/margi/video.h Thu Apr 4 15:55:29 2002 @@ -0,0 +1,85 @@ +/* + video.h + + Copyright (C) Christian Wolff for convergence integrated media. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef CVDV_VIDEO_H +#define CVDV_VIDEO_H + + // + // Video Decoder +// + +#include "cardbase.h" + +// Set the background of the OSD and SPU and it's color +// mode=0: Video on Black +// mode=1: Black +// mode=2: Selected Color +// mode=3: Video on Selected Color +void VideoSetBackground(struct cvdv_cards *card, int mode, u8 Y, u8 Cb, + u8 Cr); + + +int DecoderStartDecode(struct cvdv_cards *card); + +int DecoderStopDecode(struct cvdv_cards *card); + +// Sets Display Override (Still Image Display) to Frame Buffer at specified addresses, +// addresses are 16 bit, in 64 byte resolution +// mode: 0=off, 1=Frame, 2=Field +// width: width of the still picture in 8 pixel units +int DecoderStillImageDisplay(struct cvdv_cards *card, int mode, int width, + u16 LumaAddr, u16 ChromaAddr); + +// Frees allocated frame buffers +int DecoderKillFrameBuffers(struct cvdv_cards *card); + +int DecoderSetFrameBuffers(struct cvdv_cards *card, int lines, // number of lines of the decoded MPEG + int TwoFrames, // 1 if no B-Frames are present in the video stream, thus allowing only 2 framestores + int RMM); // 1 if RMM + +// returns size of the Video ES Buffer in bytes or 0=error +u32 DecoderGetVideoESSize(struct cvdv_cards *card); + +// returns level of fullness in bytes +u32 DecoderGetVideoESLevel(struct cvdv_cards *card); + +// pics=0 --> items=bytes +// pics=1 --> items=pictures +void DecoderSetVideoPanic(struct cvdv_cards *card, int pics, int items); + +int DecoderClose(struct cvdv_cards *card); + +// returns 0 on success, 1 on "picture size too big", 2 on "out of DRAM memory" +int DecoderOpen(struct cvdv_cards *card, int x, int y, // size of the decoded MPEG picture + int aspect, // pixel or picture aspect ratio of the MPEG picture: 1=square pixel 2=3:4 3=9:16 4=1:2.21 + int Field, // 0:Frame (interlaced, MPEG-2) , 1:Field (non-interlaced, MPEG-1) structure + int Letterbox, // 0:PanScan (4:3), 1:letterbox (16:9, 8:3) picture ratio // TODO, ignored for now + int RMM // 1:use ReducedMemoryMode + ); + +// displays a still image, whose pixel data is in luma and chroma +int DecoderShowStill(struct cvdv_cards *card, int width, int height, + u8 * luma, u8 * chroma); + +// TODO: untested, probably won't work (have to use "main reads per line" instead of width on SIF) +int DecoderGetStill(struct cvdv_cards *card, int *width, int *height, + u8 * luma, u8 * chroma); + +#endif /* CVDV_VIDEO_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/message/i2o/Makefile linux.19pre5-ac1/drivers/message/i2o/Makefile --- linux.19p5/drivers/message/i2o/Makefile Thu Apr 4 13:19:52 2002 +++ linux.19pre5-ac1/drivers/message/i2o/Makefile Sun Mar 10 01:30:21 2002 @@ -9,8 +9,13 @@ export-objs := i2o_pci.o i2o_core.o i2o_config.o i2o_block.o i2o_lan.o i2o_scsi.o i2o_proc.o +# +# Do not touch the order here +# We must link i2o_core, then i2o_pci, then protocols +# +obj-$(CONFIG_I2O) += i2o_core.o obj-$(CONFIG_I2O_PCI) += i2o_pci.o -obj-$(CONFIG_I2O) += i2o_core.o i2o_config.o +obj-$(CONFIG_I2O) += i2o_config.o obj-$(CONFIG_I2O_BLOCK) += i2o_block.o obj-$(CONFIG_I2O_LAN) += i2o_lan.o obj-$(CONFIG_I2O_SCSI) += i2o_scsi.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/message/i2o/i2o_block.c linux.19pre5-ac1/drivers/message/i2o/i2o_block.c --- linux.19p5/drivers/message/i2o/i2o_block.c Thu Apr 4 13:19:52 2002 +++ linux.19pre5-ac1/drivers/message/i2o/i2o_block.c Thu Mar 14 23:07:16 2002 @@ -143,6 +143,7 @@ int done_flag; int constipated; int depth; + int rwcache; }; /* @@ -264,9 +265,9 @@ /* * Build the message based on the request. */ - __raw_writel(i2ob_context|(unit<<8), msg+8); - __raw_writel(ireq->num, msg+12); - __raw_writel(req->nr_sectors << 9, msg+20); + i2o_raw_writel(i2ob_context|(unit<<8), msg+8); + i2o_raw_writel(ireq->num, msg+12); + i2o_raw_writel(req->nr_sectors << 9, msg+20); /* * Mask out partitions from now on @@ -276,31 +277,32 @@ /* This can be optimised later - just want to be sure its right for starters */ offset = ((u64)(req->sector+base)) << 9; - __raw_writel( offset & 0xFFFFFFFF, msg+24); - __raw_writel(offset>>32, msg+28); + i2o_raw_writel( offset & 0xFFFFFFFF, msg+24); + i2o_raw_writel(offset>>32, msg+28); mptr=msg+32; if(req->cmd == READ) { DEBUG("READ\n"); - __raw_writel(I2O_CMD_BLOCK_READ<<24|HOST_TID<<12|tid, msg+4); + i2o_raw_writel(I2O_CMD_BLOCK_READ<<24|HOST_TID<<12|tid, msg+4); while(bh!=NULL) { if(bh->b_data == last) { size += bh->b_size; last += bh->b_size; if(bh->b_reqnext) - __raw_writel(0x14000000|(size), mptr-8); + i2o_raw_writel(0x14000000|(size), mptr-8); else - __raw_writel(0xD4000000|(size), mptr-8); + i2o_raw_writel(0xD4000000|(size), mptr-8); } else { if(bh->b_reqnext) - __raw_writel(0x10000000|(bh->b_size), mptr); + i2o_raw_writel(0x10000000|(bh->b_size), mptr); else - __raw_writel(0xD0000000|(bh->b_size), mptr); - __raw_writel(virt_to_bus(bh->b_data), mptr+4); + i2o_raw_writel(0xD0000000|(bh->b_size), mptr); + /* FIXME: pci map */ + i2o_raw_writel(virt_to_bus(bh->b_data), mptr+4); mptr += 8; size = bh->b_size; last = bh->b_data + size; @@ -315,32 +317,34 @@ * readahead on controller. If its small then don't read * ahead but do use the controller cache. */ - if(size >= 8192) - __raw_writel((8<<24)|(1<<16)|8, msg+16); + if(!dev->rwcache) + i2o_raw_writel(0, msg+16); + else if(size >= 8192) + i2o_raw_writel((8<<24)|8, msg+16); else - __raw_writel((8<<24)|(1<<16)|4, msg+16); + i2o_raw_writel((8<<24)|4, msg+16); } else if(req->cmd == WRITE) { DEBUG("WRITE\n"); - __raw_writel(I2O_CMD_BLOCK_WRITE<<24|HOST_TID<<12|tid, msg+4); + i2o_raw_writel(I2O_CMD_BLOCK_WRITE<<24|HOST_TID<<12|tid, msg+4); while(bh!=NULL) { if(bh->b_data == last) { size += bh->b_size; last += bh->b_size; if(bh->b_reqnext) - __raw_writel(0x14000000|(size), mptr-8); + i2o_raw_writel(0x14000000|(size), mptr-8); else - __raw_writel(0xD4000000|(size), mptr-8); + i2o_raw_writel(0xD4000000|(size), mptr-8); } else { if(bh->b_reqnext) - __raw_writel(0x14000000|(bh->b_size), mptr); + i2o_raw_writel(0x14000000|(bh->b_size), mptr); else - __raw_writel(0xD4000000|(bh->b_size), mptr); - __raw_writel(virt_to_bus(bh->b_data), mptr+4); + i2o_raw_writel(0xD4000000|(bh->b_size), mptr); + i2o_raw_writel(virt_to_bus(bh->b_data), mptr+4); mptr += 8; size = bh->b_size; last = bh->b_data + size; @@ -350,30 +354,28 @@ bh = bh->b_reqnext; } - if(c->battery) + if(!dev->rwcache) + i2o_raw_writel(0, msg+16); + else if(c->battery) { - - if(size>16384) - __raw_writel(4, msg+16); - else - /* - * Allow replies to come back once data is cached in the controller - * This allows us to handle writes quickly thus giving more of the - * queue to reads. - */ - __raw_writel(16, msg+16); + /* + * Allow replies to come back once data is cached in the controller + * This allows us to handle writes quickly thus giving more of the + * queue to reads. + */ + i2o_raw_writel(16, msg+16); } else { /* Large write, don't cache */ - if(size>8192) - __raw_writel(4, msg+16); + if(size>=65536) + i2o_raw_writel(4, msg+16); else - /* write through */ - __raw_writel(8, msg+16); + /* write through */ + i2o_raw_writel(8, msg+16); } } - __raw_writel(I2O_MESSAGE_SIZE(mptr-msg)>>2 | SGL_OFFSET_8, msg); + i2o_raw_writel(I2O_MESSAGE_SIZE(mptr-msg)>>2 | SGL_OFFSET_8, msg); if(count != 0) { @@ -405,6 +407,8 @@ static inline void i2ob_end_request(struct request *req) { + /* FIXME - pci unmap the request */ + /* * Loop until all of the buffers that are linked * to this request have been marked updated and @@ -491,11 +495,11 @@ * thing for other cases too. */ - __raw_writel(FIVE_WORD_MSG_SIZE|SGL_OFFSET_0, msg); - __raw_writel(I2O_CMD_BLOCK_CFLUSH<<24|HOST_TID<<12|d->tid, msg+4); - __raw_writel(i2ob_context|(unit<<8), msg+8); - __raw_writel(0, msg+12); - __raw_writel(60<<16, msg+16); + i2o_raw_writel(FIVE_WORD_MSG_SIZE|SGL_OFFSET_0, msg); + i2o_raw_writel(I2O_CMD_BLOCK_CFLUSH<<24|HOST_TID<<12|d->tid, msg+4); + i2o_raw_writel(i2ob_context|(unit<<8), msg+8); + i2o_raw_writel(0, msg+12); + i2o_raw_writel(60<<16, msg+16); DEBUG("FLUSH"); i2o_post_message(c,m); return 0; @@ -531,7 +535,7 @@ * We increment the error count and abort it * * In theory this will never happen. The I2O block class - * speficiation states that block devices never return + * specification states that block devices never return * FAILs but instead use the REQ status field...but * better be on the safe side since no one really follows * the spec to the book :) @@ -634,7 +638,7 @@ spin_lock_irqsave(&io_request_lock, flags); - if(err==4) + if(err==4 && c->bus.pci.queue_buggy) { /* * Time to uncork stuff @@ -734,6 +738,7 @@ u32 evt_indicator; u8 ASC; u8 ASCQ; + u16 pad; u8 data[16]; } *evt_local; @@ -764,8 +769,8 @@ evt_local = (struct i2o_reply *)evt_msg; spin_unlock_irqrestore(&i2ob_evt_lock, flags); - unit = evt_local->header[3]; - evt = evt_local->evt_indicator; + unit = le32_to_cpu(evt_local->header[3]); + evt = le32_to_cpu(evt_local->evt_indicator); switch(evt) { @@ -1151,11 +1156,6 @@ dev = &i2ob_dev[minor]; switch (cmd) { - case BLKGETSIZE: - return put_user(i2ob[minor].nr_sects, (long *) arg); - case BLKGETSIZE64: - return put_user((u64)i2ob[minor].nr_sects << 9, (u64 *)arg); - case HDIO_GETGEO: { struct hd_geometry g; @@ -1171,16 +1171,8 @@ return -EACCES; return do_i2ob_revalidate(inode->i_rdev,1); - case BLKFLSBUF: - case BLKROSET: - case BLKROGET: - case BLKRASET: - case BLKRAGET: - case BLKPG: - return blk_ioctl(inode->i_rdev, cmd, arg); - default: - return -EINVAL; + return blk_ioctl(inode->i_rdev, cmd, arg); } } @@ -1219,7 +1211,7 @@ */ u32 msg[5]; int *query_done = &dev->done_flag; - msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0; + msg[0] = (FIVE_WORD_MSG_SIZE|SGL_OFFSET_0); msg[1] = I2O_CMD_BLOCK_CFLUSH<<24|HOST_TID<<12|dev->tid; msg[2] = i2ob_context|0x40000000; msg[3] = (u32)query_done; @@ -1370,17 +1362,22 @@ for(i=unit;i<=unit+15;i++) { + i2ob_dev[i].rwcache = 1; /* Use cache hints */ i2ob_max_sectors[i] = 256; i2ob_dev[i].max_segments = (d->controller->status_block->inbound_frame_size - 8)/2; if(d->controller->type == I2O_TYPE_PCI && d->controller->bus.pci.queue_buggy == 2) + { i2ob_dev[i].depth = 32; + i2ob_dev[i].rwcache = 0; + } if(d->controller->type == I2O_TYPE_PCI && d->controller->bus.pci.queue_buggy == 1) { i2ob_max_sectors[i] = 32; i2ob_dev[i].max_segments = 8; i2ob_dev[i].depth = 4; + i2ob_dev[i].rwcache = 0; } if(d->controller->type == I2O_TYPE_PCI && d->controller->bus.pci.short_req) @@ -1859,11 +1856,7 @@ * (Just smiley confuses emacs :-) */ -#ifdef MODULE -#define i2o_block_init init_module -#endif - -int i2o_block_init(void) +static int i2o_block_init(void) { int i; @@ -1968,15 +1961,8 @@ return 0; } -#ifdef MODULE - -EXPORT_NO_SYMBOLS; -MODULE_AUTHOR("Red Hat Software"); -MODULE_DESCRIPTION("I2O Block Device OSM"); -MODULE_LICENSE("GPL"); - -void cleanup_module(void) +static void i2o_block_exit(void) { int i; @@ -2036,4 +2022,11 @@ del_gendisk(&i2ob_gendisk); } -#endif + +EXPORT_NO_SYMBOLS; +MODULE_AUTHOR("Red Hat Software"); +MODULE_DESCRIPTION("I2O Block Device OSM"); +MODULE_LICENSE("GPL"); + +module_init(i2o_block_init); +module_exit(i2o_block_exit); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/message/i2o/i2o_config.c linux.19pre5-ac1/drivers/message/i2o/i2o_config.c --- linux.19p5/drivers/message/i2o/i2o_config.c Thu Apr 4 13:19:52 2002 +++ linux.19pre5-ac1/drivers/message/i2o/i2o_config.c Sun Mar 10 01:27:08 2002 @@ -908,11 +908,7 @@ &config_fops }; -#ifdef MODULE -int init_module(void) -#else -int __init i2o_config_init(void) -#endif +static int __init i2o_config_init(void) { printk(KERN_INFO "I2O configuration manager v 0.04.\n"); printk(KERN_INFO " (C) Copyright 1999 Red Hat Software\n"); @@ -946,9 +942,7 @@ return 0; } -#ifdef MODULE - -void cleanup_module(void) +static void i2o_config_exit(void) { misc_deregister(&i2o_miscdev); @@ -963,4 +957,5 @@ MODULE_DESCRIPTION("I2O Configuration"); MODULE_LICENSE("GPL"); -#endif +module_init(i2o_config_init); +module_exit(i2o_config_exit); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/message/i2o/i2o_core.c linux.19pre5-ac1/drivers/message/i2o/i2o_core.c --- linux.19p5/drivers/message/i2o/i2o_core.c Thu Apr 4 13:19:52 2002 +++ linux.19pre5-ac1/drivers/message/i2o/i2o_core.c Tue Mar 19 19:19:58 2002 @@ -120,28 +120,6 @@ */ static spinlock_t i2o_dev_lock = SPIN_LOCK_UNLOCKED; -#ifdef MODULE -/* - * Function table to send to bus specific layers - * See for explanation of this - */ -static struct i2o_core_func_table i2o_core_functions = -{ - i2o_install_controller, - i2o_activate_controller, - i2o_find_controller, - i2o_unlock_controller, - i2o_run_queue, - i2o_delete_controller -}; - -#ifdef CONFIG_I2O_PCI_MODULE -extern int i2o_pci_core_attach(struct i2o_core_func_table *); -extern void i2o_pci_core_detach(void); -#endif /* CONFIG_I2O_PCI_MODULE */ - -#endif /* MODULE */ - /* * Structures and definitions for synchronous message posting. * See i2o_post_wait() for description. @@ -2013,10 +1991,10 @@ */ msg[6] = 0x54000000 | sys_tbl_len; msg[7] = virt_to_bus(sys_tbl); - msg[8] = 0x54000000 | 8; - msg[9] = virt_to_bus(privbuf); - msg[10] = 0xD4000000 | 8; - msg[11] = virt_to_bus(privbuf+2); + msg[8] = 0x54000000 | privbuf[1]; + msg[9] = privbuf[0]; + msg[10] = 0xD4000000 | privbuf[3]; + msg[11] = privbuf[2]; ret=i2o_post_wait_mem(iop, msg, sizeof(msg), 120, privbuf, NULL); @@ -2479,9 +2457,8 @@ sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ?? sys_tbl->iops[count].iop_capabilities = iop->status_block->iop_capabilities; - sys_tbl->iops[count].inbound_low = - (u32)virt_to_bus(iop->post_port); - sys_tbl->iops[count].inbound_high = 0; // TODO: 64-bit support + sys_tbl->iops[count].inbound_low = iop->post_port; + sys_tbl->iops[count].inbound_high = 0; // FIXME: 64-bit support count++; } @@ -3433,6 +3410,10 @@ EXPORT_SYMBOL(i2o_install_handler); EXPORT_SYMBOL(i2o_remove_handler); +EXPORT_SYMBOL(i2o_install_controller); +EXPORT_SYMBOL(i2o_delete_controller); +EXPORT_SYMBOL(i2o_run_queue); + EXPORT_SYMBOL(i2o_claim_device); EXPORT_SYMBOL(i2o_release_device); EXPORT_SYMBOL(i2o_device_notify_on); @@ -3457,37 +3438,26 @@ EXPORT_SYMBOL(i2o_get_class_name); -#ifdef MODULE MODULE_AUTHOR("Red Hat Software"); MODULE_DESCRIPTION("I2O Core"); MODULE_LICENSE("GPL"); - - -int init_module(void) +static int i2o_core_init(void) { printk(KERN_INFO "I2O Core - (C) Copyright 1999 Red Hat Software\n"); if (i2o_install_handler(&i2o_core_handler) < 0) { - printk(KERN_ERR - "i2o_core: Unable to install core handler.\nI2O stack not loaded!"); + printk(KERN_ERR "i2o_core: Unable to install core handler.\nI2O stack not loaded!"); return 0; } core_context = i2o_core_handler.context; /* - * Attach core to I2O PCI transport (and others as they are developed) - */ -#ifdef CONFIG_I2O_PCI_MODULE - if(i2o_pci_core_attach(&i2o_core_functions) < 0) - printk(KERN_INFO "i2o: No PCI I2O controllers found\n"); -#endif - - /* * Initialize event handling thread */ + init_MUTEX_LOCKED(&evt_sem); evt_pid = kernel_thread(i2o_core_evt, &evt_reply, CLONE_SIGHAND); if(evt_pid < 0) @@ -3507,7 +3477,7 @@ return 0; } -void cleanup_module(void) +static void i2o_core_exit(void) { int stat; @@ -3528,73 +3498,10 @@ } printk("done.\n"); } - -#ifdef CONFIG_I2O_PCI_MODULE - i2o_pci_core_detach(); -#endif - i2o_remove_handler(&i2o_core_handler); - unregister_reboot_notifier(&i2o_reboot_notifier); } -#else - -extern int i2o_block_init(void); -extern int i2o_config_init(void); -extern int i2o_lan_init(void); -extern int i2o_pci_init(void); -extern int i2o_proc_init(void); -extern int i2o_scsi_init(void); - -int __init i2o_init(void) -{ - printk(KERN_INFO "Loading I2O Core - (c) Copyright 1999 Red Hat Software\n"); - - if (i2o_install_handler(&i2o_core_handler) < 0) - { - printk(KERN_ERR - "i2o_core: Unable to install core handler.\nI2O stack not loaded!"); - return 0; - } - - core_context = i2o_core_handler.context; - - /* - * Initialize event handling thread - * We may not find any controllers, but still want this as - * down the road we may have hot pluggable controllers that - * need to be dealt with. - */ - init_MUTEX_LOCKED(&evt_sem); - if((evt_pid = kernel_thread(i2o_core_evt, &evt_reply, CLONE_SIGHAND)) < 0) - { - printk(KERN_ERR "I2O: Could not create event handler kernel thread\n"); - i2o_remove_handler(&i2o_core_handler); - return 0; - } - +module_init(i2o_core_init); +module_exit(i2o_core_exit); -#ifdef CONFIG_I2O_PCI - i2o_pci_init(); -#endif - - if(i2o_num_controllers) - i2o_sys_init(); - - register_reboot_notifier(&i2o_reboot_notifier); - - i2o_config_init(); -#ifdef CONFIG_I2O_BLOCK - i2o_block_init(); -#endif -#ifdef CONFIG_I2O_LAN - i2o_lan_init(); -#endif -#ifdef CONFIG_I2O_PROC - i2o_proc_init(); -#endif - return 0; -} - -#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/message/i2o/i2o_lan.c linux.19pre5-ac1/drivers/message/i2o/i2o_lan.c --- linux.19p5/drivers/message/i2o/i2o_lan.c Thu Apr 4 13:19:52 2002 +++ linux.19pre5-ac1/drivers/message/i2o/i2o_lan.c Sun Mar 10 01:27:46 2002 @@ -1430,11 +1430,7 @@ return dev; } -#ifdef MODULE -#define i2o_lan_init init_module -#endif - -int __init i2o_lan_init(void) +static int __init i2o_lan_init(void) { struct net_device *dev; int i; @@ -1515,9 +1511,7 @@ return 0; } -#ifdef MODULE - -void cleanup_module(void) +static void i2o_lan_exit(void) { int i; @@ -1576,4 +1570,5 @@ MODULE_PARM(tx_batch_mode, "0-2" "i"); MODULE_PARM_DESC(tx_batch_mode, "0=Send immediatelly, 1=Send in batches, 2=Switch automatically"); -#endif +module_init(i2o_lan_init); +module_exit(i2o_lan_exit); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/message/i2o/i2o_pci.c linux.19pre5-ac1/drivers/message/i2o/i2o_pci.c --- linux.19p5/drivers/message/i2o/i2o_pci.c Thu Apr 4 13:19:52 2002 +++ linux.19pre5-ac1/drivers/message/i2o/i2o_pci.c Sun Mar 10 01:22:05 2002 @@ -15,6 +15,8 @@ * * TODO: * Support polled I2O PCI controllers. + * 2.4 hotplug support + * Finish verifying 64bit/bigendian clean */ #include @@ -31,18 +33,6 @@ #include #endif // CONFIG_MTRR -#ifdef MODULE -/* - * Core function table - * See for an explanation - */ -static struct i2o_core_func_table *core; - -/* Core attach function */ -extern int i2o_pci_core_attach(struct i2o_core_func_table *); -extern void i2o_pci_core_detach(void); -#endif /* MODULE */ - /* * Free bus specific resources */ @@ -62,8 +52,7 @@ } /* - * No real bus specific handling yet (note that later we will - * need to 'steal' PCI devices on i960 mainboards) + * No real bus specific handling yet. */ static int i2o_pci_bind(struct i2o_controller *c, struct i2o_device *dev) @@ -81,6 +70,7 @@ /* * Bus specific enable/disable functions */ + static void i2o_pci_enable(struct i2o_controller *c) { I2O_IRQ_WRITE32(c, 0); @@ -100,23 +90,20 @@ static void i2o_pci_interrupt(int irq, void *dev_id, struct pt_regs *r) { struct i2o_controller *c = dev_id; -#ifdef MODULE - core->run_queue(c); -#else i2o_run_queue(c); -#endif /* MODULE */ } /* * Install a PCI (or in theory AGP) i2o controller * - * TODO: Add support for polled controllers + * TODO: Add support for polled controllers */ + int __init i2o_pci_install(struct pci_dev *dev) { struct i2o_controller *c=kmalloc(sizeof(struct i2o_controller), GFP_KERNEL); - u8 *mem; + unsigned long mem; u32 memptr = 0; u32 size; @@ -150,8 +137,8 @@ /* Map the I2O controller */ printk(KERN_INFO "i2o: PCI I2O controller at 0x%08X size=%d\n", memptr, size); - mem = ioremap(memptr, size); - if(mem==NULL) + mem = (unsigned long)ioremap(memptr, size); + if(mem==0) { printk(KERN_ERR "i2o: Unable to map controller.\n"); kfree(c); @@ -164,12 +151,12 @@ c->bus.pci.short_req = 0; c->pdev = dev; - c->irq_mask = (volatile u32 *)(mem+0x34); - c->post_port = (volatile u32 *)(mem+0x40); - c->reply_port = (volatile u32 *)(mem+0x44); + c->irq_mask = mem+0x34; + c->post_port = mem+0x40; + c->reply_port = mem+0x44; c->mem_phys = memptr; - c->mem_offset = (u32)mem; + c->mem_offset = mem; c->destructor = i2o_pci_dispose; c->bind = i2o_pci_bind; @@ -192,8 +179,11 @@ if(dev->subsystem_vendor == PCI_VENDOR_ID_PROMISE) { c->bus.pci.queue_buggy=1; + /* Build 60 at least needs queue_buggy of 1 */ +#if 0 if (dev->subsystem_device == 0x0000) /* SX6000 ???? */ c->bus.pci.queue_buggy=2; +#endif printk(KERN_INFO "I2O: Promise workarounds activated.\n"); } @@ -211,10 +201,11 @@ #ifdef CONFIG_MTRR c->bus.pci.mtrr_reg0 = mtrr_add(c->mem_phys, size, MTRR_TYPE_WRCOMB, 1); -/* -* If it is an INTEL i960 I/O processor then set the first 64K to Uncacheable -* since the region contains the Messaging unit which shouldn't be cached. -*/ + /* + * If it is an INTEL i960 I/O processor then set the first 64K to + * Uncacheable since the region contains the Messaging unit which + * shouldn't be cached. + */ c->bus.pci.mtrr_reg1 = -1; if(dev->vendor == PCI_VENDOR_ID_INTEL || dev->vendor == PCI_VENDOR_ID_DPT) { @@ -232,17 +223,13 @@ I2O_IRQ_WRITE32(c,0xFFFFFFFF); -#ifdef MODULE - i = core->install(c); -#else i = i2o_install_controller(c); -#endif /* MODULE */ if(i<0) { printk(KERN_ERR "i2o: Unable to install controller.\n"); kfree(c); - iounmap(mem); + iounmap((void *)mem); return i; } @@ -256,12 +243,8 @@ printk(KERN_ERR "%s: unable to allocate interrupt %d.\n", c->name, dev->irq); c->bus.pci.irq = -1; -#ifdef MODULE - core->delete(c); -#else i2o_delete_controller(c); -#endif /* MODULE */ - iounmap(mem); + iounmap((void *)mem); return -EBUSY; } } @@ -310,84 +293,22 @@ return count?count:-ENODEV; } -#ifdef I2O_HOTPLUG_SUPPORT -/* - * Activate a newly found PCI I2O controller - * Not used now, but will be needed in future for - * hot plug PCI support - */ -static void i2o_pci_activate(i2o_controller * c) -{ - int i=0; - struct i2o_controller *c; - - if(c->type == I2O_TYPE_PCI) - { - I2O_IRQ_WRITE32(c,0); -#ifdef MODULE - if(core->activate(c)) -#else - if(i2o_activate_controller(c)) -#endif /* MODULE */ - { - printk("%s: Failed to initialize.\n", c->name); -#ifdef MODULE - core->unlock(c); - core->delete(c); -#else - i2o_unlock_controller(c); - i2o_delete_controller(c); -#endif - continue; - } - } -} -#endif // I2O_HOTPLUG_SUPPORT - -#ifdef MODULE -int i2o_pci_core_attach(struct i2o_core_func_table *table) -{ - MOD_INC_USE_COUNT; - - core = table; - - return i2o_pci_scan(); -} - -void i2o_pci_core_detach(void) -{ - core = NULL; - - MOD_DEC_USE_COUNT; -} - -int init_module(void) +static int i2o_pci_core_attach(void) { printk(KERN_INFO "Linux I2O PCI support (c) 1999 Red Hat Software.\n"); - - core = NULL; - - return 0; - + if(i2o_pci_scan()>0) + return 0; + return -ENODEV; } -void cleanup_module(void) +static void i2o_pci_core_detach(void) { } -EXPORT_SYMBOL(i2o_pci_core_attach); -EXPORT_SYMBOL(i2o_pci_core_detach); - MODULE_AUTHOR("Red Hat Software"); MODULE_DESCRIPTION("I2O PCI Interface"); MODULE_LICENSE("GPL"); - -#else -void __init i2o_pci_init(void) -{ - printk(KERN_INFO "Linux I2O PCI support (c) 1999 Red Hat Software.\n"); - i2o_pci_scan(); -} -#endif +module_init(i2o_pci_core_attach); +module_exit(i2o_pci_core_detach); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/message/i2o/i2o_proc.c linux.19pre5-ac1/drivers/message/i2o/i2o_proc.c --- linux.19p5/drivers/message/i2o/i2o_proc.c Thu Apr 4 13:19:52 2002 +++ linux.19pre5-ac1/drivers/message/i2o/i2o_proc.c Sun Mar 10 01:32:07 2002 @@ -20,18 +20,12 @@ * LAN entries by Juha Sievänen (Juha.Sievanen@cs.Helsinki.FI), * Auvo Häkkinen (Auvo.Hakkinen@cs.Helsinki.FI) * University of Helsinki, Department of Computer Science - */ - -/* - * set tabstop=3 - */ - -/* - * TODO List * - * - Add support for any version 2.0 spec changes once 2.0 IRTOS is - * is available to test with - * - Clean up code to use official structure definitions + * Some cleanup (c) 2002 Red Hat + * Working to make I2O 64bit safe and following the PCI API + * + * TODO List + * - Clean up code to use official structure definitions */ // FIXME! @@ -3371,8 +3365,5 @@ i2o_remove_handler(&i2o_proc_handler); } -#ifdef MODULE module_init(i2o_proc_init); -#endif module_exit(i2o_proc_exit); - diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/message/i2o/i2o_scsi.c linux.19pre5-ac1/drivers/message/i2o/i2o_scsi.c --- linux.19p5/drivers/message/i2o/i2o_scsi.c Thu Apr 4 13:19:52 2002 +++ linux.19pre5-ac1/drivers/message/i2o/i2o_scsi.c Thu Feb 14 14:49:00 2002 @@ -119,14 +119,12 @@ int i; unsigned long flags; - save_flags(flags); - cli(); - + spin_lock_irqsave(&io_request_lock, flags); for(i=0;i>8); - st=(u8)(m[4]>>24); + ds=(u8)le32_to_cpu(m[4]); + as=(u8)le32_to_cpu(m[4]>>8); + st=(u8)le32_to_cpu(m[4]>>24); dprintk(("i2o got a scsi reply %08X: ", m[0])); dprintk(("m[2]=%08X: ", m[2])); @@ -231,7 +228,10 @@ printk(KERN_ERR "i2o_scsi: bus reset reply.\n"); return; } - + + /* + * FIXME: 64bit breakage + */ current_command = (Scsi_Cmnd *)m[3]; /* @@ -252,11 +252,11 @@ if(st == 0x06) { - if(m[5] < current_command->underflow) + if(le32_to_cpu(m[5]) < current_command->underflow) { int i; printk(KERN_ERR "SCSI: underflow 0x%08X 0x%08X\n", - m[5], current_command->underflow); + le32_to_cpu(m[5]), current_command->underflow); printk("Cmd: "); for(i=0;i<15;i++) printk("%02X ", current_command->cmnd[i]); @@ -319,7 +319,7 @@ return 0; } -void i2o_scsi_init(struct i2o_controller *c, struct i2o_device *d, struct Scsi_Host *shpnt) +static void i2o_scsi_init(struct i2o_controller *c, struct i2o_device *d, struct Scsi_Host *shpnt) { struct i2o_device *unit; struct i2o_scsi_host *h =(struct i2o_scsi_host *)shpnt->hostdata; @@ -379,7 +379,7 @@ } } -int i2o_scsi_detect(Scsi_Host_Template * tpnt) +static int i2o_scsi_detect(Scsi_Host_Template * tpnt) { unsigned long flags; struct Scsi_Host *shpnt = NULL; @@ -473,7 +473,7 @@ return count; } -int i2o_scsi_release(struct Scsi_Host *host) +static int i2o_scsi_release(struct Scsi_Host *host) { if(--i2o_scsi_hosts==0) { @@ -490,45 +490,14 @@ } -const char *i2o_scsi_info(struct Scsi_Host *SChost) +static const char *i2o_scsi_info(struct Scsi_Host *SChost) { struct i2o_scsi_host *hostdata; - hostdata = (struct i2o_scsi_host *)SChost->hostdata; - return(&hostdata->controller->name[0]); } - -/* - * From the wd93 driver: - * Returns true if there will be a DATA_OUT phase with this command, - * false otherwise. - * (Thanks to Joerg Dorchain for the research and suggestion.) - * - */ -static int is_dir_out(Scsi_Cmnd *cmd) -{ - switch (cmd->cmnd[0]) - { - case WRITE_6: case WRITE_10: case WRITE_12: - case WRITE_LONG: case WRITE_SAME: case WRITE_BUFFER: - case WRITE_VERIFY: case WRITE_VERIFY_12: - case COMPARE: case COPY: case COPY_VERIFY: - case SEARCH_EQUAL: case SEARCH_HIGH: case SEARCH_LOW: - case SEARCH_EQUAL_12: case SEARCH_HIGH_12: case SEARCH_LOW_12: - case FORMAT_UNIT: case REASSIGN_BLOCKS: case RESERVE: - case MODE_SELECT: case MODE_SELECT_10: case LOG_SELECT: - case SEND_DIAGNOSTIC: case CHANGE_DEFINITION: case UPDATE_BLOCK: - case SET_WINDOW: case MEDIUM_SCAN: case SEND_VOLUME_TAG: - case 0xea: - return 1; - default: - return 0; - } -} - -int i2o_scsi_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *)) +static int i2o_scsi_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *)) { int i; int tid; @@ -594,9 +563,10 @@ do { mb(); - m = I2O_POST_READ32(c); + m = le32_to_cpu(I2O_POST_READ32(c)); } while(m==0xFFFFFFFF); + msg = (u32 *)(c->mem_offset + m); /* @@ -606,28 +576,29 @@ len = SCpnt->request_bufflen; direction = 0x00000000; // SGL IN (osm<--iop) - /* - * The scsi layer should be handling this stuff - */ - - scsidir = 0x00000000; // DATA NO XFER - if(len) + if(SCpnt->sc_data_direction == SCSI_DATA_NONE) + scsidir = 0x00000000; // DATA NO XFER + else if(SCpnt->sc_data_direction == SCSI_DATA_WRITE) { - if(is_dir_out(SCpnt)) - { - direction=0x04000000; // SGL OUT (osm-->iop) - scsidir =0x80000000; // DATA OUT (iop-->dev) - } - else - { - scsidir =0x40000000; // DATA IN (iop<--dev) - } + direction=0x04000000; // SGL OUT (osm-->iop) + scsidir =0x80000000; // DATA OUT (iop-->dev) + } + else if(SCpnt->sc_data_direction == SCSI_DATA_READ) + { + scsidir =0x40000000; // DATA IN (iop<--dev) + } + else + { + /* Unknown - kill the command */ + SCpnt->result = DID_NO_CONNECT << 16; + done(SCpnt); + return 0; } - __raw_writel(I2O_CMD_SCSI_EXEC<<24|HOST_TID<<12|tid, &msg[1]); - __raw_writel(scsi_context, &msg[2]); /* So the I2O layer passes to us */ + i2o_raw_writel(I2O_CMD_SCSI_EXEC<<24|HOST_TID<<12|tid, &msg[1]); + i2o_raw_writel(scsi_context, &msg[2]); /* So the I2O layer passes to us */ /* Sorry 64bit folks. FIXME */ - __raw_writel((u32)SCpnt, &msg[3]); /* We want the SCSI control block back */ + i2o_raw_writel((u32)SCpnt, &msg[3]); /* We want the SCSI control block back */ /* LSI_920_PCI_QUIRK * @@ -670,7 +641,7 @@ } /* Direction, disconnect ok, tag, CDBLen */ - __raw_writel(scsidir|0x20000000|SCpnt->cmd_len|tag, &msg[4]); + i2o_raw_writel(scsidir|0x20000000|SCpnt->cmd_len|tag, &msg[4]); mptr=msg+5; @@ -690,6 +661,8 @@ * FIXME: we need to set the sglist limits according to the * message size of the I2O controller. We might only have room * for 6 or so worst case + * + * FIXME: pci dma mapping */ if(SCpnt->use_sg) @@ -705,8 +678,8 @@ /* * Need to chain! */ - __raw_writel(direction|0xB0000000|(SCpnt->use_sg*2*4), mptr++); - __raw_writel(virt_to_bus(sg_chain_pool + sg_chain_tag), mptr); + i2o_raw_writel(direction|0xB0000000|(SCpnt->use_sg*2*4), mptr++); + i2o_raw_writel(virt_to_bus(sg_chain_pool + sg_chain_tag), mptr); mptr = (u32*)(sg_chain_pool + sg_chain_tag); if (SCpnt->use_sg > max_sg_len) { @@ -729,22 +702,22 @@ { for(i = 0 ; i < SCpnt->use_sg; i++) { - __raw_writel(direction|0x10000000|sg->length, mptr++); + i2o_raw_writel(direction|0x10000000|sg->length, mptr++); len+=sg->length; - __raw_writel(virt_to_bus(sg->address), mptr++); + i2o_raw_writel(virt_to_bus(sg->address), mptr++); sg++; } /* Make this an end of list. Again evade the 920 bug and unwanted PCI read traffic */ - __raw_writel(direction|0xD0000000|(sg-1)->length, &mptr[-2]); + i2o_raw_writel(direction|0xD0000000|(sg-1)->length, &mptr[-2]); } if(!chain) reqlen = mptr - msg; - __raw_writel(len, lenptr); + i2o_raw_writel(len, lenptr); if(len != SCpnt->underflow) printk("Cmd len %08X Cmd underflow %08X\n", @@ -754,15 +727,15 @@ { dprintk(("non sg for %p, %d\n", SCpnt->request_buffer, SCpnt->request_bufflen)); - __raw_writel(len = SCpnt->request_bufflen, lenptr); + i2o_raw_writel(len = SCpnt->request_bufflen, lenptr); if(len == 0) { reqlen = 9; } else { - __raw_writel(0xD0000000|direction|SCpnt->request_bufflen, mptr++); - __raw_writel(virt_to_bus(SCpnt->request_buffer), mptr++); + i2o_raw_writel(0xD0000000|direction|SCpnt->request_bufflen, mptr++); + i2o_raw_writel(virt_to_bus(SCpnt->request_buffer), mptr++); } } @@ -770,7 +743,7 @@ * Stick the headers on */ - __raw_writel(reqlen<<16 | SGL_OFFSET_10, msg); + i2o_raw_writel(reqlen<<16 | SGL_OFFSET_10, msg); /* Queue the message */ i2o_post_message(c,m); @@ -794,7 +767,7 @@ SCpnt->SCp.Status++; } -int i2o_scsi_command(Scsi_Cmnd * SCpnt) +static int i2o_scsi_command(Scsi_Cmnd * SCpnt) { i2o_scsi_queuecommand(SCpnt, internal_done); SCpnt->SCp.Status = 0; @@ -803,12 +776,12 @@ return SCpnt->result; } -int i2o_scsi_abort(Scsi_Cmnd * SCpnt) +static int i2o_scsi_abort(Scsi_Cmnd * SCpnt) { struct i2o_controller *c; struct Scsi_Host *host; struct i2o_scsi_host *hostdata; - u32 *msg; + unsigned long msg; u32 m; int tid; @@ -832,30 +805,30 @@ do { mb(); - m = I2O_POST_READ32(c); + m = le32_to_cpu(I2O_POST_READ32(c)); } while(m==0xFFFFFFFF); - msg = (u32 *)(c->mem_offset + m); + msg = c->mem_offset + m; - __raw_writel(FIVE_WORD_MSG_SIZE, &msg[0]); - __raw_writel(I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|tid, &msg[1]); - __raw_writel(scsi_context, &msg[2]); - __raw_writel(0, &msg[3]); /* Not needed for an abort */ - __raw_writel((u32)SCpnt, &msg[4]); + i2o_raw_writel(FIVE_WORD_MSG_SIZE, msg); + i2o_raw_writel(I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|tid, msg+4); + i2o_raw_writel(scsi_context, msg+8); + i2o_raw_writel(0, msg+12); /* Not needed for an abort */ + i2o_raw_writel((u32)SCpnt, msg+16); /* FIXME 32bitism */ wmb(); i2o_post_message(c,m); wmb(); return SCSI_ABORT_PENDING; } -int i2o_scsi_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags) +static int i2o_scsi_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags) { int tid; struct i2o_controller *c; struct Scsi_Host *host; struct i2o_scsi_host *hostdata; u32 m; - u32 *msg; + unsigned long msg; /* * Find the TID for the bus @@ -874,7 +847,7 @@ * possibly ? */ - m = I2O_POST_READ32(c); + m = le32_to_cpu(I2O_POST_READ32(c)); /* * No free messages, try again next time - no big deal @@ -883,13 +856,13 @@ if(m == 0xFFFFFFFF) return SCSI_RESET_PUNT; - msg = (u32 *)(c->mem_offset + m); - __raw_writel(FOUR_WORD_MSG_SIZE|SGL_OFFSET_0, &msg[0]); - __raw_writel(I2O_CMD_SCSI_BUSRESET<<24|HOST_TID<<12|tid, &msg[1]); - __raw_writel(scsi_context|0x80000000, &msg[2]); + msg = c->mem_offset + m; + i2o_raw_writel(FOUR_WORD_MSG_SIZE|SGL_OFFSET_0, msg); + i2o_raw_writel(I2O_CMD_SCSI_BUSRESET<<24|HOST_TID<<12|tid, msg+4); + i2o_raw_writel(scsi_context|0x80000000, msg+8); /* We use the top bit to split controller and unit transactions */ /* Now store unit,tid so we can tie the completion back to a specific device */ - __raw_writel(c->unit << 16 | tid, &msg[3]); + i2o_raw_writel(c->unit << 16 | tid, msg+12); wmb(); i2o_post_message(c,m); return SCSI_RESET_PENDING; @@ -899,7 +872,7 @@ * This is anyones guess quite frankly. */ -int i2o_scsi_bios_param(Disk * disk, kdev_t dev, int *ip) +static int i2o_scsi_bios_param(Disk * disk, kdev_t dev, int *ip) { int size; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/message/i2o/i2o_scsi.h linux.19pre5-ac1/drivers/message/i2o/i2o_scsi.h --- linux.19p5/drivers/message/i2o/i2o_scsi.h Thu Apr 4 13:19:52 2002 +++ linux.19pre5-ac1/drivers/message/i2o/i2o_scsi.h Thu Apr 4 16:16:20 2002 @@ -14,15 +14,15 @@ #define I2O_SCSI_CAN_QUEUE 4 #define I2O_SCSI_CMD_PER_LUN 6 -extern int i2o_scsi_detect(Scsi_Host_Template *); -extern const char *i2o_scsi_info(struct Scsi_Host *); -extern int i2o_scsi_command(Scsi_Cmnd *); -extern int i2o_scsi_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); -extern int i2o_scsi_abort(Scsi_Cmnd *); -extern int i2o_scsi_reset(Scsi_Cmnd *, unsigned int); -extern int i2o_scsi_bios_param(Disk *, kdev_t, int *); +static int i2o_scsi_detect(Scsi_Host_Template *); +static const char *i2o_scsi_info(struct Scsi_Host *); +static int i2o_scsi_command(Scsi_Cmnd *); +static int i2o_scsi_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); +static int i2o_scsi_abort(Scsi_Cmnd *); +static int i2o_scsi_reset(Scsi_Cmnd *, unsigned int); +static int i2o_scsi_bios_param(Disk *, kdev_t, int *); extern void i2o_scsi_setup(char *str, int *ints); -extern int i2o_scsi_release(struct Scsi_Host *host); +static int i2o_scsi_release(struct Scsi_Host *host); #define I2OSCSI { \ next: NULL, \ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/3c509.c linux.19pre5-ac1/drivers/net/3c509.c --- linux.19p5/drivers/net/3c509.c Thu Apr 4 13:18:48 2002 +++ linux.19pre5-ac1/drivers/net/3c509.c Sun Mar 3 16:12:26 2002 @@ -45,11 +45,15 @@ - Reviewed against 1.18 from scyld.com v1.18a 17Nov2001 Jeff Garzik - ethtool support + v1.18b 1Mar2002 Zwane Mwaikambo + - Power Management support + v1.18c 1Mar2002 David Ruggiero + - Full duplex support */ #define DRV_NAME "3c509" -#define DRV_VERSION "1.18a" -#define DRV_RELDATE "17Nov2001" +#define DRV_VERSION "1.18c" +#define DRV_RELDATE "1Mar2002" /* A few values that may be tweaked. */ @@ -82,8 +86,9 @@ #include #include #include +#include -static char versionA[] __initdata = DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE "becker@scyld.com\n"; +static char versionA[] __initdata = DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE " becker@scyld.com\n"; static char versionB[] __initdata = "http://www.scyld.com/network/3c509.html\n"; #ifdef EL3_DEBUG @@ -116,7 +121,8 @@ FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11, SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11, SetTxThreshold = 18<<11, SetTxStart = 19<<11, StatsEnable = 21<<11, - StatsDisable = 22<<11, StopCoax = 23<<11,}; + StatsDisable = 22<<11, StopCoax = 23<<11, PowerUp = 27<<11, + PowerDown = 28<<11, PowerAuto = 29<<11}; enum c509status { IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004, @@ -136,7 +142,9 @@ #define WN0_IRQ 0x08 /* Window 0: Set IRQ line in bits 12-15. */ #define WN4_MEDIA 0x0A /* Window 4: Various transcvr/media bits. */ -#define MEDIA_TP 0x00C0 /* Enable link beat and jabber for 10baseT. */ +#define MEDIA_TP 0x00C0 /* Enable link beat and jabber for 10baseT. */ +#define WN4_NETDIAG 0x06 /* Window 4: Net diagnostic */ +#define FD_ENABLE 0x8000 /* Enable full-duplex ("external loopback") */ /* * Must be a power of two (we use a binary and in the @@ -152,6 +160,9 @@ int head, size; struct sk_buff *queue[SKB_QUEUE_SIZE]; char mca_slot; +#ifdef CONFIG_PM + struct pm_dev *pmdev; +#endif }; static int id_port __initdata = 0x110; /* Start with 0x110 to avoid new sound cards.*/ static struct net_device *el3_root_dev; @@ -168,6 +179,13 @@ static void set_multicast_list(struct net_device *dev); static void el3_tx_timeout (struct net_device *dev); static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); +static void el3_down(struct net_device *dev); +static void el3_up(struct net_device *dev); +#ifdef CONFIG_PM +static int el3_suspend(struct pm_dev *pdev); +static int el3_resume(struct pm_dev *pdev); +static int el3_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data); +#endif #ifdef CONFIG_MCA struct el3_mca_adapters_struct { @@ -219,7 +237,7 @@ #endif /* CONFIG_ISAPNP || CONFIG_ISAPNP_MODULE */ static int nopnp; -int __init el3_probe(struct net_device *dev) +int __init el3_probe(struct net_device *dev, int card_idx) { struct el3_private *lp; short lrs_state = 0xff, i; @@ -486,12 +504,18 @@ memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr)); dev->base_addr = ioaddr; dev->irq = irq; - dev->if_port = (dev->mem_start & 0x1f) ? dev->mem_start & 3 : if_port; + + if (dev->mem_start & 0x05) { /* xcvr codes 1/3/4/12 */ + dev->if_port = (dev->mem_start & 0x0f); + } else { /* xcvr codes 0/8 */ + /* use eeprom value, but save user's full-duplex selection */ + dev->if_port = (if_port | (dev->mem_start & 0x08) ); + } { const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"}; printk("%s: 3c5x9 at %#3.3lx, %s port, address ", - dev->name, dev->base_addr, if_names[dev->if_port]); + dev->name, dev->base_addr, if_names[(dev->if_port & 0x03)]); } /* Read in the station address. */ @@ -525,6 +549,16 @@ dev->watchdog_timeo = TX_TIMEOUT; dev->do_ioctl = netdev_ioctl; +#ifdef CONFIG_PM + /* register power management */ + lp->pmdev = pm_register(PM_ISA_DEV, card_idx, el3_pm_callback); + if (lp->pmdev) { + struct pm_dev *p; + p = lp->pmdev; + p->data = (struct net_device *)dev; + } +#endif + /* Fill in the generic fields of the device structure. */ ether_setup(dev); return 0; @@ -581,53 +615,7 @@ printk("%s: Opening, IRQ %d status@%x %4.4x.\n", dev->name, dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS)); - /* Activate board: this is probably unnecessary. */ - outw(0x0001, ioaddr + 4); - - /* Set the IRQ line. */ - outw((dev->irq << 12) | 0x0f00, ioaddr + WN0_IRQ); - - /* Set the station address in window 2 each time opened. */ - EL3WINDOW(2); - - for (i = 0; i < 6; i++) - outb(dev->dev_addr[i], ioaddr + i); - - if (dev->if_port == 3) - /* Start the thinnet transceiver. We should really wait 50ms...*/ - outw(StartCoax, ioaddr + EL3_CMD); - else if (dev->if_port == 0) { - /* 10baseT interface, enabled link beat and jabber check. */ - EL3WINDOW(4); - outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA); - } - - /* Switch to the stats window, and clear all stats by reading. */ - outw(StatsDisable, ioaddr + EL3_CMD); - EL3WINDOW(6); - for (i = 0; i < 9; i++) - inb(ioaddr + i); - inw(ioaddr + 10); - inw(ioaddr + 12); - - /* Switch to register set 1 for normal use. */ - EL3WINDOW(1); - - /* Accept b-case and phys addr only. */ - outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD); - outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */ - - netif_start_queue(dev); - - outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */ - outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */ - /* Allow status bits to be seen. */ - outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD); - /* Ack all pending events, and set active indicator mask. */ - outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq, - ioaddr + EL3_CMD); - outw(SetIntrEnb | IntLatch|TxAvailable|TxComplete|RxComplete|StatsFull, - ioaddr + EL3_CMD); + el3_up(dev); if (el3_debug > 3) printk("%s: Opened 3c509 IRQ %d status %4.4x.\n", @@ -986,23 +974,7 @@ if (el3_debug > 2) printk("%s: Shutting down ethercard.\n", dev->name); - netif_stop_queue(dev); - - /* Turn off statistics ASAP. We update lp->stats below. */ - outw(StatsDisable, ioaddr + EL3_CMD); - - /* Disable the receiver and transmitter. */ - outw(RxDisable, ioaddr + EL3_CMD); - outw(TxDisable, ioaddr + EL3_CMD); - - if (dev->if_port == 3) - /* Turn off thinnet power. Green! */ - outw(StopCoax, ioaddr + EL3_CMD); - else if (dev->if_port == 0) { - /* Disable link beat and jabber, if_port may change ere next open(). */ - EL3WINDOW(4); - outw(inw(ioaddr + WN4_MEDIA) & ~MEDIA_TP, ioaddr + WN4_MEDIA); - } + el3_down(dev); free_irq(dev->irq, dev); /* Switching back to window 0 disables the IRQ. */ @@ -1010,7 +982,6 @@ /* But we explicitly zero the IRQ line select anyway. */ outw(0x0f00, ioaddr + WN0_IRQ); - update_stats(dev); return 0; } @@ -1092,16 +1063,198 @@ return rc; } - + +static void el3_down(struct net_device *dev) +{ + int ioaddr = dev->base_addr; + + netif_stop_queue(dev); + + /* Turn off statistics ASAP. We update lp->stats below. */ + outw(StatsDisable, ioaddr + EL3_CMD); + + /* Disable the receiver and transmitter. */ + outw(RxDisable, ioaddr + EL3_CMD); + outw(TxDisable, ioaddr + EL3_CMD); + + if (dev->if_port == 3) + /* Turn off thinnet power. Green! */ + outw(StopCoax, ioaddr + EL3_CMD); + else if (dev->if_port == 0) { + /* Disable link beat and jabber, if_port may change ere next open(). */ + EL3WINDOW(4); + outw(inw(ioaddr + WN4_MEDIA) & ~MEDIA_TP, ioaddr + WN4_MEDIA); + } + + outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD); + + update_stats(dev); +} + +static void el3_up(struct net_device *dev) +{ + int i, sw_info, net_diag; + int ioaddr = dev->base_addr; + + /* Activating the board required and does no harm otherwise */ + outw(0x0001, ioaddr + 4); + + /* Set the IRQ line. */ + outw((dev->irq << 12) | 0x0f00, ioaddr + WN0_IRQ); + + /* Set the station address in window 2 each time opened. */ + EL3WINDOW(2); + + for (i = 0; i < 6; i++) + outb(dev->dev_addr[i], ioaddr + i); + + if ((dev->if_port & 0x03) == 3) /* BNC interface */ + /* Start the thinnet transceiver. We should really wait 50ms...*/ + outw(StartCoax, ioaddr + EL3_CMD); + else if ((dev->if_port & 0x03) == 0) { /* 10baseT interface */ + /* Combine secondary sw_info word (the adapter level) and primary + sw_info word (duplex setting plus other useless bits) */ + EL3WINDOW(0); + sw_info = (read_eeprom(ioaddr, 0x14) & 0x400f) | + (read_eeprom(ioaddr, 0x0d) & 0xBff0); + + EL3WINDOW(4); + net_diag = inw(ioaddr + WN4_NETDIAG); + net_diag = (net_diag | FD_ENABLE); /* temporarily assume full-duplex will be set */ + printk("%s: ", dev->name); + switch (dev->if_port & 0x0c) { + case 12: + /* force full-duplex mode if 3c5x9b */ + if (sw_info & 0x000f) { + printk("Forcing 3c5x9b full-duplex mode"); + break; + } + case 8: + /* set full-duplex mode based on eeprom config setting */ + if ((sw_info & 0x000f) && (sw_info & 0x8000)) { + printk("Setting 3c5x9b full-duplex mode (from EEPROM configuration bit)"); + break; + } + default: + /* xcvr=(0 || 4) OR user has an old 3c5x9 non "B" model */ + printk("Setting 3c5x9/3c5x9B half-duplex mode"); + net_diag = (net_diag & ~FD_ENABLE); /* disable full duplex */ + } + + outw(net_diag, ioaddr + WN4_NETDIAG); + printk(" if_port: %d, sw_info: %4.4x\n", dev->if_port, sw_info); + if (el3_debug > 3) + printk("%s: 3c5x9 net diag word is now: %4.4x.\n", dev->name, net_diag); + /* Enable link beat and jabber check. */ + outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA); + } + + /* Switch to the stats window, and clear all stats by reading. */ + outw(StatsDisable, ioaddr + EL3_CMD); + EL3WINDOW(6); + for (i = 0; i < 9; i++) + inb(ioaddr + i); + inw(ioaddr + 10); + inw(ioaddr + 12); + + /* Switch to register set 1 for normal use. */ + EL3WINDOW(1); + + /* Accept b-case and phys addr only. */ + outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD); + outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */ + + outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */ + outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */ + /* Allow status bits to be seen. */ + outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD); + /* Ack all pending events, and set active indicator mask. */ + outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq, + ioaddr + EL3_CMD); + outw(SetIntrEnb | IntLatch|TxAvailable|TxComplete|RxComplete|StatsFull, + ioaddr + EL3_CMD); + + netif_start_queue(dev); +} + +/* Power Management support functions */ +#ifdef CONFIG_PM + +static int el3_suspend(struct pm_dev *pdev) +{ + unsigned long flags; + struct net_device *dev; + struct el3_private *lp; + int ioaddr; + + if (!pdev && !pdev->data) + return -EINVAL; + + dev = (struct net_device *)pdev->data; + lp = (struct el3_private *)dev->priv; + ioaddr = dev->base_addr; + + spin_lock_irqsave(&lp->lock, flags); + + if (netif_running(dev)) + netif_device_detach(dev); + + el3_down(dev); + outw(PowerDown, ioaddr + EL3_CMD); + + spin_unlock_irqrestore(&lp->lock, flags); + return 0; +} + +static int el3_resume(struct pm_dev *pdev) +{ + unsigned long flags; + struct net_device *dev; + struct el3_private *lp; + int ioaddr; + + if (!pdev && !pdev->data) + return -EINVAL; + + dev = (struct net_device *)pdev->data; + lp = (struct el3_private *)dev->priv; + ioaddr = dev->base_addr; + + spin_lock_irqsave(&lp->lock, flags); + + outw(PowerUp, ioaddr + EL3_CMD); + el3_up(dev); + + if (netif_running(dev)) + netif_device_attach(dev); + + spin_unlock_irqrestore(&lp->lock, flags); + return 0; +} + +static int el3_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data) +{ + switch (rqst) { + case PM_SUSPEND: + return el3_suspend(pdev); + + case PM_RESUME: + return el3_resume(pdev); + } + return 0; +} + +#endif /* CONFIG_PM */ + #ifdef MODULE /* Parameters that may be passed into the module. */ static int debug = -1; static int irq[] = {-1, -1, -1, -1, -1, -1, -1, -1}; -static int xcvr[] = {-1, -1, -1, -1, -1, -1, -1, -1}; +static int xcvr[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; MODULE_PARM(debug,"i"); MODULE_PARM(irq,"1-8i"); -MODULE_PARM(xcvr,"1-8i"); +MODULE_PARM(xcvr,"1-12i"); MODULE_PARM(max_interrupt_work, "i"); MODULE_PARM_DESC(debug, "EtherLink III debug level (0-6)"); MODULE_PARM_DESC(irq, "EtherLink III IRQ number(s) (assigned)"); @@ -1121,7 +1274,7 @@ el3_debug = debug; el3_root_dev = NULL; - while (el3_probe(0) == 0) { + while (el3_probe(0, el3_cards) == 0) { if (irq[el3_cards] > 1) el3_root_dev->irq = irq[el3_cards]; if (xcvr[el3_cards] >= 0) @@ -1143,7 +1296,12 @@ #ifdef CONFIG_MCA if(lp->mca_slot!=-1) mca_mark_as_unused(lp->mca_slot); -#endif +#endif + +#ifdef CONFIG_PM + if (lp->pmdev) + pm_unregister(lp->pmdev); +#endif next_dev = lp->next_dev; unregister_netdev(el3_root_dev); release_region(el3_root_dev->base_addr, EL3_IO_EXTENT); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/cs89x0.h linux.19pre5-ac1/drivers/net/cs89x0.h --- linux.19p5/drivers/net/cs89x0.h Thu Apr 4 13:18:49 2002 +++ linux.19pre5-ac1/drivers/net/cs89x0.h Tue Mar 26 19:14:18 2002 @@ -385,11 +385,11 @@ #define A_CNF_10B_T 0x0001 #define A_CNF_AUI 0x0002 #define A_CNF_10B_2 0x0004 -#define A_CNF_MEDIA_TYPE 0x0060 -#define A_CNF_MEDIA_AUTO 0x0000 +#define A_CNF_MEDIA_TYPE 0x0070 +#define A_CNF_MEDIA_AUTO 0x0070 #define A_CNF_MEDIA_10B_T 0x0020 #define A_CNF_MEDIA_AUI 0x0040 -#define A_CNF_MEDIA_10B_2 0x0060 +#define A_CNF_MEDIA_10B_2 0x0010 #define A_CNF_DC_DC_POLARITY 0x0080 #define A_CNF_NO_AUTO_POLARITY 0x2000 #define A_CNF_LOW_RX_SQUELCH 0x4000 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/eepro100.c linux.19pre5-ac1/drivers/net/eepro100.c --- linux.19p5/drivers/net/eepro100.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/net/eepro100.c Thu Apr 4 14:28:22 2002 @@ -826,8 +826,9 @@ sp->phy[0] = eeprom[6]; sp->phy[1] = eeprom[7]; sp->rx_bug = (eeprom[3] & 0x03) == 3 ? 0 : 1; - if (((pdev->device > 0x1030 && (pdev->device < 0x1039))) - || (pdev->device == 0x2449)) { + if (((pdev->device > 0x1030 && (pdev->device < 0x103F))) + || (pdev->device == 0x2449) || (pdev->device = 0x2459) + || (pdev->device == 0x245D)) { sp->chip_id = 1; } @@ -1145,7 +1146,7 @@ /* Clear sticky bit. */ mdio_read(ioaddr, phy_num, 1); /* If link beat has returned... */ - if (mdio_read(ioaddr, phy_num, 1) & 0x0004) + if (mdio_read(ioaddr, phy_num, MII_BMSR) & BMSR_LSTATUS) netif_carrier_on(dev); else netif_carrier_off(dev); @@ -2287,8 +2288,17 @@ { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_INTEL, 0x1228, PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, }, { 0,} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/hamradio/mkiss.c linux.19pre5-ac1/drivers/net/hamradio/mkiss.c --- linux.19p5/drivers/net/hamradio/mkiss.c Thu Apr 4 13:18:52 2002 +++ linux.19pre5-ac1/drivers/net/hamradio/mkiss.c Thu Mar 28 22:41:32 2002 @@ -347,6 +347,7 @@ skb->protocol = htons(ETH_P_AX25); netif_rx(skb); tmp_ax->rx_packets++; + tmp_ax->rx_bytes+=count; } /* Encapsulate one AX.25 packet and stuff into a TTY queue. */ @@ -386,6 +387,7 @@ ax->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); actual = ax->tty->driver.write(ax->tty, 0, ax->xbuff, count); ax->tx_packets++; + ax->tx_bytes+=actual; ax->dev->trans_start = jiffies; ax->xleft = count - actual; ax->xhead = ax->xbuff + actual; @@ -394,6 +396,7 @@ ax->mkiss->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); actual = ax->mkiss->tty->driver.write(ax->mkiss->tty, 0, ax->mkiss->xbuff, count); ax->tx_packets++; + ax->tx_bytes+=actual; ax->mkiss->dev->trans_start = jiffies; ax->mkiss->xleft = count - actual; ax->mkiss->xhead = ax->mkiss->xbuff + actual; @@ -709,6 +712,8 @@ stats.rx_packets = ax->rx_packets; stats.tx_packets = ax->tx_packets; + stats.rx_bytes = ax->rx_bytes; + stats.tx_bytes = ax->tx_bytes; stats.rx_dropped = ax->rx_dropped; stats.tx_dropped = ax->tx_dropped; stats.tx_errors = ax->tx_errors; @@ -936,7 +941,7 @@ memcpy(dev->dev_addr, ax25_test, AX25_ADDR_LEN); /* New-style flags. */ - dev->flags = 0; + dev->flags = IFF_BROADCAST | IFF_MULTICAST; return 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/hamradio/mkiss.h linux.19pre5-ac1/drivers/net/hamradio/mkiss.h --- linux.19p5/drivers/net/hamradio/mkiss.h Thu Apr 4 13:18:52 2002 +++ linux.19pre5-ac1/drivers/net/hamradio/mkiss.h Thu Mar 28 22:41:36 2002 @@ -31,6 +31,8 @@ /* SLIP interface statistics. */ unsigned long rx_packets; /* inbound frames counter */ unsigned long tx_packets; /* outbound frames counter */ + unsigned long rx_bytes; /* inbound bytes counter */ + unsigned long tx_bytes; /* outbound bytes counter */ unsigned long rx_errors; /* Parity, etc. errors */ unsigned long tx_errors; /* Planned stuff */ unsigned long rx_dropped; /* No memory for skb */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/pcmcia/wavelan_cs.c linux.19pre5-ac1/drivers/net/pcmcia/wavelan_cs.c --- linux.19p5/drivers/net/pcmcia/wavelan_cs.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/net/pcmcia/wavelan_cs.c Thu Apr 4 13:48:29 2002 @@ -37,12 +37,6 @@ * Apr 2 '98 made changes to bring the i82593 control/int handling in line * with offical specs... * - * Changes: - * Arnaldo Carvalho de Melo - 08/08/2000 - * - reorganize kmallocs in wavelan_attach, checking all for failure - * and releasing the previous allocations if one fails - * - * **************************************************************************** * Copyright 1995 * Anthony D. Joseph @@ -72,6 +66,34 @@ /*------------------------------------------------------------------*/ /* + * Wrapper for disabling interrupts. + * (note : inline, so optimised away) + */ +static inline void +wv_splhi(net_local * lp, + unsigned long * pflags) +{ + spin_lock_irqsave(&lp->spinlock, *pflags); + /* Note : above does the cli(); itself */ +} + +/*------------------------------------------------------------------*/ +/* + * Wrapper for re-enabling interrupts. + */ +static inline void +wv_splx(net_local * lp, + unsigned long * pflags) +{ + spin_unlock_irqrestore(&lp->spinlock, *pflags); + + /* Note : enabling interrupts on the hardware is done in wv_ru_start() + * via : outb(OP1_INT_ENABLE, LCCR(base)); + */ +} + +/*------------------------------------------------------------------*/ +/* * Wrapper for reporting error to cardservices */ static void cs_error(client_handle_t handle, int func, int ret) @@ -103,7 +125,7 @@ /******************* MODEM MANAGEMENT SUBROUTINES *******************/ /* - * Usefull subroutines to manage the modem of the wavelan + * Useful subroutines to manage the modem of the wavelan */ /*------------------------------------------------------------------*/ @@ -138,7 +160,7 @@ { hacr_write(base, hacr); /* delay might only be needed sometimes */ - mdelay(1L); + mdelay(1); } /* hacr_write_slow */ /*------------------------------------------------------------------*/ @@ -529,7 +551,7 @@ lp->curr_point=NULL; /* No default WavePoint */ lp->cell_search=0; - lp->cell_timer.data=(int)lp; /* Start cell expiry timer */ + lp->cell_timer.data=(long)lp; /* Start cell expiry timer */ lp->cell_timer.function=wl_cell_expiry; lp->cell_timer.expires=jiffies+CELL_TIMEOUT; add_timer(&lp->cell_timer); @@ -569,18 +591,18 @@ #endif /* Disable interrupts & save flags */ - spin_lock_irqsave (&lp->lock, flags); + wv_splhi(lp, &flags); m.w.mmw_loopt_sel = (mode==NWID_PROMISC) ? MMW_LOOPT_SEL_DIS_NWID : 0x00; mmc_write(lp->dev->base_addr, (char *)&m.w.mmw_loopt_sel - (char *)&m, (unsigned char *)&m.w.mmw_loopt_sel, 1); - /* ReEnable interrupts & restore flags */ - spin_unlock_irqrestore (&lp->lock, flags); - if(mode==NWID_PROMISC) lp->cell_search=1; else - lp->cell_search=0; + lp->cell_search=0; + + /* ReEnable interrupts & restore flags */ + wv_splx(lp, &flags); } /* Find a record in the WavePoint table matching a given NWID */ @@ -737,7 +759,7 @@ ioaddr_t base = lp->dev->base_addr; mm_t m; unsigned long flags; - + if(wavepoint==lp->curr_point) /* Sanity check... */ { wv_nwid_filter(!NWID_PROMISC,lp); @@ -749,16 +771,16 @@ #endif /* Disable interrupts & save flags */ - spin_lock_irqsave(&lp->lock, flags); - + wv_splhi(lp, &flags); + m.w.mmw_netw_id_l = wavepoint->nwid & 0xFF; m.w.mmw_netw_id_h = (wavepoint->nwid & 0xFF00) >> 8; mmc_write(base, (char *)&m.w.mmw_netw_id_l - (char *)&m, (unsigned char *)&m.w.mmw_netw_id_l, 2); /* ReEnable interrupts & restore flags */ - spin_unlock_irqrestore (&lp->lock, flags); - + wv_splx(lp, &flags); + wv_nwid_filter(!NWID_PROMISC,lp); lp->curr_point=wavepoint; } @@ -775,6 +797,11 @@ wavepoint_history *wavepoint=NULL; /* WavePoint table entry */ net_local *lp=(net_local *)dev->priv; /* Device info */ +#ifdef I_NEED_THIS_FEATURE + /* Some people don't need this, some other may need it */ + nwid=nwid^ntohs(beacon->domain_id); +#endif + #if WAVELAN_ROAMING_DEBUG > 1 printk(KERN_DEBUG "WaveLAN: beacon, dev %s:\n",dev->name); printk(KERN_DEBUG "Domain: %.4X NWID: %.4X SigQual=%d\n",ntohs(beacon->domain_id),nwid,sigqual); @@ -832,7 +859,9 @@ /*------------------------------------------------------------------*/ /* * Routine to synchronously send a command to the i82593 chip. - * Should be called with interrupts enabled. + * Should be called with interrupts disabled. + * (called by wv_packet_write(), wv_ru_stop(), wv_ru_start(), + * wv_82593_config() & wv_diag()) */ static int wv_82593_cmd(device * dev, @@ -841,74 +870,98 @@ int result) { ioaddr_t base = dev->base_addr; - net_local * lp = (net_local *)dev->priv; int status; + int wait_completed; long spin; - u_long flags; /* Spin until the chip finishes executing its current command (if any) */ + spin = 1000; do { - spin_lock_irqsave (&lp->lock, flags); + /* Time calibration of the loop */ + udelay(10); + + /* Read the interrupt register */ outb(OP0_NOP | CR0_STATUS_3, LCCR(base)); status = inb(LCSR(base)); - spin_unlock_irqrestore (&lp->lock, flags); } - while((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE); + while(((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE) && (spin-- > 0)); - /* We are waiting for command completion */ - wv_wait_completed = TRUE; + /* If the interrupt hasn't be posted */ + if(spin <= 0) + { +#ifdef DEBUG_INTERRUPT_ERROR + printk(KERN_INFO "wv_82593_cmd: %s timeout (previous command), status 0x%02x\n", + str, status); +#endif + return(FALSE); + } /* Issue the command to the controller */ outb(cmd, LCCR(base)); - /* If we don't have to check the result of the command */ + /* If we don't have to check the result of the command + * Note : this mean that the irq handler will deal with that */ if(result == SR0_NO_RESULT) - { - wv_wait_completed = FALSE; - return(TRUE); - } + return(TRUE); - /* Busy wait while the LAN controller executes the command. - * Note : wv_wait_completed should be volatile */ - spin = 0; - while(wv_wait_completed && (spin++ < 1000)) - udelay(10); + /* We are waiting for command completion */ + wait_completed = TRUE; - /* If the interrupt handler hasn't be called */ - if(wv_wait_completed) + /* Busy wait while the LAN controller executes the command. */ + spin = 1000; + do { - outb(OP0_NOP, LCCR(base)); + /* Time calibration of the loop */ + udelay(10); + + /* Read the interrupt register */ + outb(CR0_STATUS_0 | OP0_NOP, LCCR(base)); status = inb(LCSR(base)); - if(status & SR0_INTERRUPT) + + /* Check if there was an interrupt posted */ + if((status & SR0_INTERRUPT)) { - /* There was an interrupt : call the interrupt handler */ -#ifdef DEBUG_INTERRUPT_ERROR - printk(KERN_WARNING "wv_82593_cmd: interrupt handler not installed or interrupt disabled\n"); -#endif + /* Acknowledge the interrupt */ + outb(CR0_INT_ACK | OP0_NOP, LCCR(base)); - wavelan_interrupt(dev->irq, (void *) dev, - (struct pt_regs *) NULL); + /* Check if interrupt is a command completion */ + if(((status & SR0_BOTH_RX_TX) != SR0_BOTH_RX_TX) && + ((status & SR0_BOTH_RX_TX) != 0x0) && + !(status & SR0_RECEPTION)) + { + /* Signal command completion */ + wait_completed = FALSE; + } + else + { + /* Note : Rx interrupts will be handled later, because we can + * handle multiple Rx packets at once */ +#ifdef DEBUG_INTERRUPT_INFO + printk(KERN_INFO "wv_82593_cmd: not our interrupt\n"); +#endif + } } - else - { - wv_wait_completed = 0; /* XXX */ + } + while(wait_completed && (spin-- > 0)); + + /* If the interrupt hasn't be posted */ + if(wait_completed) + { #ifdef DEBUG_INTERRUPT_ERROR - printk(KERN_INFO "wv_82593_cmd: %s timeout, status0 0x%02x\n", - str, status); + printk(KERN_INFO "wv_82593_cmd: %s timeout, status 0x%02x\n", + str, status); #endif - /* We probably should reset the controller here */ - return(FALSE); - } + return(FALSE); } - /* Check the return code provided by the interrupt handler against + /* Check the return code returned by the card (see above) against * the expected return code provided by the caller */ - if((lp->status & SR0_EVENT_MASK) != result) + if((status & SR0_EVENT_MASK) != result) { #ifdef DEBUG_INTERRUPT_ERROR - printk(KERN_INFO "wv_82593_cmd: %s failed, status0 = 0x%x\n", - str, lp->status); + printk(KERN_INFO "wv_82593_cmd: %s failed, status = 0x%x\n", + str, status); #endif return(FALSE); } @@ -924,14 +977,16 @@ static inline int wv_diag(device * dev) { + int ret = FALSE; + if(wv_82593_cmd(dev, "wv_diag(): diagnose", OP0_DIAGNOSE, SR0_DIAGNOSE_PASSED)) - return(TRUE); + ret = TRUE; #ifdef DEBUG_CONFIG_ERROR printk(KERN_INFO "wavelan_cs: i82593 Self Test failed!\n"); #endif - return(FALSE); + return(ret); } /* wv_diag */ /*------------------------------------------------------------------*/ @@ -951,15 +1006,6 @@ int chunk_len; char * buf_ptr = buf; -#ifdef OLDIES - /* After having check skb_put (net/core/skbuff.c) in the kernel, it seem - * quite safe to remove this... */ - - /* If buf is NULL, just increment the ring buffer pointer */ - if(buf == NULL) - return((ring_ptr - RX_BASE + len) % RX_SIZE + RX_BASE); -#endif - /* Get all the buffer */ while(len > 0) { @@ -990,70 +1036,32 @@ * wavelan_interrupt is not an option...), so you may experience * some delay sometime... */ -static inline void wv_82593_reconfig (device * dev) +static inline void +wv_82593_reconfig(device * dev) { - net_local *lp = (net_local *) dev->priv; - dev_link_t *link = ((net_local *) dev->priv)->link; + net_local * lp = (net_local *)dev->priv; + dev_link_t * link = ((net_local *) dev->priv)->link; + unsigned long flags; - /* Check if we can do it now ! */ - if (!(link->open)) { - lp->reconfig_82593 = TRUE; + /* Arm the flag, will be cleard in wv_82593_config() */ + lp->reconfig_82593 = TRUE; + + /* Check if we can do it now ! */ + if((link->open) && (netif_running(dev)) && !(netif_queue_stopped(dev))) + { + wv_splhi(lp, &flags); /* Disable interrupts */ + wv_82593_config(dev); + wv_splx(lp, &flags); /* Re-enable interrupts */ + } + else + { #ifdef DEBUG_IOCTL_INFO - printk (KERN_DEBUG "%s: wv_82593_reconfig(): delayed (link = %d)\n", - dev->name, link->open); + printk(KERN_DEBUG + "%s: wv_82593_reconfig(): delayed (state = %lX, link = %d)\n", + dev->name, dev->state, link->open); #endif - } else { - netif_stop_queue (dev); - - lp->reconfig_82593 = FALSE; - wv_82593_config (dev); - netif_wake_queue (dev); - } -} - -#ifdef OLDIES -/*------------------------------------------------------------------*/ -/* - * Dumps the current i82593 receive buffer to the console. - */ -static void wavelan_dump(device *dev) -{ - ioaddr_t base = dev->base_addr; - int i, c; - - /* disable receiver so we can use channel 1 */ - outb(OP0_RCV_DISABLE, LCCR(base)); - - /* reset receive DMA pointer */ - hacr_write_slow(base, HACR_PWR_STAT | HACR_RX_DMA_RESET); - hacr_write(base, HACR_DEFAULT); - - /* dump into receive buffer */ - wv_82593_cmd(dev, "wavelan_dump(): dump", CR0_CHNL|OP0_DUMP, SR0_DUMP_DONE); - - /* set read pointer to start of receive buffer */ - outb(0, PIORL(base)); - outb(0, PIORH(base)); - - printk(KERN_DEBUG "wavelan_cs: dump:\n"); - printk(KERN_DEBUG " 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F"); - for(i = 0; i < 73; i++){ - if((i % 16) == 0) { - printk("\n0x%02x:", i); - if (!i) { - printk(" "); - continue; - } } - c = inb(PIOP(base)); - printk("%02x ", c); - } - printk("\n"); - - /* enable the receiver again */ - wv_ru_start(dev); } -#endif /********************* DEBUG & INFO SUBROUTINES *********************/ /* @@ -1171,6 +1179,8 @@ return; } + wv_splhi(lp, &flags); + /* Read the mmc */ mmc_out(base, mmwoff(0, mmw_freeze), 1); mmc_read(base, 0, (u_char *)&m, sizeof(m)); @@ -1181,6 +1191,8 @@ lp->wstats.discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l; #endif /* WIRELESS_EXT */ + wv_splx(lp, &flags); + printk(KERN_DEBUG "##### wavelan modem status registers: #####\n"); #ifdef DEBUG_SHOW_UNUSED printk(KERN_DEBUG "mmc_unused0[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n", @@ -1265,6 +1277,7 @@ wv_dev_show(device * dev) { printk(KERN_DEBUG "dev:"); + printk(" state=%lX,", dev->state); printk(" trans_start=%ld,", dev->trans_start); printk(" flags=0x%x,", dev->flags); printk("\n"); @@ -1892,7 +1905,7 @@ #endif /* Disable interrupts & save flags */ - spin_lock_irqsave (&lp->lock, flags); + wv_splhi(lp, &flags); /* Look what is the request */ switch(cmd) @@ -1968,7 +1981,7 @@ case SIOCGIWFREQ: /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable) - * (does it work for everybody XXX - especially old cards...) */ + * (does it work for everybody ? - especially old cards...) */ if(!(mmc_in(base, mmroff(0, mmr_fee_status)) & (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) { @@ -2239,15 +2252,17 @@ { struct iw_range range; - /* Set the length (very important for backward compatibility) */ - wrq->u.data.length = sizeof(struct iw_range); + /* Set the length (very important for backward compatibility) */ + wrq->u.data.length = sizeof(struct iw_range); - /* Set all the info we don't care or don't know about to zero */ - memset(&range, 0, sizeof(range)); + /* Set all the info we don't care or don't know about to zero */ + memset(&range, 0, sizeof(range)); - /* Set the Wireless Extension versions */ - range.we_version_compiled = WIRELESS_EXT; - range.we_version_source = 9; /* Nothing for us in v10 and v11 */ +#if WIRELESS_EXT > 10 + /* Set the Wireless Extension versions */ + range.we_version_compiled = WIRELESS_EXT; + range.we_version_source = 9; /* Nothing for us in v10 and v11 */ +#endif /* WIRELESS_EXT > 10 */ /* Set information in the range struct */ range.throughput = 1.4 * 1000 * 1000; /* don't argue on this ! */ @@ -2517,7 +2532,7 @@ } /* ReEnable interrupts & restore flags */ - spin_unlock_irqrestore (&lp->lock, flags); + wv_splx(lp, &flags); #ifdef DEBUG_IOCTL_TRACE printk(KERN_DEBUG "%s: <-wavelan_ioctl()\n", dev->name); @@ -2543,11 +2558,8 @@ printk(KERN_DEBUG "%s: ->wavelan_get_wireless_stats()\n", dev->name); #endif - if (lp == NULL) /* XXX will this ever occur? */ - return NULL; - /* Disable interrupts & save flags */ - spin_lock_irqsave (&lp->lock, flags); + wv_splhi(lp, &flags); wstats = &lp->wstats; @@ -2573,7 +2585,7 @@ wstats->discard.misc = 0L; /* ReEnable interrupts & restore flags */ - spin_unlock_irqrestore (&lp->lock, flags); + wv_splx(lp, &flags); #ifdef DEBUG_IOCTL_TRACE printk(KERN_DEBUG "%s: <-wavelan_get_wireless_stats()\n", dev->name); @@ -2692,12 +2704,6 @@ skb->protocol = eth_type_trans(skb, dev); #ifdef DEBUG_RX_INFO - /* Another glitch : Due to the way the GET_PACKET macro is written, - * we are not sure to have the same thing in skb->data. On the other - * hand, skb->mac.raw is not defined everywhere... - * For versions between 1.2.13 and those where skb->mac.raw appear, - * I don't have a clue... - */ wv_packet_info(skb->mac.raw, sksize, dev->name, "wv_packet_read"); #endif /* DEBUG_RX_INFO */ @@ -2731,9 +2737,7 @@ wl_roam_gather(dev, skb->data, stats); #endif /* WAVELAN_ROAMING */ - /* Spying stuff */ #ifdef WIRELESS_SPY - /* Same as above */ wl_spy_gather(dev, skb->mac.raw + WAVELAN_ADDR_SIZE, stats); #endif /* WIRELESS_SPY */ #ifdef HISTOGRAM @@ -2766,6 +2770,7 @@ * called to do the actual transfer of the card's data including the * ethernet header into a packet consisting of an sk_buff chain. * (called by wavelan_interrupt()) + * Note : the spinlock is already grabbed for us and irq are disabled. */ static inline void wv_packet_rcv(device * dev) @@ -2916,7 +2921,7 @@ printk(KERN_DEBUG "%s: ->wv_packet_write(%d)\n", dev->name, length); #endif - spin_lock_irqsave (&lp->lock, flags); + wv_splhi(lp, &flags); /* Check if we need some padding */ if(clen < ETH_ZLEN) @@ -2946,15 +2951,7 @@ /* Keep stats up to date */ lp->stats.tx_bytes += length; - /* If watchdog not already active, activate it... */ - if (!timer_pending(&lp->watchdog)) - { - /* set timer to expire in WATCHDOG_JIFFIES */ - lp->watchdog.expires = jiffies + WATCHDOG_JIFFIES; - add_timer(&lp->watchdog); - } - - spin_unlock_irqrestore (&lp->lock, flags); + wv_splx(lp, &flags); #ifdef DEBUG_TX_INFO wv_packet_info((u_char *) buf, length, dev->name, "wv_packet_write"); @@ -2963,56 +2960,57 @@ #ifdef DEBUG_TX_TRACE printk(KERN_DEBUG "%s: <-wv_packet_write()\n", dev->name); #endif - - netif_start_queue (dev); } /*------------------------------------------------------------------*/ /* * This routine is called when we want to send a packet (NET3 callback) - * In this routine, we check if the hardware is ready to accept + * In this routine, we check if the harware is ready to accept * the packet. We also prevent reentrance. Then, we call the function * to send the packet... */ -static int wavelan_packet_xmit (struct sk_buff *skb, - device * dev) +static int +wavelan_packet_xmit(struct sk_buff * skb, + device * dev) { - net_local *lp = (net_local *) dev->priv; + net_local * lp = (net_local *)dev->priv; + unsigned long flags; #ifdef DEBUG_TX_TRACE - printk (KERN_DEBUG "%s: ->wavelan_packet_xmit(0x%X)\n", dev->name, - (unsigned) skb); + printk(KERN_DEBUG "%s: ->wavelan_packet_xmit(0x%X)\n", dev->name, + (unsigned) skb); #endif - /* - * For ethernet, fill in the header. - */ + /* + * Block a timer-based transmit from overlapping a previous transmit. + * In other words, prevent reentering this routine. + */ + netif_stop_queue(dev); - netif_stop_queue (dev); + /* If somebody has asked to reconfigure the controller, + * we can do it now */ + if(lp->reconfig_82593) + { + wv_splhi(lp, &flags); /* Disable interrupts */ + wv_82593_config(dev); + wv_splx(lp, &flags); /* Re-enable interrupts */ + /* Note : the configure procedure was totally synchronous, + * so the Tx buffer is now free */ + } - /* - * Block a timer-based transmit from overlapping a previous transmit. - * In other words, prevent reentering this routine. - */ - if (1) { - /* If somebody has asked to reconfigure the controller, we can do it now */ - if (lp->reconfig_82593) { - lp->reconfig_82593 = FALSE; - wv_82593_config (dev); - } #ifdef DEBUG_TX_ERROR - if (skb->next) - printk (KERN_INFO "skb has next\n"); + if (skb->next) + printk(KERN_INFO "skb has next\n"); #endif - wv_packet_write (dev, skb->data, skb->len); - } - dev_kfree_skb (skb); + wv_packet_write(dev, skb->data, skb->len); + + dev_kfree_skb(skb); #ifdef DEBUG_TX_TRACE - printk (KERN_DEBUG "%s: <-wavelan_packet_xmit()\n", dev->name); + printk(KERN_DEBUG "%s: <-wavelan_packet_xmit()\n", dev->name); #endif - return (0); + return(0); } /********************** HARDWARE CONFIGURATION **********************/ @@ -3165,7 +3163,7 @@ */ /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable) - * (does it work for everybody XXX - especially old cards...) */ + * (does it work for everybody ? - especially old cards...) */ /* Note : WFREQSEL verify that it is able to read from EEprom * a sensible frequency (address 0x00) + that MMR_FEE_STATUS_ID * is 0xA (Xilinx version) or 0xB (Ariadne version). @@ -3223,7 +3221,7 @@ wv_ru_stop(device * dev) { ioaddr_t base = dev->base_addr; - net_local *lp = (net_local *) dev->priv; + net_local * lp = (net_local *) dev->priv; unsigned long flags; int status; int spin; @@ -3232,35 +3230,35 @@ printk(KERN_DEBUG "%s: ->wv_ru_stop()\n", dev->name); #endif + wv_splhi(lp, &flags); + /* First, send the LAN controller a stop receive command */ wv_82593_cmd(dev, "wv_graceful_shutdown(): stop-rcv", OP0_STOP_RCV, SR0_NO_RESULT); /* Then, spin until the receive unit goes idle */ - spin = 0; + spin = 300; do { udelay(10); - spin_lock_irqsave (&lp->lock, flags); outb(OP0_NOP | CR0_STATUS_3, LCCR(base)); status = inb(LCSR(base)); - spin_unlock_irqrestore (&lp->lock, flags); } - while(((status & SR3_RCV_STATE_MASK) != SR3_RCV_IDLE) && (spin++ < 300)); + while(((status & SR3_RCV_STATE_MASK) != SR3_RCV_IDLE) && (spin-- > 0)); /* Now, spin until the chip finishes executing its current command */ do { udelay(10); - spin_lock_irqsave (&lp->lock, flags); outb(OP0_NOP | CR0_STATUS_3, LCCR(base)); status = inb(LCSR(base)); - spin_unlock_irqrestore (&lp->lock, flags); } - while(((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE) && (spin++ < 300)); + while(((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE) && (spin-- > 0)); + + wv_splx(lp, &flags); /* If there was a problem */ - if(spin > 300) + if(spin <= 0) { #ifdef DEBUG_CONFIG_ERROR printk(KERN_INFO "%s: wv_ru_stop(): The chip doesn't want to stop...\n", @@ -3287,6 +3285,7 @@ { ioaddr_t base = dev->base_addr; net_local * lp = (net_local *) dev->priv; + unsigned long flags; #ifdef DEBUG_CONFIG_TRACE printk(KERN_DEBUG "%s: ->wv_ru_start()\n", dev->name); @@ -3300,6 +3299,8 @@ if(!wv_ru_stop(dev)) return FALSE; + wv_splhi(lp, &flags); + /* Now we know that no command is being executed. */ /* Set the receive frame pointer and stop pointer */ @@ -3309,8 +3310,17 @@ /* Reset ring management. This sets the receive frame pointer to 1 */ outb(OP1_RESET_RING_MNGMT, LCCR(base)); +#if 0 + /* XXX the i82593 manual page 6-4 seems to indicate that the stop register + should be set as below */ + /* outb(CR1_STOP_REG_UPDATE|((RX_SIZE - 0x40)>> RX_SIZE_SHIFT),LCCR(base));*/ +#elif 0 + /* but I set it 0 instead */ + lp->stop = 0; +#else /* but I set it to 3 bytes per packet less than 8K */ lp->stop = (0 + RX_SIZE - ((RX_SIZE / 64) * 3)) % RX_SIZE; +#endif outb(CR1_STOP_REG_UPDATE | (lp->stop >> RX_SIZE_SHIFT), LCCR(base)); outb(OP1_INT_ENABLE, LCCR(base)); outb(OP1_SWIT_TO_PORT_0, LCCR(base)); @@ -3326,17 +3336,15 @@ #ifdef DEBUG_I82593_SHOW { int status; - unsigned long flags; - int i = 0; + int opri; + int spin = 10000; /* spin until the chip starts receiving */ do { - spin_lock_irqsave (&lp->lock, flags); outb(OP0_NOP | CR0_STATUS_3, LCCR(base)); status = inb(LCSR(base)); - spin_unlock_irqrestore (&lp->lock, flags); - if(i++ > 10000) + if(spin-- <= 0) break; } while(((status & SR3_RCV_STATE_MASK) != SR3_RCV_ACTIVE) && @@ -3345,6 +3353,9 @@ (status & SR3_RCV_STATE_MASK), i); } #endif + + wv_splx(lp, &flags); + #ifdef DEBUG_CONFIG_TRACE printk(KERN_DEBUG "%s: <-wv_ru_start()\n", dev->name); #endif @@ -3363,6 +3374,7 @@ ioaddr_t base = dev->base_addr; net_local * lp = (net_local *) dev->priv; struct i82593_conf_block cfblk; + int ret = TRUE; #ifdef DEBUG_CONFIG_TRACE printk(KERN_DEBUG "%s: ->wv_82593_config()\n", dev->name); @@ -3457,7 +3469,7 @@ hacr_write(base, HACR_DEFAULT); if(!wv_82593_cmd(dev, "wv_82593_config(): configure", OP0_CONFIGURE, SR0_CONFIGURE_DONE)) - return(FALSE); + ret = FALSE; /* Initialize adapter's ethernet MAC address */ outb(TX_BASE & 0xff, PIORL(base)); @@ -3471,7 +3483,7 @@ hacr_write(base, HACR_DEFAULT); if(!wv_82593_cmd(dev, "wv_82593_config(): ia-setup", OP0_IA_SETUP, SR0_IA_SETUP_DONE)) - return(FALSE); + ret = FALSE; #ifdef WAVELAN_ROAMING /* If roaming is enabled, join the "Beacon Request" multicast group... */ @@ -3508,14 +3520,17 @@ hacr_write(base, HACR_DEFAULT); if(!wv_82593_cmd(dev, "wv_82593_config(): mc-setup", OP0_MC_SETUP, SR0_MC_SETUP_DONE)) - return(FALSE); + ret = FALSE; lp->mc_count = dev->mc_count; /* remember to avoid repeated reset */ } + /* Job done, clear the flag */ + lp->reconfig_82593 = FALSE; + #ifdef DEBUG_CONFIG_TRACE printk(KERN_DEBUG "%s: <-wv_82593_config()\n", dev->name); #endif - return(TRUE); + return(ret); } /*------------------------------------------------------------------*/ @@ -3594,6 +3609,8 @@ { net_local * lp = (net_local *) dev->priv; ioaddr_t base = dev->base_addr; + unsigned long flags; + int ret = FALSE; #ifdef DEBUG_CONFIG_TRACE printk(KERN_DEBUG "%s: ->wv_hw_config()\n", dev->name); @@ -3612,50 +3629,78 @@ if(wv_pcmcia_reset(dev) == FALSE) return FALSE; - /* Power UP the module + reset the modem + reset host adapter - * (in fact, reset DMA channels) */ - hacr_write_slow(base, HACR_RESET); - hacr_write(base, HACR_DEFAULT); + /* Disable interrupts */ + wv_splhi(lp, &flags); - /* Check if the module has been powered up... */ - if(hasr_read(base) & HASR_NO_CLK) + /* Disguised goto ;-) */ + do { + /* Power UP the module + reset the modem + reset host adapter + * (in fact, reset DMA channels) */ + hacr_write_slow(base, HACR_RESET); + hacr_write(base, HACR_DEFAULT); + + /* Check if the module has been powered up... */ + if(hasr_read(base) & HASR_NO_CLK) + { #ifdef DEBUG_CONFIG_ERRORS - printk(KERN_WARNING "%s: wv_hw_config(): modem not connected or not a wavelan card\n", - dev->name); + printk(KERN_WARNING "%s: wv_hw_config(): modem not connected or not a wavelan card\n", + dev->name); #endif - return FALSE; - } + break; + } - /* initialize the modem */ - if(wv_mmc_init(dev) == FALSE) - return FALSE; + /* initialize the modem */ + if(wv_mmc_init(dev) == FALSE) + { +#ifdef DEBUG_CONFIG_ERRORS + printk(KERN_WARNING "%s: wv_hw_config(): Can't configure the modem\n", + dev->name); +#endif + break; + } - /* reset the LAN controller (i82593) */ - outb(OP0_RESET, LCCR(base)); - mdelay(1); /* A bit crude ! */ - - /* Initialize the LAN controller */ - if((wv_82593_config(dev) == FALSE) || - (wv_diag(dev) == FALSE)) - { + /* reset the LAN controller (i82593) */ + outb(OP0_RESET, LCCR(base)); + mdelay(1); /* A bit crude ! */ + + /* Initialize the LAN controller */ + if(wv_82593_config(dev) == FALSE) + { #ifdef DEBUG_CONFIG_ERRORS - printk(KERN_INFO "%s: wv_hw_config(): i82593 init failed\n", dev->name); + printk(KERN_INFO "%s: wv_hw_config(): i82593 init failed\n", + dev->name); #endif - return FALSE; - } + break; + } - /* - * insert code for loopback test here - */ + /* Diagnostic */ + if(wv_diag(dev) == FALSE) + { +#ifdef DEBUG_CONFIG_ERRORS + printk(KERN_INFO "%s: wv_hw_config(): i82593 diagnostic failed\n", + dev->name); +#endif + break; + } + + /* + * insert code for loopback test here + */ + + /* The device is now configured */ + lp->configured = 1; + ret = TRUE; + } + while(0); - /* The device is now configured */ - lp->configured = 1; + /* Re-enable interrupts */ + wv_splx(lp, &flags); #ifdef DEBUG_CONFIG_TRACE printk(KERN_DEBUG "%s: <-wv_hw_config()\n", dev->name); #endif - return TRUE; + return(ret); } /*------------------------------------------------------------------*/ @@ -3675,10 +3720,6 @@ printk(KERN_DEBUG "%s: ->wv_hw_reset()\n", dev->name); #endif - /* If watchdog was activated, kill it ! */ - if (timer_pending(&lp->watchdog)) - del_timer(&lp->watchdog); - lp->nresets++; lp->configured = 0; @@ -3786,13 +3827,13 @@ } /* - * Allocate a 4K memory window. Note that the dev_link_t + * Allocate a small memory window. Note that the dev_link_t * structure provides space for one window handle -- if your * device needs several windows, you'll need to keep track of * the handles in your private data structure, link->priv. */ req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; - req.Base = 0; req.Size = 0x1000; + req.Base = req.Size = 0; req.AccessSpeed = mem_speed; link->win = (window_handle_t)link->handle; i = CardServices(RequestWindow, &link->win, &req); @@ -3803,7 +3844,7 @@ } dev->rmem_start = dev->mem_start = - (u_long)ioremap(req.Base, 0x1000); + (u_long)ioremap(req.Base, req.Size); dev->rmem_end = dev->mem_end = dev->mem_start + req.Size; mem.CardOffset = 0; mem.Page = 0; @@ -3817,7 +3858,7 @@ /* Feed device with this info... */ dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; - netif_start_queue (dev); + netif_start_queue(dev); #ifdef DEBUG_CONFIG_INFO printk(KERN_DEBUG "wv_pcmcia_config: MEMSTART 0x%x IRQ %d IOPORT 0x%x\n", @@ -3843,7 +3884,7 @@ return FALSE; } - /* XXX Could you explain me this, Dave ? */ + strcpy(((net_local *) dev->priv)->node.dev_name, dev->name); link->dev = &((net_local *) dev->priv)->node; #ifdef DEBUG_CONFIG_TRACE @@ -3887,7 +3928,7 @@ CardServices(ReleaseIO, link->handle, &link->io); CardServices(ReleaseIRQ, link->handle, &link->irq); - link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING | DEV_STALE_CONFIG); + link->state &= ~(DEV_CONFIG | DEV_STALE_CONFIG); #ifdef DEBUG_CONFIG_TRACE printk(KERN_DEBUG "%s: <- wv_pcmcia_release()\n", dev->name); @@ -3896,7 +3937,7 @@ /*------------------------------------------------------------------*/ /* - * Sometimes, netwave_detach can't be performed following a call from + * Sometimes, wavelan_detach can't be performed following a call from * cardmgr (device still open, pcmcia_release not done) and the device * is put in a STALE_LINK state and remains in memory. * @@ -3970,7 +4011,19 @@ lp = (net_local *) dev->priv; base = dev->base_addr; - spin_lock (&lp->lock); +#ifdef DEBUG_INTERRUPT_INFO + /* Check state of our spinlock (it should be cleared) */ + if(spin_is_locked(&lp->spinlock)) + printk(KERN_DEBUG + "%s: wavelan_interrupt(): spinlock is already locked !!!\n", + dev->name); +#endif + + /* Prevent reentrancy. We need to do that because we may have + * multiple interrupt handler running concurently. + * It is safe because wv_splhi() disable interrupts before aquiring + * the spinlock. */ + spin_lock(&lp->spinlock); /* Treat all pending interrupts */ while(1) @@ -4015,8 +4068,6 @@ break; } - lp->status = status0; /* Save current status (for commands) */ - /* ----------------- RECEIVING PACKET ----------------- */ /* * When the wavelan signal the reception of a new packet, @@ -4054,22 +4105,6 @@ * Most likely : transmission done */ - /* If we are already waiting elsewhere for the command to complete */ - if(wv_wait_completed) - { -#ifdef DEBUG_INTERRUPT_INFO - printk(KERN_DEBUG "%s: wv_interrupt(): command completed\n", - dev->name); -#endif - - /* Signal command completion */ - wv_wait_completed = 0; - - /* Acknowledge the interrupt */ - outb(CR0_INT_ACK | OP0_NOP, LCCR(base)); - continue; - } - /* If a transmission has been done */ if((status0 & SR0_EVENT_MASK) == SR0_TRANSMIT_DONE || (status0 & SR0_EVENT_MASK) == SR0_RETRANSMIT_DONE || @@ -4081,10 +4116,6 @@ dev->name); #endif - /* If watchdog was activated, kill it ! */ - if(timer_pending(&lp->watchdog)) - del_timer(&lp->watchdog); - /* Get transmission status */ tx_status = inb(LCSR(base)); tx_status |= (inb(LCSR(base)) << 8); @@ -4174,7 +4205,7 @@ lp->stats.collisions += (tx_status & TX_NCOL_MASK); lp->stats.tx_packets++; - netif_wake_queue (dev); + netif_wake_queue(dev); outb(CR0_INT_ACK | OP0_NOP, LCCR(base)); /* Acknowledge the interrupt */ } else /* if interrupt = transmit done or retransmit done */ @@ -4185,9 +4216,9 @@ #endif outb(CR0_INT_ACK | OP0_NOP, LCCR(base)); /* Acknowledge the interrupt */ } - } + } /* while(1) */ - spin_unlock_irq (&lp->lock); + spin_unlock(&lp->spinlock); #ifdef DEBUG_INTERRUPT_TRACE printk(KERN_DEBUG "%s: <-wavelan_interrupt()\n", dev->name); @@ -4196,30 +4227,23 @@ /*------------------------------------------------------------------*/ /* - * Watchdog : when we start a transmission, we set a timer in the - * kernel. If the transmission complete, this timer is disabled. If - * it expire, it try to unlock the hardware. + * Watchdog: when we start a transmission, a timer is set for us in the + * kernel. If the transmission completes, this timer is disabled. If + * the timer expires, we are called and we try to unlock the hardware. * - * Note : this watchdog doesn't work on the same principle as the - * watchdog in the ISA driver. I make it this way because the overhead - * of add_timer() and del_timer() is nothing and that it avoid calling - * the watchdog, saving some CPU... If you want to apply the same - * watchdog to the ISA driver, you should be a bit carefull, because - * of the many transmit buffers... - * This watchdog is also move clever, it try to abort the current - * command before reseting everything... + * Note : This watchdog is move clever than the one in the ISA driver, + * because it try to abort the current command before reseting + * everything... + * On the other hand, it's a bit simpler, because we don't have to + * deal with the multiple Tx buffers... */ static void -wavelan_watchdog(u_long a) +wavelan_watchdog(device * dev) { - device * dev; - net_local * lp; - ioaddr_t base; - int spin; - - dev = (device *) a; - base = dev->base_addr; - lp = (net_local *) dev->priv; + net_local * lp = (net_local *) dev->priv; + ioaddr_t base = dev->base_addr; + unsigned long flags; + int aborted = FALSE; #ifdef DEBUG_INTERRUPT_TRACE printk(KERN_DEBUG "%s: ->wavelan_watchdog()\n", dev->name); @@ -4230,21 +4254,21 @@ dev->name); #endif - /* We are waiting for command completion */ - wv_wait_completed = TRUE; + wv_splhi(lp, &flags); /* Ask to abort the current command */ outb(OP0_ABORT, LCCR(base)); - /* Busy wait while the LAN controller executes the command. - * Note : wv_wait_completed should be volatile */ - spin = 0; - while(wv_wait_completed && (spin++ < 250)) - udelay(10); - - /* If the interrupt handler hasn't be called or invalid status */ - if((wv_wait_completed) || - ((lp->status & SR0_EVENT_MASK) != SR0_EXECUTION_ABORTED)) + /* Wait for the end of the command (a bit hackish) */ + if(wv_82593_cmd(dev, "wavelan_watchdog(): abort", + OP0_NOP | CR0_STATUS_3, SR0_EXECUTION_ABORTED)) + aborted = TRUE; + + /* Release spinlock here so that wv_hw_reset() can grab it */ + wv_splx(lp, &flags); + + /* Check if we were successful in aborting it */ + if(!aborted) { /* It seem that it wasn't enough */ #ifdef DEBUG_INTERRUPT_ERROR @@ -4269,7 +4293,7 @@ #endif /* We are no more waiting for something... */ - netif_start_queue (dev); + netif_wake_queue(dev); #ifdef DEBUG_INTERRUPT_TRACE printk(KERN_DEBUG "%s: <-wavelan_watchdog()\n", dev->name); @@ -4322,7 +4346,7 @@ return FALSE; if(!wv_ru_start(dev)) wv_hw_reset(dev); /* If problem : reset */ - netif_start_queue (dev); + netif_start_queue(dev); /* Mark the device as used */ link->open++; @@ -4348,7 +4372,6 @@ wavelan_close(device * dev) { dev_link_t * link = ((net_local *) dev->priv)->link; - net_local * lp = (net_local *)dev->priv; ioaddr_t base = dev->base_addr; #ifdef DEBUG_CALLBACK_TRACE @@ -4356,8 +4379,6 @@ (unsigned int) dev); #endif - netif_stop_queue (dev); - /* If the device isn't open, then nothing to do */ if(!link->open) { @@ -4373,17 +4394,13 @@ wv_roam_cleanup(dev); #endif /* WAVELAN_ROAMING */ - /* If watchdog was activated, kill it ! */ - if(timer_pending(&lp->watchdog)) - del_timer(&lp->watchdog); - link->open--; MOD_DEC_USE_COUNT; /* If the card is still present */ - if (netif_device_present(dev)) + if(netif_running(dev)) { - netif_stop_queue (dev); + netif_stop_queue(dev); /* Stop receiving new messages and wait end of transmission */ wv_ru_stop(dev); @@ -4404,21 +4421,6 @@ /*------------------------------------------------------------------*/ /* - * We never need to do anything when a wavelan device is "initialized" - * by the net software, because we only register already-found cards. - */ -static int -wavelan_init(device * dev) -{ -#ifdef DEBUG_CALLBACK_TRACE - printk(KERN_DEBUG "<>wavelan_init()\n"); -#endif - - return(0); -} - -/*------------------------------------------------------------------*/ -/* * wavelan_attach() creates an "instance" of the driver, allocating * local data structures for one device (one interface). The device * is registered with Card Services. @@ -4445,24 +4447,8 @@ /* Initialize the dev_link_t structure */ link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); - if (!link) - return NULL; - - /* Allocate the generic data structure */ - dev = kmalloc(sizeof(struct net_device), GFP_KERNEL); - if (!dev) - goto fail_alloc_dev; - - /* Allocate the wavelan-specific data structure. */ - lp = (net_local *) kmalloc(sizeof(net_local), GFP_KERNEL); - if (!lp) - goto fail_alloc_dev_priv; - - memset(lp, 0, sizeof(net_local)); + if (!link) return NULL; memset(link, 0, sizeof(struct dev_link_t)); - memset(dev, 0, sizeof(struct net_device)); - - dev->priv = lp; /* Unused for the Wavelan */ link->release.function = &wv_pcmcia_release; @@ -4492,18 +4478,35 @@ link->next = dev_list; dev_list = link; + /* Allocate the generic data structure */ + dev = kmalloc(sizeof(struct net_device), GFP_KERNEL); + if (!dev) { + kfree(link); + return NULL; + } + memset(dev, 0x00, sizeof(struct net_device)); link->priv = link->irq.Instance = dev; + /* Allocate the wavelan-specific data structure. */ + dev->priv = lp = (net_local *) kmalloc(sizeof(net_local), GFP_KERNEL); + if (!lp) { + kfree(link); + kfree(dev); + return NULL; + } + memset(lp, 0x00, sizeof(net_local)); + /* Init specific data */ - wv_wait_completed = 0; - lp->status = FALSE; lp->configured = 0; lp->reconfig_82593 = FALSE; lp->nresets = 0; + /* Multicast stuff */ + lp->promiscuous = 0; + lp->allmulticast = 0; + lp->mc_count = 0; - /* Set the watchdog timer */ - lp->watchdog.function = wavelan_watchdog; - lp->watchdog.data = (unsigned long) dev; + /* Init spinlock */ + spin_lock_init(&lp->spinlock); /* back links */ lp->link = link; @@ -4513,7 +4516,6 @@ ether_setup(dev); /* wavelan NET3 callbacks */ - dev->init = &wavelan_init; dev->open = &wavelan_open; dev->stop = &wavelan_close; dev->hard_start_xmit = &wavelan_packet_xmit; @@ -4523,14 +4525,16 @@ dev->set_mac_address = &wavelan_set_mac_address; #endif /* SET_MAC_ADDRESS */ + /* Set the watchdog timer */ + dev->tx_timeout = &wavelan_watchdog; + dev->watchdog_timeo = WATCHDOG_JIFFIES; + #ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */ dev->do_ioctl = wavelan_ioctl; /* wireless extensions */ dev->get_wireless_stats = wavelan_get_wireless_stats; #endif /* Other specific data */ - strcpy(dev->name, ((net_local *)dev->priv)->node.dev_name); - netif_start_queue (dev); dev->mtu = WAVELAN_MTU; /* Register with Card Services */ @@ -4562,12 +4566,6 @@ #endif return link; - -fail_alloc_dev_priv: - kfree(dev); -fail_alloc_dev: - kfree(link); - return NULL; } /*------------------------------------------------------------------*/ @@ -4698,7 +4696,7 @@ if(link->state & DEV_CONFIG) { /* Accept no more transmissions */ - netif_device_detach(dev); + netif_device_detach(dev); /* Release the card */ wv_pcmcia_release((u_long) link); @@ -4720,7 +4718,7 @@ * obliged to close nicely the wavelan here. David, could you * close the device before suspending them ? And, by the way, * could you, on resume, add a "route add -net ..." after the - * ifconfig up XXX Thanks... */ + * ifconfig up ? Thanks... */ /* Stop receiving new messages and wait end of transmission */ wv_ru_stop(dev); @@ -4735,8 +4733,7 @@ if(link->state & DEV_CONFIG) { if(link->open) - netif_device_detach(dev); - + netif_device_detach(dev); CardServices(ReleaseConfiguration, link->handle); } break; @@ -4748,7 +4745,7 @@ if(link->state & DEV_CONFIG) { CardServices(RequestConfiguration, link->handle, &link->conf); - if(link->open) /* If RESET -> True, If RESUME -> False XXX */ + if(link->open) /* If RESET -> True, If RESUME -> False ? */ { wv_hw_reset(dev); netif_device_attach(dev); @@ -4838,4 +4835,3 @@ module_init(init_wavelan_cs); module_exit(exit_wavelan_cs); -MODULE_LICENSE("Dual BSD/GPL"); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/pcmcia/wavelan_cs.h linux.19pre5-ac1/drivers/net/pcmcia/wavelan_cs.h --- linux.19p5/drivers/net/pcmcia/wavelan_cs.h Thu Apr 4 13:19:00 2002 +++ linux.19pre5-ac1/drivers/net/pcmcia/wavelan_cs.h Thu Apr 4 15:57:56 2002 @@ -34,6 +34,25 @@ * I try to maintain a web page with the Wireless LAN Howto at : * http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Wavelan.html * + * SMP + * --- + * We now are SMP compliant (I eventually fixed the remaining bugs). + * The driver has been tested on a dual P6-150 and survived my usual + * set of torture tests. + * Anyway, I spent enough time chasing interrupt re-entrancy during + * errors or reconfigure, and I designed the locked/unlocked sections + * of the driver with great care, and with the recent addition of + * the spinlock (thanks to the new API), we should be quite close to + * the truth. + * The SMP/IRQ locking is quite coarse and conservative (i.e. not fast), + * but better safe than sorry (especially at 2 Mb/s ;-). + * + * I have also looked into disabling only our interrupt on the card + * (via HACR) instead of all interrupts in the processor (via cli), + * so that other driver are not impacted, and it look like it's + * possible, but it's very tricky to do right (full of races). As + * the gain would be mostly for SMP systems, it can wait... + * * Debugging and options * --------------------- * You will find below a set of '#define" allowing a very fine control @@ -122,7 +141,7 @@ * Yunzhou Li finished is work. * Joe Finney patched the driver to start * correctly 2.00 cards (2.4 GHz with frequency selection). - * David Hinds integrated the whole in his + * David Hinds integrated the whole in his * Pcmcia package (+ bug corrections). * * I (Jean Tourrilhes - jt@hplb.hpl.hp.com) then started to make some @@ -158,8 +177,8 @@ * * This software was originally developed under Linux 1.2.3 * (Slackware 2.0 distribution). - * And then under Linux 2.0.x (Debian 1.1 - pcmcia 2.8.18-23) with - * HP OmniBook 4000 & 5500. + * And then under Linux 2.0.x (Debian 1.1 -> 2.2 - pcmcia 2.8.18+) + * with an HP OmniBook 4000 and then a 5500. * * It is based on other device drivers and information either written * or supplied by: @@ -174,7 +193,7 @@ * Matthew Geier (matthew@cs.su.oz.au), * Remo di Giovanni (remo@cs.su.oz.au), * Mark Hagan (mhagan@wtcpost.daytonoh.NCR.COM), - * David Hinds , + * David Hinds , * Jan Hoogendoorn (c/o marteijn@lucent.com), * Bruce Janson , * Anthony D. Joseph , @@ -349,6 +368,32 @@ * - Fix check for root permission (break instead of exit) * - New nwid & encoding setting (Wireless Extension 9) * + * Changes made for release in 3.1.12 : + * ---------------------------------- + * - reworked wv_82593_cmd to avoid using the IRQ handler and doing + * ugly things with interrupts. + * - Add IRQ protection in 82593_config/ru_start/ru_stop/watchdog + * - Update to new network API (softnet - 2.3.43) : + * o replace dev->tbusy (David + me) + * o replace dev->tstart (David + me) + * o remove dev->interrupt (David) + * o add SMP locking via spinlock in splxx (me) + * o add spinlock in interrupt handler (me) + * o use kernel watchdog instead of ours (me) + * o verify that all the changes make sense and work (me) + * - Re-sync kernel/pcmcia versions (not much actually) + * - A few other cleanups (David & me)... + * + * Changes made for release in 3.1.22 : + * ---------------------------------- + * - Check that SMP works, remove annoying log message + * + * Changes made for release in 3.1.24 : + * ---------------------------------- + * - Fix unfrequent card lockup when watchdog was reseting the hardware : + * o control first busy loop in wv_82593_cmd() + * o Extend spinlock protection in wv_hw_config() + * * Wishes & dreams: * ---------------- * - Cleanup and integrate the roaming code @@ -368,6 +413,7 @@ #include #include #include +#include #include #include #include @@ -384,7 +430,7 @@ #ifdef CONFIG_NET_PCMCIA_RADIO #include /* Wireless extensions */ -#endif /* CONFIG_NET_PCMCIA_RADIO */ +#endif /* Pcmcia headers that we need */ #include @@ -437,7 +483,7 @@ #undef DEBUG_RX_INFO /* Header of the transmitted packet */ #undef DEBUG_RX_FAIL /* Normal failure conditions */ #define DEBUG_RX_ERROR /* Unexpected conditions */ -#undef DEBUG_PACKET_DUMP /* Dump packet on the screen */ +#undef DEBUG_PACKET_DUMP 32 /* Dump packet on the screen */ #undef DEBUG_IOCTL_TRACE /* Misc call by Linux */ #undef DEBUG_IOCTL_INFO /* Various debug info */ #define DEBUG_IOCTL_ERROR /* What's going wrong */ @@ -452,7 +498,7 @@ /************************ CONSTANTS & MACROS ************************/ #ifdef DEBUG_VERSION_SHOW -static const char *version = "wavelan_cs.c : v21 (wireless extensions) 18/10/99\n"; +static const char *version = "wavelan_cs.c : v23 (SMP + wireless extensions) 20/12/00\n"; #endif /* Watchdog temporisation */ @@ -557,9 +603,9 @@ */ struct net_local { - spinlock_t lock; dev_node_t node; /* ???? What is this stuff ???? */ device * dev; /* Reverse link... */ + spinlock_t spinlock; /* Serialize access to the hardware (SMP) */ dev_link_t * link; /* pcmcia structure */ en_stats stats; /* Ethernet interface statistics */ int nresets; /* Number of hw resets */ @@ -568,9 +614,7 @@ u_char promiscuous; /* Promiscuous mode */ u_char allmulticast; /* All Multicast mode */ int mc_count; /* Number of multicast addresses */ - timer_list watchdog; /* To avoid blocking state */ - u_char status; /* Current i82593 status */ int stop; /* Current i82593 Stop Hit Register */ int rfp; /* Last DMA machine receive pointer */ int overrunning; /* Receiver overrun flag */ @@ -617,8 +661,14 @@ #endif /* WAVELAN_ROAMING */ /* ----------------------- MISC SUBROUTINES ------------------------ */ +static inline void + wv_splhi(net_local *, /* Disable interrupts */ + unsigned long *); /* flags */ +static inline void + wv_splx(net_local *, /* ReEnable interrupts */ + unsigned long *); /* flags */ static void - cs_error(client_handle_t, /* Report error to cardmgr */ + cs_error(client_handle_t, /* Report error to cardmgr */ int, int); /* ----------------- MODEM MANAGEMENT SUBROUTINES ----------------- */ @@ -722,16 +772,15 @@ wv_flush_stale_links(void); /* "detach" all possible devices */ /* ---------------------- INTERRUPT HANDLING ---------------------- */ static void -wavelan_interrupt(int, /* Interrupt handler */ - void *, - struct pt_regs *); + wavelan_interrupt(int, /* Interrupt handler */ + void *, + struct pt_regs *); static void - wavelan_watchdog(u_long); /* Transmission watchdog */ + wavelan_watchdog(device *); /* Transmission watchdog */ /* ------------------- CONFIGURATION CALLBACKS ------------------- */ static int wavelan_open(device *), /* Open the device */ - wavelan_close(device *), /* Close the device */ - wavelan_init(device *); /* Do nothing */ + wavelan_close(device *); /* Close the device */ static dev_link_t * wavelan_attach(void); /* Create a new device */ static void @@ -744,11 +793,7 @@ /**************************** VARIABLES ****************************/ static dev_info_t dev_info = "wavelan_cs"; -static dev_link_t *dev_list; /* Linked list of devices */ - -/* WARNING : the following variable MUST be volatile - * It is used by wv_82593_cmd to syncronise with wavelan_interrupt */ -static volatile int wv_wait_completed; +static dev_link_t *dev_list = NULL; /* Linked list of devices */ /* * Parameters that can be set with 'insmod' @@ -761,7 +806,7 @@ static int irq_list[4] = { -1 }; /* Shared memory speed, in ns */ -static int mem_speed; +static int mem_speed = 0; /* New module interface */ MODULE_PARM(irq_mask, "i"); @@ -770,9 +815,11 @@ #ifdef WAVELAN_ROAMING /* Conditional compile, see above in options */ /* Enable roaming mode ? No ! Please keep this to 0 */ -static int do_roaming; +static int do_roaming = 0; MODULE_PARM(do_roaming, "i"); #endif /* WAVELAN_ROAMING */ +MODULE_LICENSE("GPL"); + #endif /* WAVELAN_CS_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/pcnet32.c linux.19pre5-ac1/drivers/net/pcnet32.c --- linux.19p5/drivers/net/pcnet32.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/net/pcnet32.c Tue Mar 26 19:28:07 2002 @@ -511,7 +511,6 @@ struct pci_dev *pdev) { struct pcnet32_private *lp; - struct resource *res; dma_addr_t lp_dma_addr; int i, media; int fdx, mii, fset, dxsuflo, ltint; @@ -544,7 +543,7 @@ /* initialize variables */ fdx = mii = fset = dxsuflo = ltint = 0; chip_version = (chip_version >> 12) & 0xffff; - + switch (chip_version) { case 0x2420: chipname = "PCnet/PCI 79C970"; /* PCI */ @@ -689,13 +688,12 @@ } dev->base_addr = ioaddr; - res = request_region(ioaddr, PCNET32_TOTAL_SIZE, chipname); - if (!res) + if (request_region(ioaddr, PCNET32_TOTAL_SIZE, chipname) == NULL) return -EBUSY; /* pci_alloc_consistent returns page-aligned memory, so we do not have to check the alignment */ if ((lp = pci_alloc_consistent(pdev, sizeof(*lp), &lp_dma_addr)) == NULL) { - release_resource(res); + release_region(ioaddr, PCNET32_TOTAL_SIZE); return -ENOMEM; } @@ -727,7 +725,7 @@ if (!a) { printk(KERN_ERR PFX "No access methods\n"); pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); - release_resource(res); + release_region(ioaddr, PCNET32_TOTAL_SIZE); return -ENODEV; } lp->a = *a; @@ -775,7 +773,7 @@ else { printk(", failed to detect IRQ line.\n"); pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); - release_resource(res); + release_region(ioaddr, PCNET32_TOTAL_SIZE); return -ENODEV; } } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/ppp_deflate.c linux.19pre5-ac1/drivers/net/ppp_deflate.c --- linux.19p5/drivers/net/ppp_deflate.c Thu Apr 4 13:18:56 2002 +++ linux.19pre5-ac1/drivers/net/ppp_deflate.c Thu Mar 14 22:45:37 2002 @@ -39,7 +39,7 @@ #include #include -#include "zlib.c" +#include /* * State for a Deflate (de)compressor. @@ -56,10 +56,6 @@ #define DEFLATE_OVHD 2 /* Deflate overhead/packet */ -static void *zalloc __P((void *, unsigned int items, unsigned int size)); -static void *zalloc_init __P((void *, unsigned int items, - unsigned int size)); -static void zfree __P((void *, void *ptr)); static void *z_comp_alloc __P((unsigned char *options, int opt_len)); static void *z_decomp_alloc __P((unsigned char *options, int opt_len)); static void z_comp_free __P((void *state)); @@ -80,72 +76,6 @@ static void z_decomp_reset __P((void *state)); static void z_comp_stats __P((void *state, struct compstat *stats)); -struct chunk_header { - int valloced; /* allocated with valloc, not kmalloc */ - int guard; /* check for overwritten header */ -}; - -#define GUARD_MAGIC 0x77a8011a -#define MIN_VMALLOC 2048 /* use kmalloc for blocks < this */ - -/* - * Space allocation and freeing routines for use by zlib routines. - */ -void -zfree(arg, ptr) - void *arg; - void *ptr; -{ - struct chunk_header *hdr = ((struct chunk_header *)ptr) - 1; - - if (hdr->guard != GUARD_MAGIC) { - printk(KERN_WARNING "zfree: header corrupted (%x %x) at %p\n", - hdr->valloced, hdr->guard, hdr); - return; - } - if (hdr->valloced) - vfree(hdr); - else - kfree(hdr); -} - -void * -zalloc(arg, items, size) - void *arg; - unsigned int items, size; -{ - struct chunk_header *hdr; - unsigned nbytes; - - nbytes = items * size + sizeof(*hdr); - hdr = kmalloc(nbytes, GFP_ATOMIC); - if (hdr == 0) - return 0; - hdr->valloced = 0; - hdr->guard = GUARD_MAGIC; - return (void *) (hdr + 1); -} - -void * -zalloc_init(arg, items, size) - void *arg; - unsigned int items, size; -{ - struct chunk_header *hdr; - unsigned nbytes; - - nbytes = items * size + sizeof(*hdr); - if (nbytes >= MIN_VMALLOC) - hdr = vmalloc(nbytes); - else - hdr = kmalloc(nbytes, GFP_KERNEL); - if (hdr == 0) - return 0; - hdr->valloced = nbytes >= MIN_VMALLOC; - hdr->guard = GUARD_MAGIC; - return (void *) (hdr + 1); -} - static void z_comp_free(arg) void *arg; @@ -153,7 +83,9 @@ struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg; if (state) { - deflateEnd(&state->strm); + zlib_deflateEnd(&state->strm); + if (state->strm.workspace) + vfree(state->strm.workspace); kfree(state); MOD_DEC_USE_COUNT; } @@ -180,27 +112,27 @@ if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE) return NULL; - state = (struct ppp_deflate_state *) kmalloc(sizeof(*state), GFP_KERNEL); + state = (struct ppp_deflate_state *) kmalloc(sizeof(*state), + GFP_KERNEL); if (state == NULL) return NULL; MOD_INC_USE_COUNT; memset (state, 0, sizeof (struct ppp_deflate_state)); - state->strm.next_in = NULL; - state->strm.zalloc = zalloc_init; - state->strm.zfree = zfree; - state->w_size = w_size; + state->strm.next_in = NULL; + state->w_size = w_size; + state->strm.workspace = vmalloc(zlib_deflate_workspacesize()); + if (state->strm.workspace == NULL) + goto out_free; - if (deflateInit2(&state->strm, Z_DEFAULT_COMPRESSION, + if (zlib_deflateInit2(&state->strm, Z_DEFAULT_COMPRESSION, DEFLATE_METHOD_VAL, -w_size, 8, Z_DEFAULT_STRATEGY) != Z_OK) goto out_free; - state->strm.zalloc = zalloc; return (void *) state; out_free: z_comp_free(state); - MOD_DEC_USE_COUNT; return NULL; } @@ -224,7 +156,7 @@ state->unit = unit; state->debug = debug; - deflateReset(&state->strm); + zlib_deflateReset(&state->strm); return 1; } @@ -236,7 +168,7 @@ struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg; state->seqno = 0; - deflateReset(&state->strm); + zlib_deflateReset(&state->strm); } int @@ -286,7 +218,7 @@ state->strm.avail_in = (isize - off); for (;;) { - r = deflate(&state->strm, Z_PACKET_FLUSH); + r = zlib_deflate(&state->strm, Z_PACKET_FLUSH); if (r != Z_OK) { if (state->debug) printk(KERN_ERR @@ -337,7 +269,9 @@ struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg; if (state) { - inflateEnd(&state->strm); + zlib_inflateEnd(&state->strm); + if (state->strm.workspace) + kfree(state->strm.workspace); kfree(state); MOD_DEC_USE_COUNT; } @@ -370,19 +304,19 @@ MOD_INC_USE_COUNT; memset (state, 0, sizeof (struct ppp_deflate_state)); - state->w_size = w_size; - state->strm.next_out = NULL; - state->strm.zalloc = zalloc_init; - state->strm.zfree = zfree; + state->w_size = w_size; + state->strm.next_out = NULL; + state->strm.workspace = kmalloc(zlib_inflate_workspacesize(), + GFP_KERNEL); + if (state->strm.workspace == NULL) + goto out_free; - if (inflateInit2(&state->strm, -w_size) != Z_OK) + if (zlib_inflateInit2(&state->strm, -w_size) != Z_OK) goto out_free; - state->strm.zalloc = zalloc; return (void *) state; out_free: z_decomp_free(state); - MOD_DEC_USE_COUNT; return NULL; } @@ -407,7 +341,7 @@ state->debug = debug; state->mru = mru; - inflateReset(&state->strm); + zlib_inflateReset(&state->strm); return 1; } @@ -419,7 +353,7 @@ struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg; state->seqno = 0; - inflateReset(&state->strm); + zlib_inflateReset(&state->strm); } /* @@ -492,7 +426,7 @@ * Call inflate, supplying more input or output as needed. */ for (;;) { - r = inflate(&state->strm, Z_PACKET_FLUSH); + r = zlib_inflate(&state->strm, Z_PACKET_FLUSH); if (r != Z_OK) { if (state->debug) printk(KERN_DEBUG "z_decompress%d: inflate returned %d (%s)\n", @@ -575,7 +509,7 @@ ++state->strm.avail_in; } - r = inflateIncomp(&state->strm); + r = zlib_inflateIncomp(&state->strm); if (r != Z_OK) { /* gak! */ if (state->debug) { @@ -657,4 +591,4 @@ module_init(deflate_init); module_exit(deflate_cleanup); -MODULE_LICENSE("BSD without advertisement clause"); +MODULE_LICENSE("Dual BSD/GPL"); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/slip.c linux.19pre5-ac1/drivers/net/slip.c --- linux.19p5/drivers/net/slip.c Thu Apr 4 13:18:48 2002 +++ linux.19pre5-ac1/drivers/net/slip.c Wed Feb 27 18:32:03 2002 @@ -1393,10 +1393,8 @@ /* First of all: check for active disciplines and hangup them. */ do { - if (busy) { - current->counter = 0; - schedule(); - } + if (busy) + sys_sched_yield(); busy = 0; local_bh_disable(); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/zlib.c linux.19pre5-ac1/drivers/net/zlib.c --- linux.19p5/drivers/net/zlib.c Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/net/zlib.c Thu Jan 1 01:00:00 1970 @@ -1,5376 +0,0 @@ -/* - * This file is derived from various .h and .c files from the zlib-1.0.4 - * distribution by Jean-loup Gailly and Mark Adler, with some additions - * by Paul Mackerras to aid in implementing Deflate compression and - * decompression for PPP packets. See zlib.h for conditions of - * distribution and use. - * - * Changes that have been made include: - * - added Z_PACKET_FLUSH (see zlib.h for details) - * - added inflateIncomp and deflateOutputPending - * - allow strm->next_out to be NULL, meaning discard the output - * - * $Id: zlib.c,v 1.3 1997/12/23 10:47:42 paulus Exp $ - */ - -/* - * ==FILEVERSION 20020318== - * - * This marker is used by the Linux installation script to determine - * whether an up-to-date version of this file is already installed. - */ - -#define NO_DUMMY_DECL -#define NO_ZCFUNCS -#define MY_ZCALLOC - -#if defined(__FreeBSD__) && (defined(KERNEL) || defined(_KERNEL)) -#define inflate inflate_ppp /* FreeBSD already has an inflate :-( */ -#endif - - -/* +++ zutil.h */ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-1996 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* From: zutil.h,v 1.16 1996/07/24 13:41:13 me Exp $ */ - -#ifndef _Z_UTIL_H -#define _Z_UTIL_H - -#include "zlib.h" - -#if defined(KERNEL) || defined(_KERNEL) -/* Assume this is a *BSD or SVR4 kernel */ -#include -#include -#include -# define HAVE_MEMCPY -# define memcpy(d, s, n) bcopy((s), (d), (n)) -# define memset(d, v, n) bzero((d), (n)) -# define memcmp bcmp - -#else -#if defined(__KERNEL__) -/* Assume this is a Linux kernel */ -#include -#define HAVE_MEMCPY - -#else /* not kernel */ - -#if defined(MSDOS)||defined(VMS)||defined(CRAY)||defined(WIN32)||defined(RISCOS) -# include -# include -#else - extern int errno; -#endif -#ifdef STDC -# include -# include -#endif -#endif /* __KERNEL__ */ -#endif /* _KERNEL || KERNEL */ - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ -/* (size given to avoid silly warnings with Visual C++) */ - -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] - -#define ERR_RETURN(strm,err) \ - return (strm->msg = (char*)ERR_MSG(err), (err)) -/* To be used only when the state is known to be valid */ - - /* common constants */ - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - - /* target dependencies */ - -#ifdef MSDOS -# define OS_CODE 0x00 -# ifdef __TURBOC__ -# include -# else /* MSC or DJGPP */ -# include -# endif -#endif - -#ifdef OS2 -# define OS_CODE 0x06 -#endif - -#ifdef WIN32 /* Window 95 & Windows NT */ -# define OS_CODE 0x0b -#endif - -#if defined(VAXC) || defined(VMS) -# define OS_CODE 0x02 -# define FOPEN(name, mode) \ - fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") -#endif - -#ifdef AMIGA -# define OS_CODE 0x01 -#endif - -#if defined(ATARI) || defined(atarist) -# define OS_CODE 0x05 -#endif - -#ifdef MACOS -# define OS_CODE 0x07 -#endif - -#ifdef __50SERIES /* Prime/PRIMOS */ -# define OS_CODE 0x0F -#endif - -#ifdef TOPS20 -# define OS_CODE 0x0a -#endif - -#if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ -#endif - - /* Common defaults */ - -#ifndef OS_CODE -# define OS_CODE 0x03 /* assume Unix */ -#endif - -#ifndef FOPEN -# define FOPEN(name, mode) fopen((name), (mode)) -#endif - - /* functions */ - -#ifdef HAVE_STRERROR - extern char *strerror OF((int)); -# define zstrerror(errnum) strerror(errnum) -#else -# define zstrerror(errnum) "" -#endif - -#if defined(pyr) -# define NO_MEMCPY -#endif -#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(_MSC_VER) - /* Use our own functions for small and medium model with MSC <= 5.0. - * You may have to use the same strategy for Borland C (untested). - */ -# define NO_MEMCPY -#endif -#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) -# define HAVE_MEMCPY -#endif -#ifdef HAVE_MEMCPY -# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ -# define zmemcpy _fmemcpy -# define zmemcmp _fmemcmp -# define zmemzero(dest, len) _fmemset(dest, 0, len) -# else -# define zmemcpy memcpy -# define zmemcmp memcmp -# define zmemzero(dest, len) memset(dest, 0, len) -# endif -#else - extern void zmemcpy OF((Bytef* dest, Bytef* source, uInt len)); - extern int zmemcmp OF((Bytef* s1, Bytef* s2, uInt len)); - extern void zmemzero OF((Bytef* dest, uInt len)); -#endif - -/* Diagnostic functions */ -#ifdef DEBUG_ZLIB -# include -# ifndef verbose -# define verbose 0 -# endif - extern void z_error OF((char *m)); -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) fprintf x -# define Tracev(x) {if (verbose) fprintf x ;} -# define Tracevv(x) {if (verbose>1) fprintf x ;} -# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} -# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - - -typedef uLong (*check_func) OF((uLong check, const Bytef *buf, uInt len)); - -voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); -void zcfree OF((voidpf opaque, voidpf ptr)); - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} - -#endif /* _Z_UTIL_H */ -/* --- zutil.h */ - -/* +++ deflate.h */ -/* deflate.h -- internal compression state - * Copyright (C) 1995-1996 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* From: deflate.h,v 1.10 1996/07/02 12:41:00 me Exp $ */ - -#ifndef _DEFLATE_H -#define _DEFLATE_H - -/* #include "zutil.h" */ - -/* =========================================================================== - * Internal compression state. - */ - -#define LENGTH_CODES 29 -/* number of length codes, not counting the special END_BLOCK code */ - -#define LITERALS 256 -/* number of literal bytes 0..255 */ - -#define L_CODES (LITERALS+1+LENGTH_CODES) -/* number of Literal or Length codes, including the END_BLOCK code */ - -#define D_CODES 30 -/* number of distance codes */ - -#define BL_CODES 19 -/* number of codes used to transfer the bit lengths */ - -#define HEAP_SIZE (2*L_CODES+1) -/* maximum heap size */ - -#define MAX_BITS 15 -/* All codes must not exceed MAX_BITS bits */ - -#define INIT_STATE 42 -#define BUSY_STATE 113 -#define FINISH_STATE 666 -/* Stream status */ - - -/* Data structure describing a single value and its code string. */ -typedef struct ct_data_s { - union { - ush freq; /* frequency count */ - ush code; /* bit string */ - } fc; - union { - ush dad; /* father node in Huffman tree */ - ush len; /* length of bit string */ - } dl; -} FAR ct_data; - -#define Freq fc.freq -#define Code fc.code -#define Dad dl.dad -#define Len dl.len - -typedef struct static_tree_desc_s static_tree_desc; - -typedef struct tree_desc_s { - ct_data *dyn_tree; /* the dynamic tree */ - int max_code; /* largest code with non zero frequency */ - static_tree_desc *stat_desc; /* the corresponding static tree */ -} FAR tree_desc; - -typedef ush Pos; -typedef Pos FAR Posf; -typedef unsigned IPos; - -/* A Pos is an index in the character window. We use short instead of int to - * save space in the various tables. IPos is used only for parameter passing. - */ - -typedef struct deflate_state { - z_streamp strm; /* pointer back to this zlib stream */ - int status; /* as the name implies */ - Bytef *pending_buf; /* output still pending */ - ulg pending_buf_size; /* size of pending_buf */ - Bytef *pending_out; /* next pending byte to output to the stream */ - int pending; /* nb of bytes in the pending buffer */ - int noheader; /* suppress zlib header and adler32 */ - Byte data_type; /* UNKNOWN, BINARY or ASCII */ - Byte method; /* STORED (for zip only) or DEFLATED */ - int last_flush; /* value of flush param for previous deflate call */ - - /* used by deflate.c: */ - - uInt w_size; /* LZ77 window size (32K by default) */ - uInt w_bits; /* log2(w_size) (8..16) */ - uInt w_mask; /* w_size - 1 */ - - Bytef *window; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. Also, it limits - * the window size to 64K, which is quite useful on MSDOS. - * To do: use the user input buffer as sliding window. - */ - - ulg window_size; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - Posf *prev; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - Posf *head; /* Heads of the hash chains or NIL. */ - - uInt ins_h; /* hash index of string to be inserted */ - uInt hash_size; /* number of elements in hash table */ - uInt hash_bits; /* log2(hash_size) */ - uInt hash_mask; /* hash_size-1 */ - - uInt hash_shift; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - long block_start; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - uInt match_length; /* length of best match */ - IPos prev_match; /* previous match */ - int match_available; /* set if previous match exists */ - uInt strstart; /* start of string to insert */ - uInt match_start; /* start of matching string */ - uInt lookahead; /* number of valid bytes ahead in window */ - - uInt prev_length; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - uInt max_chain_length; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - uInt max_lazy_match; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ -# define max_insert_length max_lazy_match - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - int level; /* compression level (1..9) */ - int strategy; /* favor or force Huffman coding*/ - - uInt good_match; - /* Use a faster search when the previous match is longer than this */ - - int nice_match; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - /* Didn't use ct_data typedef below to suppress compiler warning */ - struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - struct tree_desc_s l_desc; /* desc. for literal tree */ - struct tree_desc_s d_desc; /* desc. for distance tree */ - struct tree_desc_s bl_desc; /* desc. for bit length tree */ - - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - int heap_len; /* number of elements in the heap */ - int heap_max; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - uch depth[2*L_CODES+1]; - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - uchf *l_buf; /* buffer for literals or lengths */ - - uInt lit_bufsize; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - uInt last_lit; /* running index in l_buf */ - - ushf *d_buf; - /* Buffer for distances. To simplify the code, d_buf and l_buf have - * the same number of elements. To use different lengths, an extra flag - * array would be necessary. - */ - - ulg opt_len; /* bit length of current block with optimal trees */ - ulg static_len; /* bit length of current block with static trees */ - ulg compressed_len; /* total bit length of compressed file */ - uInt matches; /* number of string matches in current block */ - int last_eob_len; /* bit length of EOB code for last block */ - -#ifdef DEBUG_ZLIB - ulg bits_sent; /* bit length of the compressed data */ -#endif - - ush bi_buf; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - int bi_valid; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - -} FAR deflate_state; - -/* Output a byte on the stream. - * IN assertion: there is enough room in pending_buf. - */ -#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} - - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) -/* In order to simplify the code, particularly on 16 bit machines, match - * distances are limited to MAX_DIST instead of WSIZE. - */ - - /* in trees.c */ -void _tr_init OF((deflate_state *s)); -int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); -ulg _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, - int eof)); -void _tr_align OF((deflate_state *s)); -void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, - int eof)); -void _tr_stored_type_only OF((deflate_state *)); - -#endif -/* --- deflate.h */ - -/* +++ deflate.c */ -/* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-1996 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process depends on being able to identify portions - * of the input text which are identical to earlier input (within a - * sliding window trailing behind the input currently being processed). - * - * The most straightforward technique turns out to be the fastest for - * most input files: try all possible matches and select the longest. - * The key feature of this algorithm is that insertions into the string - * dictionary are very simple and thus fast, and deletions are avoided - * completely. Insertions are performed at each input character, whereas - * string matches are performed only when the previous match ends. So it - * is preferable to spend more time in matches to allow very fast string - * insertions and avoid deletions. The matching algorithm for small - * strings is inspired from that of Rabin & Karp. A brute force approach - * is used to find longer strings when a small match has been found. - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze - * (by Leonid Broukhis). - * A previous version of this file used a more sophisticated algorithm - * (by Fiala and Greene) which is guaranteed to run in linear amortized - * time, but has a larger average cost, uses more memory and is patented. - * However the F&G algorithm may be faster for some highly redundant - * files if the parameter max_chain_length (described below) is too large. - * - * ACKNOWLEDGEMENTS - * - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and - * I found it in 'freeze' written by Leonid Broukhis. - * Thanks to many people for bug reports and testing. - * - * REFERENCES - * - * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". - * Available in ftp://ds.internic.net/rfc/rfc1951.txt - * - * A description of the Rabin and Karp algorithm is given in the book - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. - * - * Fiala,E.R., and Greene,D.H. - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 - * - */ - -/* From: deflate.c,v 1.15 1996/07/24 13:40:58 me Exp $ */ - -/* #include "deflate.h" */ - -char deflate_copyright[] = " deflate 1.0.4 Copyright 1995-1996 Jean-loup Gailly "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* =========================================================================== - * Function prototypes. - */ -typedef enum { - need_more, /* block not completed, need more input or more output */ - block_done, /* block flush performed */ - finish_started, /* finish started, need only more output at next deflate */ - finish_done /* finish done, accept no more input or output */ -} block_state; - -typedef block_state (*compress_func) OF((deflate_state *s, int flush)); -/* Compression function. Returns the block state after the call. */ - -local void fill_window OF((deflate_state *s)); -local block_state deflate_stored OF((deflate_state *s, int flush)); -local block_state deflate_fast OF((deflate_state *s, int flush)); -local block_state deflate_slow OF((deflate_state *s, int flush)); -local void lm_init OF((deflate_state *s)); -local void putShortMSB OF((deflate_state *s, uInt b)); -local void flush_pending OF((z_streamp strm)); -local int read_buf OF((z_streamp strm, charf *buf, unsigned size)); -#ifdef ASMV - void match_init OF((void)); /* asm code initialization */ - uInt longest_match OF((deflate_state *s, IPos cur_match)); -#else -local uInt longest_match OF((deflate_state *s, IPos cur_match)); -#endif - -#ifdef DEBUG_ZLIB -local void check_match OF((deflate_state *s, IPos start, IPos match, - int length)); -#endif - -/* =========================================================================== - * Local data - */ - -#define NIL 0 -/* Tail of hash chains */ - -#ifndef TOO_FAR -# define TOO_FAR 4096 -#endif -/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -typedef struct config_s { - ush good_length; /* reduce lazy search above this match length */ - ush max_lazy; /* do not perform lazy search above this match length */ - ush nice_length; /* quit search above this match length */ - ush max_chain; - compress_func func; -} config; - -local config configuration_table[10] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */ -/* 2 */ {4, 5, 16, 8, deflate_fast}, -/* 3 */ {4, 6, 32, 32, deflate_fast}, - -/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ -/* 5 */ {8, 16, 32, 32, deflate_slow}, -/* 6 */ {8, 16, 128, 128, deflate_slow}, -/* 7 */ {8, 32, 128, 256, deflate_slow}, -/* 8 */ {32, 128, 258, 1024, deflate_slow}, -/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */ - -/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 - * For deflate_fast() (levels <= 3) good is ignored and lazy has a different - * meaning. - */ - -#define EQUAL 0 -/* result of memcmp for equal strings */ - -#ifndef NO_DUMMY_DECL -struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ -#endif - -/* =========================================================================== - * Update a hash value with the given input byte - * IN assertion: all calls to UPDATE_HASH are made with consecutive - * input characters, so that a running hash key can be computed from the - * previous key instead of complete recalculation each time. - */ -#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) - - -/* =========================================================================== - * Insert string str in the dictionary and set match_head to the previous head - * of the hash chain (the most recent string with same hash key). Return - * the previous length of the hash chain. - * IN assertion: all calls to INSERT_STRING are made with consecutive - * input characters and the first MIN_MATCH bytes of str are valid - * (except for the last MIN_MATCH-1 bytes of the input file). - */ -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) - -/* =========================================================================== - * Initialize the hash table (avoiding 64K overflow for 16 bit systems). - * prev[] will be initialized on the fly. - */ -#define CLEAR_HASH(s) \ - s->head[s->hash_size-1] = NIL; \ - zmemzero((charf *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); - -/* ========================================================================= */ -int deflateInit_(strm, level, version, stream_size) - z_streamp strm; - int level; - const char *version; - int stream_size; -{ - return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY, version, stream_size); - /* To do: ignore strm->next_in if we use it as window */ -} - -/* ========================================================================= */ -int deflateInit2_(strm, level, method, windowBits, memLevel, strategy, - version, stream_size) - z_streamp strm; - int level; - int method; - int windowBits; - int memLevel; - int strategy; - const char *version; - int stream_size; -{ - deflate_state *s; - int noheader = 0; - static char* my_version = ZLIB_VERSION; - - ushf *overlay; - /* We overlay pending_buf and d_buf+l_buf. This works since the average - * output size for (length,distance) codes is <= 24 bits. - */ - - if (version == Z_NULL || version[0] != my_version[0] || - stream_size != sizeof(z_stream)) { - return Z_VERSION_ERROR; - } - if (strm == Z_NULL) return Z_STREAM_ERROR; - - strm->msg = Z_NULL; -#ifndef NO_ZCFUNCS - if (strm->zalloc == Z_NULL) { - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; - } - if (strm->zfree == Z_NULL) strm->zfree = zcfree; -#endif - - if (level == Z_DEFAULT_COMPRESSION) level = 6; - - if (windowBits < 0) { /* undocumented feature: suppress zlib header */ - noheader = 1; - windowBits = -windowBits; - } - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || - windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_HUFFMAN_ONLY) { - return Z_STREAM_ERROR; - } - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); - if (s == Z_NULL) return Z_MEM_ERROR; - strm->state = (struct internal_state FAR *)s; - s->strm = strm; - - s->noheader = noheader; - s->w_bits = windowBits; - s->w_size = 1 << s->w_bits; - s->w_mask = s->w_size - 1; - - s->hash_bits = memLevel + 7; - s->hash_size = 1 << s->hash_bits; - s->hash_mask = s->hash_size - 1; - s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); - - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); - - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); - s->pending_buf = (uchf *) overlay; - s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); - - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || - s->pending_buf == Z_NULL) { - strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); - deflateEnd (strm); - return Z_MEM_ERROR; - } - s->d_buf = overlay + s->lit_bufsize/sizeof(ush); - s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; - - s->level = level; - s->strategy = strategy; - s->method = (Byte)method; - - return deflateReset(strm); -} - -/* ========================================================================= */ -int deflateSetDictionary (strm, dictionary, dictLength) - z_streamp strm; - const Bytef *dictionary; - uInt dictLength; -{ - deflate_state *s; - uInt length = dictLength; - uInt n; - IPos hash_head = 0; - - if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) - return Z_STREAM_ERROR; - - s = (deflate_state *) strm->state; - if (s->status != INIT_STATE) return Z_STREAM_ERROR; - - strm->adler = adler32(strm->adler, dictionary, dictLength); - - if (length < MIN_MATCH) return Z_OK; - if (length > MAX_DIST(s)) { - length = MAX_DIST(s); -#ifndef USE_DICT_HEAD - dictionary += dictLength - length; /* use the tail of the dictionary */ -#endif - } - zmemcpy((charf *)s->window, dictionary, length); - s->strstart = length; - s->block_start = (long)length; - - /* Insert all strings in the hash table (except for the last two bytes). - * s->lookahead stays null, so s->ins_h will be recomputed at the next - * call of fill_window. - */ - s->ins_h = s->window[0]; - UPDATE_HASH(s, s->ins_h, s->window[1]); - for (n = 0; n <= length - MIN_MATCH; n++) { - INSERT_STRING(s, n, hash_head); - } - if (hash_head) hash_head = 0; /* to make compiler happy */ - return Z_OK; -} - -/* ========================================================================= */ -int deflateReset (strm) - z_streamp strm; -{ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR; - - strm->total_in = strm->total_out = 0; - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ - strm->data_type = Z_UNKNOWN; - - s = (deflate_state *)strm->state; - s->pending = 0; - s->pending_out = s->pending_buf; - - if (s->noheader < 0) { - s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */ - } - s->status = s->noheader ? BUSY_STATE : INIT_STATE; - strm->adler = 1; - s->last_flush = Z_NO_FLUSH; - - _tr_init(s); - lm_init(s); - - return Z_OK; -} - -/* ========================================================================= */ -int deflateParams(strm, level, strategy) - z_streamp strm; - int level; - int strategy; -{ - deflate_state *s; - compress_func func; - int err = Z_OK; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = (deflate_state *) strm->state; - - if (level == Z_DEFAULT_COMPRESSION) { - level = 6; - } - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { - return Z_STREAM_ERROR; - } - func = configuration_table[s->level].func; - - if (func != configuration_table[level].func && strm->total_in != 0) { - /* Flush the last buffer: */ - err = deflate(strm, Z_PARTIAL_FLUSH); - } - if (s->level != level) { - s->level = level; - s->max_lazy_match = configuration_table[level].max_lazy; - s->good_match = configuration_table[level].good_length; - s->nice_match = configuration_table[level].nice_length; - s->max_chain_length = configuration_table[level].max_chain; - } - s->strategy = strategy; - return err; -} - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -local void putShortMSB (s, b) - deflate_state *s; - uInt b; -{ - put_byte(s, (Byte)(b >> 8)); - put_byte(s, (Byte)(b & 0xff)); -} - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output goes - * through this function so some applications may wish to modify it - * to avoid allocating a large strm->next_out buffer and copying into it. - * (See also read_buf()). - */ -local void flush_pending(strm) - z_streamp strm; -{ - deflate_state *s = (deflate_state *) strm->state; - unsigned len = s->pending; - - if (len > strm->avail_out) len = strm->avail_out; - if (len == 0) return; - - if (strm->next_out != Z_NULL) { - zmemcpy(strm->next_out, s->pending_out, len); - strm->next_out += len; - } - s->pending_out += len; - strm->total_out += len; - strm->avail_out -= len; - s->pending -= len; - if (s->pending == 0) { - s->pending_out = s->pending_buf; - } -} - -/* ========================================================================= */ -int deflate (strm, flush) - z_streamp strm; - int flush; -{ - int old_flush; /* value of flush param for previous deflate call */ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - flush > Z_FINISH || flush < 0) { - return Z_STREAM_ERROR; - } - s = (deflate_state *) strm->state; - - if ((strm->next_in == Z_NULL && strm->avail_in != 0) || - (s->status == FINISH_STATE && flush != Z_FINISH)) { - ERR_RETURN(strm, Z_STREAM_ERROR); - } - if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - - s->strm = strm; /* just in case */ - old_flush = s->last_flush; - s->last_flush = flush; - - /* Write the zlib header */ - if (s->status == INIT_STATE) { - - uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; - uInt level_flags = (s->level-1) >> 1; - - if (level_flags > 3) level_flags = 3; - header |= (level_flags << 6); - if (s->strstart != 0) header |= PRESET_DICT; - header += 31 - (header % 31); - - s->status = BUSY_STATE; - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s->strstart != 0) { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - strm->adler = 1L; - } - - /* Flush as much pending output as possible */ - if (s->pending != 0) { - flush_pending(strm); - if (strm->avail_out == 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s->last_flush = -1; - return Z_OK; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUFF_ERROR. - */ - } else if (strm->avail_in == 0 && flush <= old_flush && - flush != Z_FINISH) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* User must not provide more input after the first FINISH: */ - if (s->status == FINISH_STATE && strm->avail_in != 0) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* Start a new block or continue the current one. - */ - if (strm->avail_in != 0 || s->lookahead != 0 || - (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { - block_state bstate; - - bstate = (*(configuration_table[s->level].func))(s, flush); - - if (bstate == finish_started || bstate == finish_done) { - s->status = FINISH_STATE; - } - if (bstate == need_more || bstate == finish_started) { - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ - } - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate == block_done) { - if (flush == Z_PARTIAL_FLUSH) { - _tr_align(s); - } else if (flush == Z_PACKET_FLUSH) { - /* Output just the 3-bit `stored' block type value, - but not a zero length. */ - _tr_stored_type_only(s); - } else { /* FULL_FLUSH or SYNC_FLUSH */ - _tr_stored_block(s, (char*)0, 0L, 0); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush == Z_FULL_FLUSH) { - CLEAR_HASH(s); /* forget history */ - } - } - flush_pending(strm); - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK; - } - } - } - Assert(strm->avail_out > 0, "bug2"); - - if (flush != Z_FINISH) return Z_OK; - if (s->noheader) return Z_STREAM_END; - - /* Write the zlib trailer (adler32) */ - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - s->noheader = -1; /* write the trailer only once! */ - return s->pending != 0 ? Z_OK : Z_STREAM_END; -} - -/* ========================================================================= */ -int deflateEnd (strm) - z_streamp strm; -{ - int status; - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = (deflate_state *) strm->state; - - status = s->status; - if (status != INIT_STATE && status != BUSY_STATE && - status != FINISH_STATE) { - return Z_STREAM_ERROR; - } - - /* Deallocate in reverse order of allocations: */ - TRY_FREE(strm, s->pending_buf); - TRY_FREE(strm, s->head); - TRY_FREE(strm, s->prev); - TRY_FREE(strm, s->window); - - ZFREE(strm, s); - strm->state = Z_NULL; - - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -} - -/* ========================================================================= - * Copy the source state to the destination state. - */ -int deflateCopy (dest, source) - z_streamp dest; - z_streamp source; -{ - deflate_state *ds; - deflate_state *ss; - ushf *overlay; - - if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) - return Z_STREAM_ERROR; - ss = (deflate_state *) source->state; - - *dest = *source; - - ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); - if (ds == Z_NULL) return Z_MEM_ERROR; - dest->state = (struct internal_state FAR *) ds; - *ds = *ss; - ds->strm = dest; - - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); - ds->pending_buf = (uchf *) overlay; - - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || - ds->pending_buf == Z_NULL) { - deflateEnd (dest); - return Z_MEM_ERROR; - } - /* ??? following zmemcpy doesn't work for 16-bit MSDOS */ - zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); - zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); - zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); - - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); - ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); - ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; - - ds->l_desc.dyn_tree = ds->dyn_ltree; - ds->d_desc.dyn_tree = ds->dyn_dtree; - ds->bl_desc.dyn_tree = ds->bl_tree; - - return Z_OK; -} - -/* =========================================================================== - * Return the number of bytes of output which are immediately available - * for output from the decompressor. - */ -int deflateOutputPending (strm) - z_streamp strm; -{ - if (strm == Z_NULL || strm->state == Z_NULL) return 0; - - return ((deflate_state *)(strm->state))->pending; -} - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->next_in buffer and copying from it. - * (See also flush_pending()). - */ -local int read_buf(strm, buf, size) - z_streamp strm; - charf *buf; - unsigned size; -{ - unsigned len = strm->avail_in; - - if (len > size) len = size; - if (len == 0) return 0; - - strm->avail_in -= len; - - if (!((deflate_state *)(strm->state))->noheader) { - strm->adler = adler32(strm->adler, strm->next_in, len); - } - zmemcpy(buf, strm->next_in, len); - strm->next_in += len; - strm->total_in += len; - - return (int)len; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init (s) - deflate_state *s; -{ - s->window_size = (ulg)2L*s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; -#ifdef ASMV - match_init(); /* initialize the asm code */ -#endif -} - -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ -#ifndef ASMV -/* For 80x86 and 680x0, an optimized version will be provided in match.asm or - * match.S. The code will be functionally equivalent. - */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - unsigned chain_length = s->max_chain_length;/* max hash chain length */ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - int best_len = s->prev_length; /* best match length so far */ - int nice_match = s->nice_match; /* stop if match long enough */ - IPos limit = s->strstart > (IPos)MAX_DIST(s) ? - s->strstart - (IPos)MAX_DIST(s) : NIL; - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - Posf *prev = s->prev; - uInt wmask = s->w_mask; - -#ifdef UNALIGNED_OK - /* Compare two bytes at a time. Note: this is not always beneficial. - * Try with and without -DUNALIGNED_OK to check. - */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - register ush scan_start = *(ushf*)scan; - register ush scan_end = *(ushf*)(scan+best_len-1); -#else - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - register Byte scan_end1 = scan[best_len-1]; - register Byte scan_end = scan[best_len]; -#endif - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s->prev_length >= s->good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2: - */ -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) - /* This code assumes sizeof(unsigned short) == 2. Do not use - * UNALIGNED_OK if your compiler uses a different size. - */ - if (*(ushf*)(match+best_len-1) != scan_end || - *(ushf*)match != scan_start) continue; - - /* It is not necessary to compare scan[2] and match[2] since they are - * always equal when the other bytes match, given that the hash keys - * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at - * strstart+3, +5, ... up to strstart+257. We check for insufficient - * lookahead only every 4th comparison; the 128th check will be made - * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is - * necessary to put more guard bytes at the end of the window, or - * to check more often for insufficient lookahead. - */ - Assert(scan[2] == match[2], "scan[2]?"); - scan++, match++; - do { - } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - scan < strend); - /* The funny "do {}" generates better code on most compilers */ - - /* Here, scan <= window+strstart+257 */ - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - if (*scan == *match) scan++; - - len = (MAX_MATCH - 1) - (int)(strend-scan); - scan = strend - (MAX_MATCH-1); - -#else /* UNALIGNED_OK */ - - if (match[best_len] != scan_end || - match[best_len-1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match++; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - -#endif /* UNALIGNED_OK */ - - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= nice_match) break; -#ifdef UNALIGNED_OK - scan_end = *(ushf*)(scan+best_len-1); -#else - scan_end1 = scan[best_len-1]; - scan_end = scan[best_len]; -#endif - } - } while ((cur_match = prev[cur_match & wmask]) > limit - && --chain_length != 0); - - if ((uInt)best_len <= s->lookahead) return best_len; - return s->lookahead; -} -#endif /* ASMV */ - -#ifdef DEBUG_ZLIB -/* =========================================================================== - * Check that the match at match_start is indeed a match. - */ -local void check_match(s, start, match, length) - deflate_state *s; - IPos start, match; - int length; -{ - /* check that the match is indeed a match */ - if (zmemcmp((charf *)s->window + match, - (charf *)s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); - do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); - z_error("invalid match"); - } - if (z_verbose > 1) { - fprintf(stderr,"\\[%d,%d]", start-match, length); - do { putc(s->window[start++], stderr); } while (--length != 0); - } -} -#else -# define check_match(s, start, match, length) -#endif - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -local void fill_window(s) - deflate_state *s; -{ - register unsigned n, m; - register Posf *p; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; - - do { - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); - - /* Deal with !@#$% 64K limit: */ - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if strstart == 0 - * and lookahead == 1 (input done one byte at time) - */ - more--; - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - } else if (s->strstart >= wsize+MAX_DIST(s)) { - - zmemcpy((charf *)s->window, (charf *)s->window+wsize, - (unsigned)wsize); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - - /* Slide the hash table (could be avoided with 32 bit values - at the expense of memory usage). We slide even when level == 0 - to keep the hash table consistent if we switch back to level > 0 - later. (Using level 0 permanently is not an optimal usage of - zlib, so we don't care about this pathological case.) - */ - n = s->hash_size; - p = &s->head[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - } while (--n); - - n = wsize; - p = &s->prev[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); - more += wsize; - } - if (s->strm->avail_in == 0) return; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, (charf *)s->window + s->strstart + s->lookahead, - more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead >= MIN_MATCH) { - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); -} - -/* =========================================================================== - * Flush the current block, with given end-of-file flag. - * IN assertion: strstart is set to the end of the current match. - */ -#define FLUSH_BLOCK_ONLY(s, eof) { \ - _tr_flush_block(s, (s->block_start >= 0L ? \ - (charf *)&s->window[(unsigned)s->block_start] : \ - (charf *)Z_NULL), \ - (ulg)((long)s->strstart - s->block_start), \ - (eof)); \ - s->block_start = s->strstart; \ - flush_pending(s->strm); \ - Tracev((stderr,"[FLUSH]")); \ -} - -/* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, eof) { \ - FLUSH_BLOCK_ONLY(s, eof); \ - if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ -} - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * This function does not insert new strings in the dictionary since - * uncompressible data is probably not useful. This function is used - * only for the level=0 compression option. - * NOTE: this function should be optimized to avoid extra copying from - * window to pending_buf. - */ -local block_state deflate_stored(s, flush) - deflate_state *s; - int flush; -{ - /* Stored blocks are limited to 0xffff bytes, pending_buf is limited - * to pending_buf_size, and each stored block has a 5 byte header: - */ - ulg max_block_size = 0xffff; - ulg max_start; - - if (max_block_size > s->pending_buf_size - 5) { - max_block_size = s->pending_buf_size - 5; - } - - /* Copy as much as possible from input to output: */ - for (;;) { - /* Fill the window as much as possible: */ - if (s->lookahead <= 1) { - - Assert(s->strstart < s->w_size+MAX_DIST(s) || - s->block_start >= (long)s->w_size, "slide too late"); - - fill_window(s); - if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; - - if (s->lookahead == 0) break; /* flush the current block */ - } - Assert(s->block_start >= 0L, "block gone"); - - s->strstart += s->lookahead; - s->lookahead = 0; - - /* Emit a stored block if pending_buf will be full: */ - max_start = s->block_start + max_block_size; - if (s->strstart == 0 || (ulg)s->strstart >= max_start) { - /* strstart == 0 is possible when wraparound on 16-bit machine */ - s->lookahead = (uInt)(s->strstart - max_start); - s->strstart = (uInt)max_start; - FLUSH_BLOCK(s, 0); - } - /* Flush if we may have to slide, otherwise block_start may become - * negative and the data will be gone: - */ - if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { - FLUSH_BLOCK(s, 0); - } - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -local block_state deflate_fast(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head = NIL; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - if (s->strategy != Z_HUFFMAN_ONLY) { - s->match_length = longest_match (s, hash_head); - } - /* longest_match() sets match_start */ - } - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->match_start, s->match_length); - - bflush = _tr_tally(s, s->strstart - s->match_start, - s->match_length - MIN_MATCH); - - s->lookahead -= s->match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ - if (s->match_length <= s->max_insert_length && - s->lookahead >= MIN_MATCH) { - s->match_length--; /* string at strstart already in hash table */ - do { - s->strstart++; - INSERT_STRING(s, s->strstart, hash_head); - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s->match_length != 0); - s->strstart++; - } else { - s->strstart += s->match_length; - s->match_length = 0; - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - bflush = _tr_tally (s, 0, s->window[s->strstart]); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -local block_state deflate_slow(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head = NIL; /* head of hash chain */ - int bflush; /* set if current block must be flushed */ - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - */ - s->prev_length = s->match_length, s->prev_match = s->match_start; - s->match_length = MIN_MATCH-1; - - if (hash_head != NIL && s->prev_length < s->max_lazy_match && - s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - if (s->strategy != Z_HUFFMAN_ONLY) { - s->match_length = longest_match (s, hash_head); - } - /* longest_match() sets match_start */ - - if (s->match_length <= 5 && (s->strategy == Z_FILTERED || - (s->match_length == MIN_MATCH && - s->strstart - s->match_start > TOO_FAR))) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s->match_length = MIN_MATCH-1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - check_match(s, s->strstart-1, s->prev_match, s->prev_length); - - bflush = _tr_tally(s, s->strstart -1 - s->prev_match, - s->prev_length - MIN_MATCH); - - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s->lookahead -= s->prev_length-1; - s->prev_length -= 2; - do { - if (++s->strstart <= max_insert) { - INSERT_STRING(s, s->strstart, hash_head); - } - } while (--s->prev_length != 0); - s->match_available = 0; - s->match_length = MIN_MATCH-1; - s->strstart++; - - if (bflush) FLUSH_BLOCK(s, 0); - - } else if (s->match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - Tracevv((stderr,"%c", s->window[s->strstart-1])); - if (_tr_tally (s, 0, s->window[s->strstart-1])) { - FLUSH_BLOCK_ONLY(s, 0); - } - s->strstart++; - s->lookahead--; - if (s->strm->avail_out == 0) return need_more; - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s->match_available = 1; - s->strstart++; - s->lookahead--; - } - } - Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s->match_available) { - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally (s, 0, s->window[s->strstart-1]); - s->match_available = 0; - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} -/* --- deflate.c */ - -/* +++ trees.c */ -/* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-1996 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process uses several Huffman trees. The more - * common source values are represented by shorter bit sequences. - * - * Each code tree is stored in a compressed form which is itself - * a Huffman encoding of the lengths of all the code strings (in - * ascending order by source values). The actual code strings are - * reconstructed from the lengths in the inflate process, as described - * in the deflate specification. - * - * REFERENCES - * - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc - * - * Storer, James A. - * Data Compression: Methods and Theory, pp. 49-50. - * Computer Science Press, 1988. ISBN 0-7167-8156-5. - * - * Sedgewick, R. - * Algorithms, p290. - * Addison-Wesley, 1983. ISBN 0-201-06672-6. - */ - -/* From: trees.c,v 1.11 1996/07/24 13:41:06 me Exp $ */ - -/* #include "deflate.h" */ - -#ifdef DEBUG_ZLIB -# include -#endif - -/* =========================================================================== - * Constants - */ - -#define MAX_BL_BITS 7 -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -#define END_BLOCK 256 -/* end of block literal code */ - -#define REP_3_6 16 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -#define REPZ_3_10 17 -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -#define REPZ_11_138 18 -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -local int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; - -local int extra_dbits[D_CODES] /* extra bits for each distance code */ - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -local int extra_blbits[BL_CODES]/* extra bits for each bit length code */ - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -local uch bl_order[BL_CODES] - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -#define Buf_size (8 * 2*sizeof(char)) -/* Number of bits used within bi_buf. (bi_buf might be implemented on - * more than 16 bits on some systems.) - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -local ct_data static_ltree[L_CODES+2]; -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -local ct_data static_dtree[D_CODES]; -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -local uch dist_code[512]; -/* distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -local uch length_code[MAX_MATCH-MIN_MATCH+1]; -/* length code for each normalized match length (0 == MIN_MATCH) */ - -local int base_length[LENGTH_CODES]; -/* First normalized length for each code (0 = MIN_MATCH) */ - -local int base_dist[D_CODES]; -/* First normalized distance for each code (0 = distance of 1) */ - -struct static_tree_desc_s { - ct_data *static_tree; /* static tree or NULL */ - intf *extra_bits; /* extra bits for each code or NULL */ - int extra_base; /* base index for extra_bits */ - int elems; /* max number of elements in the tree */ - int max_length; /* max bit length for the codes */ -}; - -local static_tree_desc static_l_desc = -{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; - -local static_tree_desc static_d_desc = -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; - -local static_tree_desc static_bl_desc = -{(ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; - -/* =========================================================================== - * Local (static) routines in this file. - */ - -local void tr_static_init OF((void)); -local void init_block OF((deflate_state *s)); -local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); -local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); -local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); -local void build_tree OF((deflate_state *s, tree_desc *desc)); -local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local int build_bl_tree OF((deflate_state *s)); -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, - int blcodes)); -local void compress_block OF((deflate_state *s, ct_data *ltree, - ct_data *dtree)); -local void set_data_type OF((deflate_state *s)); -local unsigned bi_reverse OF((unsigned value, int length)); -local void bi_windup OF((deflate_state *s)); -local void bi_flush OF((deflate_state *s)); -local void copy_block OF((deflate_state *s, charf *buf, unsigned len, - int header)); - -#ifndef DEBUG_ZLIB -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) - /* Send a code of the given tree. c and tree must not have side effects */ - -#else /* DEBUG_ZLIB */ -# define send_code(s, c, tree) \ - { if (verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ - send_bits(s, tree[c].Code, tree[c].Len); } -#endif - -#define d_code(dist) \ - ((dist) < 256 ? dist_code[dist] : dist_code[256+((dist)>>7)]) -/* Mapping from a distance to a distance code. dist is the distance - 1 and - * must not have side effects. dist_code[256] and dist_code[257] are never - * used. - */ - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -#ifdef DEBUG_ZLIB -local void send_bits OF((deflate_state *s, int value, int length)); - -local void send_bits(s, value, length) - deflate_state *s; - int value; /* value to send */ - int length; /* number of bits */ -{ - Tracevv((stderr," l %2d v %4x ", length, value)); - Assert(length > 0 && length <= 15, "invalid length"); - s->bits_sent += (ulg)length; - - /* If not enough room in bi_buf, use (valid) bits from bi_buf and - * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) - * unused bits in value. - */ - if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (value << s->bi_valid); - put_short(s, s->bi_buf); - s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); - s->bi_valid += length - Buf_size; - } else { - s->bi_buf |= value << s->bi_valid; - s->bi_valid += length; - } -} -#else /* !DEBUG_ZLIB */ - -#define send_bits(s, value, length) \ -{ int len = length;\ - if (s->bi_valid > (int)Buf_size - len) {\ - int val = value;\ - s->bi_buf |= (val << s->bi_valid);\ - put_short(s, s->bi_buf);\ - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ - s->bi_valid += len - Buf_size;\ - } else {\ - s->bi_buf |= (value) << s->bi_valid;\ - s->bi_valid += len;\ - }\ -} -#endif /* DEBUG_ZLIB */ - - -#define MAX(a,b) (a >= b ? a : b) -/* the arguments must not have side effects */ - -/* =========================================================================== - * Initialize the various 'constant' tables. In a multi-threaded environment, - * this function may be called by two threads concurrently, but this is - * harmless since both invocations do exactly the same thing. - */ -local void tr_static_init() -{ - static int static_init_done; - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - if (static_init_done) return; - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - base_length[code] = length; - for (n = 0; n < (1< dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { - dist_code[256 + dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse((unsigned)n, 5); - } - static_init_done = 1; -} - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -void _tr_init(s) - deflate_state *s; -{ - tr_static_init(); - - s->compressed_len = 0L; - - s->l_desc.dyn_tree = s->dyn_ltree; - s->l_desc.stat_desc = &static_l_desc; - - s->d_desc.dyn_tree = s->dyn_dtree; - s->d_desc.stat_desc = &static_d_desc; - - s->bl_desc.dyn_tree = s->bl_tree; - s->bl_desc.stat_desc = &static_bl_desc; - - s->bi_buf = 0; - s->bi_valid = 0; - s->last_eob_len = 8; /* enough lookahead for inflate */ -#ifdef DEBUG_ZLIB - s->bits_sent = 0L; -#endif - - /* Initialize the first block of the first file: */ - init_block(s); -} - -/* =========================================================================== - * Initialize a new block. - */ -local void init_block(s) - deflate_state *s; -{ - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->last_lit = s->matches = 0; -} - -#define SMALLEST 1 -/* Index within the heap array of least frequent node in the Huffman tree */ - - -/* =========================================================================== - * Remove the smallest element from the heap and recreate the heap with - * one less element. Updates heap and heap_len. - */ -#define pqremove(s, tree, top) \ -{\ - top = s->heap[SMALLEST]; \ - s->heap[SMALLEST] = s->heap[s->heap_len--]; \ - pqdownheap(s, tree, SMALLEST); \ -} - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -#define smaller(tree, n, m, depth) \ - (tree[n].Freq < tree[m].Freq || \ - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -local void pqdownheap(s, tree, k) - deflate_state *s; - ct_data *tree; /* the tree to restore */ - int k; /* node to move down */ -{ - int v = s->heap[k]; - int j = k << 1; /* left son of k */ - while (j <= s->heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s->heap_len && - smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s->heap[j], s->depth)) break; - - /* Exchange v with the smallest son */ - s->heap[k] = s->heap[j]; k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s->heap[k] = v; -} - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -local void gen_bitlen(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ - ct_data *tree = desc->dyn_tree; - int max_code = desc->max_code; - ct_data *stree = desc->stat_desc->static_tree; - intf *extra = desc->stat_desc->extra_bits; - int base = desc->stat_desc->extra_base; - int max_length = desc->stat_desc->max_length; - int h; /* heap index */ - int n, m; /* iterate over the tree elements */ - int bits; /* bit length */ - int xbits; /* extra bits */ - ush f; /* frequency */ - int overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ - - for (h = s->heap_max+1; h < HEAP_SIZE; h++) { - n = s->heap[h]; - bits = tree[tree[n].Dad].Len + 1; - if (bits > max_length) bits = max_length, overflow++; - tree[n].Len = (ush)bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) continue; /* not a leaf node */ - - s->bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n-base]; - f = tree[n].Freq; - s->opt_len += (ulg)f * (bits + xbits); - if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); - } - if (overflow == 0) return; - - Trace((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length-1; - while (s->bl_count[bits] == 0) bits--; - s->bl_count[bits]--; /* move one leaf down the tree */ - s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ - s->bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits != 0; bits--) { - n = s->bl_count[bits]; - while (n != 0) { - m = s->heap[--h]; - if (m > max_code) continue; - if (tree[m].Len != (unsigned) bits) { - Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s->opt_len += ((long)bits - (long)tree[m].Len) - *(long)tree[m].Freq; - tree[m].Len = (ush)bits; - } - n--; - } - } -} - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes (tree, max_code, bl_count) - ct_data *tree; /* the tree to decorate */ - int max_code; /* largest code with non zero frequency */ - ushf *bl_count; /* number of codes at each bit length */ -{ - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - ush code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - next_code[bits] = code = (code + bl_count[bits-1]) << 1; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; - ct_data *stree = desc->stat_desc->static_tree; - int elems = desc->stat_desc->elems; - int n, m; /* iterate over heap elements */ - int max_code = -1; /* largest code with non zero frequency */ - int node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s->heap_len = 0, s->heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n].Freq != 0) { - s->heap[++(s->heap_len)] = max_code = n; - s->depth[n] = 0; - } else { - tree[n].Len = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s->heap_len < 2) { - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); - tree[node].Freq = 1; - s->depth[node] = 0; - s->opt_len--; if (stree) s->static_len -= stree[node].Len; - /* node is 0 or 1 so it does not have extra bits */ - } - desc->max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - pqremove(s, tree, n); /* n = node of least frequency */ - m = s->heap[SMALLEST]; /* m = node of next least frequency */ - - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ - s->heap[--(s->heap_max)] = m; - - /* Create a new node father of n and m */ - tree[node].Freq = tree[n].Freq + tree[m].Freq; - s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1); - tree[n].Dad = tree[m].Dad = (ush)node; -#ifdef DUMP_BL_TREE - if (tree == s->bl_tree) { - fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); - } -#endif - /* and insert the new node in the heap */ - s->heap[SMALLEST] = node++; - pqdownheap(s, tree, SMALLEST); - - } while (s->heap_len >= 2); - - s->heap[--(s->heap_max)] = s->heap[SMALLEST]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, (tree_desc *)desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes ((ct_data *)tree, max_code, s->bl_count); -} - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -local void scan_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - if (nextlen == 0) max_count = 138, min_count = 3; - tree[max_code+1].Len = (ush)0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - s->bl_tree[curlen].Freq += count; - } else if (curlen != 0) { - if (curlen != prevlen) s->bl_tree[curlen].Freq++; - s->bl_tree[REP_3_6].Freq++; - } else if (count <= 10) { - s->bl_tree[REPZ_3_10].Freq++; - } else { - s->bl_tree[REPZ_11_138].Freq++; - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -local void send_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen == 0) max_count = 138, min_count = 3; - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { send_code(s, curlen, s->bl_tree); } while (--count != 0); - - } else if (curlen != 0) { - if (curlen != prevlen) { - send_code(s, curlen, s->bl_tree); count--; - } - Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); - - } else { - send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -local int build_bl_tree(s) - deflate_state *s; -{ - int max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, (tree_desc *)(&(s->bl_desc))); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { - if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; - } - /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3*(max_blindex+1) + 5+5+4; - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - s->opt_len, s->static_len)); - - return max_blindex; -} - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -local void send_all_trees(s, lcodes, dcodes, blcodes) - deflate_state *s; - int lcodes, dcodes, blcodes; /* number of codes for each tree */ -{ - int rank; /* index in bl_order */ - - Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - "too many codes"); - Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes-1, 5); - send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); - } - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -} - -/* =========================================================================== - * Send a stored block - */ -void _tr_stored_block(s, buf, stored_len, eof) - deflate_state *s; - charf *buf; /* input block */ - ulg stored_len; /* length of input block */ - int eof; /* true if this is the last block for a file */ -{ - send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ - s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; - s->compressed_len += (stored_len + 4) << 3; - - copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ -} - -/* Send just the `stored block' type code without any length bytes or data. - */ -void _tr_stored_type_only(s) - deflate_state *s; -{ - send_bits(s, (STORED_BLOCK << 1), 3); - bi_windup(s); - s->compressed_len = (s->compressed_len + 3) & ~7L; -} - - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - * The current inflate code requires 9 bits of lookahead. If the - * last two codes for the previous block (real code plus EOB) were coded - * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode - * the last real code. In this case we send two empty static blocks instead - * of one. (There are no problems if the previous block is stored or fixed.) - * To simplify the code, we assume the worst case of last real code encoded - * on one bit only. - */ -void _tr_align(s) - deflate_state *s; -{ - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ - bi_flush(s); - /* Of the 10 bits for the empty block, we have already sent - * (10 - bi_valid) bits. The lookahead for the last real code (before - * the EOB of the previous block) was thus at least one plus the length - * of the EOB plus what we have just sent of the empty static block. - */ - if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); - s->compressed_len += 10L; - bi_flush(s); - } - s->last_eob_len = 7; -} - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and output the encoded block to the zip file. This function - * returns the total compressed length for the file so far. - */ -ulg _tr_flush_block(s, buf, stored_len, eof) - deflate_state *s; - charf *buf; /* input block, or NULL if too old */ - ulg stored_len; /* length of input block */ - int eof; /* true if this is the last block for a file */ -{ - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - int max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s->level > 0) { - - /* Check if the file is ascii or binary */ - if (s->data_type == Z_UNKNOWN) set_data_type(s); - - /* Construct the literal and distance trees */ - build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - - build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute first the block length in bytes*/ - opt_lenb = (s->opt_len+3+7)>>3; - static_lenb = (s->static_len+3+7)>>3; - - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - s->last_lit)); - - if (static_lenb <= opt_lenb) opt_lenb = static_lenb; - - } else { - Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - - /* If compression failed and this is the first and last block, - * and if the .zip file can be seeked (to rewrite the local header), - * the whole file is transformed into a stored file: - */ -#ifdef STORED_FILE_OK -# ifdef FORCE_STORED_FILE - if (eof && s->compressed_len == 0L) { /* force stored file */ -# else - if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) { -# endif - /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */ - if (buf == (charf*)0) error ("block vanished"); - - copy_block(s, buf, (unsigned)stored_len, 0); /* without header */ - s->compressed_len = stored_len << 3; - s->method = STORED; - } else -#endif /* STORED_FILE_OK */ - -#ifdef FORCE_STORED - if (buf != (char*)0) { /* force stored block */ -#else - if (stored_len+4 <= opt_lenb && buf != (char*)0) { - /* 4: two words for the lengths */ -#endif - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block(s, buf, stored_len, eof); - -#ifdef FORCE_STATIC - } else if (static_lenb >= 0) { /* force static trees */ -#else - } else if (static_lenb == opt_lenb) { -#endif - send_bits(s, (STATIC_TREES<<1)+eof, 3); - compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); - s->compressed_len += 3 + s->static_len; - } else { - send_bits(s, (DYN_TREES<<1)+eof, 3); - send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, - max_blindex+1); - compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); - s->compressed_len += 3 + s->opt_len; - } - Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - init_block(s); - - if (eof) { - bi_windup(s); - s->compressed_len += 7; /* align on byte boundary */ - } - Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - s->compressed_len-7*eof)); - - return s->compressed_len >> 3; -} - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -int _tr_tally (s, dist, lc) - deflate_state *s; - unsigned dist; /* distance of matched string */ - unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ -{ - s->d_buf[s->last_lit] = (ush)dist; - s->l_buf[s->last_lit++] = (uch)lc; - if (dist == 0) { - /* lc is the unmatched char */ - s->dyn_ltree[lc].Freq++; - } else { - s->matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - Assert((ush)dist < (ush)MAX_DIST(s) && - (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s->dyn_ltree[length_code[lc]+LITERALS+1].Freq++; - s->dyn_dtree[d_code(dist)].Freq++; - } - - /* Try to guess if it is profitable to stop the current block here */ - if (s->level > 2 && (s->last_lit & 0xfff) == 0) { - /* Compute an upper bound for the compressed length */ - ulg out_length = (ulg)s->last_lit*8L; - ulg in_length = (ulg)((long)s->strstart - s->block_start); - int dcode; - for (dcode = 0; dcode < D_CODES; dcode++) { - out_length += (ulg)s->dyn_dtree[dcode].Freq * - (5L+extra_dbits[dcode]); - } - out_length >>= 3; - Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", - s->last_lit, in_length, out_length, - 100L - out_length*100L/in_length)); - if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; - } - return (s->last_lit == s->lit_bufsize-1); - /* We avoid equality with lit_bufsize because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ -} - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block(s, ltree, dtree) - deflate_state *s; - ct_data *ltree; /* literal tree */ - ct_data *dtree; /* distance tree */ -{ - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned lx = 0; /* running index in l_buf */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->last_lit != 0) do { - dist = s->d_buf[lx]; - lc = s->l_buf[lx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = length_code[lc]; - send_code(s, code+LITERALS+1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ - Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow"); - - } while (lx < s->last_lit); - - send_code(s, END_BLOCK, ltree); - s->last_eob_len = ltree[END_BLOCK].Len; -} - -/* =========================================================================== - * Set the data type to ASCII or BINARY, using a crude approximation: - * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. - * IN assertion: the fields freq of dyn_ltree are set and the total of all - * frequencies does not exceed 64K (to fit in an int on 16 bit machines). - */ -local void set_data_type(s) - deflate_state *s; -{ - int n = 0; - unsigned ascii_freq = 0; - unsigned bin_freq = 0; - while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; - while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; - while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; - s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse(code, len) - unsigned code; /* the value to invert */ - int len; /* its bit length */ -{ - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush(s) - deflate_state *s; -{ - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -local void bi_windup(s) - deflate_state *s; -{ - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef DEBUG_ZLIB - s->bits_sent = (s->bits_sent+7) & ~7; -#endif -} - -/* =========================================================================== - * Copy a stored block, storing first the length and its - * one's complement if requested. - */ -local void copy_block(s, buf, len, header) - deflate_state *s; - charf *buf; /* the input data */ - unsigned len; /* its length */ - int header; /* true if block header must be written */ -{ - bi_windup(s); /* align on byte boundary */ - s->last_eob_len = 8; /* enough lookahead for inflate */ - - if (header) { - put_short(s, (ush)len); - put_short(s, (ush)~len); -#ifdef DEBUG_ZLIB - s->bits_sent += 2*16; -#endif - } -#ifdef DEBUG_ZLIB - s->bits_sent += (ulg)len<<3; -#endif - /* bundle up the put_byte(s, *buf++) calls */ - zmemcpy(&s->pending_buf[s->pending], buf, len); - s->pending += len; -} -/* --- trees.c */ - -/* +++ inflate.c */ -/* inflate.c -- zlib interface to inflate modules - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* #include "zutil.h" */ - -/* +++ infblock.h */ -/* infblock.h -- header to use infblock.c - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -struct inflate_blocks_state; -typedef struct inflate_blocks_state FAR inflate_blocks_statef; - -extern inflate_blocks_statef * inflate_blocks_new OF(( - z_streamp z, - check_func c, /* check function */ - uInt w)); /* window size */ - -extern int inflate_blocks OF(( - inflate_blocks_statef *, - z_streamp , - int)); /* initial return code */ - -extern void inflate_blocks_reset OF(( - inflate_blocks_statef *, - z_streamp , - uLongf *)); /* check value on output */ - -extern int inflate_blocks_free OF(( - inflate_blocks_statef *, - z_streamp , - uLongf *)); /* check value on output */ - -extern void inflate_set_dictionary OF(( - inflate_blocks_statef *s, - const Bytef *d, /* dictionary */ - uInt n)); /* dictionary length */ - -extern int inflate_addhistory OF(( - inflate_blocks_statef *, - z_streamp)); - -extern int inflate_packet_flush OF(( - inflate_blocks_statef *)); -/* --- infblock.h */ - -#ifndef NO_DUMMY_DECL -struct inflate_blocks_state {int dummy;}; /* for buggy compilers */ -#endif - -/* inflate private state */ -struct internal_state { - - /* mode */ - enum { - METHOD, /* waiting for method byte */ - FLAG, /* waiting for flag byte */ - DICT4, /* four dictionary check bytes to go */ - DICT3, /* three dictionary check bytes to go */ - DICT2, /* two dictionary check bytes to go */ - DICT1, /* one dictionary check byte to go */ - DICT0, /* waiting for inflateSetDictionary */ - BLOCKS, /* decompressing blocks */ - CHECK4, /* four check bytes to go */ - CHECK3, /* three check bytes to go */ - CHECK2, /* two check bytes to go */ - CHECK1, /* one check byte to go */ - DONE, /* finished check, done */ - BAD} /* got an error--stay here */ - mode; /* current inflate mode */ - - /* mode dependent information */ - union { - uInt method; /* if FLAGS, method byte */ - struct { - uLong was; /* computed check value */ - uLong need; /* stream check value */ - } check; /* if CHECK, check values to compare */ - uInt marker; /* if BAD, inflateSync's marker bytes count */ - } sub; /* submode */ - - /* mode independent information */ - int nowrap; /* flag for no wrapper */ - uInt wbits; /* log2(window size) (8..15, defaults to 15) */ - inflate_blocks_statef - *blocks; /* current inflate_blocks state */ - -}; - - -int inflateReset(z) -z_streamp z; -{ - uLong c; - - if (z == Z_NULL || z->state == Z_NULL) - return Z_STREAM_ERROR; - z->total_in = z->total_out = 0; - z->msg = Z_NULL; - z->state->mode = z->state->nowrap ? BLOCKS : METHOD; - inflate_blocks_reset(z->state->blocks, z, &c); - Trace((stderr, "inflate: reset\n")); - return Z_OK; -} - - -int inflateEnd(z) -z_streamp z; -{ - uLong c; - - if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) - return Z_STREAM_ERROR; - if (z->state->blocks != Z_NULL) - inflate_blocks_free(z->state->blocks, z, &c); - ZFREE(z, z->state); - z->state = Z_NULL; - Trace((stderr, "inflate: end\n")); - return Z_OK; -} - - -int inflateInit2_(z, w, version, stream_size) -z_streamp z; -int w; -const char *version; -int stream_size; -{ - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != sizeof(z_stream)) - return Z_VERSION_ERROR; - - /* initialize state */ - if (z == Z_NULL) - return Z_STREAM_ERROR; - z->msg = Z_NULL; -#ifndef NO_ZCFUNCS - if (z->zalloc == Z_NULL) - { - z->zalloc = zcalloc; - z->opaque = (voidpf)0; - } - if (z->zfree == Z_NULL) z->zfree = zcfree; -#endif - if ((z->state = (struct internal_state FAR *) - ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) - return Z_MEM_ERROR; - z->state->blocks = Z_NULL; - - /* handle undocumented nowrap option (no zlib header or check) */ - z->state->nowrap = 0; - if (w < 0) - { - w = - w; - z->state->nowrap = 1; - } - - /* set window size */ - if (w < 8 || w > 15) - { - inflateEnd(z); - return Z_STREAM_ERROR; - } - z->state->wbits = (uInt)w; - - /* create inflate_blocks state */ - if ((z->state->blocks = - inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) - == Z_NULL) - { - inflateEnd(z); - return Z_MEM_ERROR; - } - Trace((stderr, "inflate: allocated\n")); - - /* reset state */ - inflateReset(z); - return Z_OK; -} - - -int inflateInit_(z, version, stream_size) -z_streamp z; -const char *version; -int stream_size; -{ - return inflateInit2_(z, DEF_WBITS, version, stream_size); -} - - -#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;} -#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) - -int inflate(z, f) -z_streamp z; -int f; -{ - int r; - uInt b; - - if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL || f < 0) - return Z_STREAM_ERROR; - r = Z_BUF_ERROR; - while (1) switch (z->state->mode) - { - case METHOD: - NEEDBYTE - if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) - { - z->state->mode = BAD; - z->msg = (char*)"unknown compression method"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - if ((z->state->sub.method >> 4) + 8 > z->state->wbits) - { - z->state->mode = BAD; - z->msg = (char*)"invalid window size"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - z->state->mode = FLAG; - case FLAG: - NEEDBYTE - b = NEXTBYTE; - if (((z->state->sub.method << 8) + b) % 31) - { - z->state->mode = BAD; - z->msg = (char*)"incorrect header check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - Trace((stderr, "inflate: zlib header ok\n")); - if (!(b & PRESET_DICT)) - { - z->state->mode = BLOCKS; - break; - } - z->state->mode = DICT4; - case DICT4: - NEEDBYTE - z->state->sub.check.need = (uLong)NEXTBYTE << 24; - z->state->mode = DICT3; - case DICT3: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 16; - z->state->mode = DICT2; - case DICT2: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 8; - z->state->mode = DICT1; - case DICT1: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE; - z->adler = z->state->sub.check.need; - z->state->mode = DICT0; - return Z_NEED_DICT; - case DICT0: - z->state->mode = BAD; - z->msg = (char*)"need dictionary"; - z->state->sub.marker = 0; /* can try inflateSync */ - return Z_STREAM_ERROR; - case BLOCKS: - r = inflate_blocks(z->state->blocks, z, r); - if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0) - r = inflate_packet_flush(z->state->blocks); - if (r == Z_DATA_ERROR) - { - z->state->mode = BAD; - z->state->sub.marker = 0; /* can try inflateSync */ - break; - } - if (r != Z_STREAM_END) - return r; - r = Z_OK; - inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); - if (z->state->nowrap) - { - z->state->mode = DONE; - break; - } - z->state->mode = CHECK4; - case CHECK4: - NEEDBYTE - z->state->sub.check.need = (uLong)NEXTBYTE << 24; - z->state->mode = CHECK3; - case CHECK3: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 16; - z->state->mode = CHECK2; - case CHECK2: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 8; - z->state->mode = CHECK1; - case CHECK1: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE; - - if (z->state->sub.check.was != z->state->sub.check.need) - { - z->state->mode = BAD; - z->msg = (char*)"incorrect data check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - Trace((stderr, "inflate: zlib check ok\n")); - z->state->mode = DONE; - case DONE: - return Z_STREAM_END; - case BAD: - return Z_DATA_ERROR; - default: - return Z_STREAM_ERROR; - } - - empty: - if (f != Z_PACKET_FLUSH) - return r; - z->state->mode = BAD; - z->msg = (char *)"need more for packet flush"; - z->state->sub.marker = 0; /* can try inflateSync */ - return Z_DATA_ERROR; -} - - -int inflateSetDictionary(z, dictionary, dictLength) -z_streamp z; -const Bytef *dictionary; -uInt dictLength; -{ - uInt length = dictLength; - - if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0) - return Z_STREAM_ERROR; - - if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR; - z->adler = 1L; - - if (length >= ((uInt)1<state->wbits)) - { - length = (1<state->wbits)-1; - dictionary += dictLength - length; - } - inflate_set_dictionary(z->state->blocks, dictionary, length); - z->state->mode = BLOCKS; - return Z_OK; -} - -/* - * This subroutine adds the data at next_in/avail_in to the output history - * without performing any output. The output buffer must be "caught up"; - * i.e. no pending output (hence s->read equals s->write), and the state must - * be BLOCKS (i.e. we should be willing to see the start of a series of - * BLOCKS). On exit, the output will also be caught up, and the checksum - * will have been updated if need be. - */ - -int inflateIncomp(z) -z_stream *z; -{ - if (z->state->mode != BLOCKS) - return Z_DATA_ERROR; - return inflate_addhistory(z->state->blocks, z); -} - - -int inflateSync(z) -z_streamp z; -{ - uInt n; /* number of bytes to look at */ - Bytef *p; /* pointer to bytes */ - uInt m; /* number of marker bytes found in a row */ - uLong r, w; /* temporaries to save total_in and total_out */ - - /* set up */ - if (z == Z_NULL || z->state == Z_NULL) - return Z_STREAM_ERROR; - if (z->state->mode != BAD) - { - z->state->mode = BAD; - z->state->sub.marker = 0; - } - if ((n = z->avail_in) == 0) - return Z_BUF_ERROR; - p = z->next_in; - m = z->state->sub.marker; - - /* search */ - while (n && m < 4) - { - if (*p == (Byte)(m < 2 ? 0 : 0xff)) - m++; - else if (*p) - m = 0; - else - m = 4 - m; - p++, n--; - } - - /* restore */ - z->total_in += p - z->next_in; - z->next_in = p; - z->avail_in = n; - z->state->sub.marker = m; - - /* return no joy or set up to restart on a new block */ - if (m != 4) - return Z_DATA_ERROR; - r = z->total_in; w = z->total_out; - inflateReset(z); - z->total_in = r; z->total_out = w; - z->state->mode = BLOCKS; - return Z_OK; -} - -#undef NEEDBYTE -#undef NEXTBYTE -/* --- inflate.c */ - -/* +++ infblock.c */ -/* infblock.c -- interpret and process block types to last block - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* #include "zutil.h" */ -/* #include "infblock.h" */ - -/* +++ inftrees.h */ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Huffman code lookup table entry--this entry is four bytes for machines - that have 16-bit pointers (e.g. PC's in the small or medium model). */ - -typedef struct inflate_huft_s FAR inflate_huft; - -struct inflate_huft_s { - union { - struct { - Byte Exop; /* number of extra bits or operation */ - Byte Bits; /* number of bits in this code or subcode */ - } what; - Bytef *pad; /* pad structure to a power of 2 (4 bytes for */ - } word; /* 16-bit, 8 bytes for 32-bit machines) */ - union { - uInt Base; /* literal, length base, or distance base */ - inflate_huft *Next; /* pointer to next level of table */ - } more; -}; - -#ifdef DEBUG_ZLIB - extern uInt inflate_hufts; -#endif - -extern int inflate_trees_bits OF(( - uIntf *, /* 19 code lengths */ - uIntf *, /* bits tree desired/actual depth */ - inflate_huft * FAR *, /* bits tree result */ - z_streamp )); /* for zalloc, zfree functions */ - -extern int inflate_trees_dynamic OF(( - uInt, /* number of literal/length codes */ - uInt, /* number of distance codes */ - uIntf *, /* that many (total) code lengths */ - uIntf *, /* literal desired/actual bit depth */ - uIntf *, /* distance desired/actual bit depth */ - inflate_huft * FAR *, /* literal/length tree result */ - inflate_huft * FAR *, /* distance tree result */ - z_streamp )); /* for zalloc, zfree functions */ - -extern int inflate_trees_fixed OF(( - uIntf *, /* literal desired/actual bit depth */ - uIntf *, /* distance desired/actual bit depth */ - inflate_huft * FAR *, /* literal/length tree result */ - inflate_huft * FAR *)); /* distance tree result */ - -extern int inflate_trees_free OF(( - inflate_huft *, /* tables to free */ - z_streamp )); /* for zfree function */ - -/* --- inftrees.h */ - -/* +++ infcodes.h */ -/* infcodes.h -- header to use infcodes.c - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -struct inflate_codes_state; -typedef struct inflate_codes_state FAR inflate_codes_statef; - -extern inflate_codes_statef *inflate_codes_new OF(( - uInt, uInt, - inflate_huft *, inflate_huft *, - z_streamp )); - -extern int inflate_codes OF(( - inflate_blocks_statef *, - z_streamp , - int)); - -extern void inflate_codes_free OF(( - inflate_codes_statef *, - z_streamp )); - -/* --- infcodes.h */ - -/* +++ infutil.h */ -/* infutil.h -- types and macros common to blocks and codes - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -#ifndef _INFUTIL_H -#define _INFUTIL_H - -typedef enum { - TYPE, /* get type bits (3, including end bit) */ - LENS, /* get lengths for stored */ - STORED, /* processing stored block */ - TABLE, /* get table lengths */ - BTREE, /* get bit lengths tree for a dynamic block */ - DTREE, /* get length, distance trees for a dynamic block */ - CODES, /* processing fixed or dynamic block */ - DRY, /* output remaining window bytes */ - DONEB, /* finished last block, done */ - BADB} /* got a data error--stuck here */ -inflate_block_mode; - -/* inflate blocks semi-private state */ -struct inflate_blocks_state { - - /* mode */ - inflate_block_mode mode; /* current inflate_block mode */ - - /* mode dependent information */ - union { - uInt left; /* if STORED, bytes left to copy */ - struct { - uInt table; /* table lengths (14 bits) */ - uInt index; /* index into blens (or border) */ - uIntf *blens; /* bit lengths of codes */ - uInt bb; /* bit length tree depth */ - inflate_huft *tb; /* bit length decoding tree */ - } trees; /* if DTREE, decoding info for trees */ - struct { - inflate_huft *tl; - inflate_huft *td; /* trees to free */ - inflate_codes_statef - *codes; - } decode; /* if CODES, current state */ - } sub; /* submode */ - uInt last; /* true if this block is the last block */ - - /* mode independent information */ - uInt bitk; /* bits in bit buffer */ - uLong bitb; /* bit buffer */ - Bytef *window; /* sliding window */ - Bytef *end; /* one byte after sliding window */ - Bytef *read; /* window read pointer */ - Bytef *write; /* window write pointer */ - check_func checkfn; /* check function */ - uLong check; /* check on output */ - -}; - - -/* defines for inflate input/output */ -/* update pointers and return */ -#define UPDBITS {s->bitb=b;s->bitk=k;} -#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} -#define UPDOUT {s->write=q;} -#define UPDATE {UPDBITS UPDIN UPDOUT} -#define LEAVE {UPDATE return inflate_flush(s,z,r);} -/* get bytes and bits */ -#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} -#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} -#define NEXTBYTE (n--,*p++) -#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} -/* output bytes */ -#define WAVAIL (uInt)(qread?s->read-q-1:s->end-q) -#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} -#define WWRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} -#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} -#define NEEDOUT {if(m==0){WWRAP if(m==0){FLUSH WWRAP if(m==0) LEAVE}}r=Z_OK;} -#define OUTBYTE(a) {*q++=(Byte)(a);m--;} -/* load local pointers */ -#define LOAD {LOADIN LOADOUT} - -/* masks for lower bits (size given to avoid silly warnings with Visual C++) */ -extern uInt inflate_mask[17]; - -/* copy as much as possible from the sliding window to the output area */ -extern int inflate_flush OF(( - inflate_blocks_statef *, - z_streamp , - int)); - -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - -#endif -/* --- infutil.h */ - -#ifndef NO_DUMMY_DECL -struct inflate_codes_state {int dummy;}; /* for buggy compilers */ -#endif - -/* Table for deflate from PKZIP's appnote.txt. */ -local const uInt border[] = { /* Order of the bit length code lengths */ - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - -/* - Notes beyond the 1.93a appnote.txt: - - 1. Distance pointers never point before the beginning of the output - stream. - 2. Distance pointers can point back across blocks, up to 32k away. - 3. There is an implied maximum of 7 bits for the bit length table and - 15 bits for the actual data. - 4. If only one code exists, then it is encoded using one bit. (Zero - would be more efficient, but perhaps a little confusing.) If two - codes exist, they are coded using one bit each (0 and 1). - 5. There is no way of sending zero distance codes--a dummy must be - sent if there are none. (History: a pre 2.0 version of PKZIP would - store blocks with no distance codes, but this was discovered to be - too harsh a criterion.) Valid only for 1.93a. 2.04c does allow - zero distance codes, which is sent as one code of zero bits in - length. - 6. There are up to 286 literal/length codes. Code 256 represents the - end-of-block. Note however that the static length tree defines - 288 codes just to fill out the Huffman codes. Codes 286 and 287 - cannot be used though, since there is no length base or extra bits - defined for them. Similarily, there are up to 30 distance codes. - However, static trees define 32 codes (all 5 bits) to fill out the - Huffman codes, but the last two had better not show up in the data. - 7. Unzip can check dynamic Huffman blocks for complete code sets. - The exception is that a single code would not be complete (see #4). - 8. The five bits following the block type is really the number of - literal codes sent minus 257. - 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits - (1+6+6). Therefore, to output three times the length, you output - three codes (1+1+1), whereas to output four times the same length, - you only need two codes (1+3). Hmm. - 10. In the tree reconstruction algorithm, Code = Code + Increment - only if BitLength(i) is not zero. (Pretty obvious.) - 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) - 12. Note: length code 284 can represent 227-258, but length code 285 - really is 258. The last length deserves its own, short code - since it gets used a lot in very redundant files. The length - 258 is special since 258 - 3 (the min match length) is 255. - 13. The literal/length and distance code bit lengths are read as a - single stream of lengths. It is possible (and advantageous) for - a repeat code (16, 17, or 18) to go across the boundary between - the two sets of lengths. - */ - - -void inflate_blocks_reset(s, z, c) -inflate_blocks_statef *s; -z_streamp z; -uLongf *c; -{ - if (s->checkfn != Z_NULL) - *c = s->check; - if (s->mode == BTREE || s->mode == DTREE) - ZFREE(z, s->sub.trees.blens); - if (s->mode == CODES) - { - inflate_codes_free(s->sub.decode.codes, z); - inflate_trees_free(s->sub.decode.td, z); - inflate_trees_free(s->sub.decode.tl, z); - } - s->mode = TYPE; - s->bitk = 0; - s->bitb = 0; - s->read = s->write = s->window; - if (s->checkfn != Z_NULL) - z->adler = s->check = (*s->checkfn)(0L, Z_NULL, 0); - Trace((stderr, "inflate: blocks reset\n")); -} - - -inflate_blocks_statef *inflate_blocks_new(z, c, w) -z_streamp z; -check_func c; -uInt w; -{ - inflate_blocks_statef *s; - - if ((s = (inflate_blocks_statef *)ZALLOC - (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) - return s; - if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) - { - ZFREE(z, s); - return Z_NULL; - } - s->end = s->window + w; - s->checkfn = c; - s->mode = TYPE; - Trace((stderr, "inflate: blocks allocated\n")); - inflate_blocks_reset(s, z, &s->check); - return s; -} - - -#ifdef DEBUG_ZLIB - extern uInt inflate_hufts; -#endif -int inflate_blocks(s, z, r) -inflate_blocks_statef *s; -z_streamp z; -int r; -{ - uInt t; /* temporary storage */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD - - /* process input based on current state */ - while (1) switch (s->mode) - { - case TYPE: - NEEDBITS(3) - t = (uInt)b & 7; - s->last = t & 1; - switch (t >> 1) - { - case 0: /* stored */ - Trace((stderr, "inflate: stored block%s\n", - s->last ? " (last)" : "")); - DUMPBITS(3) - t = k & 7; /* go to byte boundary */ - DUMPBITS(t) - s->mode = LENS; /* get length of stored block */ - break; - case 1: /* fixed */ - Trace((stderr, "inflate: fixed codes block%s\n", - s->last ? " (last)" : "")); - { - uInt bl, bd; - inflate_huft *tl, *td; - - inflate_trees_fixed(&bl, &bd, &tl, &td); - s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); - if (s->sub.decode.codes == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - s->sub.decode.tl = Z_NULL; /* don't try to free these */ - s->sub.decode.td = Z_NULL; - } - DUMPBITS(3) - s->mode = CODES; - break; - case 2: /* dynamic */ - Trace((stderr, "inflate: dynamic codes block%s\n", - s->last ? " (last)" : "")); - DUMPBITS(3) - s->mode = TABLE; - break; - case 3: /* illegal */ - DUMPBITS(3) - s->mode = BADB; - z->msg = (char*)"invalid block type"; - r = Z_DATA_ERROR; - LEAVE - } - break; - case LENS: - NEEDBITS(32) - if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) - { - s->mode = BADB; - z->msg = (char*)"invalid stored block lengths"; - r = Z_DATA_ERROR; - LEAVE - } - s->sub.left = (uInt)b & 0xffff; - b = k = 0; /* dump bits */ - Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); - s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); - break; - case STORED: - if (n == 0) - LEAVE - NEEDOUT - t = s->sub.left; - if (t > n) t = n; - if (t > m) t = m; - zmemcpy(q, p, t); - p += t; n -= t; - q += t; m -= t; - if ((s->sub.left -= t) != 0) - break; - Tracev((stderr, "inflate: stored end, %lu total out\n", - z->total_out + (q >= s->read ? q - s->read : - (s->end - s->read) + (q - s->window)))); - s->mode = s->last ? DRY : TYPE; - break; - case TABLE: - NEEDBITS(14) - s->sub.trees.table = t = (uInt)b & 0x3fff; -#ifndef PKZIP_BUG_WORKAROUND - if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) - { - s->mode = BADB; - z->msg = (char*)"too many length or distance symbols"; - r = Z_DATA_ERROR; - LEAVE - } -#endif - t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); - if (t < 19) - t = 19; - if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - DUMPBITS(14) - s->sub.trees.index = 0; - Tracev((stderr, "inflate: table sizes ok\n")); - s->mode = BTREE; - case BTREE: - while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) - { - NEEDBITS(3) - s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; - DUMPBITS(3) - } - while (s->sub.trees.index < 19) - s->sub.trees.blens[border[s->sub.trees.index++]] = 0; - s->sub.trees.bb = 7; - t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, - &s->sub.trees.tb, z); - if (t != Z_OK) - { - r = t; - if (r == Z_DATA_ERROR) - { - ZFREE(z, s->sub.trees.blens); - s->mode = BADB; - } - LEAVE - } - s->sub.trees.index = 0; - Tracev((stderr, "inflate: bits tree ok\n")); - s->mode = DTREE; - case DTREE: - while (t = s->sub.trees.table, - s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) - { - inflate_huft *h; - uInt i, j, c; - - t = s->sub.trees.bb; - NEEDBITS(t) - h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); - t = h->word.what.Bits; - c = h->more.Base; - if (c < 16) - { - DUMPBITS(t) - s->sub.trees.blens[s->sub.trees.index++] = c; - } - else /* c == 16..18 */ - { - i = c == 18 ? 7 : c - 14; - j = c == 18 ? 11 : 3; - NEEDBITS(t + i) - DUMPBITS(t) - j += (uInt)b & inflate_mask[i]; - DUMPBITS(i) - i = s->sub.trees.index; - t = s->sub.trees.table; - if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || - (c == 16 && i < 1)) - { - inflate_trees_free(s->sub.trees.tb, z); - ZFREE(z, s->sub.trees.blens); - s->mode = BADB; - z->msg = (char*)"invalid bit length repeat"; - r = Z_DATA_ERROR; - LEAVE - } - c = c == 16 ? s->sub.trees.blens[i - 1] : 0; - do { - s->sub.trees.blens[i++] = c; - } while (--j); - s->sub.trees.index = i; - } - } - inflate_trees_free(s->sub.trees.tb, z); - s->sub.trees.tb = Z_NULL; - { - uInt bl, bd; - inflate_huft *tl, *td; - inflate_codes_statef *c; - - bl = 9; /* must be <= 9 for lookahead assumptions */ - bd = 6; /* must be <= 9 for lookahead assumptions */ - t = s->sub.trees.table; -#ifdef DEBUG_ZLIB - inflate_hufts = 0; -#endif - t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), - s->sub.trees.blens, &bl, &bd, &tl, &td, z); - if (t != Z_OK) - { - if (t == (uInt)Z_DATA_ERROR) - { - ZFREE(z, s->sub.trees.blens); - s->mode = BADB; - } - r = t; - LEAVE - } - Tracev((stderr, "inflate: trees ok, %d * %d bytes used\n", - inflate_hufts, sizeof(inflate_huft))); - if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) - { - inflate_trees_free(td, z); - inflate_trees_free(tl, z); - r = Z_MEM_ERROR; - LEAVE - } - ZFREE(z, s->sub.trees.blens); - s->sub.decode.codes = c; - s->sub.decode.tl = tl; - s->sub.decode.td = td; - } - s->mode = CODES; - case CODES: - UPDATE - if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) - return inflate_flush(s, z, r); - r = Z_OK; - inflate_codes_free(s->sub.decode.codes, z); - inflate_trees_free(s->sub.decode.td, z); - inflate_trees_free(s->sub.decode.tl, z); - LOAD - Tracev((stderr, "inflate: codes end, %lu total out\n", - z->total_out + (q >= s->read ? q - s->read : - (s->end - s->read) + (q - s->window)))); - if (!s->last) - { - s->mode = TYPE; - break; - } - if (k > 7) /* return unused byte, if any */ - { - Assert(k < 16, "inflate_codes grabbed too many bytes") - k -= 8; - n++; - p--; /* can always return one */ - } - s->mode = DRY; - case DRY: - FLUSH - if (s->read != s->write) - LEAVE - s->mode = DONEB; - case DONEB: - r = Z_STREAM_END; - LEAVE - case BADB: - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } -} - - -int inflate_blocks_free(s, z, c) -inflate_blocks_statef *s; -z_streamp z; -uLongf *c; -{ - inflate_blocks_reset(s, z, c); - ZFREE(z, s->window); - ZFREE(z, s); - Trace((stderr, "inflate: blocks freed\n")); - return Z_OK; -} - - -void inflate_set_dictionary(s, d, n) -inflate_blocks_statef *s; -const Bytef *d; -uInt n; -{ - zmemcpy((charf *)s->window, d, n); - s->read = s->write = s->window + n; -} - -/* - * This subroutine adds the data at next_in/avail_in to the output history - * without performing any output. The output buffer must be "caught up"; - * i.e. no pending output (hence s->read equals s->write), and the state must - * be BLOCKS (i.e. we should be willing to see the start of a series of - * BLOCKS). On exit, the output will also be caught up, and the checksum - * will have been updated if need be. - */ -int inflate_addhistory(s, z) -inflate_blocks_statef *s; -z_stream *z; -{ - uLong b; /* bit buffer */ /* NOT USED HERE */ - uInt k; /* bits in bit buffer */ /* NOT USED HERE */ - uInt t; /* temporary storage */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - - if (s->read != s->write) - return Z_STREAM_ERROR; - if (s->mode != TYPE) - return Z_DATA_ERROR; - - /* we're ready to rock */ - LOAD - /* while there is input ready, copy to output buffer, moving - * pointers as needed. - */ - while (n) { - t = n; /* how many to do */ - /* is there room until end of buffer? */ - if (t > m) t = m; - /* update check information */ - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(s->check, q, t); - zmemcpy(q, p, t); - q += t; - p += t; - n -= t; - z->total_out += t; - s->read = q; /* drag read pointer forward */ -/* WWRAP */ /* expand WWRAP macro by hand to handle s->read */ - if (q == s->end) { - s->read = q = s->window; - m = WAVAIL; - } - } - UPDATE - return Z_OK; -} - - -/* - * At the end of a Deflate-compressed PPP packet, we expect to have seen - * a `stored' block type value but not the (zero) length bytes. - */ -int inflate_packet_flush(s) - inflate_blocks_statef *s; -{ - if (s->mode != LENS) - return Z_DATA_ERROR; - s->mode = TYPE; - return Z_OK; -} -/* --- infblock.c */ - -/* +++ inftrees.c */ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* #include "zutil.h" */ -/* #include "inftrees.h" */ - -char inflate_copyright[] = " inflate 1.0.4 Copyright 1995-1996 Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - - -local int huft_build OF(( - uIntf *, /* code lengths in bits */ - uInt, /* number of codes */ - uInt, /* number of "simple" codes */ - const uIntf *, /* list of base values for non-simple codes */ - const uIntf *, /* list of extra bits for non-simple codes */ - inflate_huft * FAR*,/* result: starting table */ - uIntf *, /* maximum lookup bits (returns actual) */ - z_streamp )); /* for zalloc function */ - -local voidpf falloc OF(( - voidpf, /* opaque pointer (not used) */ - uInt, /* number of items */ - uInt)); /* size of item */ - -/* Tables for deflate from PKZIP's appnote.txt. */ -local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - /* see note #13 above about 258 */ -local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */ -local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577}; -local const uInt cpdext[30] = { /* Extra bits for distance codes */ - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13}; - -/* - Huffman code decoding is performed using a multi-level table lookup. - The fastest way to decode is to simply build a lookup table whose - size is determined by the longest code. However, the time it takes - to build this table can also be a factor if the data being decoded - is not very long. The most common codes are necessarily the - shortest codes, so those codes dominate the decoding time, and hence - the speed. The idea is you can have a shorter table that decodes the - shorter, more probable codes, and then point to subsidiary tables for - the longer codes. The time it costs to decode the longer codes is - then traded against the time it takes to make longer tables. - - This results of this trade are in the variables lbits and dbits - below. lbits is the number of bits the first level table for literal/ - length codes can decode in one step, and dbits is the same thing for - the distance codes. Subsequent tables are also less than or equal to - those sizes. These values may be adjusted either when all of the - codes are shorter than that, in which case the longest code length in - bits is used, or when the shortest code is *longer* than the requested - table size, in which case the length of the shortest code in bits is - used. - - There are two different values for the two tables, since they code a - different number of possibilities each. The literal/length table - codes 286 possible values, or in a flat code, a little over eight - bits. The distance table codes 30 possible values, or a little less - than five bits, flat. The optimum values for speed end up being - about one bit more than those, so lbits is 8+1 and dbits is 5+1. - The optimum values may differ though from machine to machine, and - possibly even between compilers. Your mileage may vary. - */ - - -/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ -#define BMAX 15 /* maximum bit length of any code */ -#define N_MAX 288 /* maximum number of codes in any set */ - -#ifdef DEBUG_ZLIB - uInt inflate_hufts; -#endif - -local int huft_build(b, n, s, d, e, t, m, zs) -uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ -uInt n; /* number of codes (assumed <= N_MAX) */ -uInt s; /* number of simple-valued codes (0..s-1) */ -const uIntf *d; /* list of base values for non-simple codes */ -const uIntf *e; /* list of extra bits for non-simple codes */ -inflate_huft * FAR *t; /* result: starting table */ -uIntf *m; /* maximum lookup bits, returns actual */ -z_streamp zs; /* for zalloc function */ -/* Given a list of code lengths and a maximum table size, make a set of - tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR - if the given code set is incomplete (the tables are still built in this - case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of - lengths), or Z_MEM_ERROR if not enough memory. */ -{ - - uInt a; /* counter for codes of length k */ - uInt c[BMAX+1]; /* bit length count table */ - uInt f; /* i repeats in table every f entries */ - int g; /* maximum code length */ - int h; /* table level */ - register uInt i; /* counter, current code */ - register uInt j; /* counter */ - register int k; /* number of bits in current code */ - int l; /* bits per table (returned in m) */ - register uIntf *p; /* pointer into c[], b[], or v[] */ - inflate_huft *q; /* points to current table */ - struct inflate_huft_s r; /* table entry for structure assignment */ - inflate_huft *u[BMAX]; /* table stack */ - uInt v[N_MAX]; /* values in order of bit length */ - register int w; /* bits before this table == (l * h) */ - uInt x[BMAX+1]; /* bit offsets, then code stack */ - uIntf *xp; /* pointer into x */ - int y; /* number of dummy codes added */ - uInt z; /* number of entries in current table */ - - - /* Generate counts for each bit length */ - p = c; -#define C0 *p++ = 0; -#define C2 C0 C0 C0 C0 -#define C4 C2 C2 C2 C2 - C4 /* clear c[]--assume BMAX+1 is 16 */ - p = b; i = n; - do { - c[*p++]++; /* assume all entries <= BMAX */ - } while (--i); - if (c[0] == n) /* null input--all zero length codes */ - { - *t = (inflate_huft *)Z_NULL; - *m = 0; - return Z_OK; - } - - - /* Find minimum and maximum length, bound *m by those */ - l = *m; - for (j = 1; j <= BMAX; j++) - if (c[j]) - break; - k = j; /* minimum code length */ - if ((uInt)l < j) - l = j; - for (i = BMAX; i; i--) - if (c[i]) - break; - g = i; /* maximum code length */ - if ((uInt)l > i) - l = i; - *m = l; - - - /* Adjust last length count to fill out codes, if needed */ - for (y = 1 << j; j < i; j++, y <<= 1) - if ((y -= c[j]) < 0) - return Z_DATA_ERROR; - if ((y -= c[i]) < 0) - return Z_DATA_ERROR; - c[i] += y; - - - /* Generate starting offsets into the value table for each length */ - x[1] = j = 0; - p = c + 1; xp = x + 2; - while (--i) { /* note that i == g from above */ - *xp++ = (j += *p++); - } - - - /* Make a table of values in order of bit lengths */ - p = b; i = 0; - do { - if ((j = *p++) != 0) - v[x[j]++] = i; - } while (++i < n); - n = x[g]; /* set n to length of v */ - - - /* Generate the Huffman codes and for each, make the table entries */ - x[0] = i = 0; /* first Huffman code is zero */ - p = v; /* grab values in bit order */ - h = -1; /* no tables yet--level -1 */ - w = -l; /* bits decoded == (l * h) */ - u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ - q = (inflate_huft *)Z_NULL; /* ditto */ - z = 0; /* ditto */ - - /* go through the bit lengths (k already is bits in shortest code) */ - for (; k <= g; k++) - { - a = c[k]; - while (a--) - { - /* here i is the Huffman code of length k bits for value *p */ - /* make tables up to required level */ - while (k > w + l) - { - h++; - w += l; /* previous table always l bits */ - - /* compute minimum size table less than or equal to l bits */ - z = g - w; - z = z > (uInt)l ? l : z; /* table size upper limit */ - if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ - { /* too few codes for k-w bit table */ - f -= a + 1; /* deduct codes from patterns left */ - xp = c + k; - if (j < z) - while (++j < z) /* try smaller tables up to z bits */ - { - if ((f <<= 1) <= *++xp) - break; /* enough codes to use up j bits */ - f -= *xp; /* else deduct codes from patterns */ - } - } - z = 1 << j; /* table entries for j-bit table */ - - /* allocate and link in new table */ - if ((q = (inflate_huft *)ZALLOC - (zs,z + 1,sizeof(inflate_huft))) == Z_NULL) - { - if (h) - inflate_trees_free(u[0], zs); - return Z_MEM_ERROR; /* not enough memory */ - } -#ifdef DEBUG_ZLIB - inflate_hufts += z + 1; -#endif - *t = q + 1; /* link to list for huft_free() */ - *(t = &(q->next)) = Z_NULL; - u[h] = ++q; /* table starts after link */ - - /* connect to last table, if there is one */ - if (h) - { - x[h] = i; /* save pattern for backing up */ - r.bits = (Byte)l; /* bits to dump before this table */ - r.exop = (Byte)j; /* bits in this table */ - r.next = q; /* pointer to this table */ - j = i >> (w - l); /* (get around Turbo C bug) */ - u[h-1][j] = r; /* connect to last table */ - } - } - - /* set up table entry in r */ - r.bits = (Byte)(k - w); - if (p >= v + n) - r.exop = 128 + 64; /* out of values--invalid code */ - else if (*p < s) - { - r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ - r.base = *p++; /* simple code is just the value */ - } - else - { - r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ - r.base = d[*p++ - s]; - } - - /* fill code-like entries with r */ - f = 1 << (k - w); - for (j = i >> w; j < z; j += f) - q[j] = r; - - /* backwards increment the k-bit code i */ - for (j = 1 << (k - 1); i & j; j >>= 1) - i ^= j; - i ^= j; - - /* backup over finished tables */ - while ((i & ((1 << w) - 1)) != x[h]) - { - h--; /* don't need to update q */ - w -= l; - } - } - } - - - /* Return Z_BUF_ERROR if we were given an incomplete table */ - return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; -} - - -int inflate_trees_bits(c, bb, tb, z) -uIntf *c; /* 19 code lengths */ -uIntf *bb; /* bits tree desired/actual depth */ -inflate_huft * FAR *tb; /* bits tree result */ -z_streamp z; /* for zfree function */ -{ - int r; - - r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z); - if (r == Z_DATA_ERROR) - z->msg = (char*)"oversubscribed dynamic bit lengths tree"; - else if (r == Z_BUF_ERROR || *bb == 0) - { - inflate_trees_free(*tb, z); - z->msg = (char*)"incomplete dynamic bit lengths tree"; - r = Z_DATA_ERROR; - } - return r; -} - - -int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z) -uInt nl; /* number of literal/length codes */ -uInt nd; /* number of distance codes */ -uIntf *c; /* that many (total) code lengths */ -uIntf *bl; /* literal desired/actual bit depth */ -uIntf *bd; /* distance desired/actual bit depth */ -inflate_huft * FAR *tl; /* literal/length tree result */ -inflate_huft * FAR *td; /* distance tree result */ -z_streamp z; /* for zfree function */ -{ - int r; - - /* build literal/length tree */ - r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z); - if (r != Z_OK || *bl == 0) - { - if (r == Z_DATA_ERROR) - z->msg = (char*)"oversubscribed literal/length tree"; - else if (r != Z_MEM_ERROR) - { - inflate_trees_free(*tl, z); - z->msg = (char*)"incomplete literal/length tree"; - r = Z_DATA_ERROR; - } - return r; - } - - /* build distance tree */ - r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z); - if (r != Z_OK || (*bd == 0 && nl > 257)) - { - if (r == Z_DATA_ERROR) - z->msg = (char*)"oversubscribed distance tree"; - else if (r == Z_BUF_ERROR) { -#ifdef PKZIP_BUG_WORKAROUND - r = Z_OK; - } -#else - inflate_trees_free(*td, z); - z->msg = (char*)"incomplete distance tree"; - r = Z_DATA_ERROR; - } - else if (r != Z_MEM_ERROR) - { - z->msg = (char*)"empty distance tree with lengths"; - r = Z_DATA_ERROR; - } - inflate_trees_free(*tl, z); - return r; -#endif - } - - /* done */ - return Z_OK; -} - - -/* build fixed tables only once--keep them here */ -local int fixed_built = 0; -#define FIXEDH 530 /* number of hufts used by fixed tables */ -local inflate_huft fixed_mem[FIXEDH]; -local uInt fixed_bl; -local uInt fixed_bd; -local inflate_huft *fixed_tl; -local inflate_huft *fixed_td; - - -local voidpf falloc(q, n, s) -voidpf q; /* opaque pointer */ -uInt n; /* number of items */ -uInt s; /* size of item */ -{ - Assert(s == sizeof(inflate_huft) && n <= *(intf *)q, - "inflate_trees falloc overflow"); - *(intf *)q -= n+s-s; /* s-s to avoid warning */ - return (voidpf)(fixed_mem + *(intf *)q); -} - - -int inflate_trees_fixed(bl, bd, tl, td) -uIntf *bl; /* literal desired/actual bit depth */ -uIntf *bd; /* distance desired/actual bit depth */ -inflate_huft * FAR *tl; /* literal/length tree result */ -inflate_huft * FAR *td; /* distance tree result */ -{ - /* build fixed tables if not already (multiple overlapped executions ok) */ - if (!fixed_built) - { - int k; /* temporary variable */ - unsigned c[288]; /* length list for huft_build */ - z_stream z; /* for falloc function */ - int f = FIXEDH; /* number of hufts left in fixed_mem */ - - /* set up fake z_stream for memory routines */ - z.zalloc = falloc; - z.zfree = Z_NULL; - z.opaque = (voidpf)&f; - - /* literal table */ - for (k = 0; k < 144; k++) - c[k] = 8; - for (; k < 256; k++) - c[k] = 9; - for (; k < 280; k++) - c[k] = 7; - for (; k < 288; k++) - c[k] = 8; - fixed_bl = 7; - huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z); - - /* distance table */ - for (k = 0; k < 30; k++) - c[k] = 5; - fixed_bd = 5; - huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z); - - /* done */ - Assert(f == 0, "invalid build of fixed tables"); - fixed_built = 1; - } - *bl = fixed_bl; - *bd = fixed_bd; - *tl = fixed_tl; - *td = fixed_td; - return Z_OK; -} - - -int inflate_trees_free(t, z) -inflate_huft *t; /* table to free */ -z_streamp z; /* for zfree function */ -/* Free the malloc'ed tables built by huft_build(), which makes a linked - list of the tables it made, with the links in a dummy first entry of - each table. */ -{ - register inflate_huft *p, *q, *r; - - /* Reverse linked list */ - p = Z_NULL; - q = t; - while (q != Z_NULL) - { - r = (q - 1)->next; - (q - 1)->next = p; - p = q; - q = r; - } - /* Go through linked list, freeing from the malloced (t[-1]) address. */ - while (p != Z_NULL) - { - q = (--p)->next; - ZFREE(z,p); - p = q; - } - return Z_OK; -} -/* --- inftrees.c */ - -/* +++ infcodes.c */ -/* infcodes.c -- process literals and length/distance pairs - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* #include "zutil.h" */ -/* #include "inftrees.h" */ -/* #include "infblock.h" */ -/* #include "infcodes.h" */ -/* #include "infutil.h" */ - -/* +++ inffast.h */ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -extern int inflate_fast OF(( - uInt, - uInt, - inflate_huft *, - inflate_huft *, - inflate_blocks_statef *, - z_streamp )); -/* --- inffast.h */ - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - -/* inflate codes private state */ -struct inflate_codes_state { - - /* mode */ - enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - START, /* x: set up for LEN */ - LEN, /* i: get length/literal/eob next */ - LENEXT, /* i: getting length extra (have base) */ - DIST, /* i: get distance next */ - DISTEXT, /* i: getting distance extra */ - COPY, /* o: copying bytes in window, waiting for space */ - LIT, /* o: got literal, waiting for output space */ - WASH, /* o: got eob, possibly still output waiting */ - END, /* x: got eob and all data flushed */ - BADCODE} /* x: got error */ - mode; /* current inflate_codes mode */ - - /* mode dependent information */ - uInt len; - union { - struct { - inflate_huft *tree; /* pointer into tree */ - uInt need; /* bits needed */ - } code; /* if LEN or DIST, where in tree */ - uInt lit; /* if LIT, literal */ - struct { - uInt get; /* bits to get for extra */ - uInt dist; /* distance back to copy from */ - } copy; /* if EXT or COPY, where and how much */ - } sub; /* submode */ - - /* mode independent information */ - Byte lbits; /* ltree bits decoded per branch */ - Byte dbits; /* dtree bits decoder per branch */ - inflate_huft *ltree; /* literal/length/eob tree */ - inflate_huft *dtree; /* distance tree */ - -}; - - -inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) -uInt bl, bd; -inflate_huft *tl; -inflate_huft *td; /* need separate declaration for Borland C++ */ -z_streamp z; -{ - inflate_codes_statef *c; - - if ((c = (inflate_codes_statef *) - ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) - { - c->mode = START; - c->lbits = (Byte)bl; - c->dbits = (Byte)bd; - c->ltree = tl; - c->dtree = td; - Tracev((stderr, "inflate: codes new\n")); - } - return c; -} - - -int inflate_codes(s, z, r) -inflate_blocks_statef *s; -z_streamp z; -int r; -{ - uInt j; /* temporary storage */ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - Bytef *f; /* pointer to copy strings from */ - inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ - - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD - - /* process input and output based on current state */ - while (1) switch (c->mode) - { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - case START: /* x: set up for LEN */ -#ifndef SLOW - if (m >= 258 && n >= 10) - { - UPDATE - r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); - LOAD - if (r != Z_OK) - { - c->mode = r == Z_STREAM_END ? WASH : BADCODE; - break; - } - } -#endif /* !SLOW */ - c->sub.code.need = c->lbits; - c->sub.code.tree = c->ltree; - c->mode = LEN; - case LEN: /* i: get length/literal/eob next */ - j = c->sub.code.need; - NEEDBITS(j) - t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); - DUMPBITS(t->bits) - e = (uInt)(t->exop); - if (e == 0) /* literal */ - { - c->sub.lit = t->base; - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", t->base)); - c->mode = LIT; - break; - } - if (e & 16) /* length */ - { - c->sub.copy.get = e & 15; - c->len = t->base; - c->mode = LENEXT; - break; - } - if ((e & 64) == 0) /* next table */ - { - c->sub.code.need = e; - c->sub.code.tree = t->next; - break; - } - if (e & 32) /* end of block */ - { - Tracevv((stderr, "inflate: end of block\n")); - c->mode = WASH; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = (char*)"invalid literal/length code"; - r = Z_DATA_ERROR; - LEAVE - case LENEXT: /* i: getting length extra (have base) */ - j = c->sub.copy.get; - NEEDBITS(j) - c->len += (uInt)b & inflate_mask[j]; - DUMPBITS(j) - c->sub.code.need = c->dbits; - c->sub.code.tree = c->dtree; - Tracevv((stderr, "inflate: length %u\n", c->len)); - c->mode = DIST; - case DIST: /* i: get distance next */ - j = c->sub.code.need; - NEEDBITS(j) - t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); - DUMPBITS(t->bits) - e = (uInt)(t->exop); - if (e & 16) /* distance */ - { - c->sub.copy.get = e & 15; - c->sub.copy.dist = t->base; - c->mode = DISTEXT; - break; - } - if ((e & 64) == 0) /* next table */ - { - c->sub.code.need = e; - c->sub.code.tree = t->next; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = (char*)"invalid distance code"; - r = Z_DATA_ERROR; - LEAVE - case DISTEXT: /* i: getting distance extra */ - j = c->sub.copy.get; - NEEDBITS(j) - c->sub.copy.dist += (uInt)b & inflate_mask[j]; - DUMPBITS(j) - Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); - c->mode = COPY; - case COPY: /* o: copying bytes in window, waiting for space */ -#ifndef __TURBOC__ /* Turbo C bug for following expression */ - f = (uInt)(q - s->window) < c->sub.copy.dist ? - s->end - (c->sub.copy.dist - (q - s->window)) : - q - c->sub.copy.dist; -#else - f = q - c->sub.copy.dist; - if ((uInt)(q - s->window) < c->sub.copy.dist) - f = s->end - (c->sub.copy.dist - (uInt)(q - s->window)); -#endif - while (c->len) - { - NEEDOUT - OUTBYTE(*f++) - if (f == s->end) - f = s->window; - c->len--; - } - c->mode = START; - break; - case LIT: /* o: got literal, waiting for output space */ - NEEDOUT - OUTBYTE(c->sub.lit) - c->mode = START; - break; - case WASH: /* o: got eob, possibly more output */ - FLUSH - if (s->read != s->write) - LEAVE - c->mode = END; - case END: - r = Z_STREAM_END; - LEAVE - case BADCODE: /* x: got error */ - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } -} - - -void inflate_codes_free(c, z) -inflate_codes_statef *c; -z_streamp z; -{ - ZFREE(z, c); - Tracev((stderr, "inflate: codes free\n")); -} -/* --- infcodes.c */ - -/* +++ infutil.c */ -/* inflate_util.c -- data and routines common to blocks and codes - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* #include "zutil.h" */ -/* #include "infblock.h" */ -/* #include "inftrees.h" */ -/* #include "infcodes.h" */ -/* #include "infutil.h" */ - -#ifndef NO_DUMMY_DECL -struct inflate_codes_state {int dummy;}; /* for buggy compilers */ -#endif - -/* And'ing with mask[n] masks the lower n bits */ -uInt inflate_mask[17] = { - 0x0000, - 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, - 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff -}; - - -/* copy as much as possible from the sliding window to the output area */ -int inflate_flush(s, z, r) -inflate_blocks_statef *s; -z_streamp z; -int r; -{ - uInt n; - Bytef *p; - Bytef *q; - - /* local copies of source and destination pointers */ - p = z->next_out; - q = s->read; - - /* compute number of bytes to copy as far as end of window */ - n = (uInt)((q <= s->write ? s->write : s->end) - q); - if (n > z->avail_out) n = z->avail_out; - if (n && r == Z_BUF_ERROR) r = Z_OK; - - /* update counters */ - z->avail_out -= n; - z->total_out += n; - - /* update check information */ - if (s->checkfn != Z_NULL) - z->adler = s->check = (*s->checkfn)(s->check, q, n); - - /* copy as far as end of window */ - if (p != Z_NULL) { - zmemcpy(p, q, n); - p += n; - } - q += n; - - /* see if more to copy at beginning of window */ - if (q == s->end) - { - /* wrap pointers */ - q = s->window; - if (s->write == s->end) - s->write = s->window; - - /* compute bytes to copy */ - n = (uInt)(s->write - q); - if (n > z->avail_out) n = z->avail_out; - if (n && r == Z_BUF_ERROR) r = Z_OK; - - /* update counters */ - z->avail_out -= n; - z->total_out += n; - - /* update check information */ - if (s->checkfn != Z_NULL) - z->adler = s->check = (*s->checkfn)(s->check, q, n); - - /* copy */ - if (p != Z_NULL) { - zmemcpy(p, q, n); - p += n; - } - q += n; - } - - /* update pointers */ - z->next_out = p; - s->read = q; - - /* done */ - return r; -} -/* --- infutil.c */ - -/* +++ inffast.c */ -/* inffast.c -- process literals and length/distance pairs fast - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* #include "zutil.h" */ -/* #include "inftrees.h" */ -/* #include "infblock.h" */ -/* #include "infcodes.h" */ -/* #include "infutil.h" */ -/* #include "inffast.h" */ - -#ifndef NO_DUMMY_DECL -struct inflate_codes_state {int dummy;}; /* for buggy compilers */ -#endif - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - -/* macros for bit input with no checking and for returning unused bytes */ -#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<>3);p-=c;k&=7;} - -/* Called with number of bytes left to write in window at least 258 - (the maximum string length) and number of input bytes available - at least ten. The ten bytes are six bytes for the longest length/ - distance pair plus four bytes for overloading the bit buffer. */ - -int inflate_fast(bl, bd, tl, td, s, z) -uInt bl, bd; -inflate_huft *tl; -inflate_huft *td; /* need separate declaration for Borland C++ */ -inflate_blocks_statef *s; -z_streamp z; -{ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - uInt ml; /* mask for literal/length tree */ - uInt md; /* mask for distance tree */ - uInt c; /* bytes to copy */ - uInt d; /* distance back to copy from */ - Bytef *r; /* copy source pointer */ - - /* load input, output, bit values */ - LOAD - - /* initialize masks */ - ml = inflate_mask[bl]; - md = inflate_mask[bd]; - - /* do until not enough input or output space for fast loop */ - do { /* assume called with m >= 258 && n >= 10 */ - /* get literal/length code */ - GRABBITS(20) /* max bits for literal/length code */ - if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) - { - DUMPBITS(t->bits) - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base)); - *q++ = (Byte)t->base; - m--; - continue; - } - do { - DUMPBITS(t->bits) - if (e & 16) - { - /* get extra bits for length */ - e &= 15; - c = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e) - Tracevv((stderr, "inflate: * length %u\n", c)); - - /* decode distance base of block to copy */ - GRABBITS(15); /* max bits for distance code */ - e = (t = td + ((uInt)b & md))->exop; - do { - DUMPBITS(t->bits) - if (e & 16) - { - /* get extra bits to add to distance base */ - e &= 15; - GRABBITS(e) /* get extra bits (up to 13) */ - d = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e) - Tracevv((stderr, "inflate: * distance %u\n", d)); - - /* do the copy */ - m -= c; - if ((uInt)(q - s->window) >= d) /* offset before dest */ - { /* just copy */ - r = q - d; - *q++ = *r++; c--; /* minimum count is three, */ - *q++ = *r++; c--; /* so unroll loop a little */ - } - else /* else offset after destination */ - { - e = d - (uInt)(q - s->window); /* bytes from offset to end */ - r = s->end - e; /* pointer to offset */ - if (c > e) /* if source crosses, */ - { - c -= e; /* copy to end of window */ - do { - *q++ = *r++; - } while (--e); - r = s->window; /* copy rest from start of window */ - } - } - do { /* copy all or what's left */ - *q++ = *r++; - } while (--c); - break; - } - else if ((e & 64) == 0) - e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop; - else - { - z->msg = (char*)"invalid distance code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while (1); - break; - } - if ((e & 64) == 0) - { - if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0) - { - DUMPBITS(t->bits) - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base)); - *q++ = (Byte)t->base; - m--; - break; - } - } - else if (e & 32) - { - Tracevv((stderr, "inflate: * end of block\n")); - UNGRAB - UPDATE - return Z_STREAM_END; - } - else - { - z->msg = (char*)"invalid literal/length code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while (1); - } while (m >= 258 && n >= 10); - - /* not enough input or output--restore pointers and return */ - UNGRAB - UPDATE - return Z_OK; -} -/* --- inffast.c */ - -/* +++ zutil.c */ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-1996 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: zutil.c,v 1.17 1996/07/24 13:41:12 me Exp $ */ - -/* #include "zutil.h" */ - -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - -#ifndef STDC -extern void exit OF((int)); -#endif - -const char *z_errmsg[10] = { -"need dictionary", /* Z_NEED_DICT 2 */ -"stream end", /* Z_STREAM_END 1 */ -"", /* Z_OK 0 */ -"file error", /* Z_ERRNO (-1) */ -"stream error", /* Z_STREAM_ERROR (-2) */ -"data error", /* Z_DATA_ERROR (-3) */ -"insufficient memory", /* Z_MEM_ERROR (-4) */ -"buffer error", /* Z_BUF_ERROR (-5) */ -"incompatible version",/* Z_VERSION_ERROR (-6) */ -""}; - - -const char *zlibVersion() -{ - return ZLIB_VERSION; -} - -#ifdef DEBUG_ZLIB -void z_error (m) - char *m; -{ - fprintf(stderr, "%s\n", m); - exit(1); -} -#endif - -#ifndef HAVE_MEMCPY - -void zmemcpy(dest, source, len) - Bytef* dest; - Bytef* source; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = *source++; /* ??? to be unrolled */ - } while (--len != 0); -} - -int zmemcmp(s1, s2, len) - Bytef* s1; - Bytef* s2; - uInt len; -{ - uInt j; - - for (j = 0; j < len; j++) { - if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; - } - return 0; -} - -void zmemzero(dest, len) - Bytef* dest; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = 0; /* ??? to be unrolled */ - } while (--len != 0); -} -#endif - -#ifdef __TURBOC__ -#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__) -/* Small and medium model in Turbo C are for now limited to near allocation - * with reduced MAX_WBITS and MAX_MEM_LEVEL - */ -# define MY_ZCALLOC - -/* Turbo C malloc() does not allow dynamic allocation of 64K bytes - * and farmalloc(64K) returns a pointer with an offset of 8, so we - * must fix the pointer. Warning: the pointer must be put back to its - * original form in order to free it, use zcfree(). - */ - -#define MAX_PTR 10 -/* 10*64K = 640K */ - -local int next_ptr = 0; - -typedef struct ptr_table_s { - voidpf org_ptr; - voidpf new_ptr; -} ptr_table; - -local ptr_table table[MAX_PTR]; -/* This table is used to remember the original form of pointers - * to large buffers (64K). Such pointers are normalized with a zero offset. - * Since MSDOS is not a preemptive multitasking OS, this table is not - * protected from concurrent access. This hack doesn't work anyway on - * a protected system like OS/2. Use Microsoft C instead. - */ - -voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - voidpf buf = opaque; /* just to make some compilers happy */ - ulg bsize = (ulg)items*size; - - /* If we allocate less than 65520 bytes, we assume that farmalloc - * will return a usable pointer which doesn't have to be normalized. - */ - if (bsize < 65520L) { - buf = farmalloc(bsize); - if (*(ush*)&buf != 0) return buf; - } else { - buf = farmalloc(bsize + 16L); - } - if (buf == NULL || next_ptr >= MAX_PTR) return NULL; - table[next_ptr].org_ptr = buf; - - /* Normalize the pointer to seg:0 */ - *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; - *(ush*)&buf = 0; - table[next_ptr++].new_ptr = buf; - return buf; -} - -void zcfree (voidpf opaque, voidpf ptr) -{ - int n; - if (*(ush*)&ptr != 0) { /* object < 64K */ - farfree(ptr); - return; - } - /* Find the original pointer */ - for (n = 0; n < next_ptr; n++) { - if (ptr != table[n].new_ptr) continue; - - farfree(table[n].org_ptr); - while (++n < next_ptr) { - table[n-1] = table[n]; - } - next_ptr--; - return; - } - ptr = opaque; /* just to make some compilers happy */ - Assert(0, "zcfree: ptr not found"); -} -#endif -#endif /* __TURBOC__ */ - - -#if defined(M_I86) && !defined(__32BIT__) -/* Microsoft C in 16-bit mode */ - -# define MY_ZCALLOC - -#if (!defined(_MSC_VER) || (_MSC_VER < 600)) -# define _halloc halloc -# define _hfree hfree -#endif - -voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - return _halloc((long)items, size); -} - -void zcfree (voidpf opaque, voidpf ptr) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - _hfree(ptr); -} - -#endif /* MSC */ - - -#ifndef MY_ZCALLOC /* Any system without a special alloc function */ - -#ifndef STDC -extern voidp calloc OF((uInt items, uInt size)); -extern void free OF((voidpf ptr)); -#endif - -voidpf zcalloc (opaque, items, size) - voidpf opaque; - unsigned items; - unsigned size; -{ - if (opaque) items += size - size; /* make compiler happy */ - return (voidpf)calloc(items, size); -} - -void zcfree (opaque, ptr) - voidpf opaque; - voidpf ptr; -{ - free(ptr); - if (opaque) return; /* make compiler happy */ -} - -#endif /* MY_ZCALLOC */ -/* --- zutil.c */ - -/* +++ adler32.c */ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: adler32.c,v 1.10 1996/05/22 11:52:18 me Exp $ */ - -/* #include "zlib.h" */ - -#define BASE 65521L /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - -/* ========================================================================= */ -uLong adler32(adler, buf, len) - uLong adler; - const Bytef *buf; - uInt len; -{ - unsigned long s1 = adler & 0xffff; - unsigned long s2 = (adler >> 16) & 0xffff; - int k; - - if (buf == Z_NULL) return 1L; - - while (len > 0) { - k = len < NMAX ? len : NMAX; - len -= k; - while (k >= 16) { - DO16(buf); - buf += 16; - k -= 16; - } - if (k != 0) do { - s1 += *buf++; - s2 += s1; - } while (--k); - s1 %= BASE; - s2 %= BASE; - } - return (s2 << 16) | s1; -} -/* --- adler32.c */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/zlib.h linux.19pre5-ac1/drivers/net/zlib.h --- linux.19p5/drivers/net/zlib.h Thu Apr 4 13:18:57 2002 +++ linux.19pre5-ac1/drivers/net/zlib.h Thu Jan 1 01:00:00 1970 @@ -1,1010 +0,0 @@ -/* $Id: zlib.h,v 1.2 1997/12/23 10:47:44 paulus Exp $ */ - -/* - * This file is derived from zlib.h and zconf.h from the zlib-1.0.4 - * distribution by Jean-loup Gailly and Mark Adler, with some additions - * by Paul Mackerras to aid in implementing Deflate compression and - * decompression for PPP packets. - */ - -/* - * ==FILEVERSION 971127== - * - * This marker is used by the Linux installation script to determine - * whether an up-to-date version of this file is already installed. - */ - - -/* +++ zlib.h */ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.0.4, Jul 24th, 1996. - - Copyright (C) 1995-1996 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - gzip@prep.ai.mit.edu madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt - (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). -*/ - -#ifndef _ZLIB_H -#define _ZLIB_H - -#ifdef __cplusplus -extern "C" { -#endif - - -/* +++ zconf.h */ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-1996 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: zconf.h,v 1.20 1996/07/02 15:09:28 me Exp $ */ - -#ifndef _ZCONF_H -#define _ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - */ -#ifdef Z_PREFIX -# define deflateInit_ z_deflateInit_ -# define deflate z_deflate -# define deflateEnd z_deflateEnd -# define inflateInit_ z_inflateInit_ -# define inflate z_inflate -# define inflateEnd z_inflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateSetDictionary z_deflateSetDictionary -# define deflateCopy z_deflateCopy -# define deflateReset z_deflateReset -# define deflateParams z_deflateParams -# define inflateInit2_ z_inflateInit2_ -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateReset z_inflateReset -# define compress z_compress -# define uncompress z_uncompress -# define adler32 z_adler32 -# define crc32 z_crc32 -# define get_crc_table z_get_crc_table - -# define Byte z_Byte -# define uInt z_uInt -# define uLong z_uLong -# define Bytef z_Bytef -# define charf z_charf -# define intf z_intf -# define uIntf z_uIntf -# define uLongf z_uLongf -# define voidpf z_voidpf -# define voidp z_voidp -#endif - -#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) -# define WIN32 -#endif -#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) -# ifndef __32BIT__ -# define __32BIT__ -# endif -#endif -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#if defined(MSDOS) && !defined(__32BIT__) -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) -# define STDC -#endif -#if (defined(__STDC__) || defined(__cplusplus)) && !defined(STDC) -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const -# endif -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2 */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - 1 << (windowBits+2) + 1 << (memLevel+9) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR __far -# else -# define FAR far -# endif -#endif -#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) -# ifndef __32BIT__ -# define SMALL_MEDIUM -# define FAR __far -# endif -#endif -#ifndef FAR -# define FAR -#endif - -typedef unsigned char Byte; /* 8 bits */ -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#if defined(__BORLANDC__) && defined(SMALL_MEDIUM) - /* Borland C/C++ ignores FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - - -/* Compile with -DZLIB_DLL for Windows DLL support */ -#if (defined(_WINDOWS) || defined(WINDOWS)) && defined(ZLIB_DLL) -# include -# define EXPORT WINAPI -#else -# define EXPORT -#endif - -#endif /* _ZCONF_H */ -/* --- zconf.h */ - -#define ZLIB_VERSION "1.0.4P" - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed - data. This version of the library supports only one compression method - (deflation) but other algorithms may be added later and will have the same - stream interface. - - For compression the application must provide the output buffer and - may optionally provide the input buffer for optimization. For decompression, - the application must provide the input buffer and may optionally provide - the output buffer for optimization. - - Compression can be done in a single step if the buffers are large - enough (for example if an input file is mmap'ed), or can be done by - repeated calls of the compression function. In the latter case, the - application must provide more input and/or consume the output - (providing more output space) before each call. - - The library does not install any signal handler. It is recommended to - add at least a handler for SIGSEGV when decompressing; the library checks - the consistency of the input data whenever possible but may go nuts - for some forms of corrupted input. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); - -struct internal_state; - -typedef struct z_stream_s { - Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total nb of input bytes read so far */ - - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total nb of bytes output so far */ - - char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: ascii or binary */ - uLong adler; /* adler32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - The application must update next_in and avail_in when avail_in has - dropped to zero. It must update next_out and avail_out when avail_out - has dropped to zero. The application must initialize zalloc, zfree and - opaque before calling the init function. All other fields are set by the - compression library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this - if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, - pointers returned by zalloc for objects of exactly 65536 bytes *must* - have their offset normalized to zero. The default allocation function - provided by this library ensures this (see zutil.c). To reduce memory - requirements and avoid any allocation of 64K objects, at the expense of - compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or - progress reports. After compression, total_in holds the total size of - the uncompressed data and may be saved for use in the decompressor - (particularly if the decompressor wants to decompress everything in - a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_PACKET_FLUSH 2 -#define Z_SYNC_FLUSH 3 -#define Z_FULL_FLUSH 4 -#define Z_FINISH 5 -/* Allowed flush values; see deflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative - * values are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_ASCII 1 -#define Z_UNKNOWN 2 -/* Possible values of the data_type field */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - /* basic functions */ - -extern const char * EXPORT zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is - not compatible with the zlib.h header file used by the application. - This check is automatically made by deflateInit and inflateInit. - */ - -/* -extern int EXPORT deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. - If zalloc and zfree are set to Z_NULL, deflateInit updates them to - use default allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at - all (the input data is simply copied a block at a time). - Z_DEFAULT_COMPRESSION requests a default compromise between speed and - compression (currently equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if level is not a valid compression level, - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). - msg is set to null if there is no error message. deflateInit does not - perform any compression: this will be done by deflate(). -*/ - - -extern int EXPORT deflate OF((z_streamp strm, int flush)); -/* - Performs one or both of the following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). - Some output may be provided even if flush is not set. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating avail_in or avail_out accordingly; avail_out - should never be zero before the call. The application can consume the - compressed output when it wants, for example when the output buffer is full - (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK - and with zero avail_out, it must be called again after making room in the - output buffer because there might be more output pending. - - If the parameter flush is set to Z_PARTIAL_FLUSH, the current compression - block is terminated and flushed to the output buffer so that the - decompressor can get all input data available so far. For method 9, a future - variant on method 8, the current block will be flushed but not terminated. - Z_SYNC_FLUSH has the same effect as partial flush except that the compressed - output is byte aligned (the compressor can clear its internal bit buffer) - and the current block is always terminated; this can be useful if the - compressor has to be restarted from scratch after an interruption (in which - case the internal state of the compressor may be lost). - If flush is set to Z_FULL_FLUSH, the compression block is terminated, a - special marker is output and the compression dictionary is discarded; this - is useful to allow the decompressor to synchronize if one compressed block - has been damaged (see inflateSync below). Flushing degrades compression and - so should be used only when necessary. Using Z_FULL_FLUSH too often can - seriously degrade the compression. If deflate returns with avail_out == 0, - this function must be called again with the same value of the flush - parameter and more output space (updated avail_out), until the flush is - complete (deflate returns with non-zero avail_out). - - If the parameter flush is set to Z_PACKET_FLUSH, the compression - block is terminated, and a zero-length stored block is output, - omitting the length bytes (the effect of this is that the 3-bit type - code 000 for a stored block is output, and the output is then - byte-aligned). This is designed for use at the end of a PPP packet. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there - was enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the - stream are deflateReset or deflateEnd. - - Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least - 0.1% larger than avail_in plus 12 bytes. If deflate does not return - Z_STREAM_END, then it must be called again as described above. - - deflate() may update data_type if it can make a good guess about - the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered - binary. This field is only for information purposes and does not affect - the compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible. -*/ - - -extern int EXPORT deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, - msg may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -extern int EXPORT inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - zalloc, zfree and opaque must be initialized before by the caller. If - zalloc and zfree are set to Z_NULL, inflateInit updates them to use default - allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_VERSION_ERROR if the zlib library version is incompatible - with the version assumed by the caller. msg is set to null if there is no - error message. inflateInit does not perform any decompression: this will be - done by inflate(). -*/ - - -extern int EXPORT inflate OF((z_streamp strm, int flush)); -/* - Performs one or both of the following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing - will resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there - is no more input data or no more space in the output buffer (see below - about the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating the next_* and avail_* values accordingly. - The application can consume the uncompressed output when it wants, for - example when the output buffer is full (avail_out == 0), or after each - call of inflate(). If inflate returns Z_OK and with zero avail_out, it - must be called again after making room in the output buffer because there - might be more output pending. - - If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH, - inflate flushes as much output as possible to the output buffer. The - flushing behavior of inflate is not specified for values of the flush - parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the - current implementation actually flushes as much output as possible - anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data - has been consumed, it is expecting to see the length field of a stored - block; if not, it returns Z_DATA_ERROR. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step - (a single call of inflate), the parameter flush should be set to - Z_FINISH. In this case all pending input is processed and all pending - output is flushed; avail_out must be large enough to hold all the - uncompressed data. (The size of the uncompressed data may have been saved - by the compressor for this purpose.) The next operation on this stream must - be inflateEnd to deallocate the decompression state. The use of Z_FINISH - is never required, but can be used to inform inflate that a faster routine - may be used for the single inflate() call. - - inflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if the end of the - compressed data has been reached and all uncompressed output has been - produced, Z_NEED_DICT if a preset dictionary is needed at this point (see - inflateSetDictionary below), Z_DATA_ERROR if the input data was corrupted, - Z_STREAM_ERROR if the stream structure was inconsistent (for example if - next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, - Z_BUF_ERROR if no progress is possible or if there was not enough room in - the output buffer when Z_FINISH is used. In the Z_DATA_ERROR case, the - application may then call inflateSync to look for a good compression block. - In the Z_NEED_DICT case, strm->adler is set to the Adler32 value of the - dictionary chosen by the compressor. -*/ - - -extern int EXPORT inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -extern int EXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by - the caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. (Method 9 will allow a 64K history buffer and - partial block flushes.) - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library (the value 16 will be allowed for method 9). Larger - values of this parameter result in better compression at the expense of - memory usage. The default value is 15 if deflateInit is used instead. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but - is slow and reduces compression ratio; memLevel=9 uses maximum memory - for optimal speed. The default value is 8. See zconf.h for total memory - usage as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match). Filtered data consists mostly of small values with a - somewhat random distribution. In this case, the compression algorithm is - tuned to compress them better. The effect of Z_FILTERED is to force more - Huffman coding and less string matching; it is somewhat intermediate - between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects - the compression ratio but not the correctness of the compressed output even - if it is not set appropriately. - - If next_in is not null, the library will use this buffer to hold also - some history information; the buffer must either hold the entire input - data, or have at least 1<<(windowBits+1) bytes and be writable. If next_in - is null, the library will allocate its own history buffer (and leave next_in - null). next_out need not be provided here but must be provided by the - application for the next call of deflate(). - - If the history buffer is provided by the application, next_in must - must never be changed by the application since the compressor maintains - information inside this buffer from call to call; the application - must provide more input only by increasing avail_in. next_in is always - reset by the library in this case. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was - not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as - an invalid method). msg is set to null if there is no error message. - deflateInit2 does not perform any compression: this will be done by - deflate(). -*/ - -extern int EXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the compression dictionary (history buffer) from the given - byte sequence without producing any compressed output. This function must - be called immediately after deflateInit or deflateInit2, before any call - of deflate. The compressor and decompressor must use exactly the same - dictionary (see inflateSetDictionary). - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and - can be predicted with good accuracy; the data can then be compressed better - than with the default empty dictionary. In this version of the library, - only the last 32K bytes of the dictionary are used. - Upon return of this function, strm->adler is set to the Adler32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The Adler32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state - is inconsistent (for example if deflate has already been called for this - stream). deflateSetDictionary does not perform any compression: this will - be done by deflate(). -*/ - -extern int EXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. If - the source stream is using an application-supplied history buffer, a new - buffer is allocated for the destination stream. The compressed output - buffer is always application-supplied. It's the responsibility of the - application to provide the correct values of next_out and avail_out for the - next call of deflate. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and - can consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being NULL). msg is left unchanged in both source and - destination. -*/ - -extern int EXPORT deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, - but does not free and reallocate all the internal compression state. - The stream will keep the same compression level and any other attributes - that may have been set by deflateInit2. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - -extern int EXPORT deflateParams OF((z_streamp strm, int level, int strategy)); -/* - Dynamically update the compression level and compression strategy. - This can be used to switch between compression and straight copy of - the input data, or to switch to a different kind of input data requiring - a different strategy. If the compression level is changed, the input - available so far is compressed with the old level (and may be flushed); - the new level will take effect only at the next call of deflate(). - - Before the call of deflateParams, the stream state must be set as for - a call of deflate(), since the currently available input may have to - be compressed and flushed. In particular, strm->avail_out must be non-zero. - - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR - if strm->avail_out was zero. -*/ - -extern int EXPORT deflateOutputPending OF((z_streamp strm)); -/* - Returns the number of bytes of output which are immediately - available from the compressor (i.e. without any further input - or flush). -*/ - -/* -extern int EXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with more compression options. The - fields next_out, zalloc, zfree and opaque must be initialized before by - the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library (the value 16 will be allowed soon). The - default value is 15 if inflateInit is used instead. If a compressed stream - with a larger window size is given as input, inflate() will return with - the error code Z_DATA_ERROR instead of trying to allocate a larger window. - - If next_out is not null, the library will use this buffer for the history - buffer; the buffer must either be large enough to hold the entire output - data, or have at least 1<resource[0]->end = ranges->io_end - 1; b->resource[1]->end = ranges->mem_end - 1; + /* Add bridge resources to the resource tree. */ + if (b->resource[0]->end > b->resource[0]->start && + request_resource(bus->resource[0], b->resource[0]) < 0) + printk(KERN_ERR "PCI: failed to reserve IO " + "for bus %d\n", b->number); + if (b->resource[1]->end > b->resource[1]->start && + request_resource(bus->resource[1], b->resource[1]) < 0) + printk(KERN_ERR "PCI: failed to reserve MEM " + "for bus %d\n", b->number); + pci_setup_bridge(b); } } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/pcmcia/Config.in linux.19pre5-ac1/drivers/pcmcia/Config.in --- linux.19p5/drivers/pcmcia/Config.in Thu Apr 4 13:21:12 2002 +++ linux.19pre5-ac1/drivers/pcmcia/Config.in Thu Apr 4 14:49:25 2002 @@ -17,13 +17,14 @@ if [ "$CONFIG_PCI" != "n" ]; then bool ' CardBus support' CONFIG_CARDBUS fi - dep_bool ' i82092 compatible bridge support' CONFIG_I82092 $CONFIG_PCI - bool ' i82365 compatible bridge support' CONFIG_I82365 bool ' Databook TCIC host bridge support' CONFIG_TCIC if [ "$CONFIG_HD64465" = "y" ]; then dep_tristate ' HD64465 host bridge support' CONFIG_HD64465_PCMCIA $CONFIG_PCMCIA fi + dep_bool ' i82092 compatible bridge support' CONFIG_I82092 $CONFIG_PCI + bool ' i82365 compatible bridge support' CONFIG_I82365 + if [ "$CONFIG_ARCH_SA1100" = "y" ]; then + dep_tristate ' SA1100 support' CONFIG_PCMCIA_SA1100 + fi fi -dep_tristate ' SA1100 support' CONFIG_PCMCIA_SA1100 $CONFIG_ARCH_SA1100 $CONFIG_PCMCIA - endmenu diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/pnp/Config.in linux.19pre5-ac1/drivers/pnp/Config.in --- linux.19p5/drivers/pnp/Config.in Thu Apr 4 13:19:32 2002 +++ linux.19pre5-ac1/drivers/pnp/Config.in Tue Jan 29 18:25:02 2002 @@ -8,4 +8,8 @@ dep_tristate ' ISA Plug and Play support' CONFIG_ISAPNP $CONFIG_PNP +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_bool ' PNPBIOS support (EXPERIMENTAL)' CONFIG_PNPBIOS $CONFIG_PNP +fi + endmenu diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/pnp/Makefile linux.19pre5-ac1/drivers/pnp/Makefile --- linux.19p5/drivers/pnp/Makefile Thu Apr 4 13:19:32 2002 +++ linux.19pre5-ac1/drivers/pnp/Makefile Tue Jan 29 18:25:02 2002 @@ -10,15 +10,22 @@ O_TARGET := pnp.o -export-objs := isapnp.o -list-multi := isa-pnp.o +export-objs := isapnp.o pnpbios_core.o +multi-objs := isa-pnp.o pnpbios.o -proc-$(CONFIG_PROC_FS) = isapnp_proc.o -isa-pnp-objs := isapnp.o quirks.o $(proc-y) +isa-pnp-proc-$(CONFIG_PROC_FS) = isapnp_proc.o +pnpbios-proc-$(CONFIG_PROC_FS) = pnpbios_proc.o + +isa-pnp-objs := isapnp.o quirks.o $(isa-pnp-proc-y) +pnpbios-objs := pnpbios_core.o $(pnpbios-proc-y) obj-$(CONFIG_ISAPNP) += isa-pnp.o +obj-$(CONFIG_PNPBIOS) += pnpbios.o include $(TOPDIR)/Rules.make isa-pnp.o: $(isa-pnp-objs) $(LD) $(LD_RFLAG) -r -o $@ $(isa-pnp-objs) + +pnpbios.o: $(pnpbios-objs) + $(LD) $(LD_RFLAG) -r -o $@ $(pnpbios-objs) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/pnp/isapnp.c linux.19pre5-ac1/drivers/pnp/isapnp.c --- linux.19p5/drivers/pnp/isapnp.c Thu Apr 4 13:19:32 2002 +++ linux.19pre5-ac1/drivers/pnp/isapnp.c Wed Feb 27 18:28:35 2002 @@ -56,10 +56,6 @@ #define ISAPNP_DEBUG #endif -struct resource *pidxr_res; -struct resource *pnpwrp_res; -struct resource *isapnp_rdp_res; - int isapnp_disable; /* Disable ISA PnP */ int isapnp_rdp; /* Read Data Port */ int isapnp_reset = 1; /* reset all PnP cards (deactivate) */ @@ -2147,13 +2143,10 @@ static void isapnp_free_all_resources(void) { #ifdef ISAPNP_REGION_OK - if (pidxr_res) - release_resource(pidxr_res); + release_region(_PIDXR, 1); #endif - if (pnpwrp_res) - release_resource(pnpwrp_res); - if (isapnp_rdp >= 0x203 && isapnp_rdp <= 0x3ff && isapnp_rdp_res) - release_resource(isapnp_rdp_res); + release_region(_PNPWRP, 1); + release_region(isapnp_rdp, 1); #ifdef MODULE #ifdef CONFIG_PROC_FS isapnp_proc_done(); @@ -2284,14 +2277,12 @@ return 0; } #ifdef ISAPNP_REGION_OK - pidxr_res=request_region(_PIDXR, 1, "isapnp index"); - if(!pidxr_res) { + if (!request_region(_PIDXR, 1, "isapnp index")) { printk(KERN_ERR "isapnp: Index Register 0x%x already used\n", _PIDXR); return -EBUSY; } #endif - pnpwrp_res=request_region(_PNPWRP, 1, "isapnp write"); - if(!pnpwrp_res) { + if (!request_region(_PNPWRP, 1, "isapnp write")) { printk(KERN_ERR "isapnp: Write Data Register 0x%x already used\n", _PNPWRP); #ifdef ISAPNP_REGION_OK release_region(_PIDXR, 1); @@ -2307,13 +2298,12 @@ printk(KERN_INFO "isapnp: Scanning for PnP cards...\n"); if (isapnp_rdp >= 0x203 && isapnp_rdp <= 0x3ff) { isapnp_rdp |= 3; - isapnp_rdp_res=request_region(isapnp_rdp, 1, "isapnp read"); - if(!isapnp_rdp_res) { + if (!request_region(isapnp_rdp, 1, "isapnp read")) { printk(KERN_ERR "isapnp: Read Data Register 0x%x already used\n", isapnp_rdp); #ifdef ISAPNP_REGION_OK release_region(_PIDXR, 1); #endif - release_region(isapnp_rdp, 1); + release_region(_PNPWRP, 1); return -EBUSY; } isapnp_set_rdp(); @@ -2323,12 +2313,15 @@ cards = isapnp_isolate(); if (cards < 0 || (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff)) { - isapnp_free_all_resources(); +#ifdef ISAPNP_REGION_OK + release_region(_PIDXR, 1); +#endif + release_region(_PNPWRP, 1); isapnp_detected = 0; printk(KERN_INFO "isapnp: No Plug & Play device found\n"); return 0; } - isapnp_rdp_res=request_region(isapnp_rdp, 1, "isapnp read"); + request_region(isapnp_rdp, 1, "isapnp read"); } isapnp_build_device_list(); cards = 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/pnp/pnpbios_core.c linux.19pre5-ac1/drivers/pnp/pnpbios_core.c --- linux.19p5/drivers/pnp/pnpbios_core.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/pnp/pnpbios_core.c Thu Apr 4 16:13:31 2002 @@ -0,0 +1,1352 @@ +/* + * PnP BIOS services + * + * Originally (C) 1998 Christian Schmidt + * Modifications (c) 1998 Tom Lees + * Minor reorganizations by David Hinds + * Modifications (c) 2001,2002 by Thomas Hood + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * References: + * Compaq Computer Corporation, Phoenix Technologies Ltd., Intel Corporation + * Plug and Play BIOS Specification, Version 1.0A, May 5, 1994 + * Plug and Play BIOS Clarification Paper, October 6, 1994 + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * + * PnP BIOS INTERFACE + * + */ + +/* PnP BIOS signature: "$PnP" */ +#define PNP_SIGNATURE (('$' << 0) + ('P' << 8) + ('n' << 16) + ('P' << 24)) + +#pragma pack(1) +union pnp_bios_expansion_header { + struct { + u32 signature; /* "$PnP" */ + u8 version; /* in BCD */ + u8 length; /* length in bytes, currently 21h */ + u16 control; /* system capabilities */ + u8 checksum; /* all bytes must add up to 0 */ + + u32 eventflag; /* phys. address of the event flag */ + u16 rmoffset; /* real mode entry point */ + u16 rmcseg; + u16 pm16offset; /* 16 bit protected mode entry */ + u32 pm16cseg; + u32 deviceID; /* EISA encoded system ID or 0 */ + u16 rmdseg; /* real mode data segment */ + u32 pm16dseg; /* 16 bit pm data segment base */ + } fields; + char chars[0x21]; /* To calculate the checksum */ +}; +#pragma pack() + +static struct { + u16 offset; + u16 segment; +} pnp_bios_callpoint; + +static union pnp_bios_expansion_header * pnp_bios_hdr = NULL; + +/* The PnP BIOS entries in the GDT */ +#define PNP_GDT (0x0060) +#define PNP_CS32 (PNP_GDT+0x00) /* segment for calling fn */ +#define PNP_CS16 (PNP_GDT+0x08) /* code segment for BIOS */ +#define PNP_DS (PNP_GDT+0x10) /* data segment for BIOS */ +#define PNP_TS1 (PNP_GDT+0x18) /* transfer data segment */ +#define PNP_TS2 (PNP_GDT+0x20) /* another data segment */ + +/* + * These are some opcodes for a "static asmlinkage" + * As this code is *not* executed inside the linux kernel segment, but in a + * alias at offset 0, we need a far return that can not be compiled by + * default (please, prove me wrong! this is *really* ugly!) + * This is the only way to get the bios to return into the kernel code, + * because the bios code runs in 16 bit protected mode and therefore can only + * return to the caller if the call is within the first 64kB, and the linux + * kernel begins at offset 3GB... + */ + +asmlinkage void pnp_bios_callfunc(void); + +__asm__( + ".text \n" + __ALIGN_STR "\n" + SYMBOL_NAME_STR(pnp_bios_callfunc) ":\n" + " pushl %edx \n" + " pushl %ecx \n" + " pushl %ebx \n" + " pushl %eax \n" + " lcallw " SYMBOL_NAME_STR(pnp_bios_callpoint) "\n" + " addl $16, %esp \n" + " lret \n" + ".previous \n" +); + +#define Q_SET_SEL(selname, address, size) \ +set_base (gdt [(selname) >> 3], __va((u32)(address))); \ +set_limit (gdt [(selname) >> 3], size) + +#define Q2_SET_SEL(selname, address, size) \ +set_base (gdt [(selname) >> 3], (u32)(address)); \ +set_limit (gdt [(selname) >> 3], size) + +/* + * At some point we want to use this stack frame pointer to unwind + * after PnP BIOS oopses. + */ + +u32 pnp_bios_fault_esp; +u32 pnp_bios_fault_eip; +u32 pnp_bios_is_utter_crap = 0; + +static spinlock_t pnp_bios_lock; + +static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3, + u16 arg4, u16 arg5, u16 arg6, u16 arg7, + void *ts1_base, u32 ts1_size, + void *ts2_base, u32 ts2_size) +{ + unsigned long flags; + u16 status; + + /* + * PnP BIOSes are generally not terribly re-entrant. + * Also, don't rely on them to save everything correctly. + */ + if(pnp_bios_is_utter_crap) + return PNP_FUNCTION_NOT_SUPPORTED; + + /* On some boxes IRQ's during PnP BIOS calls are deadly. */ + spin_lock_irqsave(&pnp_bios_lock, flags); + + if (ts1_size) + Q2_SET_SEL(PNP_TS1, ts1_base, ts1_size); + if (ts2_size) + Q2_SET_SEL(PNP_TS2, ts2_base, ts2_size); + + __asm__ __volatile__( + "pushl %%ebp\n\t" + "pushl %%edi\n\t" + "pushl %%esi\n\t" + "pushl %%ds\n\t" + "pushl %%es\n\t" + "pushl %%fs\n\t" + "pushl %%gs\n\t" + "pushfl\n\t" + "movl %%esp, pnp_bios_fault_esp\n\t" + "movl $1f, pnp_bios_fault_eip\n\t" + "lcall %5,%6\n\t" + "1:popfl\n\t" + "popl %%gs\n\t" + "popl %%fs\n\t" + "popl %%es\n\t" + "popl %%ds\n\t" + "popl %%esi\n\t" + "popl %%edi\n\t" + "popl %%ebp\n\t" + : "=a" (status) + : "0" ((func) | (((u32)arg1) << 16)), + "b" ((arg2) | (((u32)arg3) << 16)), + "c" ((arg4) | (((u32)arg5) << 16)), + "d" ((arg6) | (((u32)arg7) << 16)), + "i" (PNP_CS32), + "i" (0) + : "memory" + ); + spin_unlock_irqrestore(&pnp_bios_lock, flags); + + /* If we get here and this is set then the PnP BIOS faulted on us. */ + if(pnp_bios_is_utter_crap) + { + printk(KERN_ERR "PnPBIOS: Warning! Your PnP BIOS caused a fatal error. Attempting to continue.\n"); + printk(KERN_ERR "PnPBIOS: You may need to reboot with the \"pnpbios=off\" option to operate stably.\n"); + printk(KERN_ERR "PnPBIOS: Check with your vendor for an updated BIOS.\n"); + } + + return status; +} + + +/* + * + * UTILITY FUNCTIONS + * + */ + +static void pnpbios_warn_unexpected_status(const char * module, u16 status) +{ + printk(KERN_ERR "PnPBIOS: %s: Unexpected status 0x%x\n", module, status); +} + +void *pnpbios_kmalloc(size_t size, int f) +{ + void *p = kmalloc( size, f ); + if ( p == NULL ) + printk(KERN_ERR "PnPBIOS: kmalloc() failed\n"); + return p; +} + +/* + * Call this only after init time + */ +static inline int pnp_bios_present(void) +{ + return (pnp_bios_hdr != NULL); +} + +/* Forward declaration */ +static void update_devlist( u8 nodenum, struct pnp_bios_node *data ); + + +/* + * + * PnP BIOS ACCESS FUNCTIONS + * + */ + +#define PNP_GET_NUM_SYS_DEV_NODES 0x00 +#define PNP_GET_SYS_DEV_NODE 0x01 +#define PNP_SET_SYS_DEV_NODE 0x02 +#define PNP_GET_EVENT 0x03 +#define PNP_SEND_MESSAGE 0x04 +#define PNP_GET_DOCKING_STATION_INFORMATION 0x05 +#define PNP_SET_STATIC_ALLOCED_RES_INFO 0x09 +#define PNP_GET_STATIC_ALLOCED_RES_INFO 0x0a +#define PNP_GET_APM_ID_TABLE 0x0b +#define PNP_GET_PNP_ISA_CONFIG_STRUC 0x40 +#define PNP_GET_ESCD_INFO 0x41 +#define PNP_READ_ESCD 0x42 +#define PNP_WRITE_ESCD 0x43 + +/* + * Call PnP BIOS with function 0x00, "get number of system device nodes" + */ +static int __pnp_bios_dev_node_info(struct pnp_dev_node_info *data) +{ + u16 status; + if (!pnp_bios_present()) + return PNP_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_GET_NUM_SYS_DEV_NODES, 0, PNP_TS1, 2, PNP_TS1, PNP_DS, 0, 0, + data, sizeof(struct pnp_dev_node_info), 0, 0); + data->no_nodes &= 0xff; + return status; +} + +int pnp_bios_dev_node_info(struct pnp_dev_node_info *data) +{ + int status = __pnp_bios_dev_node_info( data ); + if ( status ) + pnpbios_warn_unexpected_status( "dev_node_info", status ); + return status; +} + +/* + * Note that some PnP BIOSes (e.g., on Sony Vaio laptops) die a horrible + * death if they are asked to access the "current" configuration. + * Therefore, if it's a matter of indifference, it's better to call + * get_dev_node() and set_dev_node() with boot=1 rather than with boot=0. + */ + +/* + * Call PnP BIOS with function 0x01, "get system device node" + * Input: *nodenum = desired node, + * boot = whether to get nonvolatile boot (!=0) + * or volatile current (0) config + * Output: *nodenum=next node or 0xff if no more nodes + */ +static int __pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data) +{ + u16 status; + if (!pnp_bios_present()) + return PNP_FUNCTION_NOT_SUPPORTED; + if ( !boot & pnpbios_dont_use_current_config ) + return PNP_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_GET_SYS_DEV_NODE, 0, PNP_TS1, 0, PNP_TS2, boot ? 2 : 1, PNP_DS, 0, + nodenum, sizeof(char), data, 65536); + return status; +} + +int pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data) +{ + int status; + status = __pnp_bios_get_dev_node( nodenum, boot, data ); + if ( status ) + pnpbios_warn_unexpected_status( "get_dev_node", status ); + return status; +} + + +/* + * Call PnP BIOS with function 0x02, "set system device node" + * Input: *nodenum = desired node, + * boot = whether to set nonvolatile boot (!=0) + * or volatile current (0) config + */ +static int __pnp_bios_set_dev_node(u8 nodenum, char boot, struct pnp_bios_node *data) +{ + u16 status; + if (!pnp_bios_present()) + return PNP_FUNCTION_NOT_SUPPORTED; + if ( !boot & pnpbios_dont_use_current_config ) + return PNP_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_SET_SYS_DEV_NODE, nodenum, 0, PNP_TS1, boot ? 2 : 1, PNP_DS, 0, 0, + data, 65536, 0, 0); + return status; +} + +int pnp_bios_set_dev_node(u8 nodenum, char boot, struct pnp_bios_node *data) +{ + int status; + status = __pnp_bios_set_dev_node( nodenum, boot, data ); + if ( status ) { + pnpbios_warn_unexpected_status( "set_dev_node", status ); + return status; + } + if ( !boot ) { /* Update devlist */ + u8 thisnodenum = nodenum; + status = pnp_bios_get_dev_node( &nodenum, boot, data ); + if ( status ) + return status; + update_devlist( thisnodenum, data ); + } + return status; +} + +#if needed +/* + * Call PnP BIOS with function 0x03, "get event" + */ +static int pnp_bios_get_event(u16 *event) +{ + u16 status; + if (!pnp_bios_present()) + return PNP_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_GET_EVENT, 0, PNP_TS1, PNP_DS, 0, 0 ,0 ,0, + event, sizeof(u16), 0, 0); + return status; +} +#endif + +#if needed +/* + * Call PnP BIOS with function 0x04, "send message" + */ +static int pnp_bios_send_message(u16 message) +{ + u16 status; + if (!pnp_bios_present()) + return PNP_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_SEND_MESSAGE, message, PNP_DS, 0, 0, 0, 0, 0, 0, 0, 0, 0); + return status; +} +#endif + +#ifdef CONFIG_HOTPLUG +/* + * Call PnP BIOS with function 0x05, "get docking station information" + */ +static int pnp_bios_dock_station_info(struct pnp_docking_station_info *data) +{ + u16 status; + if (!pnp_bios_present()) + return PNP_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_GET_DOCKING_STATION_INFORMATION, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0, + data, sizeof(struct pnp_docking_station_info), 0, 0); + return status; +} +#endif + +#if needed +/* + * Call PnP BIOS with function 0x09, "set statically allocated resource + * information" + */ +static int pnp_bios_set_stat_res(char *info) +{ + u16 status; + if (!pnp_bios_present()) + return PNP_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_SET_STATIC_ALLOCED_RES_INFO, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0, + info, *((u16 *) info), 0, 0); + return status; +} +#endif + +/* + * Call PnP BIOS with function 0x0a, "get statically allocated resource + * information" + */ +static int __pnp_bios_get_stat_res(char *info) +{ + u16 status; + if (!pnp_bios_present()) + return PNP_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_GET_STATIC_ALLOCED_RES_INFO, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0, + info, 65536, 0, 0); + return status; +} + +int pnp_bios_get_stat_res(char *info) +{ + int status; + status = __pnp_bios_get_stat_res( info ); + if ( status ) + pnpbios_warn_unexpected_status( "get_stat_res", status ); + return status; +} + +#if needed +/* + * Call PnP BIOS with function 0x0b, "get APM id table" + */ +static int pnp_bios_apm_id_table(char *table, u16 *size) +{ + u16 status; + if (!pnp_bios_present()) + return PNP_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_GET_APM_ID_TABLE, 0, PNP_TS2, 0, PNP_TS1, PNP_DS, 0, 0, + table, *size, size, sizeof(u16)); + return status; +} +#endif + +/* + * Call PnP BIOS with function 0x40, "get isa pnp configuration structure" + */ +static int __pnp_bios_isapnp_config(struct pnp_isa_config_struc *data) +{ + u16 status; + if (!pnp_bios_present()) + return PNP_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_GET_PNP_ISA_CONFIG_STRUC, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0, + data, sizeof(struct pnp_isa_config_struc), 0, 0); + return status; +} + +int pnp_bios_isapnp_config(struct pnp_isa_config_struc *data) +{ + int status; + status = __pnp_bios_isapnp_config( data ); + if ( status ) + pnpbios_warn_unexpected_status( "isapnp_config", status ); + return status; +} + +/* + * Call PnP BIOS with function 0x41, "get ESCD info" + */ +static int __pnp_bios_escd_info(struct escd_info_struc *data) +{ + u16 status; + if (!pnp_bios_present()) + return ESCD_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_GET_ESCD_INFO, 0, PNP_TS1, 2, PNP_TS1, 4, PNP_TS1, PNP_DS, + data, sizeof(struct escd_info_struc), 0, 0); + return status; +} + +int pnp_bios_escd_info(struct escd_info_struc *data) +{ + int status; + status = __pnp_bios_escd_info( data ); + if ( status ) + pnpbios_warn_unexpected_status( "escd_info", status ); + return status; +} + +/* + * Call PnP BIOS function 0x42, "read ESCD" + * nvram_base is determined by calling escd_info + */ +static int __pnp_bios_read_escd(char *data, u32 nvram_base) +{ + u16 status; + if (!pnp_bios_present()) + return ESCD_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_READ_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0, + data, 65536, (void *)nvram_base, 65536); + return status; +} + +int pnp_bios_read_escd(char *data, u32 nvram_base) +{ + int status; + status = __pnp_bios_read_escd( data, nvram_base ); + if ( status ) + pnpbios_warn_unexpected_status( "read_escd", status ); + return status; +} + +#if needed +/* + * Call PnP BIOS function 0x43, "write ESCD" + */ +static int pnp_bios_write_escd(char *data, u32 nvram_base) +{ + u16 status; + if (!pnp_bios_present()) + return ESCD_FUNCTION_NOT_SUPPORTED; + status = call_pnp_bios(PNP_WRITE_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0, + data, 65536, nvram_base, 65536); + return status; +} +#endif + + +/* + * + * DOCKING FUNCTIONS + * + */ + +#ifdef CONFIG_HOTPLUG + +static int unloading = 0; +static struct completion unload_sem; + +/* + * (Much of this belongs in a shared routine somewhere) + */ + +static int pnp_dock_event(int dock, struct pnp_docking_station_info *info) +{ + char *argv [3], **envp, *buf, *scratch; + int i = 0, value; + + if (!hotplug_path [0]) + return -ENOENT; + if (!current->fs->root) { + return -EAGAIN; + } + if (!(envp = (char **) pnpbios_kmalloc (20 * sizeof (char *), GFP_KERNEL))) { + return -ENOMEM; + } + if (!(buf = pnpbios_kmalloc (256, GFP_KERNEL))) { + kfree (envp); + return -ENOMEM; + } + + /* only one standardized param to hotplug command: type */ + argv [0] = hotplug_path; + argv [1] = "dock"; + argv [2] = 0; + + /* minimal command environment */ + envp [i++] = "HOME=/"; + envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; + +#ifdef DEBUG + /* hint that policy agent should enter no-stdout debug mode */ + envp [i++] = "DEBUG=kernel"; +#endif + /* extensible set of named bus-specific parameters, + * supporting multiple driver selection algorithms. + */ + scratch = buf; + + /* action: add, remove */ + envp [i++] = scratch; + scratch += sprintf (scratch, "ACTION=%s", dock?"add":"remove") + 1; + + /* Report the ident for the dock */ + envp [i++] = scratch; + scratch += sprintf (scratch, "DOCK=%x/%x/%x", + info->location_id, info->serial, info->capabilities); + envp[i] = 0; + + value = call_usermodehelper (argv [0], argv, envp); + kfree (buf); + kfree (envp); + return 0; +} + +/* + * Poll the PnP docking at regular intervals + */ +static int pnp_dock_thread(void * unused) +{ + static struct pnp_docking_station_info now; + int docked = -1, d = 0; + daemonize(); + reparent_to_init(); + strcpy(current->comm, "kpnpbiosd"); + while(!unloading && !signal_pending(current)) + { + int status; + + /* + * Poll every 2 seconds + */ + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ*2); + if(signal_pending(current)) + break; + + status = pnp_bios_dock_station_info(&now); + + switch(status) + { + /* + * No dock to manage + */ + case PNP_FUNCTION_NOT_SUPPORTED: + complete_and_exit(&unload_sem, 0); + case PNP_SYSTEM_NOT_DOCKED: + d = 0; + break; + case PNP_SUCCESS: + d = 1; + break; + default: + pnpbios_warn_unexpected_status( "pnp_dock_thread", status ); + continue; + } + if(d != docked) + { + if(pnp_dock_event(d, &now)==0) + { + docked = d; +#if 0 + printk(KERN_INFO "PnPBIOS: Docking station %stached\n", docked?"at":"de"); +#endif + } + } + } + complete_and_exit(&unload_sem, 0); +} + +#endif /* CONFIG_HOTPLUG */ + + +/* + * + * NODE DATA PARSING FUNCTIONS + * + */ + +static void add_irqresource(struct pci_dev *dev, int irq) +{ + int i = 0; + while (!(dev->irq_resource[i].flags & IORESOURCE_UNSET) && i < DEVICE_COUNT_IRQ) i++; + if (i < DEVICE_COUNT_IRQ) { + dev->irq_resource[i].start = (unsigned long) irq; + dev->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag + } +} + +static void add_dmaresource(struct pci_dev *dev, int dma) +{ + int i = 0; + while (!(dev->dma_resource[i].flags & IORESOURCE_UNSET) && i < DEVICE_COUNT_DMA) i++; + if (i < DEVICE_COUNT_DMA) { + dev->dma_resource[i].start = (unsigned long) dma; + dev->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag + } +} + +static void add_ioresource(struct pci_dev *dev, int io, int len) +{ + int i = 0; + while (!(dev->resource[i].flags & IORESOURCE_UNSET) && i < DEVICE_COUNT_RESOURCE) i++; + if (i < DEVICE_COUNT_RESOURCE) { + dev->resource[i].start = (unsigned long) io; + dev->resource[i].end = (unsigned long)(io + len - 1); + dev->resource[i].flags = IORESOURCE_IO; // Also clears _UNSET flag + } +} + +static void add_memresource(struct pci_dev *dev, int mem, int len) +{ + int i = 0; + while (!(dev->resource[i].flags & IORESOURCE_UNSET) && i < DEVICE_COUNT_RESOURCE) i++; + if (i < DEVICE_COUNT_RESOURCE) { + dev->resource[i].start = (unsigned long) mem; + dev->resource[i].end = (unsigned long)(mem + len - 1); + dev->resource[i].flags = IORESOURCE_MEM; // Also clears _UNSET flag + } +} + +static void node_resource_data_to_dev(struct pnp_bios_node *node, struct pci_dev *dev) +{ + unsigned char *p = node->data, *lastp=NULL; + int i; + + /* + * First, set resource info to default values + */ + for (i=0;iresource[i].start = 0; // "disabled" + dev->resource[i].flags = IORESOURCE_UNSET; + } + for (i=0;iirq_resource[i].start = (unsigned long)-1; // "disabled" + dev->irq_resource[i].flags = IORESOURCE_UNSET; + } + for (i=0;idma_resource[i].start = (unsigned long)-1; // "disabled" + dev->dma_resource[i].flags = IORESOURCE_UNSET; + } + + /* + * Fill in dev resource info + */ + while ( (char *)p < ((char *)node->data + node->size )) { + if(p==lastp) break; + + if( p[0] & 0x80 ) {// large item + switch (p[0] & 0x7f) { + case 0x01: // memory + { + int io = *(short *) &p[4]; + int len = *(short *) &p[10]; + add_memresource(dev, io, len); + break; + } + case 0x02: // device name + { + int len = *(short *) &p[1]; + memcpy(dev->name, p + 3, len >= 80 ? 79 : len); + break; + } + case 0x05: // 32-bit memory + { + int io = *(int *) &p[4]; + int len = *(int *) &p[16]; + add_memresource(dev, io, len); + break; + } + case 0x06: // fixed location 32-bit memory + { + int io = *(int *) &p[4]; + int len = *(int *) &p[8]; + add_memresource(dev, io, len); + break; + } + } /* switch */ + lastp = p+3; + p = p + p[1] + p[2]*256 + 3; + continue; + } + if ((p[0]>>3) == 0x0f) // end tag + break; + switch (p[0]>>3) { + case 0x04: // irq + { + int i, mask, irq = -1; + mask= p[1] + p[2]*256; + for (i=0;i<16;i++, mask=mask>>1) + if(mask & 0x01) irq=i; + add_irqresource(dev, irq); + break; + } + case 0x05: // dma + { + int i, mask, dma = -1; + mask = p[1]; + for (i=0;i<8;i++, mask = mask>>1) + if(mask & 0x01) dma=i; + add_dmaresource(dev, dma); + break; + } + case 0x08: // io + { + int io= p[2] + p[3] *256; + int len = p[7]; + add_ioresource(dev, io, len); + break; + } + case 0x09: // fixed location io + { + int io = p[1] + p[2] * 256; + int len = p[3]; + add_ioresource(dev, io, len); + break; + } + } /* switch */ + lastp=p+1; + p = p + (p[0] & 0x07) + 1; + + } /* while */ + + return; +} + + +/* + * + * DEVICE LIST MANAGEMENT FUNCTIONS + * + * + * Some of these are exported to give public access + * + * Question: Why maintain a device list when the PnP BIOS can + * list devices for us? Answer: Some PnP BIOSes can't report + * the current configuration, only the boot configuration. + * The boot configuration can be changed, so we need to keep + * a record of what the configuration was when we booted; + * presumably it continues to describe the current config. + * For those BIOSes that can change the current config, we + * keep the information in the devlist up to date. + * + * Note that it is currently assumed that the list does not + * grow or shrink in size after init time, and slot_name + * never changes. The list is protected by a spinlock. + */ + +static LIST_HEAD(pnpbios_devices); + +static spinlock_t pnpbios_devices_lock; + +static int inline insert_device(struct pci_dev *dev) +{ + + /* + * FIXME: Check for re-add of existing node; + * return -1 if node already present + */ + + /* We don't lock because we only do this at init time */ + list_add_tail(&dev->global_list, &pnpbios_devices); + + return 0; +} + +#define HEX(id,a) hex[((id)>>a) & 15] +#define CHAR(id,a) (0x40 + (((id)>>a) & 31)) +// +static void inline pnpid32_to_pnpid(u32 id, char *str) +{ + const char *hex = "0123456789abcdef"; + + id = be32_to_cpu(id); + str[0] = CHAR(id, 26); + str[1] = CHAR(id, 21); + str[2] = CHAR(id,16); + str[3] = HEX(id, 12); + str[4] = HEX(id, 8); + str[5] = HEX(id, 4); + str[6] = HEX(id, 0); + str[7] = '\0'; + + return; +} +// +#undef CHAR +#undef HEX + +/* + * Build a linked list of pci_devs in order of ascending node number + * Called only at init time. + */ +static void __init build_devlist(void) +{ + u8 nodenum; + unsigned int nodes_got = 0; + unsigned int devs = 0; + struct pnp_bios_node *node; + struct pnp_dev_node_info node_info; + struct pci_dev *dev; + + if (!pnp_bios_present()) + return; + + if (pnp_bios_dev_node_info(&node_info) != 0) + return; + + node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL); + if (!node) + return; + + for(nodenum=0; nodenum<0xff; ) { + u8 thisnodenum = nodenum; + /* We build the list from the "boot" config because + * asking for the "current" config causes some + * BIOSes to crash. + */ + if (pnp_bios_get_dev_node(&nodenum, (char )1 , node)) + break; + nodes_got++; + dev = pnpbios_kmalloc(sizeof (struct pci_dev), GFP_KERNEL); + if (!dev) + break; + memset(dev,0,sizeof(struct pci_dev)); + dev->devfn = thisnodenum; + memcpy(dev->name,"PNPBIOS",8); + pnpid32_to_pnpid(node->eisa_id,dev->slot_name); + node_resource_data_to_dev(node,dev); + if(insert_device(dev)<0) + kfree(dev); + else + devs++; + if (nodenum <= thisnodenum) { + printk(KERN_ERR "PnPBIOS: build_devlist: Node number 0x%x is out of sequence following node 0x%x. Aborting.\n", (unsigned int)nodenum, (unsigned int)thisnodenum); + break; + } + } + kfree(node); + + printk(KERN_INFO "PnPBIOS: %i node%s reported by PnP BIOS; %i recorded by driver\n", + nodes_got, nodes_got != 1 ? "s" : "", devs); +} + +static struct pci_dev *find_device_by_nodenum( u8 nodenum ) +{ + struct pci_dev *dev; + + pnpbios_for_each_dev(dev) { + if(dev->devfn == nodenum) + return dev; + } + + return NULL; +} + +static void update_devlist( u8 nodenum, struct pnp_bios_node *data ) +{ + unsigned long flags; + struct pci_dev *dev; + + spin_lock_irqsave(&pnpbios_devices_lock, flags); + dev = find_device_by_nodenum( nodenum ); + if ( dev ) { + node_resource_data_to_dev(data,dev); + } + spin_unlock_irqrestore(&pnpbios_devices_lock, flags); + + return; +} + + +/* + * + * DRIVER REGISTRATION FUNCTIONS + * + * + * Exported to give public access + * + */ + +static LIST_HEAD(pnpbios_drivers); + +static const struct pnpbios_device_id * +match_device(const struct pnpbios_device_id *ids, const struct pci_dev *dev) +{ + while (*ids->id) + { + if(memcmp(ids->id, dev->slot_name, 7)==0) + return ids; + ids++; + } + return NULL; +} + +static int announce_device(struct pnpbios_driver *drv, struct pci_dev *dev) +{ + const struct pnpbios_device_id *id; + struct pci_dev tmpdev; + int ret; + + if (drv->id_table) { + id = match_device(drv->id_table, dev); + if (!id) + return 0; + } else + id = NULL; + + memcpy( &tmpdev, dev, sizeof(struct pci_dev)); + tmpdev.global_list.prev = NULL; + tmpdev.global_list.next = NULL; + + dev_probe_lock(); + /* Obviously, probe() should not call any pnpbios functions */ + ret = drv->probe(&tmpdev, id); + dev_probe_unlock(); + if (ret < 1) + return 0; + + dev->driver = (void *)drv; + + return 1; +} + +/** + * pnpbios_register_driver - register a new pci driver + * @drv: the driver structure to register + * + * Adds the driver structure to the list of registered drivers + * + * For each device in the pnpbios device list that matches one of + * the ids in drv->id_table, calls the driver's "probe" function with + * arguments (1) a pointer to a *temporary* struct pci_dev containing + * resource info for the device, and (2) a pointer to the id string + * of the device. Expects the probe function to return 1 if the + * driver claims the device (otherwise 0) in which case, marks the + * device as having this driver. + * + * Returns the number of pci devices which were claimed by the driver + * during registration. The driver remains registered even if the + * return value is zero. + */ +int pnpbios_register_driver(struct pnpbios_driver *drv) +{ + struct pci_dev *dev; + unsigned long flags; + int count = 0; + + list_add_tail(&drv->node, &pnpbios_drivers); + spin_lock_irqsave(&pnpbios_devices_lock, flags); + pnpbios_for_each_dev(dev) { + if (!pnpbios_dev_driver(dev)) + count += announce_device(drv, dev); + } + spin_unlock_irqrestore(&pnpbios_devices_lock, flags); + return count; +} + +EXPORT_SYMBOL(pnpbios_register_driver); + +/** + * pnpbios_unregister_driver - unregister a pci driver + * @drv: the driver structure to unregister + * + * Deletes the driver structure from the list of registered PnPBIOS + * drivers, gives it a chance to clean up by calling its "remove" + * function for each device it was responsible for, and marks those + * devices as driverless. + */ +void pnpbios_unregister_driver(struct pnpbios_driver *drv) +{ + unsigned long flags; + struct pci_dev *dev; + + list_del(&drv->node); + spin_lock_irqsave(&pnpbios_devices_lock, flags); + pnpbios_for_each_dev(dev) { + if (dev->driver == (void *)drv) { + if (drv->remove) + drv->remove(dev); + dev->driver = NULL; + } + } + spin_unlock_irqrestore(&pnpbios_devices_lock, flags); +} + +EXPORT_SYMBOL(pnpbios_unregister_driver); + + +/* + * + * RESOURCE RESERVATION FUNCTIONS + * + * + * Used only at init time + * + */ + +static void __init reserve_ioport_range(char *pnpid, int start, int end) +{ + struct resource *res; + char *regionid; + +#if 0 + /* + * TEMPORARY hack to work around the fact that the + * floppy driver inappropriately reserves ioports 0x3f0 and 0x3f1 + * Remove this once the floppy driver is fixed. + */ + if ( + (0x3f0 >= start && 0x3f0 <= end) + || (0x3f1 >= start && 0x3f1 <= end) + ) { + printk(KERN_INFO + "PnPBIOS: %s: ioport range 0x%x-0x%x NOT reserved\n", + pnpid, start, end + ); + return; + } +#endif + + regionid = pnpbios_kmalloc(16, GFP_KERNEL); + if ( regionid == NULL ) + return; + snprintf(regionid, 16, "PnPBIOS %s", pnpid); + res = request_region(start,end-start+1,regionid); + if ( res == NULL ) + kfree( regionid ); + else + res->flags &= ~IORESOURCE_BUSY; + /* + * Failures at this point are usually harmless. pci quirks for + * example do reserve stuff they know about too, so we may well + * have double reservations. + */ + printk(KERN_INFO + "PnPBIOS: %s: ioport range 0x%x-0x%x %s reserved\n", + pnpid, start, end, + NULL != res ? "has been" : "could not be" + ); + + return; +} + +static void __init reserve_resources_of_dev( struct pci_dev *dev ) +{ + int i; + + for (i=0;iresource[i].flags & IORESOURCE_UNSET ) + /* end of resources */ + break; + if (dev->resource[i].flags & IORESOURCE_IO) { + /* ioport */ + if ( dev->resource[i].start == 0 ) + /* disabled */ + /* Do nothing */ + continue; + if ( dev->resource[i].start < 0x100 ) + /* + * Below 0x100 is only standard PC hardware + * (pics, kbd, timer, dma, ...) + * We should not get resource conflicts there, + * and the kernel reserves these anyway + * (see arch/i386/kernel/setup.c). + * So, do nothing + */ + continue; + if ( dev->resource[i].end < dev->resource[i].start ) + /* invalid endpoint */ + /* Do nothing */ + continue; + reserve_ioport_range( + dev->slot_name, + dev->resource[i].start, + dev->resource[i].end + ); + } else if (dev->resource[i].flags & IORESOURCE_MEM) { + /* iomem */ + /* For now do nothing */ + continue; + } else { + /* Neither ioport nor iomem */ + /* Do nothing */ + continue; + } + } + + return; +} + +static void __init reserve_resources( void ) +{ + struct pci_dev *dev; + + pnpbios_for_each_dev(dev) { + if ( + 0 != strcmp(dev->slot_name,"PNP0c01") && /* memory controller */ + 0 != strcmp(dev->slot_name,"PNP0c02") /* system peripheral: other */ + ) { + continue; + } + reserve_resources_of_dev(dev); + } + + return; +} + + +/* + * + * INIT AND EXIT + * + */ + +extern int is_sony_vaio_laptop; + +static int pnpbios_disabled; /* = 0 */ +static int dont_reserve_resources; /* = 0 */ +int pnpbios_dont_use_current_config; /* = 0 */ + +#ifndef MODULE +static int __init pnpbios_setup(char *str) +{ + int invert; + + while ((str != NULL) && (*str != '\0')) { + if (strncmp(str, "off", 3) == 0) + pnpbios_disabled=1; + if (strncmp(str, "on", 2) == 0) + pnpbios_disabled=0; + invert = (strncmp(str, "no-", 3) == 0); + if (invert) + str += 3; + if (strncmp(str, "curr", 4) == 0) + pnpbios_dont_use_current_config = invert; + if (strncmp(str, "res", 3) == 0) + dont_reserve_resources = invert; + str = strchr(str, ','); + if (str != NULL) + str += strspn(str, ", \t"); + } + + return 1; +} + +__setup("pnpbios=", pnpbios_setup); +#endif + +int __init pnpbios_init(void) +{ + union pnp_bios_expansion_header *check; + u8 sum; + int i, length, r; + + spin_lock_init(&pnp_bios_lock); + spin_lock_init(&pnpbios_devices_lock); + + if(pnpbios_disabled) { + printk(KERN_INFO "PnPBIOS: Disabled\n"); + return -ENODEV; + } + + if ( is_sony_vaio_laptop ) + pnpbios_dont_use_current_config = 1; + + /* + * Search the defined area (0xf0000-0xffff0) for a valid PnP BIOS + * structure and, if one is found, sets up the selectors and + * entry points + */ + for (check = (union pnp_bios_expansion_header *) __va(0xf0000); + check < (union pnp_bios_expansion_header *) __va(0xffff0); + ((void *) (check)) += 16) { + if (check->fields.signature != PNP_SIGNATURE) + continue; + length = check->fields.length; + if (!length) + continue; + for (sum = 0, i = 0; i < length; i++) + sum += check->chars[i]; + if (sum) + continue; + if (check->fields.version < 0x10) { + printk(KERN_WARNING "PnPBIOS: PnP BIOS version %d.%d is not supported\n", + check->fields.version >> 4, + check->fields.version & 15); + continue; + } + printk(KERN_INFO "PnPBIOS: Found PnP BIOS installation structure at 0x%p\n", check); + printk(KERN_INFO "PnPBIOS: PnP BIOS version %d.%d, entry 0x%x:0x%x, dseg 0x%x\n", + check->fields.version >> 4, check->fields.version & 15, + check->fields.pm16cseg, check->fields.pm16offset, + check->fields.pm16dseg); + Q2_SET_SEL(PNP_CS32, &pnp_bios_callfunc, 64 * 1024); + Q_SET_SEL(PNP_CS16, check->fields.pm16cseg, 64 * 1024); + Q_SET_SEL(PNP_DS, check->fields.pm16dseg, 64 * 1024); + pnp_bios_callpoint.offset = check->fields.pm16offset; + pnp_bios_callpoint.segment = PNP_CS16; + pnp_bios_hdr = check; + break; + } + if (!pnp_bios_present()) + return -ENODEV; + build_devlist(); + if ( ! dont_reserve_resources ) + reserve_resources(); +#ifdef CONFIG_PROC_FS + r = pnpbios_proc_init(); + if (r) + return r; +#endif + return 0; +} + +static int pnpbios_thread_init(void) +{ +#ifdef CONFIG_HOTPLUG + init_completion(&unload_sem); + if(kernel_thread(pnp_dock_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL)>0) + unloading = 0; +#endif + return 0; +} + +#ifndef MODULE + +/* init/main.c calls pnpbios_init early */ + +/* Start the kernel thread later: */ +module_init(pnpbios_thread_init); + +#else + +/* + * N.B.: Building pnpbios as a module hasn't been fully implemented + */ + +MODULE_LICENSE("GPL"); + +static int pnpbios_init_all(void) +{ + int r; + r = pnpbios_init(); + if (r) + return r; + r = pnpbios_thread_init(); + if (r) + return r; + return 0; +} + +static void __exit pnpbios_exit(void) +{ +#ifdef CONFIG_HOTPLUG + unloading = 1; + wait_for_completion(&unload_sem); +#endif + pnpbios_proc_exit(); + /* We ought to free resources here */ + return; +} + +module_init(pnpbios_init_all); +module_exit(pnpbios_exit); + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/pnp/pnpbios_proc.c linux.19pre5-ac1/drivers/pnp/pnpbios_proc.c --- linux.19p5/drivers/pnp/pnpbios_proc.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/pnp/pnpbios_proc.c Thu Feb 21 15:50:49 2002 @@ -0,0 +1,270 @@ +/* + * /proc/bus/pnp interface for Plug and Play devices + * + * Written by David Hinds, dahinds@users.sourceforge.net + * Modified by Thomas Hood, jdthood@mail.com + * + * The .../devices and .../ and .../boot/ files are + * utilized by the lspnp and setpnp utilities, supplied with the + * pcmcia-cs package. + * http://pcmcia-cs.sourceforge.net + * + * The .../escd file is utilized by the lsescd utility written by + * Gunther Mayer. + * http://home.t-online.de/home/gunther.mayer/lsescd + * + * The .../legacy_device_resources file is not used yet. + * + * The other files are human-readable. + */ + +//#include +#define __NO_VERSION__ +//#include + +#include +#include +#include +#include +#include +#include + +static struct proc_dir_entry *proc_pnp = NULL; +static struct proc_dir_entry *proc_pnp_boot = NULL; +static struct pnp_dev_node_info node_info; + +static int proc_read_pnpconfig(char *buf, char **start, off_t pos, + int count, int *eof, void *data) +{ + struct pnp_isa_config_struc pnps; + + if (pnp_bios_isapnp_config(&pnps)) + return -EIO; + return snprintf(buf, count, + "structure_revision %d\n" + "number_of_CSNs %d\n" + "ISA_read_data_port 0x%x\n", + pnps.revision, + pnps.no_csns, + pnps.isa_rd_data_port + ); +} + +static int proc_read_escdinfo(char *buf, char **start, off_t pos, + int count, int *eof, void *data) +{ + struct escd_info_struc escd; + + if (pnp_bios_escd_info(&escd)) + return -EIO; + return snprintf(buf, count, + "min_ESCD_write_size %d\n" + "ESCD_size %d\n" + "NVRAM_base 0x%x\n", + escd.min_escd_write_size, + escd.escd_size, + escd.nv_storage_base + ); +} + +static int proc_read_escd(char *buf, char **start, off_t pos, + int count, int *eof, void *data) +{ + struct escd_info_struc escd; + char *tmpbuf; + int escd_size, escd_left_to_read, n; + + if (pnp_bios_escd_info(&escd)) + return -EIO; + + /* sanity check */ + if (escd.escd_size > (32*1024)) { + printk(KERN_ERR "PnPBIOS: proc_read_escd: ESCD size is too great\n"); + return -EFBIG; + } + + tmpbuf = pnpbios_kmalloc(escd.escd_size, GFP_KERNEL); + if (!tmpbuf) return -ENOMEM; + + if (pnp_bios_read_escd(tmpbuf, escd.nv_storage_base)) + return -EIO; + + escd_size = (unsigned char)(buf[0]) + (unsigned char)(buf[1])*256; + escd_left_to_read = escd_size - pos; + if (escd_left_to_read < 0) escd_left_to_read = 0; + if (escd_left_to_read == 0) *eof = 1; + n = min(count,escd_left_to_read); + memcpy(buf, tmpbuf + pos, n); + kfree(tmpbuf); + *start = buf; + return n; +} + +static int proc_read_legacyres(char *buf, char **start, off_t pos, + int count, int *eof, void *data) +{ + /* Assume that the following won't overflow the buffer */ + if (pnp_bios_get_stat_res(buf)) + return -EIO; + + return count; // FIXME: Return actual length +} + +static int proc_read_devices(char *buf, char **start, off_t pos, + int count, int *eof, void *data) +{ + struct pnp_bios_node *node; + u8 nodenum; + char *p = buf; + + if (pos >= 0xff) + return 0; + + node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL); + if (!node) return -ENOMEM; + + for (nodenum=pos; nodenum<0xff; ) { + u8 thisnodenum = nodenum; + /* 26 = the number of characters per line sprintf'ed */ + if ((p - buf + 26) > count) + break; + if (pnp_bios_get_dev_node(&nodenum, 1, node)) + break; + p += sprintf(p, "%02x\t%08x\t%02x:%02x:%02x\t%04x\n", + node->handle, node->eisa_id, + node->type_code[0], node->type_code[1], + node->type_code[2], node->flags); + if (nodenum <= thisnodenum) { + printk(KERN_ERR "%s Node number 0x%x is out of sequence following node 0x%x. Aborting.\n", "PnPBIOS: proc_read_devices:", (unsigned int)nodenum, (unsigned int)thisnodenum); + *eof = 1; + break; + } + } + kfree(node); + if (nodenum == 0xff) + *eof = 1; + *start = (char *)((off_t)nodenum - pos); + return p - buf; +} + +static int proc_read_node(char *buf, char **start, off_t pos, + int count, int *eof, void *data) +{ + struct pnp_bios_node *node; + int boot = (long)data >> 8; + u8 nodenum = (long)data; + int len; + + node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL); + if (!node) return -ENOMEM; + if (pnp_bios_get_dev_node(&nodenum, boot, node)) + return -EIO; + len = node->size - sizeof(struct pnp_bios_node); + memcpy(buf, node->data, len); + kfree(node); + return len; +} + +static int proc_write_node(struct file *file, const char *buf, + unsigned long count, void *data) +{ + struct pnp_bios_node *node; + int boot = (long)data >> 8; + u8 nodenum = (long)data; + + node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL); + if (!node) return -ENOMEM; + if ( pnp_bios_get_dev_node(&nodenum, boot, node) ) + return -EIO; + if (count != node->size - sizeof(struct pnp_bios_node)) + return -EINVAL; + memcpy(node->data, buf, count); + if (pnp_bios_set_dev_node(node->handle, boot, node) != 0) + return -EINVAL; + kfree(node); + return count; +} + +/* + * When this is called, pnpbios functions are assumed to + * work and the pnpbios_dont_use_current_config flag + * should already have been set to the appropriate value + */ +int __init pnpbios_proc_init( void ) +{ + struct pnp_bios_node *node; + struct proc_dir_entry *ent; + char name[3]; + u8 nodenum; + + if (pnp_bios_dev_node_info(&node_info)) + return -EIO; + + proc_pnp = proc_mkdir("pnp", proc_bus); + if (!proc_pnp) + return -EIO; + proc_pnp_boot = proc_mkdir("boot", proc_pnp); + if (!proc_pnp_boot) + return -EIO; + create_proc_read_entry("devices", 0, proc_pnp, proc_read_devices, NULL); + create_proc_read_entry("configuration_info", 0, proc_pnp, proc_read_pnpconfig, NULL); + create_proc_read_entry("escd_info", 0, proc_pnp, proc_read_escdinfo, NULL); + create_proc_read_entry("escd", 0, proc_pnp, proc_read_escd, NULL); + create_proc_read_entry("legacy_device_resources", 0, proc_pnp, proc_read_legacyres, NULL); + + node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL); + if (!node) + return -ENOMEM; + + for (nodenum=0; nodenum<0xff; ) { + u8 thisnodenum = nodenum; + if (pnp_bios_get_dev_node(&nodenum, 1, node) != 0) + break; + sprintf(name, "%02x", node->handle); + if ( !pnpbios_dont_use_current_config ) { + ent = create_proc_entry(name, 0, proc_pnp); + if (ent) { + ent->read_proc = proc_read_node; + ent->write_proc = proc_write_node; + ent->data = (void *)(long)(node->handle); + } + } + ent = create_proc_entry(name, 0, proc_pnp_boot); + if (ent) { + ent->read_proc = proc_read_node; + ent->write_proc = proc_write_node; + ent->data = (void *)(long)(node->handle+0x100); + } + if (nodenum <= thisnodenum) { + printk(KERN_ERR "%s Node number 0x%x is out of sequence following node 0x%x. Aborting.\n", "PnPBIOS: proc_init:", (unsigned int)nodenum, (unsigned int)thisnodenum); + break; + } + } + kfree(node); + + return 0; +} + +void __exit pnpbios_proc_exit(void) +{ + int i; + char name[3]; + + if (!proc_pnp) return; + + for (i=0; i<0xff; i++) { + sprintf(name, "%02x", i); + if ( !pnpbios_dont_use_current_config ) + remove_proc_entry(name, proc_pnp); + remove_proc_entry(name, proc_pnp_boot); + } + remove_proc_entry("legacy_device_resources", proc_pnp); + remove_proc_entry("escd", proc_pnp); + remove_proc_entry("escd_info", proc_pnp); + remove_proc_entry("configuration_info", proc_pnp); + remove_proc_entry("devices", proc_pnp); + remove_proc_entry("boot", proc_pnp); + remove_proc_entry("pnp", proc_bus); + + return; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/scsi/hosts.h linux.19pre5-ac1/drivers/scsi/hosts.h --- linux.19p5/drivers/scsi/hosts.h Thu Apr 4 13:19:13 2002 +++ linux.19pre5-ac1/drivers/scsi/hosts.h Thu Apr 4 15:47:36 2002 @@ -292,6 +292,11 @@ unsigned emulated:1; /* + * True for drivers which can handle variable length IO + */ + unsigned can_do_varyio:1; + + /* * Name of proc directory */ char *proc_name; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/scsi/ide-scsi.c linux.19pre5-ac1/drivers/scsi/ide-scsi.c --- linux.19p5/drivers/scsi/ide-scsi.c Thu Apr 4 13:21:13 2002 +++ linux.19pre5-ac1/drivers/scsi/ide-scsi.c Thu Mar 21 00:32:25 2002 @@ -256,19 +256,18 @@ printk("]\n"); } -static void idescsi_end_request (byte uptodate, ide_hwgroup_t *hwgroup) +static int idescsi_end_request (ide_drive_t *drive, int uptodate) { - ide_drive_t *drive = hwgroup->drive; idescsi_scsi_t *scsi = drive->driver_data; - struct request *rq = hwgroup->rq; + struct request *rq = HWGROUP(drive)->rq; idescsi_pc_t *pc = (idescsi_pc_t *) rq->buffer; int log = test_bit(IDESCSI_LOG_CMD, &scsi->log); u8 *scsi_buf; unsigned long flags; if (rq->cmd != IDESCSI_PC_RQ) { - ide_end_request (uptodate, hwgroup); - return; + ide_end_request(drive, uptodate); + return 0; } ide_end_drive_cmd (drive, 0, 0); if (rq->errors >= ERROR_MAX) { @@ -297,6 +296,7 @@ idescsi_free_bh (rq->bh); kfree(pc); kfree(rq); scsi->pc = NULL; + return 0; } static inline unsigned long get_timeout(idescsi_pc_t *pc) @@ -336,7 +336,7 @@ ide__sti(); if (status & ERR_STAT) rq->errors++; - idescsi_end_request (1, HWGROUP(drive)); + idescsi_end_request(drive, 1); return ide_stopped; } bcount = IN_BYTE (IDE_BCOUNTH_REG) << 8 | IN_BYTE (IDE_BCOUNTL_REG); @@ -344,7 +344,7 @@ if (ireason & IDESCSI_IREASON_COD) { printk (KERN_ERR "ide-scsi: CoD != 0 in idescsi_pc_intr\n"); - return ide_do_reset (drive); + return ide_do_reset(drive); } if (ireason & IDESCSI_IREASON_IO) { temp = pc->actually_transferred + bcount; @@ -362,7 +362,7 @@ } pc->actually_transferred += temp; pc->current_position += temp; - idescsi_discard_data (drive,bcount - temp); + idescsi_discard_data(drive,bcount - temp); ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), NULL); return ide_started; } @@ -374,15 +374,15 @@ if (ireason & IDESCSI_IREASON_IO) { clear_bit(PC_WRITING, &pc->flags); if (pc->sg) - idescsi_input_buffers (drive, pc, bcount); + idescsi_input_buffers(drive, pc, bcount); else - atapi_input_bytes (drive,pc->current_position,bcount); + atapi_input_bytes(drive,pc->current_position,bcount); } else { set_bit(PC_WRITING, &pc->flags); if (pc->sg) - idescsi_output_buffers (drive, pc, bcount); + idescsi_output_buffers(drive, pc, bcount); else - atapi_output_bytes (drive,pc->current_position,bcount); + atapi_output_bytes(drive,pc->current_position,bcount); } pc->actually_transferred+=bcount; /* Update the current position */ pc->current_position+=bcount; @@ -391,7 +391,7 @@ return ide_started; } -static ide_startstop_t idescsi_transfer_pc (ide_drive_t *drive) +static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) { idescsi_scsi_t *scsi = drive->driver_data; idescsi_pc_t *pc = scsi->pc; @@ -405,10 +405,10 @@ ireason = IN_BYTE (IDE_IREASON_REG); if ((ireason & (IDESCSI_IREASON_IO | IDESCSI_IREASON_COD)) != IDESCSI_IREASON_COD) { printk (KERN_ERR "ide-scsi: (IO,CoD) != (0,1) while issuing a packet command\n"); - return ide_do_reset (drive); + return ide_do_reset(drive); } ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), NULL); /* Set the interrupt routine */ - atapi_output_bytes (drive, scsi->pc->c, 12); /* Send the actual packet */ + atapi_output_bytes(drive, scsi->pc->c, 12); /* Send the actual packet */ return ide_started; } @@ -465,7 +465,7 @@ return idescsi_issue_pc (drive, (idescsi_pc_t *) rq->buffer); } printk (KERN_ERR "ide-scsi: %s: unsupported command in request queue (%x)\n", drive->name, rq->cmd); - idescsi_end_request (0,HWGROUP (drive)); + idescsi_end_request(drive, 0); return ide_stopped; } @@ -529,6 +529,7 @@ return 0; } +int idescsi_init (void); int idescsi_reinit(ide_drive_t *drive); /* @@ -539,7 +540,11 @@ version: IDESCSI_VERSION, media: ide_scsi, busy: 0, +#ifdef CONFIG_IDEDMA_ONLYDISK + supports_dma: 0, +#else supports_dma: 1, +#endif supports_dsc_overlap: 0, cleanup: idescsi_cleanup, standby: NULL, @@ -555,12 +560,12 @@ capacity: NULL, special: NULL, proc: NULL, + init: idescsi_init, reinit: idescsi_reinit, ata_prebuilder: NULL, atapi_prebuilder: NULL, }; -int idescsi_init (void); static ide_module_t idescsi_module = { IDE_DRIVER_MODULE, idescsi_init, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/scsi/qlogicisp.h linux.19pre5-ac1/drivers/scsi/qlogicisp.h --- linux.19p5/drivers/scsi/qlogicisp.h Thu Apr 4 13:19:17 2002 +++ linux.19pre5-ac1/drivers/scsi/qlogicisp.h Tue Feb 12 15:57:47 2002 @@ -84,7 +84,8 @@ cmd_per_lun: 1, \ present: 0, \ unchecked_isa_dma: 0, \ - use_clustering: DISABLE_CLUSTERING \ + use_clustering: DISABLE_CLUSTERING, \ + can_do_varyio: 1 \ } #endif /* _QLOGICISP_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/scsi/scsi_lib.c linux.19pre5-ac1/drivers/scsi/scsi_lib.c --- linux.19p5/drivers/scsi/scsi_lib.c Thu Apr 4 13:19:18 2002 +++ linux.19pre5-ac1/drivers/scsi/scsi_lib.c Tue Mar 26 18:33:06 2002 @@ -426,6 +426,7 @@ if (req->waiting != NULL) { complete(req->waiting); } + req_finished_io(req); add_blkdev_randomness(MAJOR(req->rq_dev)); SDpnt = SCpnt->device; @@ -701,7 +702,7 @@ switch (SCpnt->sense_buffer[2]) { case ILLEGAL_REQUEST: - if (SCpnt->device->ten) { + if (SCpnt->device->ten && SCSI_RETRY_10(SCpnt->cmnd[0])) { SCpnt->device->ten = 0; /* * This will cause a retry with a 6-byte diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/scsi/sd.c linux.19pre5-ac1/drivers/scsi/sd.c --- linux.19p5/drivers/scsi/sd.c Thu Apr 4 13:21:13 2002 +++ linux.19pre5-ac1/drivers/scsi/sd.c Mon Mar 25 18:09:36 2002 @@ -91,6 +91,7 @@ static int *sd_blocksizes; static int *sd_hardsizes; /* Hardware sector size */ static int *sd_max_sectors; +static char *sd_varyio; static int check_scsidisk_media_change(kdev_t); static int fop_revalidate_scsidisk(kdev_t); @@ -1130,6 +1131,12 @@ if (!sd_max_sectors) goto cleanup_max_sectors; + sd_varyio = kmalloc((sd_template.dev_max << 4), GFP_ATOMIC); + if (!sd_varyio) + goto cleanup_varyio; + + memset(sd_varyio, 0, (sd_template.dev_max << 4)); + for (i = 0; i < sd_template.dev_max << 4; i++) { sd_blocksizes[i] = 1024; sd_hardsizes[i] = 512; @@ -1200,6 +1207,8 @@ cleanup_sd_gendisks: kfree(sd); cleanup_sd: + kfree(sd_varyio); +cleanup_varyio: kfree(sd_max_sectors); cleanup_max_sectors: kfree(sd_hardsizes); @@ -1264,6 +1273,8 @@ return 1; } +#define SD_DISK_MAJOR(i) SD_MAJOR((i) >> 4) + static int sd_attach(Scsi_Device * SDp) { unsigned int devnum; @@ -1302,6 +1313,14 @@ printk("Attached scsi %sdisk %s at scsi%d, channel %d, id %d, lun %d\n", SDp->removable ? "removable " : "", nbuff, SDp->host->host_no, SDp->channel, SDp->id, SDp->lun); + + if (SDp->host->hostt->can_do_varyio) { + if (blkdev_varyio[SD_DISK_MAJOR(i)] == NULL) { + blkdev_varyio[SD_DISK_MAJOR(i)] = + sd_varyio + ((i / SCSI_DISKS_PER_MAJOR) >> 8); + } + memset(blkdev_varyio[SD_DISK_MAJOR(i)] + (devnum << 4), 1, 16); + } return 0; } @@ -1430,6 +1449,7 @@ kfree(sd_sizes); kfree(sd_blocksizes); kfree(sd_hardsizes); + kfree(sd_varyio); kfree((char *) sd); } for (i = 0; i < N_USED_SD_MAJORS; i++) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/ac97_codec.c linux.19pre5-ac1/drivers/sound/ac97_codec.c --- linux.19p5/drivers/sound/ac97_codec.c Thu Apr 4 13:21:13 2002 +++ linux.19pre5-ac1/drivers/sound/ac97_codec.c Thu Mar 28 22:47:20 2002 @@ -31,6 +31,8 @@ ************************************************************************** * * History + * Mar 28, 2002 Randolph Bentson + * corrections to support WM9707 in ViewPad 1000 * v0.4 Mar 15 2000 Ollie Lho * dual codecs support verified with 4 channels output * v0.3 Feb 22 2000 Ollie Lho @@ -59,7 +61,9 @@ static int ac97_init_mixer(struct ac97_codec *codec); -static int wolfson_init(struct ac97_codec * codec); +static int wolfson_init00(struct ac97_codec * codec); +static int wolfson_init03(struct ac97_codec * codec); +static int wolfson_init04(struct ac97_codec * codec); static int tritech_init(struct ac97_codec * codec); static int tritech_maestro_init(struct ac97_codec * codec); static int sigmatel_9708_init(struct ac97_codec *codec); @@ -87,7 +91,9 @@ static struct ac97_ops null_ops = { NULL, NULL, NULL }; static struct ac97_ops default_ops = { NULL, eapd_control, NULL }; -static struct ac97_ops wolfson_ops = { wolfson_init, NULL, NULL }; +static struct ac97_ops wolfson_ops00 = { wolfson_init00, NULL, NULL }; +static struct ac97_ops wolfson_ops03 = { wolfson_init03, NULL, NULL }; +static struct ac97_ops wolfson_ops04 = { wolfson_init04, NULL, NULL }; static struct ac97_ops tritech_ops = { tritech_init, NULL, NULL }; static struct ac97_ops tritech_m_ops = { tritech_maestro_init, NULL, NULL }; static struct ac97_ops sigmatel_9708_ops = { sigmatel_9708_init, NULL, NULL }; @@ -133,9 +139,9 @@ {0x54524106, "TriTech TR28026", &null_ops}, {0x54524108, "TriTech TR28028", &tritech_ops}, {0x54524123, "TriTech TR A5", &null_ops}, - {0x574D4C00, "Wolfson WM9704", &wolfson_ops}, - {0x574D4C03, "Wolfson WM9703/9704", &wolfson_ops}, - {0x574D4C04, "Wolfson WM9704 (quad)", &wolfson_ops}, + {0x574D4C00, "Wolfson WM9700A", &wolfson_ops00}, + {0x574D4C03, "Wolfson WM9703/WM9707", &wolfson_ops03}, + {0x574D4C04, "Wolfson WM9704M/WM9704Q", &wolfson_ops04}, {0x83847600, "SigmaTel STAC????", &null_ops}, {0x83847604, "SigmaTel STAC9701/3/4/5", &null_ops}, {0x83847605, "SigmaTel STAC9704", &null_ops}, @@ -835,7 +841,38 @@ } -static int wolfson_init(struct ac97_codec * codec) +static int wolfson_init00(struct ac97_codec * codec) +{ + /* This initialization is suspect, but not known to be wrong. + It was copied from the initialization for the WM9704Q, but + that same sequence is known to fail for the WM9707. Thus + this warning may help someone with hardware to test + this code. */ + codec->codec_write(codec, 0x72, 0x0808); + codec->codec_write(codec, 0x74, 0x0808); + + // patch for DVD noise + codec->codec_write(codec, 0x5a, 0x0200); + + // init vol as PCM vol + codec->codec_write(codec, 0x70, + codec->codec_read(codec, AC97_PCMOUT_VOL)); + + codec->codec_write(codec, AC97_SURROUND_MASTER, 0x0000); + return 0; +} + + +static int wolfson_init03(struct ac97_codec * codec) +{ + /* this is known to work for the ViewSonic ViewPad 1000 */ + codec->codec_write(codec, 0x72, 0x0808); + codec->codec_write(codec, 0x20, 0x8000); + return 0; +} + + +static int wolfson_init04(struct ac97_codec * codec) { codec->codec_write(codec, 0x72, 0x0808); codec->codec_write(codec, 0x74, 0x0808); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/cmpci.c linux.19pre5-ac1/drivers/sound/cmpci.c --- linux.19p5/drivers/sound/cmpci.c Thu Apr 4 13:19:24 2002 +++ linux.19pre5-ac1/drivers/sound/cmpci.c Thu Mar 28 23:00:15 2002 @@ -2032,7 +2032,7 @@ 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)); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETOPTR: if (!(file->f_mode & FMODE_WRITE)) @@ -2049,7 +2049,7 @@ s->dma_adc.count &= s->dma_adc.fragsize-1; } spin_unlock_irqrestore(&s->lock, flags); - return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETBLKSIZE: if (file->f_mode & FMODE_WRITE) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/cs4281/cs4281m.c linux.19pre5-ac1/drivers/sound/cs4281/cs4281m.c --- linux.19p5/drivers/sound/cs4281/cs4281m.c Thu Apr 4 13:21:13 2002 +++ linux.19pre5-ac1/drivers/sound/cs4281/cs4281m.c Thu Mar 28 23:00:15 2002 @@ -3576,7 +3576,7 @@ 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)); + return copy_to_user((void *) arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETOPTR: if (!(file->f_mode & FMODE_WRITE)) @@ -3600,7 +3600,7 @@ 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)); + return copy_to_user((void *) arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETBLKSIZE: if (file->f_mode & FMODE_WRITE) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/cs46xx.c linux.19pre5-ac1/drivers/sound/cs46xx.c --- linux.19p5/drivers/sound/cs46xx.c Thu Apr 4 13:19:24 2002 +++ linux.19pre5-ac1/drivers/sound/cs46xx.c Thu Mar 28 23:00:15 2002 @@ -2960,7 +2960,7 @@ cinfo.blocks = dmabuf->count/dmabuf->divisor >> dmabuf->fragshift; cinfo.ptr = dmabuf->hwptr/dmabuf->divisor; spin_unlock_irqrestore(&state->card->lock, flags); - return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; } return -ENODEV; @@ -2993,7 +2993,7 @@ "cs46xx: GETOPTR bytes=%d blocks=%d ptr=%d\n", cinfo.bytes,cinfo.blocks,cinfo.ptr) ); spin_unlock_irqrestore(&state->card->lock, flags); - return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; } return -ENODEV; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/emu10k1/main.c linux.19pre5-ac1/drivers/sound/emu10k1/main.c --- linux.19p5/drivers/sound/emu10k1/main.c Thu Apr 4 13:19:26 2002 +++ linux.19pre5-ac1/drivers/sound/emu10k1/main.c Sat Mar 2 19:31:17 2002 @@ -867,19 +867,19 @@ } for (pagecount = 0; pagecount < MAXPAGES; pagecount++) - ((u32 *) card->virtualpagetable.addr)[pagecount] = cpu_to_le32((card->silentpage.dma_handle * 2) | pagecount); + ((u32 *) card->virtualpagetable.addr)[pagecount] = cpu_to_le32(((u32)card->silentpage.dma_handle * 2) | pagecount); /* Init page table & tank memory base register */ sblive_writeptr_tag(card, 0, - PTB, card->virtualpagetable.dma_handle, + PTB, (u32)card->virtualpagetable.dma_handle, TCB, 0, TCBS, 0, TAGLIST_END); for (nCh = 0; nCh < NUM_G; nCh++) { sblive_writeptr_tag(card, nCh, - MAPA, MAP_PTI_MASK | (card->silentpage.dma_handle * 2), - MAPB, MAP_PTI_MASK | (card->silentpage.dma_handle * 2), + MAPA, MAP_PTI_MASK |( (u32)card->silentpage.dma_handle * 2), + MAPB, MAP_PTI_MASK |( (u32)card->silentpage.dma_handle * 2), TAGLIST_END); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/emu10k1/mixer.c linux.19pre5-ac1/drivers/sound/emu10k1/mixer.c --- linux.19p5/drivers/sound/emu10k1/mixer.c Thu Apr 4 13:19:26 2002 +++ linux.19pre5-ac1/drivers/sound/emu10k1/mixer.c Sat Mar 2 19:31:17 2002 @@ -558,7 +558,7 @@ card->tankmem.size = size; - sblive_writeptr_tag(card, 0, TCB, card->tankmem.dma_handle, TCBS, size_reg, TAGLIST_END); + sblive_writeptr_tag(card, 0, TCB,(u32) card->tankmem.dma_handle, TCBS, size_reg, TAGLIST_END); emu10k1_writefn0(card, HCFG_LOCKTANKCACHE, 0); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/emu10k1/recmgr.c linux.19pre5-ac1/drivers/sound/emu10k1/recmgr.c --- linux.19p5/drivers/sound/emu10k1/recmgr.c Thu Apr 4 13:19:26 2002 +++ linux.19pre5-ac1/drivers/sound/emu10k1/recmgr.c Sat Mar 2 19:31:17 2002 @@ -132,7 +132,7 @@ DPD(2, "bus addx: %#lx\n", (unsigned long) buffer->dma_handle); - sblive_writeptr(card, buffer->addrreg, 0, buffer->dma_handle); + sblive_writeptr(card, buffer->addrreg, 0, (u32)buffer->dma_handle); return; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/emu10k1/voicemgr.c linux.19pre5-ac1/drivers/sound/emu10k1/voicemgr.c --- linux.19p5/drivers/sound/emu10k1/voicemgr.c Thu Apr 4 13:19:26 2002 +++ linux.19pre5-ac1/drivers/sound/emu10k1/voicemgr.c Sat Mar 2 19:31:17 2002 @@ -66,7 +66,7 @@ DPD(2, "Virtual Addx: %p\n", mem->addr[pagecount]); for (i = 0; i < PAGE_SIZE / EMUPAGESIZE; i++) { - busaddx = mem->dma_handle[pagecount] + i * EMUPAGESIZE; + busaddx = (u32)(mem->dma_handle[pagecount]) + i * EMUPAGESIZE; DPD(3, "Bus Addx: %#lx\n", busaddx); @@ -102,7 +102,7 @@ for (i = 0; i < PAGE_SIZE / EMUPAGESIZE; i++) { pageindex = mem->emupageindex + pagecount * PAGE_SIZE / EMUPAGESIZE + i; ((u32 *) card->virtualpagetable.addr)[pageindex] = - cpu_to_le32((card->silentpage.dma_handle * 2) | pageindex); + cpu_to_le32(((u32)card->silentpage.dma_handle * 2) | pageindex); } } @@ -231,8 +231,8 @@ Z1, 0, Z2, 0, /* Invalidate maps */ - MAPA, MAP_PTI_MASK | (card->silentpage.dma_handle * 2), - MAPB, MAP_PTI_MASK | (card->silentpage.dma_handle * 2), + MAPA, MAP_PTI_MASK | ((u32)card->silentpage.dma_handle * 2), + MAPB, MAP_PTI_MASK | ((u32)card->silentpage.dma_handle * 2), /* modulation envelope */ CVCF, 0x0000ffff, VTFT, 0x0000ffff, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/es1370.c linux.19pre5-ac1/drivers/sound/es1370.c --- linux.19p5/drivers/sound/es1370.c Thu Apr 4 13:21:13 2002 +++ linux.19pre5-ac1/drivers/sound/es1370.c Thu Mar 28 23:00:15 2002 @@ -1638,7 +1638,7 @@ 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)); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETOPTR: if (!(file->f_mode & FMODE_WRITE)) @@ -1656,7 +1656,7 @@ if (s->dma_dac2.mapped) s->dma_dac2.count &= s->dma_dac2.fragsize-1; spin_unlock_irqrestore(&s->lock, flags); - return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETBLKSIZE: if (file->f_mode & FMODE_WRITE) { @@ -2115,7 +2115,7 @@ if (s->dma_dac1.mapped) s->dma_dac1.count &= s->dma_dac1.fragsize-1; spin_unlock_irqrestore(&s->lock, flags); - return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETBLKSIZE: if ((val = prog_dmabuf_dac1(s))) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/es1371.c linux.19pre5-ac1/drivers/sound/es1371.c --- linux.19p5/drivers/sound/es1371.c Thu Apr 4 13:19:23 2002 +++ linux.19pre5-ac1/drivers/sound/es1371.c Thu Mar 28 23:00:15 2002 @@ -1824,7 +1824,7 @@ 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)); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETOPTR: if (!(file->f_mode & FMODE_WRITE)) @@ -1842,7 +1842,7 @@ if (s->dma_dac2.mapped) s->dma_dac2.count &= s->dma_dac2.fragsize-1; spin_unlock_irqrestore(&s->lock, flags); - return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETBLKSIZE: if (file->f_mode & FMODE_WRITE) { @@ -2292,7 +2292,7 @@ if (s->dma_dac1.mapped) s->dma_dac1.count &= s->dma_dac1.fragsize-1; spin_unlock_irqrestore(&s->lock, flags); - return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETBLKSIZE: if ((val = prog_dmabuf_dac1(s))) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/esssolo1.c linux.19pre5-ac1/drivers/sound/esssolo1.c --- linux.19p5/drivers/sound/esssolo1.c Thu Apr 4 13:19:24 2002 +++ linux.19pre5-ac1/drivers/sound/esssolo1.c Thu Mar 28 23:00:15 2002 @@ -1468,7 +1468,7 @@ 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)); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETOPTR: if (!(file->f_mode & FMODE_WRITE)) @@ -1492,7 +1492,7 @@ cinfo.bytes, cinfo.blocks, cinfo.ptr, s->dma_dac.buforder, s->dma_dac.numfrag, s->dma_dac.fragshift, s->dma_dac.swptr, s->dma_dac.count, s->dma_dac.fragsize, s->dma_dac.dmasize, s->dma_dac.fragsamples); #endif - return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETBLKSIZE: if (file->f_mode & FMODE_WRITE) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/i810_audio.c linux.19pre5-ac1/drivers/sound/i810_audio.c --- linux.19p5/drivers/sound/i810_audio.c Thu Apr 4 13:21:13 2002 +++ linux.19pre5-ac1/drivers/sound/i810_audio.c Thu Mar 28 23:00:15 2002 @@ -2022,7 +2022,7 @@ printk("SNDCTL_DSP_GETOPTR %d, %d, %d, %d\n", cinfo.bytes, cinfo.blocks, cinfo.ptr, dmabuf->count); #endif - return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETISPACE: if (!(file->f_mode & FMODE_READ)) @@ -2061,7 +2061,7 @@ printk("SNDCTL_DSP_GETIPTR %d, %d, %d, %d\n", cinfo.bytes, cinfo.blocks, cinfo.ptr, dmabuf->count); #endif - return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_NONBLOCK: #ifdef DEBUG diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/mad16.c linux.19pre5-ac1/drivers/sound/mad16.c --- linux.19p5/drivers/sound/mad16.c Thu Apr 4 13:19:23 2002 +++ linux.19pre5-ac1/drivers/sound/mad16.c Thu Mar 28 22:49:12 2002 @@ -42,6 +42,7 @@ #include #include #include +#include #include "sound_config.h" @@ -51,6 +52,7 @@ static int mad16_conf; static int mad16_cdsel; +static struct gameport gameport; static int already_initialized = 0; @@ -664,13 +666,13 @@ outb((bits | dma_bits[dma] | dma2_bit), config_port); /* Write IRQ+DMA setup */ - hw_config->slots[0] = ad1848_init("MAD16 WSS", hw_config->io_base + 4, + hw_config->slots[0] = ad1848_init("mad16 WSS", hw_config->io_base + 4, hw_config->irq, dma, dma2, 0, hw_config->osp, THIS_MODULE); - request_region(hw_config->io_base, 4, "MAD16 WSS config"); + request_region(hw_config->io_base, 4, "mad16 WSS config"); } static int __init probe_mad16_mpu(struct address_info *hw_config) @@ -1010,14 +1012,6 @@ } printk(".\n"); - printk(KERN_INFO "Joystick port "); - if (joystick == 1) - printk("enabled.\n"); - else - { - joystick = 0; - printk("disabled.\n"); - } cfg.io_base = io; cfg.irq = irq; @@ -1038,6 +1032,18 @@ attach_mad16(&cfg); found_mpu = probe_mad16_mpu(&cfg_mpu); + + if (joystick == 1) { + /* register gameport */ + if (!request_region(0x201, 1, "mad16 gameport")) + printk(KERN_ERR "mad16: gameport address 0x201 already in use\n"); + else { + printk(KERN_ERR "mad16: gameport enabled at 0x201\n"); + gameport.io = 0x201; + gameport_register_port(&gameport); + } + } + else printk(KERN_ERR "mad16: gameport disabled.\n"); return 0; } @@ -1055,16 +1061,17 @@ static int __init setup_mad16(char *str) { /* io, irq */ - int ints[7]; + int ints[8]; str = get_options(str, ARRAY_SIZE(ints), ints); - io = ints[1]; - irq = ints[2]; - dma = ints[3]; - dma16 = ints[4]; - mpu_io = ints[5]; - mpu_irq = ints[6]; + io = ints[1]; + irq = ints[2]; + dma = ints[3]; + dma16 = ints[4]; + mpu_io = ints[5]; + mpu_irq = ints[6]; + joystick = ints[7]; return 1; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/maestro.c linux.19pre5-ac1/drivers/sound/maestro.c --- linux.19p5/drivers/sound/maestro.c Thu Apr 4 13:19:23 2002 +++ linux.19pre5-ac1/drivers/sound/maestro.c Thu Mar 28 23:00:15 2002 @@ -2756,7 +2756,7 @@ 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)); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETOPTR: if (!(file->f_mode & FMODE_WRITE)) @@ -2771,7 +2771,7 @@ 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)); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETBLKSIZE: if (file->f_mode & FMODE_WRITE) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/maestro3.c linux.19pre5-ac1/drivers/sound/maestro3.c --- linux.19p5/drivers/sound/maestro3.c Thu Apr 4 13:19:24 2002 +++ linux.19pre5-ac1/drivers/sound/maestro3.c Thu Mar 28 23:00:15 2002 @@ -1805,7 +1805,7 @@ 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)); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETOPTR: if (!(file->f_mode & FMODE_WRITE)) @@ -1818,7 +1818,7 @@ 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)); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETBLKSIZE: if (file->f_mode & FMODE_WRITE) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/rme96xx.c linux.19pre5-ac1/drivers/sound/rme96xx.c --- linux.19p5/drivers/sound/rme96xx.c Thu Apr 4 13:21:13 2002 +++ linux.19pre5-ac1/drivers/sound/rme96xx.c Thu Mar 28 23:00:51 2002 @@ -1348,7 +1348,7 @@ dma->readptr &= s->fragsize<<1; spin_unlock_irqrestore(&s->lock,flags); - return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETOPTR: if (!(file->f_mode & FMODE_READ)) @@ -1365,7 +1365,7 @@ if (dma->mmapped) dma->writeptr &= s->fragsize<<1; spin_unlock_irqrestore(&s->lock,flags); - return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETBLKSIZE: return put_user(s->fragsize, (int *)arg); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/sb_card.c linux.19pre5-ac1/drivers/sound/sb_card.c --- linux.19p5/drivers/sound/sb_card.c Thu Apr 4 13:19:23 2002 +++ linux.19pre5-ac1/drivers/sound/sb_card.c Mon Feb 11 22:28:30 2002 @@ -373,6 +373,11 @@ 0,0,0,0, 0,1,1,-1}, {"Sound Blaster AWE 32", + ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0046), + ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), + 0,0,0,0, + 0,1,1,-1}, + {"Sound Blaster AWE 32", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0047), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0,0,0,0, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/sonicvibes.c linux.19pre5-ac1/drivers/sound/sonicvibes.c --- linux.19p5/drivers/sound/sonicvibes.c Thu Apr 4 13:19:24 2002 +++ linux.19pre5-ac1/drivers/sound/sonicvibes.c Thu Mar 28 23:00:51 2002 @@ -1802,7 +1802,7 @@ 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)); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETOPTR: if (!(file->f_mode & FMODE_WRITE)) @@ -1820,7 +1820,7 @@ 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)); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETBLKSIZE: if (file->f_mode & FMODE_WRITE) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/vwsnd.c linux.19pre5-ac1/drivers/sound/vwsnd.c --- linux.19p5/drivers/sound/vwsnd.c Thu Apr 4 13:21:13 2002 +++ linux.19pre5-ac1/drivers/sound/vwsnd.c Thu Mar 28 23:01:04 2002 @@ -2650,7 +2650,7 @@ DBGXV("SNDCTL_DSP_GETOSPACE returns { %d %d %d %d }\n", buf_info.fragments, buf_info.fragstotal, buf_info.fragsize, buf_info.bytes); - return copy_to_user((void *) arg, &buf_info, sizeof buf_info); + return copy_to_user((void *) arg, &buf_info, sizeof buf_info) ? -EFAULT : 0; case SNDCTL_DSP_GETISPACE: /* _SIOR ('P',13, audio_buf_info) */ DBGX("SNDCTL_DSP_GETISPACE\n"); @@ -2667,7 +2667,7 @@ DBGX("SNDCTL_DSP_GETISPACE returns { %d %d %d %d }\n", buf_info.fragments, buf_info.fragstotal, buf_info.fragsize, buf_info.bytes); - return copy_to_user((void *) arg, &buf_info, sizeof buf_info); + return copy_to_user((void *) arg, &buf_info, sizeof buf_info) ? -EFAULT : 0; case SNDCTL_DSP_NONBLOCK: /* _SIO ('P',14) */ DBGX("SNDCTL_DSP_NONBLOCK\n"); @@ -2725,7 +2725,7 @@ rport->frag_count = 0; } spin_unlock_irqrestore(&rport->lock, flags); - return copy_to_user((void *) arg, &info, sizeof info); + return copy_to_user((void *) arg, &info, sizeof info) ? -EFAULT : 0; case SNDCTL_DSP_GETOPTR: /* _SIOR ('P',18, count_info) */ DBGX("SNDCTL_DSP_GETOPTR\n"); @@ -2747,7 +2747,7 @@ wport->frag_count = 0; } spin_unlock_irqrestore(&wport->lock, flags); - return copy_to_user((void *) arg, &info, sizeof info); + return copy_to_user((void *) arg, &info, sizeof info) ? -EFAULT : 0; case SNDCTL_DSP_GETODELAY: /* _SIOR ('P', 23, int) */ DBGX("SNDCTL_DSP_GETODELAY\n"); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/audio.c linux.19pre5-ac1/drivers/usb/audio.c --- linux.19p5/drivers/usb/audio.c Thu Apr 4 13:19:38 2002 +++ linux.19pre5-ac1/drivers/usb/audio.c Thu Mar 28 23:01:15 2002 @@ -2536,7 +2536,7 @@ 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)); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETOPTR: if (!(file->f_mode & FMODE_WRITE)) @@ -2548,7 +2548,7 @@ 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)); + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETBLKSIZE: if (file->f_mode & FMODE_WRITE) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/belkin_sa.c linux.19pre5-ac1/drivers/usb/serial/belkin_sa.c --- linux.19p5/drivers/usb/serial/belkin_sa.c Thu Apr 4 13:19:39 2002 +++ linux.19pre5-ac1/drivers/usb/serial/belkin_sa.c Thu Mar 28 22:48:13 2002 @@ -361,8 +361,6 @@ dbg(__FUNCTION__" port %d", port->number); - down (&port->sem); - --port->open_count; if (port->open_count <= 0) { @@ -375,7 +373,6 @@ port->active = 0; } - up (&port->sem); MOD_DEC_USE_COUNT; } /* belkin_sa_close */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/cyberjack.c linux.19pre5-ac1/drivers/usb/serial/cyberjack.c --- linux.19p5/drivers/usb/serial/cyberjack.c Thu Apr 4 13:21:13 2002 +++ linux.19pre5-ac1/drivers/usb/serial/cyberjack.c Thu Mar 28 22:48:13 2002 @@ -193,8 +193,6 @@ { dbg(__FUNCTION__ " - port %d", port->number); - down (&port->sem); - --port->open_count; if (port->open_count <= 0) { @@ -209,7 +207,6 @@ port->open_count = 0; } - up (&port->sem); MOD_DEC_USE_COUNT; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/empeg.c linux.19pre5-ac1/drivers/usb/serial/empeg.c --- linux.19p5/drivers/usb/serial/empeg.c Thu Apr 4 13:19:39 2002 +++ linux.19pre5-ac1/drivers/usb/serial/empeg.c Thu Mar 28 22:48:13 2002 @@ -212,8 +212,6 @@ if (!serial) return; - down (&port->sem); - --port->open_count; if (port->open_count <= 0) { @@ -225,8 +223,6 @@ port->open_count = 0; } - up (&port->sem); - /* Uncomment the following line if you want to see some statistics in your syslog */ /* info ("Bytes In = %d Bytes Out = %d", bytes_in, bytes_out); */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/ftdi_sio.c linux.19pre5-ac1/drivers/usb/serial/ftdi_sio.c --- linux.19p5/drivers/usb/serial/ftdi_sio.c Thu Apr 4 13:21:13 2002 +++ linux.19pre5-ac1/drivers/usb/serial/ftdi_sio.c Thu Mar 28 22:48:13 2002 @@ -382,7 +382,6 @@ dbg( __FUNCTION__); - down (&port->sem); --port->open_count; if (port->open_count <= 0) { @@ -421,7 +420,6 @@ } } - up (&port->sem); MOD_DEC_USE_COUNT; } /* ftdi_sio_close */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/ipaq.c linux.19pre5-ac1/drivers/usb/serial/ipaq.c --- linux.19p5/drivers/usb/serial/ipaq.c Thu Apr 4 13:21:13 2002 +++ linux.19pre5-ac1/drivers/usb/serial/ipaq.c Thu Mar 28 22:48:13 2002 @@ -245,8 +245,6 @@ if (!serial) return; - down (&port->sem); - --port->open_count; if (port->open_count <= 0) { @@ -264,7 +262,6 @@ port->open_count = 0; } - up (&port->sem); /* Uncomment the following line if you want to see some statistics in your syslog */ /* info ("Bytes In = %d Bytes Out = %d", bytes_in, bytes_out); */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/ir-usb.c linux.19pre5-ac1/drivers/usb/serial/ir-usb.c --- linux.19p5/drivers/usb/serial/ir-usb.c Thu Apr 4 13:19:39 2002 +++ linux.19pre5-ac1/drivers/usb/serial/ir-usb.c Thu Mar 28 22:48:13 2002 @@ -317,8 +317,6 @@ if (!serial) return; - down (&port->sem); - --port->open_count; if (port->open_count <= 0) { @@ -330,7 +328,6 @@ port->open_count = 0; } - up (&port->sem); MOD_DEC_USE_COUNT; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/keyspan.c linux.19pre5-ac1/drivers/usb/serial/keyspan.c --- linux.19p5/drivers/usb/serial/keyspan.c Thu Apr 4 13:19:39 2002 +++ linux.19pre5-ac1/drivers/usb/serial/keyspan.c Thu Mar 28 22:48:14 2002 @@ -945,8 +945,6 @@ p_priv->out_flip = 0; p_priv->in_flip = 0; - down (&port->sem); - if (--port->open_count <= 0) { if (port->active) { if (serial->dev) { @@ -963,7 +961,6 @@ port->open_count = 0; port->tty = 0; } - up (&port->sem); MOD_DEC_USE_COUNT; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/keyspan_pda.c linux.19pre5-ac1/drivers/usb/serial/keyspan_pda.c --- linux.19p5/drivers/usb/serial/keyspan_pda.c Thu Apr 4 13:19:39 2002 +++ linux.19pre5-ac1/drivers/usb/serial/keyspan_pda.c Thu Mar 28 22:48:14 2002 @@ -738,8 +738,6 @@ { struct usb_serial *serial = port->serial; - down (&port->sem); - --port->open_count; if (port->open_count <= 0) { @@ -756,7 +754,6 @@ port->open_count = 0; } - up (&port->sem); MOD_DEC_USE_COUNT; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/kl5kusb105.c linux.19pre5-ac1/drivers/usb/serial/kl5kusb105.c --- linux.19p5/drivers/usb/serial/kl5kusb105.c Thu Apr 4 13:19:39 2002 +++ linux.19pre5-ac1/drivers/usb/serial/kl5kusb105.c Thu Mar 28 22:48:14 2002 @@ -499,8 +499,6 @@ if(!serial) return; - down (&port->sem); - --port->open_count; if (port->open_count <= 0) { @@ -527,7 +525,6 @@ info("kl5kusb105 port stats: %ld bytes in, %ld bytes out", priv->bytes_in, priv->bytes_out); } - up (&port->sem); MOD_DEC_USE_COUNT; } /* klsi_105_close */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/mct_u232.c linux.19pre5-ac1/drivers/usb/serial/mct_u232.c --- linux.19p5/drivers/usb/serial/mct_u232.c Thu Apr 4 13:19:39 2002 +++ linux.19pre5-ac1/drivers/usb/serial/mct_u232.c Thu Mar 28 22:48:14 2002 @@ -479,8 +479,6 @@ { dbg(__FUNCTION__" port %d", port->number); - down (&port->sem); - --port->open_count; if (port->open_count <= 0) { @@ -493,7 +491,6 @@ port->active = 0; } - up (&port->sem); MOD_DEC_USE_COUNT; } /* mct_u232_close */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/omninet.c linux.19pre5-ac1/drivers/usb/serial/omninet.c --- linux.19p5/drivers/usb/serial/omninet.c Thu Apr 4 13:19:39 2002 +++ linux.19pre5-ac1/drivers/usb/serial/omninet.c Thu Mar 28 22:48:14 2002 @@ -211,8 +211,6 @@ if (!serial) return; - down (&port->sem); - --port->open_count; if (port->open_count <= 0) { @@ -229,7 +227,6 @@ kfree(od); } - up (&port->sem); MOD_DEC_USE_COUNT; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/pl2303.c linux.19pre5-ac1/drivers/usb/serial/pl2303.c --- linux.19p5/drivers/usb/serial/pl2303.c Thu Apr 4 13:19:39 2002 +++ linux.19pre5-ac1/drivers/usb/serial/pl2303.c Thu Mar 28 22:48:14 2002 @@ -447,8 +447,6 @@ dbg (__FUNCTION__ " - port %d", port->number); - down (&port->sem); - --port->open_count; if (port->open_count <= 0) { if (serial->dev) { @@ -486,7 +484,6 @@ port->open_count = 0; } - up (&port->sem); MOD_DEC_USE_COUNT; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/usbserial.c linux.19pre5-ac1/drivers/usb/serial/usbserial.c --- linux.19p5/drivers/usb/serial/usbserial.c Thu Apr 4 13:19:39 2002 +++ linux.19pre5-ac1/drivers/usb/serial/usbserial.c Thu Mar 28 22:48:14 2002 @@ -553,12 +553,21 @@ return; } + down (&port->sem); + + if (tty->driver_data == NULL) { + /* disconnect beat us to the punch here, so handle it gracefully */ + goto exit; + } + /* pass on to the driver specific version of this function if it is available */ if (serial->type->close) { serial->type->close(port, filp); } else { generic_close(port, filp); } +exit: + up (&port->sem); } @@ -1350,8 +1359,10 @@ if (serial) { /* fail all future close/read/write/ioctl/etc calls */ for (i = 0; i < serial->num_ports; ++i) { + down (&serial->port[i].sem); if (serial->port[i].tty != NULL) serial->port[i].tty->driver_data = NULL; + up (&serial->port[i].sem); } serial->dev = NULL; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/visor.c linux.19pre5-ac1/drivers/usb/serial/visor.c --- linux.19p5/drivers/usb/serial/visor.c Thu Apr 4 13:21:13 2002 +++ linux.19pre5-ac1/drivers/usb/serial/visor.c Thu Mar 28 22:48:14 2002 @@ -379,8 +379,6 @@ if (!serial) return; - down (&port->sem); - --port->open_count; if (port->open_count <= 0) { @@ -405,7 +403,6 @@ port->active = 0; port->open_count = 0; } - up (&port->sem); /* Uncomment the following line if you want to see some statistics in your syslog */ /* info ("Bytes In = %d Bytes Out = %d", bytes_in, bytes_out); */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/whiteheat.c linux.19pre5-ac1/drivers/usb/serial/whiteheat.c --- linux.19p5/drivers/usb/serial/whiteheat.c Thu Apr 4 13:19:39 2002 +++ linux.19pre5-ac1/drivers/usb/serial/whiteheat.c Thu Mar 28 22:48:14 2002 @@ -380,7 +380,6 @@ dbg(__FUNCTION__ " - port %d", port->number); - down (&port->sem); --port->open_count; if (port->open_count <= 0) { @@ -398,7 +397,6 @@ port->active = 0; } MOD_DEC_USE_COUNT; - up (&port->sem); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/storage/unusual_devs.h linux.19pre5-ac1/drivers/usb/storage/unusual_devs.h --- linux.19p5/drivers/usb/storage/unusual_devs.h Thu Apr 4 13:21:13 2002 +++ linux.19pre5-ac1/drivers/usb/storage/unusual_devs.h Thu Mar 28 22:40:04 2002 @@ -480,6 +480,12 @@ US_SC_SCSI, US_PR_CB, NULL, US_FL_MODE_XLATE ), +UNUSUAL_DEV( 0x0a16, 0x8888, 0x0100, 0x0100, + "IBM", + "IBM USB Memory Key", + US_SC_SCSI, US_PR_BULK, NULL, + US_FL_FIX_INQUIRY ), + #ifdef CONFIG_USB_STORAGE_ISD200 UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110, "ATI", diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/video/Config.in linux.19pre5-ac1/drivers/video/Config.in --- linux.19p5/drivers/video/Config.in Thu Apr 4 13:21:13 2002 +++ linux.19pre5-ac1/drivers/video/Config.in Fri Mar 1 19:14:19 2002 @@ -132,6 +132,7 @@ fi fi dep_tristate ' G450/G550 second head support (mandatory for G550)' CONFIG_FB_MATROX_G450 $CONFIG_FB_MATROX_G100 + dep_tristate ' Matrox /proc interface' CONFIG_FB_MATROX_PROC $CONFIG_FB_MATROX bool ' Multihead support' CONFIG_FB_MATROX_MULTIHEAD fi tristate ' ATI Mach64 display support (EXPERIMENTAL)' CONFIG_FB_ATY diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/video/matrox/Makefile linux.19pre5-ac1/drivers/video/matrox/Makefile --- linux.19p5/drivers/video/matrox/Makefile Thu Apr 4 13:21:13 2002 +++ linux.19pre5-ac1/drivers/video/matrox/Makefile Tue Jan 29 19:22:50 2002 @@ -17,6 +17,7 @@ obj-$(CONFIG_FB_MATROX_I2C) += i2c-matroxfb.o obj-$(CONFIG_FB_MATROX_MAVEN) += matroxfb_maven.o matroxfb_crtc2.o obj-$(CONFIG_FB_MATROX_G450) += matroxfb_g450.o matroxfb_crtc2.o +obj-$(CONFIG_FB_MATROX_PROC) += matroxfb_proc.o include $(TOPDIR)/Rules.make diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/video/matrox/matroxfb_proc.c linux.19pre5-ac1/drivers/video/matrox/matroxfb_proc.c --- linux.19p5/drivers/video/matrox/matroxfb_proc.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/drivers/video/matrox/matroxfb_proc.c Tue Jan 29 19:22:50 2002 @@ -0,0 +1,151 @@ +/* + * + * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450. + * + * (c) 1998-2001 Petr Vandrovec + * + * Version: 1.62 2001/11/29 + * + */ + +#include "matroxfb_base.h" +#include + +static struct proc_dir_entry* mga_pde; + +struct procinfo { + struct matrox_fb_info* info; + struct proc_dir_entry* pde; +}; + +static inline void remove_pde(struct proc_dir_entry* pde) { + if (pde) { + remove_proc_entry(pde->name, pde->parent); + } +} + +#ifndef CONFIG_PROC_FS +static int bios_read_proc(char* buffer, char** start, off_t offset, + int size, int *eof, void *data) { + return 0; +} + +static int pins_read_proc(char* buffer, char** start, off_t offset, + int size, int *eof, void *data) { + return 0; +} +#else +/* This macro frees the machine specific function from bounds checking and + * this like that... */ +#define PRINT_PROC(fmt,args...) \ + do { \ + len += sprintf(buffer+len, fmt, ##args ); \ + if (begin + len > offset + size) \ + break; \ + if (begin + len < offset) { \ + begin += len; \ + len = 0; \ + } \ + } while(0) + +static int bios_read_proc(char* buffer, char** start, off_t offset, + int size, int *eof, void *data) { + int len = 0; + off_t begin = 0; + struct matrox_bios* bd = data; + + do { + *eof = 0; + if (bd->bios_valid) { + PRINT_PROC("BIOS: %u.%u.%u\n", bd->version.vMaj, bd->version.vMin, bd->version.vRev); + PRINT_PROC("Output: 0x%02X\n", bd->output.state); + PRINT_PROC("TVOut: %s\n", bd->output.tvout?"yes":"no"); + PRINT_PROC("PINS: %s\n", bd->pins_len ? "found" : "not found"); + PRINT_PROC("Info: %p\n", bd); + } else { + PRINT_PROC("BIOS: Invalid\n"); + } + *eof = 1; + } while (0); + if (offset >= begin + len) + return 0; + *start = buffer + (offset - begin); + return size < begin + len - offset ? size : begin + len - offset; +} + +static int pins_read_proc(char* buffer, char** start, off_t offset, + int size, int *eof, void *data) { + struct matrox_bios* bd = data; + + if (offset >= bd->pins_len) { + *eof = 1; + return 0; + } + if (offset + size >= bd->pins_len) { + size = bd->pins_len - offset; + *eof = 1; + } + memcpy(buffer, bd->pins + offset, size); + *start = buffer; + return size; +} +#endif /* CONFIG_PROC_FS */ + +static void* matroxfb_proc_probe(struct matrox_fb_info* minfo) { + struct procinfo* binfo; + char b[10]; + + binfo = (struct procinfo*)kmalloc(sizeof(*binfo), GFP_KERNEL); + if (!binfo) { + printk(KERN_ERR "matroxfb_proc: Not enough memory for /proc control structs\n"); + return NULL; + } + binfo->info = minfo; + sprintf(b, "fb%u", GET_FB_IDX(minfo->fbcon.node)); + binfo->pde = proc_mkdir(b, mga_pde); + if (binfo->pde) { + create_proc_read_entry("bios", 0, binfo->pde, bios_read_proc, &minfo->bios); + if (minfo->bios.pins_len) { + struct proc_dir_entry* p = create_proc_read_entry("pins", 0, binfo->pde, pins_read_proc, &minfo->bios); + if (p) { + p->size = minfo->bios.pins_len; + } + } + } + return binfo; +} + +static void matroxfb_proc_remove(struct matrox_fb_info* minfo, void* binfoI) { + struct procinfo* binfo = binfoI; + + if (binfo->pde) { + remove_proc_entry("pins", binfo->pde); + remove_proc_entry("bios", binfo->pde); + remove_pde(binfo->pde); + } + kfree(binfo); +} + +static struct matroxfb_driver procfn = { + name: "Matrox /proc driver", + probe: matroxfb_proc_probe, + remove: matroxfb_proc_remove +}; + +static int matroxfb_proc_init(void) { + mga_pde = proc_mkdir("driver/mga", NULL); + matroxfb_register_driver(&procfn); + return 0; +} + +static void matroxfb_proc_exit(void) { + matroxfb_unregister_driver(&procfn); + remove_pde(mga_pde); +} + +MODULE_AUTHOR("(c) 2001 Petr Vandrovec "); +MODULE_DESCRIPTION("Matrox /proc driver"); +MODULE_LICENSE("GPL"); +module_init(matroxfb_proc_init); +module_exit(matroxfb_proc_exit); +/* we do not have __setup() */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/Config.in linux.19pre5-ac1/fs/Config.in --- linux.19p5/fs/Config.in Thu Apr 4 13:21:14 2002 +++ linux.19pre5-ac1/fs/Config.in Thu Mar 21 00:48:42 2002 @@ -51,6 +51,10 @@ dep_mbool ' Microsoft Joliet CDROM extensions' CONFIG_JOLIET $CONFIG_ISO9660_FS dep_mbool ' Transparent decompression extension' CONFIG_ZISOFS $CONFIG_ISO9660_FS +tristate 'JFS filesystem support' CONFIG_JFS_FS +dep_mbool ' JFS debugging' CONFIG_JFS_DEBUG $CONFIG_JFS_FS +dep_mbool ' JFS statistics' CONFIG_JFS_STATISTICS $CONFIG_JFS_FS + tristate 'Minix fs support' CONFIG_MINIX_FS tristate 'FreeVxFS file system support (VERITAS VxFS(TM) compatible)' CONFIG_VXFS_FS @@ -99,6 +103,7 @@ dep_tristate 'NFS server support' CONFIG_NFSD $CONFIG_INET dep_mbool ' Provide NFSv3 server support' CONFIG_NFSD_V3 $CONFIG_NFSD + dep_mbool ' Provide NFS server over TCP support (EXPERIMENTAL)' CONFIG_NFSD_TCP $CONFIG_NFSD $CONFIG_EXPERIMENTAL if [ "$CONFIG_NFS_FS" = "y" -o "$CONFIG_NFSD" = "y" ]; then define_tristate CONFIG_SUNRPC y @@ -146,15 +151,6 @@ else define_tristate CONFIG_ZISOFS_FS n fi -if [ "$CONFIG_CRAMFS" = "y" -o "$CONFIG_ZISOFS_FS" = "y" ]; then - define_tristate CONFIG_ZLIB_FS_INFLATE y -else - if [ "$CONFIG_CRAMFS" = "m" -o "$CONFIG_ZISOFS_FS" = "m" ]; then - define_tristate CONFIG_ZLIB_FS_INFLATE m - else - define_tristate CONFIG_ZLIB_FS_INFLATE n - fi -fi mainmenu_option next_comment comment 'Partition Types' diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/Makefile linux.19pre5-ac1/fs/Makefile --- linux.19p5/fs/Makefile Thu Apr 4 13:18:06 2002 +++ linux.19pre5-ac1/fs/Makefile Sat Mar 9 20:41:05 2002 @@ -29,7 +29,6 @@ subdir-$(CONFIG_EXT3_FS) += ext3 # Before ext2 so root fs can be ext3 subdir-$(CONFIG_JBD) += jbd subdir-$(CONFIG_EXT2_FS) += ext2 -subdir-$(CONFIG_ZLIB_FS_INFLATE) += inflate_fs subdir-$(CONFIG_CRAMFS) += cramfs subdir-$(CONFIG_RAMFS) += ramfs subdir-$(CONFIG_CODA_FS) += coda @@ -67,6 +66,7 @@ subdir-$(CONFIG_REISERFS_FS) += reiserfs subdir-$(CONFIG_DEVPTS_FS) += devpts subdir-$(CONFIG_SUN_OPENPROMFS) += openpromfs +subdir-$(CONFIG_JFS_FS) += jfs obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/binfmt_elf.c linux.19pre5-ac1/fs/binfmt_elf.c --- linux.19p5/fs/binfmt_elf.c Thu Apr 4 13:21:14 2002 +++ linux.19pre5-ac1/fs/binfmt_elf.c Fri Mar 15 21:54:01 2002 @@ -604,7 +604,12 @@ /* Do this so that we can load the interpreter, if need be. We will change some of these later */ current->mm->rss = 0; - setup_arg_pages(bprm); /* XXX: check error */ + retval = setup_arg_pages(bprm); + if (retval < 0) { + send_sig(SIGKILL, current, 0); + return retval; + } + current->mm->start_stack = bprm->p; /* Now we do a little grungy work by mmaping the ELF image into @@ -1138,7 +1143,7 @@ psinfo.pr_state = i; psinfo.pr_sname = (i < 0 || i > 5) ? '.' : "RSDZTD"[i]; psinfo.pr_zomb = psinfo.pr_sname == 'Z'; - psinfo.pr_nice = current->nice; + psinfo.pr_nice = task_nice(current); psinfo.pr_flag = current->flags; psinfo.pr_uid = NEW_TO_OLD_UID(current->uid); psinfo.pr_gid = NEW_TO_OLD_GID(current->gid); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/block_dev.c linux.19pre5-ac1/fs/block_dev.c --- linux.19p5/fs/block_dev.c Thu Apr 4 13:18:06 2002 +++ linux.19pre5-ac1/fs/block_dev.c Thu Mar 21 00:36:01 2002 @@ -616,7 +616,7 @@ down(&bdev->bd_sem); lock_kernel(); - if (kind == BDEV_FILE) + if (kind == BDEV_FILE && bdev->bd_openers == 1) __block_fsync(bd_inode); else if (kind == BDEV_FS) fsync_no_super(rdev); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/buffer.c linux.19pre5-ac1/fs/buffer.c --- linux.19p5/fs/buffer.c Thu Apr 4 13:21:14 2002 +++ linux.19pre5-ac1/fs/buffer.c Fri Mar 15 22:06:57 2002 @@ -47,7 +47,7 @@ #include #include #include -#include +#include #include #include @@ -103,35 +103,27 @@ struct { int nfract; /* Percentage of buffer cache dirty to activate bdflush */ - int ndirty; /* Maximum number of dirty blocks to write out per - wake-cycle */ + int dummy1; /* old "ndirty" */ int dummy2; /* old "nrefill" */ int dummy3; /* unused */ int interval; /* jiffies delay between kupdate flushes */ int age_buffer; /* Time for normal buffer to age before we flush it */ int nfract_sync;/* Percentage of buffer cache dirty to activate bdflush synchronously */ - int nfract_stop_bdflush; /* Percetange of buffer cache dirty to stop bdflush */ + int dummy4; /* unused */ int dummy5; /* unused */ } b_un; unsigned int data[N_PARAM]; -} bdf_prm = {{30, 500, 0, 0, 5*HZ, 30*HZ, 60, 20, 0}}; +} bdf_prm = {{40, 0, 0, 0, 5*HZ, 30*HZ, 60, 0, 0}}; /* These are the min and max parameter values that we will allow to be assigned */ -int bdflush_min[N_PARAM] = { 0, 1, 0, 0, 0, 1*HZ, 0, 0, 0}; -int bdflush_max[N_PARAM] = {100,50000, 20000, 20000,10000*HZ, 10000*HZ, 100, 100, 0}; +int bdflush_min[N_PARAM] = { 0, 10, 5, 25, 0, 1*HZ, 0, 0, 0}; +int bdflush_max[N_PARAM] = {100,50000, 20000, 20000,10000*HZ, 6000*HZ, 100, 0, 0}; void unlock_buffer(struct buffer_head *bh) { clear_bit(BH_Wait_IO, &bh->b_state); - clear_bit(BH_Launder, &bh->b_state); - /* - * When a locked buffer is visible to the I/O layer BH_Launder - * is set. This means before unlocking we must clear BH_Launder, - * mb() on alpha and then clear BH_Lock, so no reader can see - * BH_Launder set on an unlocked buffer and then risk to deadlock. - */ - smp_mb__after_clear_bit(); + clear_bit(BH_launder, &bh->b_state); clear_bit(BH_Lock, &bh->b_state); smp_mb__after_clear_bit(); if (waitqueue_active(&bh->b_wait)) @@ -139,9 +131,13 @@ } /* + * Rewrote the wait-routines to use the "new" wait-queue functionality, + * and getting rid of the cli-sti pairs. The wait-queue routines still + * need cli-sti, but now it's just a couple of 386 instructions or so. + * * Note that the real wait_on_buffer() is an inline function that checks - * that the buffer is locked before calling this, so that unnecessary disk - * unplugging does not occur. + * if 'b_wait' is set before calling this, so that the queues aren't set + * up unnecessarily. */ void __wait_on_buffer(struct buffer_head * bh) { @@ -237,9 +233,10 @@ */ static void write_unlocked_buffers(kdev_t dev) { - do + do { spin_lock(&lru_list_lock); - while (write_some_buffers(dev)); + } while (write_some_buffers(dev)); + run_task_queue(&tq_disk); } /* @@ -277,6 +274,12 @@ return 0; } +static inline void wait_for_some_buffers(kdev_t dev) +{ + spin_lock(&lru_list_lock); + wait_for_buffers(dev, BUF_LOCKED, 1); +} + static int wait_for_locked_buffers(kdev_t dev, int index, int refile) { do { @@ -727,15 +730,12 @@ static void free_more_memory(void) { - zone_t * zone = contig_page_data.node_zonelists[GFP_NOFS & GFP_ZONEMASK].zones[0]; - balance_dirty(); wakeup_bdflush(); - try_to_free_pages(zone, GFP_NOFS, 0); + try_to_free_pages(GFP_NOFS); run_task_queue(&tq_disk); - current->policy |= SCHED_YIELD; __set_current_state(TASK_RUNNING); - schedule(); + sys_sched_yield(); } void init_buffer(struct buffer_head *bh, bh_end_io_t *handler, void *private) @@ -1060,21 +1060,6 @@ return -1; } -static int bdflush_stop(void) -{ - unsigned long dirty, tot, dirty_limit; - - dirty = size_buffers_type[BUF_DIRTY] >> PAGE_SHIFT; - tot = nr_free_buffer_pages(); - - dirty *= 100; - dirty_limit = tot * bdf_prm.b_un.nfract_stop_bdflush; - - if (dirty > dirty_limit) - return 0; - return 1; -} - /* * if a new dirty buffer is created we need to balance bdflush. * @@ -1089,6 +1074,7 @@ if (state < 0) return; + /* If we're getting into imbalance, start write-out */ wakeup_bdflush(); /* @@ -1099,6 +1085,7 @@ if (state > 0) { spin_lock(&lru_list_lock); write_some_buffers(NODEV); + wait_for_some_buffers(NODEV); } } @@ -2241,11 +2228,11 @@ err = 0; for (i = nr; --i >= 0; ) { - iosize += size; tmp = bh[i]; if (buffer_locked(tmp)) { wait_on_buffer(tmp); } + iosize += tmp->b_size; if (!buffer_uptodate(tmp)) { /* We are traversing bh'es in reverse order so @@ -2266,7 +2253,8 @@ * of kiobuf structs (much like a user-space iovec list). * * The kiobuf must already be locked for IO. IO is submitted - * asynchronously: you need to check page->locked and page->uptodate. + * asynchronously: you need to check page->locked, page->uptodate, and + * maybe wait on page_waitqueue(page). * * It is up to the caller to make sure that there are enough blocks * passed in to completely map the iobufs to disk. @@ -2287,6 +2275,7 @@ struct kiobuf * iobuf = NULL; struct page * map; struct buffer_head *tmp, **bhs = NULL; + int iosize = size; if (!nr) return 0; @@ -2323,7 +2312,7 @@ } while (length > 0) { - blocknr = b[bufind++]; + blocknr = b[bufind]; if (blocknr == -1UL) { if (rw == READ) { /* there was an hole in the filesystem */ @@ -2336,9 +2325,15 @@ } else BUG(); } + if (iobuf->dovary && (offset == 0)) { + iosize = RAWIO_BLOCKSIZE; + if (iosize > length) + iosize = length; + } + bufind += (iosize/size); tmp = bhs[bhind++]; - tmp->b_size = size; + tmp->b_size = iosize; set_bh_page(tmp, map, offset); tmp->b_this_page = tmp; @@ -2354,7 +2349,10 @@ set_bit(BH_Uptodate, &tmp->b_state); atomic_inc(&iobuf->io_count); - submit_bh(rw, tmp); + if (iobuf->dovary) + submit_bh_blknr(rw, tmp); + else + submit_bh(rw, tmp); /* * Wait for IO if we have got too much */ @@ -2369,8 +2367,8 @@ } skip_block: - length -= size; - offset += size; + length -= iosize; + offset += iosize; if (offset >= PAGE_SIZE) { offset = 0; @@ -2399,8 +2397,8 @@ /* * Start I/O on a page. * This function expects the page to be locked and may return - * before I/O is complete. You then have to check page->locked - * and page->uptodate. + * before I/O is complete. You then have to check page->locked, + * page->uptodate, and maybe wait on page_waitqueue(page). * * brw_page() is SMP-safe, although it's being called with the * kernel lock held - but the code is ready. @@ -2601,63 +2599,23 @@ return 1; } -/* - * The first time the VM inspects a page which has locked buffers, it - * will just mark it as needing waiting upon on the scan of the page LRU. - * BH_Wait_IO is used for this. - * - * The second time the VM visits the page, if it still has locked - * buffers, it is time to start writing them out. (BH_Wait_IO was set). - * - * The third time the VM visits the page, if the I/O hasn't completed - * then it's time to wait upon writeout. BH_Lock and BH_Launder are - * used for this. - * - * There is also the case of buffers which were locked by someone else - * - write(2) callers, bdflush, etc. There can be a huge number of these - * and we don't want to just skip them all and fail the page allocation. - * We want to be able to wait on these buffers as well. - * - * The BH_Launder bit is set in submit_bh() to indicate that I/O is - * underway against the buffer, doesn't matter who started it - we know - * that the buffer will eventually come unlocked, and so it's safe to - * wait on it. - * - * The caller holds the page lock and the caller will free this page - * into current->local_page, so by waiting on the page's buffers the - * caller is guaranteed to obtain this page. - * - * sync_page_buffers() will sort-of return true if all the buffers - * against this page are freeable, so try_to_free_buffers() should - * try to free the page's buffers a second time. This is a bit - * broken for blocksize < PAGE_CACHE_SIZE, but not very importantly. - */ -static int sync_page_buffers(struct buffer_head *head) +static void sync_page_buffers(struct buffer_head *head) { struct buffer_head * bh = head; - int tryagain = 1; do { if (!buffer_dirty(bh) && !buffer_locked(bh)) continue; /* Don't start IO first time around.. */ - if (!test_and_set_bit(BH_Wait_IO, &bh->b_state)) { - tryagain = 0; + if (!test_and_set_bit(BH_Wait_IO, &bh->b_state)) continue; - } - /* Second time through we start actively writing out.. */ - if (test_and_set_bit(BH_Lock, &bh->b_state)) { - if (unlikely(!buffer_launder(bh))) { - tryagain = 0; - continue; - } - wait_on_buffer(bh); - tryagain = 1; + /* If we cannot lock the buffer just skip it. */ + if (test_and_set_bit(BH_Lock, &bh->b_state)) continue; - } + /* Second time through we start actively writing out.. */ if (!atomic_set_buffer_clean(bh)) { unlock_buffer(bh); continue; @@ -2665,12 +2623,12 @@ __mark_buffer_clean(bh); get_bh(bh); + set_bit(BH_launder, &bh->b_state); bh->b_end_io = end_buffer_io_sync; submit_bh(WRITE, bh); - tryagain = 0; } while ((bh = bh->b_this_page) != head); - return tryagain; + return; } /* @@ -2694,7 +2652,6 @@ { struct buffer_head * tmp, * bh = page->buffers; -cleaned_buffers_try_again: spin_lock(&lru_list_lock); write_lock(&hash_table_lock); tmp = bh; @@ -2737,15 +2694,9 @@ write_unlock(&hash_table_lock); spin_unlock(&lru_list_lock); gfp_mask = pf_gfp_mask(gfp_mask); - if (gfp_mask & __GFP_IO) { - if ((gfp_mask & __GFP_HIGHIO) || !PageHighMem(page)) { - if (sync_page_buffers(bh)) { - /* no IO or waiting next time */ - gfp_mask = 0; - goto cleaned_buffers_try_again; - } - } - } + if ((gfp_mask & __GFP_IO) && + ((gfp_mask & __GFP_HIGHIO) || !PageHighMem(page))) + sync_page_buffers(bh); if (balance_dirty_state() >= 0) wakeup_bdflush(); return 0; @@ -2841,7 +2792,7 @@ hash_table = (struct buffer_head **) __get_free_pages(GFP_ATOMIC, order); } while (hash_table == NULL && --order > 0); - printk("Buffer-cache hash table entries: %d (order: %d, %ld bytes)\n", + printk(KERN_INFO "Buffer cache hash table entries: %d (order: %d, %ld bytes)\n", nr_hash, order, (PAGE_SIZE << order)); if (!hash_table) @@ -2989,29 +2940,14 @@ complete((struct completion *)startup); - /* - * FIXME: The ndirty logic here is wrong. It's supposed to - * send bdflush back to sleep after writing ndirty buffers. - * In fact, the test is wrong so bdflush will in fact - * sleep when bdflush_stop() returns true. - * - * FIXME: If it proves useful to implement ndirty properly, - * then perhaps the value of ndirty should be scaled by the - * amount of memory in the machine. - */ for (;;) { - int ndirty = bdf_prm.b_un.ndirty; - CHECK_EMERGENCY_SYNC - while (ndirty > 0) { - spin_lock(&lru_list_lock); - if (!write_some_buffers(NODEV)) - break; - ndirty -= NRSYNC; - } - if (ndirty > 0 || bdflush_stop()) + spin_lock(&lru_list_lock); + if (!write_some_buffers(NODEV) || balance_dirty_state() < 0) { + run_task_queue(&tq_disk); interruptible_sleep_on(&bdflush_wait); + } } } @@ -3040,6 +2976,7 @@ complete((struct completion *)startup); for (;;) { + /* update interval */ interval = bdf_prm.b_un.interval; if (interval) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/cramfs/uncompress.c linux.19pre5-ac1/fs/cramfs/uncompress.c --- linux.19p5/fs/cramfs/uncompress.c Thu Apr 4 13:18:13 2002 +++ linux.19pre5-ac1/fs/cramfs/uncompress.c Sat Mar 9 20:41:05 2002 @@ -18,7 +18,7 @@ #include #include #include -#include +#include static z_stream stream; static int initialized; @@ -34,14 +34,14 @@ stream.next_out = dst; stream.avail_out = dstlen; - err = zlib_fs_inflateReset(&stream); + err = zlib_inflateReset(&stream); if (err != Z_OK) { - printk("zlib_fs_inflateReset error %d\n", err); - zlib_fs_inflateEnd(&stream); - zlib_fs_inflateInit(&stream); + printk("zlib_inflateReset error %d\n", err); + zlib_inflateEnd(&stream); + zlib_inflateInit(&stream); } - err = zlib_fs_inflate(&stream, Z_FINISH); + err = zlib_inflate(&stream, Z_FINISH); if (err != Z_STREAM_END) goto err; return stream.total_out; @@ -55,14 +55,14 @@ int cramfs_uncompress_init(void) { if (!initialized++) { - stream.workspace = vmalloc(zlib_fs_inflate_workspacesize()); + stream.workspace = vmalloc(zlib_inflate_workspacesize()); if ( !stream.workspace ) { initialized = 0; return -ENOMEM; } stream.next_in = NULL; stream.avail_in = 0; - zlib_fs_inflateInit(&stream); + zlib_inflateInit(&stream); } return 0; } @@ -70,7 +70,7 @@ int cramfs_uncompress_exit(void) { if (!--initialized) { - zlib_fs_inflateEnd(&stream); + zlib_inflateEnd(&stream); vfree(stream.workspace); } return 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/dcache.c linux.19pre5-ac1/fs/dcache.c --- linux.19p5/fs/dcache.c Thu Apr 4 13:18:07 2002 +++ linux.19pre5-ac1/fs/dcache.c Fri Mar 15 22:06:57 2002 @@ -568,8 +568,7 @@ count = dentry_stat.nr_unused / priority; prune_dcache(count); - kmem_cache_shrink(dentry_cache); - return 0; + return kmem_cache_shrink_nr(dentry_cache); } #define NAME_ALLOC_LEN(len) ((len+16) & ~15) @@ -1210,7 +1209,7 @@ __get_free_pages(GFP_ATOMIC, order); } while (dentry_hashtable == NULL && --order >= 0); - printk("Dentry-cache hash table entries: %d (order: %ld, %ld bytes)\n", + printk(KERN_INFO "Dentry cache hash table entries: %d (order: %ld, %ld bytes)\n", nr_hash, order, (PAGE_SIZE << order)); if (!dentry_hashtable) @@ -1283,6 +1282,7 @@ dcache_init(mempages); inode_init(mempages); + files_init(mempages); mnt_init(mempages); bdev_cache_init(); cdev_cache_init(); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/devfs/base.c linux.19pre5-ac1/fs/devfs/base.c --- linux.19p5/fs/devfs/base.c Thu Apr 4 13:18:13 2002 +++ linux.19pre5-ac1/fs/devfs/base.c Fri Mar 15 22:08:18 2002 @@ -3463,18 +3463,17 @@ static int __init init_devfs_fs (void) { int err; - - printk ("%s: v%s Richard Gooch (rgooch@atnf.csiro.au)\n", - DEVFS_NAME, DEVFS_VERSION); + printk (KERN_INFO DEVFS_NAME ": v" DEVFS_VERSION + " Richard Gooch (rgooch@atnf.csiro.au)\n"); devfsd_buf_cache = kmem_cache_create ("devfsd_event", sizeof (struct devfsd_buf_entry), 0, 0, NULL, NULL); if (!devfsd_buf_cache) OOPS ("(): unable to allocate event slab\n"); #ifdef CONFIG_DEVFS_DEBUG devfs_debug = devfs_debug_init; - printk ("%s: devfs_debug: 0x%0x\n", DEVFS_NAME, devfs_debug); + printk (KERN_INFO DEVFS_NAME ": devfs_debug: 0x%0x\n", devfs_debug); #endif - printk ("%s: boot_options: 0x%0x\n", DEVFS_NAME, boot_options); + printk (KERN_INFO DEVFS_NAME ": boot_options: 0x%0x\n", boot_options); err = register_filesystem (&devfs_fs_type); if (!err) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/dquot.c linux.19pre5-ac1/fs/dquot.c --- linux.19p5/fs/dquot.c Thu Apr 4 13:18:07 2002 +++ linux.19pre5-ac1/fs/dquot.c Sun Mar 3 16:06:59 2002 @@ -35,7 +35,7 @@ * Jan Kara, , sponsored by SuSE CR, 10-11/99 * * Used struct list_head instead of own list struct - * Invalidation of dquots with dq_count > 0 no longer possible + * Invalidation of referenced dquots is no longer possible * Improved free_dquots list management * Quota and i_blocks are now updated in one place to avoid races * Warnings are now delayed so we won't block in critical section @@ -45,6 +45,10 @@ * Added dynamic quota structure allocation * Jan Kara 12/2000 * + * New quotafile format + * Alocation units changed to bytes + * Jan Kara, , 2000 + * * (C) Copyright 1994 - 1997 Marco van Wieringen */ @@ -63,14 +67,19 @@ #include #include +#include -#define __DQUOT_VERSION__ "dquot_6.4.0" +#define __DQUOT_VERSION__ "dquot_6.5.0" +#define __DQUOT_NUM_VERSION__ (6*10000+5*100+0) +#define __DQUOT_PARANOIA int nr_dquots, nr_free_dquots; -static char *quotatypes[] = INITQFNAMES; +static const char *quotatypes[] = INITQFNAMES; +static const uint quota_magics[] = INITQMAGICS; +static const uint quota_versions[] = INITQVERSIONS; -static inline struct quota_mount_options *sb_dqopt(struct super_block *sb) +static inline struct quota_info *sb_dqopt(struct super_block *sb) { return &sb->s_dquot; } @@ -120,7 +129,7 @@ static void dqput(struct dquot *); static struct dquot *dqduplicate(struct dquot *); -static inline char is_enabled(struct quota_mount_options *dqopt, short type) +static inline char is_enabled(struct quota_info *dqopt, short type) { switch (type) { case USRQUOTA: @@ -136,6 +145,26 @@ return is_enabled(sb_dqopt(sb), type); } +static inline void get_dquot_ref(struct dquot *dquot) +{ + dquot->dq_count++; +} + +static inline void put_dquot_ref(struct dquot *dquot) +{ + dquot->dq_count--; +} + +static inline void get_dquot_dup_ref(struct dquot *dquot) +{ + dquot->dq_dup_ref++; +} + +static inline void put_dquot_dup_ref(struct dquot *dquot) +{ + dquot->dq_dup_ref--; +} + static inline int const hashfn(kdev_t dev, unsigned int id, short type) { return((HASHDEV(dev) ^ id) * (MAXQUOTAS - type)) % NR_DQHASH; @@ -243,6 +272,7 @@ wake_up(&dquot->dq_wait_lock); } +/* Wait for dquot to be unused */ static void __wait_dquot_unused(struct dquot *dquot) { DECLARE_WAITQUEUE(wait, current); @@ -258,6 +288,394 @@ current->state = TASK_RUNNING; } +/* Wait for all duplicated dquot references to be dropped */ +static void __wait_dup_drop(struct dquot *dquot) +{ + DECLARE_WAITQUEUE(wait, current); + + add_wait_queue(&dquot->dq_wait_free, &wait); +repeat: + set_current_state(TASK_UNINTERRUPTIBLE); + if (dquot->dq_dup_ref) { + schedule(); + goto repeat; + } + remove_wait_queue(&dquot->dq_wait_free, &wait); + current->state = TASK_RUNNING; +} + +/* + * IO operations on file + */ + +#define GETIDINDEX(id, depth) (((id) >> ((DQTREEDEPTH-(depth)-1)*8)) & 0xff) +#define GETENTRIES(buf) ((struct disk_dqblk *)(((char *)buf)+sizeof(struct disk_dqdbheader))) + +static inline void mark_quotafile_info_dirty(struct mem_dqinfo *info) +{ + info->dqi_flags |= DQF_DIRTY; +} + +static inline int quotafile_info_dirty(struct mem_dqinfo *info) +{ + return info->dqi_flags & DQF_DIRTY; +} + +/* Read information header from quota file */ +static int read_quotafile_info(struct super_block *sb, short type) +{ + mm_segment_t fs; + struct disk_dqinfo dinfo; + struct mem_dqinfo *info = sb_dqopt(sb)->info+type; + struct file *f = sb_dqopt(sb)->files[type]; + ssize_t size; + loff_t offset = DQINFOOFF; + + fs = get_fs(); + set_fs(KERNEL_DS); + size = f->f_op->read(f, (char *)&dinfo, sizeof(struct disk_dqinfo), &offset); + set_fs(fs); + if (size != sizeof(struct disk_dqinfo)) { + printk(KERN_WARNING "Can't read info structure on device %s.\n", + kdevname(f->f_dentry->d_sb->s_dev)); + return -1; + } + info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace); + info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace); + info->dqi_flags = le32_to_cpu(dinfo.dqi_flags); + info->dqi_blocks = le32_to_cpu(dinfo.dqi_blocks); + info->dqi_free_blk = le32_to_cpu(dinfo.dqi_free_blk); + info->dqi_free_entry = le32_to_cpu(dinfo.dqi_free_entry); + return 0; +} + +/* Write information header to quota file */ +static int write_quotafile_info(struct super_block *sb, short type) +{ + mm_segment_t fs; + struct disk_dqinfo dinfo; + struct mem_dqinfo *info = sb_dqopt(sb)->info+type; + struct file *f = sb_dqopt(sb)->files[type]; + ssize_t size; + loff_t offset = DQINFOOFF; + + info[type].dqi_flags &= ~DQF_DIRTY; + dinfo.dqi_bgrace = cpu_to_le32(info->dqi_bgrace); + dinfo.dqi_igrace = cpu_to_le32(info->dqi_igrace); + dinfo.dqi_flags = cpu_to_le32(info->dqi_flags & DQF_MASK); + dinfo.dqi_blocks = cpu_to_le32(info->dqi_blocks); + dinfo.dqi_free_blk = cpu_to_le32(info->dqi_free_blk); + dinfo.dqi_free_entry = cpu_to_le32(info->dqi_free_entry); + fs = get_fs(); + set_fs(KERNEL_DS); + size = f->f_op->write(f, (char *)&dinfo, sizeof(struct disk_dqinfo), &offset); + set_fs(fs); + if (size != sizeof(struct disk_dqinfo)) { + printk(KERN_WARNING "Can't write info structure on device %s.\n", + kdevname(f->f_dentry->d_sb->s_dev)); + return -1; + } + return 0; +} + +static void disk2memdqb(struct mem_dqblk *m, struct disk_dqblk *d) +{ + m->dqb_ihardlimit = le32_to_cpu(d->dqb_ihardlimit); + m->dqb_isoftlimit = le32_to_cpu(d->dqb_isoftlimit); + m->dqb_curinodes = le32_to_cpu(d->dqb_curinodes); + m->dqb_itime = le64_to_cpu(d->dqb_itime); + m->dqb_bhardlimit = le32_to_cpu(d->dqb_bhardlimit); + m->dqb_bsoftlimit = le32_to_cpu(d->dqb_bsoftlimit); + m->dqb_curspace = le64_to_cpu(d->dqb_curspace); + m->dqb_btime = le64_to_cpu(d->dqb_btime); +} + +static void mem2diskdqb(struct disk_dqblk *d, struct mem_dqblk *m, qid_t id) +{ + d->dqb_ihardlimit = cpu_to_le32(m->dqb_ihardlimit); + d->dqb_isoftlimit = cpu_to_le32(m->dqb_isoftlimit); + d->dqb_curinodes = cpu_to_le32(m->dqb_curinodes); + d->dqb_itime = cpu_to_le64(m->dqb_itime); + d->dqb_bhardlimit = cpu_to_le32(m->dqb_bhardlimit); + d->dqb_bsoftlimit = cpu_to_le32(m->dqb_bsoftlimit); + d->dqb_curspace = cpu_to_le64(m->dqb_curspace); + d->dqb_btime = cpu_to_le64(m->dqb_btime); + d->dqb_id = cpu_to_le32(id); +} + +static dqbuf_t getdqbuf(void) +{ + dqbuf_t buf = kmalloc(DQBLKSIZE, GFP_KERNEL); + if (!buf) + printk(KERN_WARNING "VFS: Not enough memory for quota buffers.\n"); + return buf; +} + +static inline void freedqbuf(dqbuf_t buf) +{ + kfree(buf); +} + +static ssize_t read_blk(struct file *filp, uint blk, dqbuf_t buf) +{ + mm_segment_t fs; + ssize_t ret; + loff_t offset = blk<f_op->read(filp, (char *)buf, DQBLKSIZE, &offset); + set_fs(fs); + return ret; +} + +static ssize_t write_blk(struct file *filp, uint blk, dqbuf_t buf) +{ + mm_segment_t fs; + ssize_t ret; + loff_t offset = blk<f_op->write(filp, (char *)buf, DQBLKSIZE, &offset); + set_fs(fs); + return ret; + +} + +/* Remove empty block from list and return it */ +static int get_free_dqblk(struct file *filp, struct mem_dqinfo *info) +{ + dqbuf_t buf = getdqbuf(); + struct disk_dqdbheader *dh = (struct disk_dqdbheader *)buf; + int ret, blk; + + if (!buf) + return -ENOMEM; + if (info->dqi_free_blk) { + blk = info->dqi_free_blk; + if ((ret = read_blk(filp, blk, buf)) < 0) + goto out_buf; + info->dqi_free_blk = le32_to_cpu(dh->dqdh_next_free); + } + else { + memset(buf, 0, DQBLKSIZE); + if ((ret = write_blk(filp, info->dqi_blocks, buf)) < 0) /* Assure block allocation... */ + goto out_buf; + blk = info->dqi_blocks++; + } + mark_quotafile_info_dirty(info); + ret = blk; +out_buf: + freedqbuf(buf); + return ret; +} + +/* Insert empty block to the list */ +static int put_free_dqblk(struct file *filp, struct mem_dqinfo *info, dqbuf_t buf, uint blk) +{ + struct disk_dqdbheader *dh = (struct disk_dqdbheader *)buf; + int err; + + dh->dqdh_next_free = cpu_to_le32(info->dqi_free_blk); + dh->dqdh_prev_free = cpu_to_le32(0); + dh->dqdh_entries = cpu_to_le16(0); + info->dqi_free_blk = blk; + mark_quotafile_info_dirty(info); + if ((err = write_blk(filp, blk, buf)) < 0) /* Some strange block. We had better leave it... */ + return err; + return 0; +} + +/* Remove given block from the list of blocks with free entries */ +static int remove_free_dqentry(struct file *filp, struct mem_dqinfo *info, dqbuf_t buf, uint blk) +{ + dqbuf_t tmpbuf = getdqbuf(); + struct disk_dqdbheader *dh = (struct disk_dqdbheader *)buf; + uint nextblk = le32_to_cpu(dh->dqdh_next_free), prevblk = le32_to_cpu(dh->dqdh_prev_free); + int err; + + if (!tmpbuf) + return -ENOMEM; + if (nextblk) { + if ((err = read_blk(filp, nextblk, tmpbuf)) < 0) + goto out_buf; + ((struct disk_dqdbheader *)tmpbuf)->dqdh_prev_free = dh->dqdh_prev_free; + if ((err = write_blk(filp, nextblk, tmpbuf)) < 0) + goto out_buf; + } + if (prevblk) { + if ((err = read_blk(filp, prevblk, tmpbuf)) < 0) + goto out_buf; + ((struct disk_dqdbheader *)tmpbuf)->dqdh_next_free = dh->dqdh_next_free; + if ((err = write_blk(filp, prevblk, tmpbuf)) < 0) + goto out_buf; + } + else { + info->dqi_free_entry = nextblk; + mark_quotafile_info_dirty(info); + } + freedqbuf(tmpbuf); + dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0); + if (write_blk(filp, blk, buf) < 0) /* No matter whether write succeeds block is out of list */ + printk(KERN_ERR "VFS: Can't write block (%u) with free entries.\n", blk); + return 0; +out_buf: + freedqbuf(tmpbuf); + return err; +} + +/* Insert given block to the beginning of list with free entries */ +static int insert_free_dqentry(struct file *filp, struct mem_dqinfo *info, dqbuf_t buf, uint blk) +{ + dqbuf_t tmpbuf = getdqbuf(); + struct disk_dqdbheader *dh = (struct disk_dqdbheader *)buf; + int err; + + if (!tmpbuf) + return -ENOMEM; + dh->dqdh_next_free = cpu_to_le32(info->dqi_free_entry); + dh->dqdh_prev_free = cpu_to_le32(0); + if ((err = write_blk(filp, blk, buf)) < 0) + goto out_buf; + if (info->dqi_free_entry) { + if ((err = read_blk(filp, info->dqi_free_entry, tmpbuf)) < 0) + goto out_buf; + ((struct disk_dqdbheader *)tmpbuf)->dqdh_prev_free = cpu_to_le32(blk); + if ((err = write_blk(filp, info->dqi_free_entry, tmpbuf)) < 0) + goto out_buf; + } + freedqbuf(tmpbuf); + info->dqi_free_entry = blk; + mark_quotafile_info_dirty(info); + return 0; +out_buf: + freedqbuf(tmpbuf); + return err; +} + +/* Find space for dquot */ +static uint find_free_dqentry(struct dquot *dquot, int *err) +{ + struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type]; + struct mem_dqinfo *info = sb_dqopt(dquot->dq_sb)->info+dquot->dq_type; + uint blk, i; + struct disk_dqdbheader *dh; + struct disk_dqblk *ddquot; + struct disk_dqblk fakedquot; + dqbuf_t buf; + + *err = 0; + if (!(buf = getdqbuf())) { + *err = -ENOMEM; + return 0; + } + dh = (struct disk_dqdbheader *)buf; + ddquot = GETENTRIES(buf); + if (info->dqi_free_entry) { + blk = info->dqi_free_entry; + if ((*err = read_blk(filp, blk, buf)) < 0) + goto out_buf; + } + else { + blk = get_free_dqblk(filp, info); + if ((int)blk < 0) { + *err = blk; + return 0; + } + memset(buf, 0, DQBLKSIZE); + info->dqi_free_entry = blk; /* This is enough as block is already zeroed and entry list is empty... */ + mark_quotafile_info_dirty(info); + } + if (le16_to_cpu(dh->dqdh_entries)+1 >= DQSTRINBLK) /* Block will be full? */ + if ((*err = remove_free_dqentry(filp, info, buf, blk)) < 0) { + printk(KERN_ERR "VFS: find_free_dqentry(): Can't remove block (%u) from entry free list.\n", blk); + goto out_buf; + } + dh->dqdh_entries = cpu_to_le16(le16_to_cpu(dh->dqdh_entries)+1); + memset(&fakedquot, 0, sizeof(struct disk_dqblk)); + /* Find free structure in block */ + for (i = 0; i < DQSTRINBLK && memcmp(&fakedquot, ddquot+i, sizeof(struct disk_dqblk)); i++); +#ifdef __DQUOT_PARANOIA + if (i == DQSTRINBLK) { + printk(KERN_ERR "VFS: find_free_dqentry(): Data block full but it shouldn't.\n"); + *err = -EIO; + goto out_buf; + } +#endif + if ((*err = write_blk(filp, blk, buf)) < 0) { + printk(KERN_ERR "VFS: find_free_dqentry(): Can't write quota data block %u.\n", blk); + goto out_buf; + } + dquot->dq_off = (blk<dq_sb)->files[dquot->dq_type]; + struct mem_dqinfo *info = sb_dqopt(dquot->dq_sb)->info + dquot->dq_type; + dqbuf_t buf; + int ret = 0, newson = 0, newact = 0; + u32 *ref; + uint newblk; + + if (!(buf = getdqbuf())) + return -ENOMEM; + if (!*treeblk) { + ret = get_free_dqblk(filp, info); + if (ret < 0) + goto out_buf; + *treeblk = ret; + memset(buf, 0, DQBLKSIZE); + newact = 1; + } + else { + if ((ret = read_blk(filp, *treeblk, buf)) < 0) { + printk(KERN_ERR "VFS: Can't read tree quota block %u.\n", *treeblk); + goto out_buf; + } + } + ref = (u32 *)buf; + newblk = le32_to_cpu(ref[GETIDINDEX(dquot->dq_id, depth)]); + if (!newblk) + newson = 1; + if (depth == DQTREEDEPTH-1) { +#ifdef __DQUOT_PARANOIA + if (newblk) { + printk(KERN_ERR "VFS: Inserting already present quota entry (block %u).\n", ref[GETIDINDEX(dquot->dq_id, depth)]); + ret = -EIO; + goto out_buf; + } +#endif + newblk = find_free_dqentry(dquot, &ret); + } + else + ret = do_insert_tree(dquot, &newblk, depth+1); + if (newson && ret >= 0) { + ref[GETIDINDEX(dquot->dq_id, depth)] = cpu_to_le32(newblk); + ret = write_blk(filp, *treeblk, buf); + } + else if (newact && ret < 0) + put_free_dqblk(filp, info, buf, *treeblk); +out_buf: + freedqbuf(buf); + return ret; +} + +/* Wrapper for inserting quota structure into tree */ +static inline int dq_insert_tree(struct dquot *dquot) +{ + int tmp = DQTREEOFF; + return do_insert_tree(dquot, &tmp, 0); +} + /* * We don't have to be afraid of deadlocks as we never have quotas on quota files... */ @@ -268,32 +686,201 @@ mm_segment_t fs; loff_t offset; ssize_t ret; - struct semaphore *sem = &dquot->dq_sb->s_dquot.dqio_sem; - struct dqblk dqbuf; + struct semaphore *sem = &sb_dqopt(dquot->dq_sb)->dqio_sem; + struct disk_dqblk ddquot; down(sem); - filp = dquot->dq_sb->s_dquot.files[type]; - offset = dqoff(dquot->dq_id); + if (!dquot->dq_off) + if ((ret = dq_insert_tree(dquot)) < 0) { + printk(KERN_ERR "VFS: Error %d occured while creating quota.\n", ret); + goto out_sem; + } + filp = sb_dqopt(dquot->dq_sb)->files[type]; + offset = dquot->dq_off; + mem2diskdqb(&ddquot, &dquot->dq_dqb, dquot->dq_id); fs = get_fs(); set_fs(KERNEL_DS); - - /* - * Note: clear the DQ_MOD flag unconditionally, - * so we don't loop forever on failure. - */ - memcpy(&dqbuf, &dquot->dq_dqb, sizeof(struct dqblk)); - dquot->dq_flags &= ~DQ_MOD; - ret = 0; - if (filp) - ret = filp->f_op->write(filp, (char *)&dqbuf, - sizeof(struct dqblk), &offset); - if (ret != sizeof(struct dqblk)) + ret = filp->f_op->write(filp, (char *)&ddquot, sizeof(struct disk_dqblk), &offset); + set_fs(fs); + if (ret != sizeof(struct disk_dqblk)) printk(KERN_WARNING "VFS: dquota write failed on dev %s\n", kdevname(dquot->dq_dev)); - - set_fs(fs); - up(sem); dqstats.writes++; +out_sem: + up(sem); +} + +/* Free dquot entry in data block */ +static int free_dqentry(struct dquot *dquot, uint blk) +{ + struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type]; + struct mem_dqinfo *info = sb_dqopt(dquot->dq_sb)->info + dquot->dq_type; + struct disk_dqdbheader *dh; + dqbuf_t buf = getdqbuf(); + int ret = 0; + + if (!buf) + return -ENOMEM; + if (dquot->dq_off >> DQBLKSIZE_BITS != blk) { + printk(KERN_ERR "VFS: Quota structure has offset to other block (%u) than it should (%u).\n", blk, (uint)(dquot->dq_off >> DQBLKSIZE_BITS)); + goto out_buf; + } + if ((ret = read_blk(filp, blk, buf)) < 0) { + printk(KERN_ERR "VFS: Can't read quota data block %u\n", blk); + goto out_buf; + } + dh = (struct disk_dqdbheader *)buf; + dh->dqdh_entries = cpu_to_le16(le16_to_cpu(dh->dqdh_entries)-1); + if (!le16_to_cpu(dh->dqdh_entries)) { /* Block got free? */ + if ((ret = remove_free_dqentry(filp, info, buf, blk)) < 0 || + (ret = put_free_dqblk(filp, info, buf, blk)) < 0) { + printk(KERN_ERR "VFS: Can't move quota data block (%u) to free list.\n", blk); + goto out_buf; + } + } + else { + memset(buf+(dquot->dq_off & ((1 << DQBLKSIZE_BITS)-1)), 0, sizeof(struct disk_dqblk)); + if (le16_to_cpu(dh->dqdh_entries) == DQSTRINBLK-1) { + /* Insert will write block itself */ + if ((ret = insert_free_dqentry(filp, info, buf, blk)) < 0) { + printk(KERN_ERR "VFS: Can't insert quota data block (%u) to free entry list.\n", blk); + goto out_buf; + } + } + else + if ((ret = write_blk(filp, blk, buf)) < 0) { + printk(KERN_ERR "VFS: Can't write quota data block %u\n", blk); + goto out_buf; + } + } + dquot->dq_off = 0; /* Quota is now unattached */ +out_buf: + freedqbuf(buf); + return ret; +} + +/* Remove reference to dquot from tree */ +static int remove_tree(struct dquot *dquot, uint *blk, int depth) +{ + struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type]; + struct mem_dqinfo *info = sb_dqopt(dquot->dq_sb)->info + dquot->dq_type; + dqbuf_t buf = getdqbuf(); + int ret = 0; + uint newblk; + u32 *ref = (u32 *)buf; + + if (!buf) + return -ENOMEM; + if ((ret = read_blk(filp, *blk, buf)) < 0) { + printk(KERN_ERR "VFS: Can't read quota data block %u\n", *blk); + goto out_buf; + } + newblk = le32_to_cpu(ref[GETIDINDEX(dquot->dq_id, depth)]); + if (depth == DQTREEDEPTH-1) { + ret = free_dqentry(dquot, newblk); + newblk = 0; + } + else + ret = remove_tree(dquot, &newblk, depth+1); + if (ret >= 0 && !newblk) { + int i; + ref[GETIDINDEX(dquot->dq_id, depth)] = cpu_to_le32(0); + for (i = 0; i < DQBLKSIZE && !buf[i]; i++); /* Block got empty? */ + if (i == DQBLKSIZE) { + put_free_dqblk(filp, info, buf, *blk); + *blk = 0; + } + else + if ((ret = write_blk(filp, *blk, buf)) < 0) + printk(KERN_ERR "VFS: Can't write quota tree block %u.\n", *blk); + } +out_buf: + freedqbuf(buf); + return ret; +} + +/* Delete dquot from tree */ +static void delete_dquot(struct dquot *dquot) +{ + uint tmp = DQTREEOFF; + + down(&sb_dqopt(dquot->dq_sb)->dqio_sem); + if (!dquot->dq_off) { /* Even not allocated? */ + up(&sb_dqopt(dquot->dq_sb)->dqio_sem); + return; + } + remove_tree(dquot, &tmp, 0); + up(&sb_dqopt(dquot->dq_sb)->dqio_sem); +} + +/* Find entry in block */ +static loff_t find_block_dqentry(struct dquot *dquot, uint blk) +{ + struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type]; + dqbuf_t buf = getdqbuf(); + loff_t ret = 0; + int i; + struct disk_dqblk *ddquot = GETENTRIES(buf); + + if (!buf) + return -ENOMEM; + if ((ret = read_blk(filp, blk, buf)) < 0) { + printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk); + goto out_buf; + } + if (dquot->dq_id) + for (i = 0; i < DQSTRINBLK && le32_to_cpu(ddquot[i].dqb_id) != dquot->dq_id; i++); + else { /* ID 0 as a bit more complicated searching... */ + struct disk_dqblk fakedquot; + + memset(&fakedquot, 0, sizeof(struct disk_dqblk)); + for (i = 0; i < DQSTRINBLK; i++) + if (!le32_to_cpu(ddquot[i].dqb_id) && memcmp(&fakedquot, ddquot+i, sizeof(struct disk_dqblk))) + break; + } + if (i == DQSTRINBLK) { + printk(KERN_ERR "VFS: Quota for id %u referenced but not present.\n", dquot->dq_id); + ret = -EIO; + goto out_buf; + } + else + ret = (blk << DQBLKSIZE_BITS) + sizeof(struct disk_dqdbheader) + i * sizeof(struct disk_dqblk); +out_buf: + freedqbuf(buf); + return ret; +} + +/* Find entry for given id in the tree */ +static loff_t find_tree_dqentry(struct dquot *dquot, uint blk, int depth) +{ + struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type]; + dqbuf_t buf = getdqbuf(); + loff_t ret = 0; + u32 *ref = (u32 *)buf; + + if (!buf) + return -ENOMEM; + if ((ret = read_blk(filp, blk, buf)) < 0) { + printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk); + goto out_buf; + } + ret = 0; + blk = le32_to_cpu(ref[GETIDINDEX(dquot->dq_id, depth)]); + if (!blk) /* No reference? */ + goto out_buf; + if (depth < DQTREEDEPTH-1) + ret = find_tree_dqentry(dquot, blk, depth+1); + else + ret = find_block_dqentry(dquot, blk); +out_buf: + freedqbuf(buf); + return ret; +} + +/* Find entry for given id in the tree - wrapper function */ +static inline loff_t find_dqentry(struct dquot *dquot) +{ + return find_tree_dqentry(dquot, DQTREEOFF, 0); } static void read_dquot(struct dquot *dquot) @@ -302,31 +889,58 @@ struct file *filp; mm_segment_t fs; loff_t offset; + struct disk_dqblk ddquot; - filp = dquot->dq_sb->s_dquot.files[type]; + filp = sb_dqopt(dquot->dq_sb)->files[type]; if (filp == (struct file *)NULL) return; lock_dquot(dquot); - if (!dquot->dq_sb) /* Invalidated quota? */ +#ifdef __DQUOT_PARANOIA + if (!dquot->dq_sb) { /* Invalidated quota? */ + printk(KERN_ERR "VFS: Quota invalidated while reading!\n"); goto out_lock; + } +#endif /* Now we are sure filp is valid - the dquot isn't invalidated */ - down(&dquot->dq_sb->s_dquot.dqio_sem); - offset = dqoff(dquot->dq_id); - fs = get_fs(); - set_fs(KERNEL_DS); - filp->f_op->read(filp, (char *)&dquot->dq_dqb, sizeof(struct dqblk), &offset); - up(&dquot->dq_sb->s_dquot.dqio_sem); - set_fs(fs); - - if (dquot->dq_bhardlimit == 0 && dquot->dq_bsoftlimit == 0 && - dquot->dq_ihardlimit == 0 && dquot->dq_isoftlimit == 0) + down(&sb_dqopt(dquot->dq_sb)->dqio_sem); + offset = find_dqentry(dquot); + if (offset <= 0) { /* Entry not present? */ + if (offset < 0) + printk(KERN_ERR "VFS: Can't read quota structure for id %u.\n", dquot->dq_id); + dquot->dq_off = 0; dquot->dq_flags |= DQ_FAKE; + memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk)); + } + else { + dquot->dq_off = offset; + fs = get_fs(); + set_fs(KERNEL_DS); + filp->f_op->read(filp, (char *)&ddquot, sizeof(struct disk_dqblk), &offset); + set_fs(fs); + disk2memdqb(&dquot->dq_dqb, &ddquot); + } + up(&sb_dqopt(dquot->dq_sb)->dqio_sem); dqstats.reads++; out_lock: unlock_dquot(dquot); } +/* Commit changes of dquot to disk - it might also mean deleting it when quota became fake one and user has no blocks... */ +static void commit_dquot(struct dquot *dquot) +{ + /* We clear the flag everytime so we don't loop when there was an IO error... */ + dquot->dq_flags &= ~DQ_MOD; + if (dquot->dq_flags & DQ_FAKE && !(dquot->dq_dqb.dqb_curinodes | dquot->dq_dqb.dqb_curspace)) + delete_dquot(dquot); + else + write_dquot(dquot); +} + +/* + * End of IO functions + */ + /* Invalidate all dquots on the list, wait for all users. Note that this function is called * after quota is disabled so no new quota might be created. As we only insert to the end of * inuse list, we don't have to restart searching... */ @@ -376,12 +990,14 @@ continue; if (!(dquot->dq_flags & (DQ_MOD | DQ_LOCKED))) continue; - /* Raise use count so quota won't be invalidated. We can't use dqduplicate() as it does too many tests */ - dquot->dq_count++; + /* Get reference to quota so it won't be invalidated. get_dquot_ref() + * is enough since if dquot is locked/modified it can't be + * on the free list */ + get_dquot_ref(dquot); if (dquot->dq_flags & DQ_LOCKED) wait_on_dquot(dquot); if (dquot->dq_flags & DQ_MOD) - write_dquot(dquot); + commit_dquot(dquot); dqput(dquot); goto restart; } @@ -413,15 +1029,18 @@ lock_kernel(); prune_dqcache(nr_free_dquots / (priority + 1)); unlock_kernel(); - kmem_cache_shrink(dquot_cachep); - return 0; + return kmem_cache_shrink_nr(dquot_cachep); } -/* NOTE: If you change this function please check whether dqput_blocks() works right... */ +/* + * Put reference to dquot + * NOTE: If you change this function please check whether dqput_blocks() works right... + */ static void dqput(struct dquot *dquot) { if (!dquot) return; +#ifdef __DQUOT_PARANOIA if (!dquot->dq_count) { printk("VFS: dqput: trying to free free dquot\n"); printk("VFS: device %s, dquot of %s %d\n", @@ -429,29 +1048,36 @@ dquot->dq_id); return; } +#endif dqstats.drops++; we_slept: + if (dquot->dq_dup_ref && dquot->dq_count - dquot->dq_dup_ref <= 1) { /* Last unduplicated reference? */ + __wait_dup_drop(dquot); + goto we_slept; + } if (dquot->dq_count > 1) { /* We have more than one user... We can simply decrement use count */ - dquot->dq_count--; + put_dquot_ref(dquot); return; } if (dquot->dq_flags & DQ_MOD) { - write_dquot(dquot); + commit_dquot(dquot); goto we_slept; } - /* sanity check */ +#ifdef __DQUOT_PARANOIA if (!list_empty(&dquot->dq_free)) { printk(KERN_ERR "dqput: dquot already on free list??\n"); - dquot->dq_count--; /* J.K. Just decrementing use count seems safer... */ + put_dquot_ref(dquot); return; } - dquot->dq_count--; - /* If dquot is going to be invalidated invalidate_dquots() is going to free it so */ +#endif + put_dquot_ref(dquot); + /* Don't put dquot on free list if it will be invalidated (to avoid races between invalidate_dquots() and prune_dqcache()) */ if (!(dquot->dq_flags & DQ_INVAL)) - put_dquot_last(dquot); /* Place at end of LRU free queue */ + /* Place at end of LRU free queue */ + put_dquot_last(dquot); wake_up(&dquot->dq_wait_free); } @@ -480,7 +1106,7 @@ { unsigned int hashent = hashfn(sb->s_dev, id, type); struct dquot *dquot, *empty = NODQUOT; - struct quota_mount_options *dqopt = sb_dqopt(sb); + struct quota_info *dqopt = sb_dqopt(sb); we_slept: if (!is_enabled(dqopt, type)) { @@ -504,42 +1130,65 @@ insert_dquot_hash(dquot); read_dquot(dquot); } else { - if (!dquot->dq_count++) + if (!dquot->dq_count) remove_free_dquot(dquot); + get_dquot_ref(dquot); dqstats.cache_hits++; wait_on_dquot(dquot); if (empty) dqput(empty); } +#ifdef __DQUOT_PARANOIA if (!dquot->dq_sb) { /* Has somebody invalidated entry under us? */ printk(KERN_ERR "VFS: dqget(): Quota invalidated in dqget()!\n"); dqput(dquot); return NODQUOT; } +#endif dquot->dq_referenced++; dqstats.lookups++; return dquot; } +/* Duplicate reference to dquot got from inode */ static struct dquot *dqduplicate(struct dquot *dquot) { if (dquot == NODQUOT) return NODQUOT; - dquot->dq_count++; + get_dquot_ref(dquot); +#ifdef __DQUOT_PARANOIA if (!dquot->dq_sb) { printk(KERN_ERR "VFS: dqduplicate(): Invalidated quota to be duplicated!\n"); - dquot->dq_count--; + put_dquot_ref(dquot); return NODQUOT; } if (dquot->dq_flags & DQ_LOCKED) printk(KERN_ERR "VFS: dqduplicate(): Locked quota to be duplicated!\n"); +#endif + get_dquot_dup_ref(dquot); dquot->dq_referenced++; dqstats.lookups++; return dquot; } +/* Put duplicated reference */ +static void dqputduplicate(struct dquot *dquot) +{ +#ifdef __DQUOT_PARANOIA + if (!dquot->dq_dup_ref) { + printk(KERN_ERR "VFS: dqputduplicate(): Duplicated dquot put without duplicate reference.\n"); + return; + } +#endif + put_dquot_dup_ref(dquot); + if (!dquot->dq_dup_ref) + wake_up(&dquot->dq_wait_free); + put_dquot_ref(dquot); + dqstats.drops++; +} + static int dqinit_needed(struct inode *inode, short type) { int cnt; @@ -583,8 +1232,10 @@ /* Return 0 if dqput() won't block (note that 1 doesn't necessarily mean blocking) */ static inline int dqput_blocks(struct dquot *dquot) { - if (dquot->dq_count == 1) + if (dquot->dq_dup_ref && dquot->dq_count - dquot->dq_dup_ref <= 1) return 1; + if (dquot->dq_count <= 1 && dquot->dq_flags & DQ_MOD) + return 1; return 0; } @@ -640,9 +1291,9 @@ dquot->dq_flags |= DQ_MOD; } -static inline void dquot_incr_blocks(struct dquot *dquot, unsigned long number) +static inline void dquot_incr_space(struct dquot *dquot, qsize_t number) { - dquot->dq_curblocks += number; + dquot->dq_curspace += number; dquot->dq_flags |= DQ_MOD; } @@ -658,13 +1309,13 @@ dquot->dq_flags |= DQ_MOD; } -static inline void dquot_decr_blocks(struct dquot *dquot, unsigned long number) +static inline void dquot_decr_space(struct dquot *dquot, qsize_t number) { - if (dquot->dq_curblocks > number) - dquot->dq_curblocks -= number; + if (dquot->dq_curspace > number) + dquot->dq_curspace -= number; else - dquot->dq_curblocks = 0; - if (dquot->dq_curblocks < dquot->dq_bsoftlimit) + dquot->dq_curspace = 0; + if (toqb(dquot->dq_curspace) < dquot->dq_bsoftlimit) dquot->dq_btime = (time_t) 0; dquot->dq_flags &= ~DQ_BLKS; dquot->dq_flags |= DQ_MOD; @@ -705,7 +1356,7 @@ tty_write_message(current->tty, ": warning, "); else tty_write_message(current->tty, ": write failed, "); - tty_write_message(current->tty, quotatypes[dquot->dq_type]); + tty_write_message(current->tty, (char *)quotatypes[dquot->dq_type]); switch (warntype) { case IHARDWARN: msg = " file limit reached.\n"; @@ -740,7 +1391,7 @@ static inline char ignore_hardlimit(struct dquot *dquot) { - return capable(CAP_SYS_RESOURCE) && !dquot->dq_sb->s_dquot.rsquash[dquot->dq_type]; + return capable(CAP_SYS_RESOURCE); } static int check_idq(struct dquot *dquot, ulong inodes, char *warntype) @@ -768,20 +1419,20 @@ (dquot->dq_curinodes + inodes) > dquot->dq_isoftlimit && dquot->dq_itime == 0) { *warntype = ISOFTWARN; - dquot->dq_itime = CURRENT_TIME + dquot->dq_sb->s_dquot.inode_expire[dquot->dq_type]; + dquot->dq_itime = CURRENT_TIME + (__kernel_time_t)(sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace); } return QUOTA_OK; } -static int check_bdq(struct dquot *dquot, ulong blocks, char prealloc, char *warntype) +static int check_bdq(struct dquot *dquot, qsize_t space, char prealloc, char *warntype) { *warntype = 0; - if (blocks <= 0 || dquot->dq_flags & DQ_FAKE) + if (space <= 0 || dquot->dq_flags & DQ_FAKE) return QUOTA_OK; if (dquot->dq_bhardlimit && - (dquot->dq_curblocks + blocks) > dquot->dq_bhardlimit && + toqb(dquot->dq_curspace + space) > dquot->dq_bhardlimit && !ignore_hardlimit(dquot)) { if (!prealloc) *warntype = BHARDWARN; @@ -789,7 +1440,7 @@ } if (dquot->dq_bsoftlimit && - (dquot->dq_curblocks + blocks) > dquot->dq_bsoftlimit && + toqb(dquot->dq_curspace + space) > dquot->dq_bsoftlimit && dquot->dq_btime && CURRENT_TIME >= dquot->dq_btime && !ignore_hardlimit(dquot)) { if (!prealloc) @@ -798,11 +1449,11 @@ } if (dquot->dq_bsoftlimit && - (dquot->dq_curblocks + blocks) > dquot->dq_bsoftlimit && + toqb(dquot->dq_curspace + space) > dquot->dq_bsoftlimit && dquot->dq_btime == 0) { if (!prealloc) { *warntype = BSOFTWARN; - dquot->dq_btime = CURRENT_TIME + dquot->dq_sb->s_dquot.block_expire[dquot->dq_type]; + dquot->dq_btime = CURRENT_TIME + (__kernel_time_t)(sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_bgrace); } else /* @@ -819,18 +1470,18 @@ * Initialize a dquot-struct with new quota info. This is used by the * system call interface functions. */ -static int set_dqblk(struct super_block *sb, int id, short type, int flags, struct dqblk *dqblk) +static int set_dqblk(struct super_block *sb, qid_t id, short type, int flags, struct mem_dqblk *dqblk) { struct dquot *dquot; int error = -EFAULT; - struct dqblk dq_dqblk; + struct mem_dqblk dq_dqblk; - if (copy_from_user(&dq_dqblk, dqblk, sizeof(struct dqblk))) + if (copy_from_user(&dq_dqblk, dqblk, sizeof(struct mem_dqblk))) return error; if (sb && (dquot = dqget(sb, id, type)) != NODQUOT) { /* We can't block while changing quota structure... */ - if (id > 0 && ((flags & SET_QUOTA) || (flags & SET_QLIMIT))) { + if ((flags & SET_QUOTA) || (flags & SET_QLIMIT)) { dquot->dq_bhardlimit = dq_dqblk.dqb_bhardlimit; dquot->dq_bsoftlimit = dq_dqblk.dqb_bsoftlimit; dquot->dq_ihardlimit = dq_dqblk.dqb_ihardlimit; @@ -841,22 +1492,22 @@ if (dquot->dq_isoftlimit && dquot->dq_curinodes < dquot->dq_isoftlimit && dq_dqblk.dqb_curinodes >= dquot->dq_isoftlimit) - dquot->dq_itime = CURRENT_TIME + dquot->dq_sb->s_dquot.inode_expire[type]; + dquot->dq_itime = CURRENT_TIME + (__kernel_time_t)(sb_dqopt(dquot->dq_sb)->info[type].dqi_igrace); dquot->dq_curinodes = dq_dqblk.dqb_curinodes; - if (dquot->dq_curinodes < dquot->dq_isoftlimit) - dquot->dq_flags &= ~DQ_INODES; if (dquot->dq_bsoftlimit && - dquot->dq_curblocks < dquot->dq_bsoftlimit && - dq_dqblk.dqb_curblocks >= dquot->dq_bsoftlimit) - dquot->dq_btime = CURRENT_TIME + dquot->dq_sb->s_dquot.block_expire[type]; - dquot->dq_curblocks = dq_dqblk.dqb_curblocks; - if (dquot->dq_curblocks < dquot->dq_bsoftlimit) - dquot->dq_flags &= ~DQ_BLKS; + toqb(dquot->dq_curspace) < dquot->dq_bsoftlimit && + toqb(dq_dqblk.dqb_curspace) >= dquot->dq_bsoftlimit) + dquot->dq_btime = CURRENT_TIME + (__kernel_time_t)(sb_dqopt(dquot->dq_sb)->info[type].dqi_bgrace); + dquot->dq_curspace = dq_dqblk.dqb_curspace; } - if (id == 0) { - dquot->dq_sb->s_dquot.block_expire[type] = dquot->dq_btime = dq_dqblk.dqb_btime; - dquot->dq_sb->s_dquot.inode_expire[type] = dquot->dq_itime = dq_dqblk.dqb_itime; + if (dquot->dq_curinodes < dquot->dq_isoftlimit || !dquot->dq_isoftlimit) { + dquot->dq_itime = 0; + dquot->dq_flags &= ~DQ_INODES; + } + if (toqb(dquot->dq_curspace) < dquot->dq_bsoftlimit || !dquot->dq_bsoftlimit) { + dquot->dq_btime = 0; + dquot->dq_flags &= ~DQ_BLKS; } if (dq_dqblk.dqb_bhardlimit == 0 && dq_dqblk.dqb_bsoftlimit == 0 && @@ -871,10 +1522,10 @@ return 0; } -static int get_quota(struct super_block *sb, int id, short type, struct dqblk *dqblk) +static int get_quota(struct super_block *sb, qid_t id, short type, struct mem_dqblk *dqblk) { struct dquot *dquot; - struct dqblk data; + struct mem_dqblk data; int error = -ESRCH; if (!sb || !sb_has_quota_enabled(sb, type)) @@ -883,10 +1534,10 @@ if (dquot == NODQUOT) goto out; - memcpy(&data, &dquot->dq_dqb, sizeof(struct dqblk)); /* We copy data to preserve them from changing */ + memcpy(&data, &dquot->dq_dqb, sizeof(struct mem_dqblk)); /* We copy data to preserve them from changing */ dqput(dquot); error = -EFAULT; - if (dqblk && !copy_to_user(dqblk, &data, sizeof(struct dqblk))) + if (dqblk && !copy_to_user(dqblk, &data, sizeof(struct mem_dqblk))) error = 0; out: return error; @@ -907,46 +1558,48 @@ return error; } -static int quota_root_squash(struct super_block *sb, short type, int *addr) +static int get_info(struct super_block *sb, short type, struct mem_dqinfo *pinfo) { - int new_value, error; - - if (!sb) - return(-ENODEV); - - error = -EFAULT; - if (!copy_from_user(&new_value, addr, sizeof(int))) { - sb_dqopt(sb)->rsquash[type] = new_value; - error = 0; - } - return error; + struct mem_dqinfo kinfo; + + if (!sb || !sb_has_quota_enabled(sb, type)) + return -ESRCH; + /* Make our own copy so we can guarantee consistent structure */ + memcpy(&kinfo, sb_dqopt(sb)->info+type, sizeof(struct mem_dqinfo)); + kinfo.dqi_flags &= DQF_MASK; + if (copy_to_user(pinfo, &kinfo, sizeof(struct mem_dqinfo))) + return -EFAULT; + return 0; } -#if 0 /* We are not going to support filesystems without i_blocks... */ -/* - * This is a simple algorithm that calculates the size of a file in blocks. - * This is only used on filesystems that do not have an i_blocks count. - */ -static u_long isize_to_blocks(loff_t isize, size_t blksize_bits) +static int set_info(int op, struct super_block *sb, short type, struct mem_dqinfo *pinfo) { - u_long blocks; - u_long indirect; + struct mem_dqinfo info; + struct quota_info *dqopt = sb_dqopt(sb); - if (!blksize_bits) - blksize_bits = BLOCK_SIZE_BITS; - blocks = (isize >> blksize_bits) + ((isize & ~((1 << blksize_bits)-1)) ? 1 : 0); - if (blocks > 10) { - indirect = ((blocks - 11) >> 8) + 1; /* single indirect blocks */ - if (blocks > (10 + 256)) { - indirect += ((blocks - 267) >> 16) + 1; /* double indirect blocks */ - if (blocks > (10 + 256 + (256 << 8))) - indirect++; /* triple indirect blocks */ - } - blocks += indirect; - } - return blocks; + if (!sb || !sb_has_quota_enabled(sb, type)) + return -ESRCH; + + if (copy_from_user(&info, pinfo, sizeof(struct mem_dqinfo))) + return -EFAULT; + + switch (op) { + case ISET_FLAGS: + dqopt->info[type].dqi_flags = (dqopt->info[type].dqi_flags & ~DQF_MASK) + | (info.dqi_flags & DQF_MASK); + break; + case ISET_GRACE: + dqopt->info[type].dqi_bgrace = info.dqi_bgrace; + dqopt->info[type].dqi_igrace = info.dqi_igrace; + break; + case ISET_ALL: + info.dqi_flags &= ~DQF_MASK; + memcpy(dqopt->info + type, &info, sizeof(struct mem_dqinfo)); + break; + } + mark_quotafile_info_dirty(dqopt->info + type); + return 0; } -#endif /* * Externally referenced functions through dquot_operations in inode. @@ -956,7 +1609,7 @@ void dquot_initialize(struct inode *inode, short type) { struct dquot *dquot[MAXQUOTAS]; - unsigned int id = 0; + qid_t id = 0; short cnt; if (IS_NOQUOTA(inode)) @@ -1005,6 +1658,7 @@ struct dquot *dquot; short cnt; + /* Here we needn't be afraid of races as inode is not used any more */ inode->i_flags &= ~S_QUOTA; for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (inode->i_dquot[cnt] == NODQUOT) @@ -1018,7 +1672,7 @@ /* * This operation can block, but only after everything is updated */ -int dquot_alloc_block(struct inode *inode, unsigned long number, char warn) +int dquot_alloc_space(struct inode *inode, qsize_t number, char prealloc) { int cnt, ret = NO_QUOTA; struct dquot *dquot[MAXQUOTAS]; @@ -1033,22 +1687,22 @@ dquot[cnt] = dqduplicate(inode->i_dquot[cnt]); if (dquot[cnt] == NODQUOT) continue; - if (check_bdq(dquot[cnt], number, warn, warntype+cnt) == NO_QUOTA) + if (check_bdq(dquot[cnt], number, prealloc, warntype+cnt) == NO_QUOTA) goto warn_put_all; } for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (dquot[cnt] == NODQUOT) continue; - dquot_incr_blocks(dquot[cnt], number); + dquot_incr_space(dquot[cnt], number); } - inode->i_blocks += number << (BLOCK_SIZE_BITS - 9); - /* NOBLOCK End */ + inode_add_bytes(inode, number); + /* NOBLOCK End */ ret = QUOTA_OK; warn_put_all: flush_warnings(dquot, warntype); for (cnt = 0; cnt < MAXQUOTAS; cnt++) if (dquot[cnt] != NODQUOT) - dqput(dquot[cnt]); + dqputduplicate(dquot[cnt]); return ret; } @@ -1085,14 +1739,14 @@ flush_warnings(dquot, warntype); for (cnt = 0; cnt < MAXQUOTAS; cnt++) if (dquot[cnt] != NODQUOT) - dqput(dquot[cnt]); + dqputduplicate(dquot[cnt]); return ret; } /* * This is a non-blocking operation. */ -void dquot_free_block(struct inode *inode, unsigned long number) +void dquot_free_space(struct inode *inode, qsize_t number) { unsigned short cnt; struct dquot *dquot; @@ -1102,10 +1756,10 @@ dquot = dqduplicate(inode->i_dquot[cnt]); if (dquot == NODQUOT) continue; - dquot_decr_blocks(dquot, number); - dqput(dquot); + dquot_decr_space(dquot, number); + dqputduplicate(dquot); } - inode->i_blocks -= number << (BLOCK_SIZE_BITS - 9); + inode_sub_bytes(inode, number); /* NOBLOCK End */ } @@ -1123,7 +1777,7 @@ if (dquot == NODQUOT) continue; dquot_decr_inodes(dquot, number); - dqput(dquot); + dqputduplicate(dquot); } /* NOBLOCK End */ } @@ -1135,7 +1789,7 @@ */ int dquot_transfer(struct inode *inode, struct iattr *iattr) { - unsigned long blocks; + qsize_t space; struct dquot *transfer_from[MAXQUOTAS]; struct dquot *transfer_to[MAXQUOTAS]; int cnt, ret = NO_QUOTA, chuid = (iattr->ia_valid & ATTR_UID) && inode->i_uid != iattr->ia_uid, @@ -1165,7 +1819,7 @@ } } /* NOBLOCK START: From now on we shouldn't block */ - blocks = (inode->i_blocks >> 1); + space = inode_get_bytes(inode); /* Build the transfer_from list and check the limits */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { /* The second test can fail when quotaoff is in progress... */ @@ -1175,7 +1829,7 @@ if (transfer_from[cnt] == NODQUOT) /* Can happen on quotafiles (quota isn't initialized on them)... */ continue; if (check_idq(transfer_to[cnt], 1, warntype+cnt) == NO_QUOTA || - check_bdq(transfer_to[cnt], blocks, 0, warntype+cnt) == NO_QUOTA) + check_bdq(transfer_to[cnt], space, 0, warntype+cnt) == NO_QUOTA) goto warn_put_all; } @@ -1190,10 +1844,10 @@ continue; dquot_decr_inodes(transfer_from[cnt], 1); - dquot_decr_blocks(transfer_from[cnt], blocks); + dquot_decr_space(transfer_from[cnt], space); dquot_incr_inodes(transfer_to[cnt], 1); - dquot_incr_blocks(transfer_to[cnt], blocks); + dquot_incr_space(transfer_to[cnt], space); if (inode->i_dquot[cnt] == NODQUOT) BUG(); @@ -1210,7 +1864,7 @@ flush_warnings(transfer_to, warntype); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (transfer_to[cnt] != NODQUOT) - dqput(transfer_to[cnt]); + dqputduplicate(transfer_to[cnt]); if (transfer_from[cnt] != NODQUOT) dqput(transfer_from[cnt]); } @@ -1223,6 +1877,7 @@ for (i = 0; i < NR_DQHASH; i++) INIT_LIST_HEAD(dquot_hash + i); + dqstats.version = __DQUOT_NUM_VERSION__; printk(KERN_NOTICE "VFS: Diskquotas version %s initialized\n", __DQUOT_VERSION__); return 0; } @@ -1234,14 +1889,14 @@ struct dquot_operations dquot_operations = { dquot_initialize, /* mandatory */ dquot_drop, /* mandatory */ - dquot_alloc_block, + dquot_alloc_space, dquot_alloc_inode, - dquot_free_block, + dquot_free_space, dquot_free_inode, dquot_transfer }; -static inline void set_enable_flags(struct quota_mount_options *dqopt, short type) +static inline void set_enable_flags(struct quota_info *dqopt, short type) { switch (type) { case USRQUOTA: @@ -1253,7 +1908,7 @@ } } -static inline void reset_enable_flags(struct quota_mount_options *dqopt, short type) +static inline void reset_enable_flags(struct quota_info *dqopt, short type) { switch (type) { case USRQUOTA: @@ -1275,7 +1930,7 @@ { struct file *filp; short cnt; - struct quota_mount_options *dqopt = sb_dqopt(sb); + struct quota_info *dqopt = sb_dqopt(sb); lock_kernel(); if (!sb) @@ -1293,11 +1948,12 @@ /* Note: these are blocking operations */ remove_dquot_ref(sb, cnt); invalidate_dquots(sb, cnt); - + /* When invalidate is finished there are no users of any dquot of our interest... */ + if (quotafile_info_dirty(sb_dqopt(sb)->info+cnt)) + write_quotafile_info(sb, cnt); filp = dqopt->files[cnt]; dqopt->files[cnt] = (struct file *)NULL; - dqopt->inode_expire[cnt] = 0; - dqopt->block_expire[cnt] = 0; + memset(dqopt->info+cnt, 0, sizeof(struct mem_dqinfo)); fput(filp); } up(&dqopt->dqoff_sem); @@ -1306,20 +1962,31 @@ return 0; } -static inline int check_quotafile_size(loff_t size) +static int check_quotafile(struct file *f, short type) { - ulong blocks = size >> BLOCK_SIZE_BITS; - size_t off = size & (BLOCK_SIZE - 1); - - return !(((blocks % sizeof(struct dqblk)) * BLOCK_SIZE + off % sizeof(struct dqblk)) % sizeof(struct dqblk)); + struct disk_dqheader dqhead; + mm_segment_t fs; + ssize_t size; + loff_t offset = 0; + + fs = get_fs(); + set_fs(KERNEL_DS); + size = f->f_op->read(f, (char *)&dqhead, sizeof(struct disk_dqheader), &offset); + set_fs(fs); + if (size != sizeof(struct disk_dqheader)) + return 0; + if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type] || + le32_to_cpu(dqhead.dqh_version) != quota_versions[type]) + return 0; + return 1; } +/* Turn quotas of given type on */ static int quota_on(struct super_block *sb, short type, char *path) { struct file *f; struct inode *inode; - struct dquot *dquot; - struct quota_mount_options *dqopt = sb_dqopt(sb); + struct quota_info *dqopt = sb_dqopt(sb); char *tmp; int error; @@ -1346,26 +2013,23 @@ if (!S_ISREG(inode->i_mode)) goto out_f; error = -EINVAL; - if (inode->i_size == 0 || !check_quotafile_size(inode->i_size)) + if (inode->i_size == 0 || !check_quotafile(f, type)) goto out_f; /* We don't want quota on quota files */ dquot_drop(inode); inode->i_flags |= S_NOQUOTA; dqopt->files[type] = f; + if (read_quotafile_info(sb, type) < 0) /* Read header from file - OK? */ + goto out_f_tab; sb->dq_op = &dquot_operations; set_enable_flags(dqopt, type); - - dquot = dqget(sb, 0, type); - dqopt->inode_expire[type] = (dquot != NODQUOT) ? dquot->dq_itime : MAX_IQ_TIME; - dqopt->block_expire[type] = (dquot != NODQUOT) ? dquot->dq_btime : MAX_DQ_TIME; - dqput(dquot); - add_dquot_ref(sb, type); up(&dqopt->dqoff_sem); return 0; - +out_f_tab: + dqopt->files[type] = NULL; out_f: filp_close(f, NULL); out_lock: @@ -1380,7 +2044,7 @@ * calls. Maybe we need to add the process quotas etc. in the future, * but we probably should use rlimits for that. */ -asmlinkage long sys_quotactl(int cmd, const char *special, int id, caddr_t addr) +asmlinkage long sys_quotactl(int cmd, const char *special, qid_t id, __kernel_caddr_t addr) { int cmds = 0, type = 0, flags = 0; kdev_t dev; @@ -1395,11 +2059,15 @@ goto out; if (id & ~0xFFFF) goto out; + if ((uint) type >= MAXQUOTAS || cmds > 0x1100 || cmds < 0x100 || cmds == 0x0300 || + cmds == 0x0400 || cmds == 0x0500 || cmds == 0x1000) + goto out; ret = -EPERM; switch (cmds) { case Q_SYNC: case Q_GETSTATS: + case Q_GETINFO: break; case Q_GETQUOTA: if (((type == USRQUOTA && current->euid != id) || @@ -1412,7 +2080,6 @@ goto out; } - ret = -EINVAL; dev = NODEV; if (special != NULL || (cmds != Q_SYNC && cmds != Q_GETSTATS)) { mode_t mode; @@ -1444,7 +2111,7 @@ ret = quota_off(sb, type); goto out; case Q_GETQUOTA: - ret = get_quota(sb, id, type, (struct dqblk *) addr); + ret = get_quota(sb, id, type, (struct mem_dqblk *) addr); goto out; case Q_SETQUOTA: flags |= SET_QUOTA; @@ -1461,16 +2128,25 @@ case Q_GETSTATS: ret = get_stats(addr); goto out; - case Q_RSQUASH: - ret = quota_root_squash(sb, type, (int *) addr); + case Q_GETINFO: + ret = get_info(sb, type, (struct mem_dqinfo *) addr); + goto out; + case Q_SETFLAGS: + ret = set_info(ISET_FLAGS, sb, type, (struct mem_dqinfo *)addr); + goto out; + case Q_SETGRACE: + ret = set_info(ISET_GRACE, sb, type, (struct mem_dqinfo *)addr); goto out; + case Q_SETINFO: + ret = set_info(ISET_ALL, sb, type, (struct mem_dqinfo *)addr); + goto out; default: goto out; } ret = -NODEV; if (sb && sb_has_quota_enabled(sb, type)) - ret = set_dqblk(sb, id, type, flags, (struct dqblk *) addr); + ret = set_dqblk(sb, id, type, flags, (struct mem_dqblk *) addr); out: if (sb) drop_super(sb); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/exec.c linux.19pre5-ac1/fs/exec.c --- linux.19p5/fs/exec.c Thu Apr 4 13:21:14 2002 +++ linux.19pre5-ac1/fs/exec.c Mon Mar 25 18:12:13 2002 @@ -35,6 +35,7 @@ #include #include #include +#include #define __NO_VERSION__ #include @@ -279,6 +280,7 @@ flush_dcache_page(page); flush_page_to_ram(page); set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte(page, PAGE_COPY)))); + page_add_rmap(page, pte); tsk->mm->rss++; spin_unlock(&tsk->mm->page_table_lock); @@ -308,6 +310,12 @@ if (!mpnt) return -ENOMEM; + if (!vm_enough_memory((STACK_TOP - (PAGE_MASK & (unsigned long) bprm->p))>>PAGE_SHIFT,1)) + { + kmem_cache_free(vm_area_cachep, mpnt); + return -ENOMEM; + } + down_write(¤t->mm->mmap_sem); { mpnt->vm_mm = current->mm; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/ext3/balloc.c linux.19pre5-ac1/fs/ext3/balloc.c --- linux.19p5/fs/ext3/balloc.c Thu Apr 4 13:18:16 2002 +++ linux.19pre5-ac1/fs/ext3/balloc.c Wed Apr 3 00:35:47 2002 @@ -542,6 +542,7 @@ int i, j, k, tmp, alloctmp; int bitmap_nr; int fatal = 0, err; + int performed_allocation = 0; struct super_block * sb; struct ext3_group_desc * gdp; struct ext3_super_block * es; @@ -644,8 +645,7 @@ } /* No space left on the device */ - unlock_super (sb); - return 0; + goto out; search_back: /* @@ -694,6 +694,7 @@ J_ASSERT_BH(bh, !ext3_test_bit(j, bh->b_data)); BUFFER_TRACE(bh, "setting bitmap bit"); ext3_set_bit(j, bh->b_data); + performed_allocation = 1; #ifdef CONFIG_JBD_DEBUG { @@ -815,6 +816,11 @@ ext3_std_error(sb, fatal); } unlock_super (sb); + /* + * Undo the block allocation + */ + if (!performed_allocation) + DQUOT_FREE_BLOCK(inode, 1); return 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/fat/inode.c linux.19pre5-ac1/fs/fat/inode.c --- linux.19p5/fs/fat/inode.c Thu Apr 4 13:18:08 2002 +++ linux.19pre5-ac1/fs/fat/inode.c Thu Mar 21 00:48:42 2002 @@ -434,12 +434,13 @@ struct dentry *result; if (fhtype != 3) - return NULL; + return ERR_PTR(-ESTALE); if (len < 5) - return NULL; + return ERR_PTR(-ESTALE); + /* We cannot find the parent, + It better just *be* there */ if (parent) - return NULL; /* We cannot find the parent, - It better just *be* there */ + return ERR_PTR(-ESTALE); inode = iget(sb, fh[0]); if (!inode || is_bad_inode(inode) || @@ -501,6 +502,7 @@ iput(inode); return ERR_PTR(-ENOMEM); } + result->d_op = sb->s_root->d_op; result->d_flags |= DCACHE_NFSD_DISCONNECTED; return result; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/fcntl.c linux.19pre5-ac1/fs/fcntl.c --- linux.19p5/fs/fcntl.c Thu Apr 4 13:18:06 2002 +++ linux.19pre5-ac1/fs/fcntl.c Fri Mar 22 16:38:44 2002 @@ -66,6 +66,10 @@ write_lock(&files->file_lock); + error = -EINVAL; + if (orig_start >= current->rlim[RLIMIT_NOFILE].rlim_cur) + goto out; + repeat: /* * Someone might have closed fd's in the range diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/file_table.c linux.19pre5-ac1/fs/file_table.c --- linux.19p5/fs/file_table.c Thu Apr 4 13:18:06 2002 +++ linux.19pre5-ac1/fs/file_table.c Wed Feb 13 00:47:32 2002 @@ -186,3 +186,17 @@ file_list_unlock(); return 0; } + +void __init files_init(unsigned long mempages) +{ + int n; + /* One file with associated inode and dcache is very roughly 1K. + * Per default don't use more than 10% of our memory for files. + */ + + n = (mempages * (PAGE_SIZE / 1024)) / 10; + files_stat.max_files = n; + if (files_stat.max_files < NR_FILE) + files_stat.max_files = NR_FILE; +} + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/filesystems.c linux.19pre5-ac1/fs/filesystems.c --- linux.19p5/fs/filesystems.c Thu Apr 4 13:18:07 2002 +++ linux.19pre5-ac1/fs/filesystems.c Thu Mar 21 00:48:42 2002 @@ -3,7 +3,7 @@ * * Copyright (C) 1991, 1992 Linus Torvalds * - * table of configured filesystems + * nfsservctl system-call when nfsd is not compiled in. */ #include @@ -13,28 +13,28 @@ #include #include -#if defined(CONFIG_NFSD_MODULE) -struct nfsd_linkage *nfsd_linkage = NULL; +#if ! defined(CONFIG_NFSD) +struct nfsd_linkage *nfsd_linkage; long asmlinkage sys_nfsservctl(int cmd, void *argp, void *resp) { int ret = -ENOSYS; +#if defined(CONFIG_MODULES) lock_kernel(); if (nfsd_linkage || - (request_module ("nfsd") == 0 && nfsd_linkage)) + (request_module ("nfsd") == 0 && nfsd_linkage)) { + __MOD_INC_USE_COUNT(nfsd_linkage->owner); + unlock_kernel(); ret = nfsd_linkage->do_nfsservctl(cmd, argp, resp); - - unlock_kernel(); + __MOD_DEC_USE_COUNT(nfsd_linkage->owner); + } else + unlock_kernel(); +#endif return ret; } EXPORT_SYMBOL(nfsd_linkage); -#elif ! defined (CONFIG_NFSD) -asmlinkage int sys_nfsservctl(int cmd, void *argp, void *resp) -{ - return -ENOSYS; -} #endif /* CONFIG_NFSD */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/Makefile linux.19pre5-ac1/fs/inflate_fs/Makefile --- linux.19p5/fs/inflate_fs/Makefile Thu Apr 4 13:18:15 2002 +++ linux.19pre5-ac1/fs/inflate_fs/Makefile Thu Jan 1 01:00:00 1970 @@ -1,33 +0,0 @@ -# -# This is a modified version of zlib, which does all memory -# allocation ahead of time. -# -# Currently only decompression is supported. -# -# Decompression needs to be serialized for each memory -# allocation. -# -# -# (The upsides of the simplification is that you can't get in -# any nasty situations wrt memory management, and that the -# uncompression can be done without blocking on allocation). -# -# The modules are named *_fs.o to distinguish from other modified -# compression libraries, like the one used by ppp. -# -# It is expected that when a deflate module is added it will be -# a separate module in a deflate_fs directory, to avoid having to -# load the deflate code for readonly filesystems. -# - -O_TARGET := inflate_fs.o - -export-objs := inflate_syms.o - -obj-y := adler32.o infblock.o infcodes.o inffast.o inflate.o \ - inftrees.o infutil.o inflate_syms.o -obj-m := $(O_TARGET) - -EXTRA_CFLAGS += -I $(TOPDIR)/fs/inflate_fs - -include $(TOPDIR)/Rules.make diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/adler32.c linux.19pre5-ac1/fs/inflate_fs/adler32.c --- linux.19p5/fs/inflate_fs/adler32.c Thu Apr 4 13:18:15 2002 +++ linux.19pre5-ac1/fs/inflate_fs/adler32.c Thu Jan 1 01:00:00 1970 @@ -1,48 +0,0 @@ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include - -#define BASE 65521L /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - -/* ========================================================================= */ -uLong ZEXPORT zlib_fs_adler32(adler, buf, len) - uLong adler; - const Bytef *buf; - uInt len; -{ - unsigned long s1 = adler & 0xffff; - unsigned long s2 = (adler >> 16) & 0xffff; - int k; - - if (buf == Z_NULL) return 1L; - - while (len > 0) { - k = len < NMAX ? len : NMAX; - len -= k; - while (k >= 16) { - DO16(buf); - buf += 16; - k -= 16; - } - if (k != 0) do { - s1 += *buf++; - s2 += s1; - } while (--k); - s1 %= BASE; - s2 %= BASE; - } - return (s2 << 16) | s1; -} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/infblock.c linux.19pre5-ac1/fs/inflate_fs/infblock.c --- linux.19p5/fs/inflate_fs/infblock.c Thu Apr 4 13:18:15 2002 +++ linux.19pre5-ac1/fs/inflate_fs/infblock.c Thu Jan 1 01:00:00 1970 @@ -1,355 +0,0 @@ -/* infblock.c -- interpret and process block types to last block - * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "infblock.h" -#include "inftrees.h" -#include "infcodes.h" -#include "infutil.h" - -struct inflate_codes_state; - -/* simplify the use of the inflate_huft type with some defines */ -#define exop word.what.Exop -#define bits word.what.Bits - -/* Table for deflate from PKZIP's appnote.txt. */ -local const uInt border[] = { /* Order of the bit length code lengths */ - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - -/* - Notes beyond the 1.93a appnote.txt: - - 1. Distance pointers never point before the beginning of the output - stream. - 2. Distance pointers can point back across blocks, up to 32k away. - 3. There is an implied maximum of 7 bits for the bit length table and - 15 bits for the actual data. - 4. If only one code exists, then it is encoded using one bit. (Zero - would be more efficient, but perhaps a little confusing.) If two - codes exist, they are coded using one bit each (0 and 1). - 5. There is no way of sending zero distance codes--a dummy must be - sent if there are none. (History: a pre 2.0 version of PKZIP would - store blocks with no distance codes, but this was discovered to be - too harsh a criterion.) Valid only for 1.93a. 2.04c does allow - zero distance codes, which is sent as one code of zero bits in - length. - 6. There are up to 286 literal/length codes. Code 256 represents the - end-of-block. Note however that the static length tree defines - 288 codes just to fill out the Huffman codes. Codes 286 and 287 - cannot be used though, since there is no length base or extra bits - defined for them. Similarily, there are up to 30 distance codes. - However, static trees define 32 codes (all 5 bits) to fill out the - Huffman codes, but the last two had better not show up in the data. - 7. Unzip can check dynamic Huffman blocks for complete code sets. - The exception is that a single code would not be complete (see #4). - 8. The five bits following the block type is really the number of - literal codes sent minus 257. - 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits - (1+6+6). Therefore, to output three times the length, you output - three codes (1+1+1), whereas to output four times the same length, - you only need two codes (1+3). Hmm. - 10. In the tree reconstruction algorithm, Code = Code + Increment - only if BitLength(i) is not zero. (Pretty obvious.) - 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) - 12. Note: length code 284 can represent 227-258, but length code 285 - really is 258. The last length deserves its own, short code - since it gets used a lot in very redundant files. The length - 258 is special since 258 - 3 (the min match length) is 255. - 13. The literal/length and distance code bit lengths are read as a - single stream of lengths. It is possible (and advantageous) for - a repeat code (16, 17, or 18) to go across the boundary between - the two sets of lengths. - */ - - -void zlib_fs_inflate_blocks_reset(s, z, c) -inflate_blocks_statef *s; -z_streamp z; -uLongf *c; -{ - if (c != Z_NULL) - *c = s->check; - if (s->mode == CODES) - zlib_fs_inflate_codes_free(s->sub.decode.codes, z); - s->mode = TYPE; - s->bitk = 0; - s->bitb = 0; - s->read = s->write = s->window; - if (s->checkfn != Z_NULL) - z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0); -} - -inflate_blocks_statef *zlib_fs_inflate_blocks_new(z, c, w) -z_streamp z; -check_func c; -uInt w; -{ - inflate_blocks_statef *s; - - s = &WS(z)->working_blocks_state; - s->hufts = WS(z)->working_hufts; - s->window = WS(z)->working_window; - s->end = s->window + w; - s->checkfn = c; - s->mode = TYPE; - zlib_fs_inflate_blocks_reset(s, z, Z_NULL); - return s; -} - - -int zlib_fs_inflate_blocks(s, z, r) -inflate_blocks_statef *s; -z_streamp z; -int r; -{ - uInt t; /* temporary storage */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD - - /* process input based on current state */ - while (1) switch (s->mode) - { - case TYPE: - NEEDBITS(3) - t = (uInt)b & 7; - s->last = t & 1; - switch (t >> 1) - { - case 0: /* stored */ - DUMPBITS(3) - t = k & 7; /* go to byte boundary */ - DUMPBITS(t) - s->mode = LENS; /* get length of stored block */ - break; - case 1: /* fixed */ - { - uInt bl, bd; - inflate_huft *tl, *td; - - zlib_fs_inflate_trees_fixed(&bl, &bd, &tl, &td, z); - s->sub.decode.codes = zlib_fs_inflate_codes_new(bl, bd, tl, td, z); - if (s->sub.decode.codes == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - } - DUMPBITS(3) - s->mode = CODES; - break; - case 2: /* dynamic */ - DUMPBITS(3) - s->mode = TABLE; - break; - case 3: /* illegal */ - DUMPBITS(3) - s->mode = B_BAD; - z->msg = (char*)"invalid block type"; - r = Z_DATA_ERROR; - LEAVE - } - break; - case LENS: - NEEDBITS(32) - if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) - { - s->mode = B_BAD; - z->msg = (char*)"invalid stored block lengths"; - r = Z_DATA_ERROR; - LEAVE - } - s->sub.left = (uInt)b & 0xffff; - b = k = 0; /* dump bits */ - s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); - break; - case STORED: - if (n == 0) - LEAVE - NEEDOUT - t = s->sub.left; - if (t > n) t = n; - if (t > m) t = m; - memcpy(q, p, t); - p += t; n -= t; - q += t; m -= t; - if ((s->sub.left -= t) != 0) - break; - s->mode = s->last ? DRY : TYPE; - break; - case TABLE: - NEEDBITS(14) - s->sub.trees.table = t = (uInt)b & 0x3fff; -#ifndef PKZIP_BUG_WORKAROUND - if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) - { - s->mode = B_BAD; - z->msg = (char*)"too many length or distance symbols"; - r = Z_DATA_ERROR; - LEAVE - } -#endif - { - s->sub.trees.blens = WS(z)->working_blens; - } - DUMPBITS(14) - s->sub.trees.index = 0; - s->mode = BTREE; - case BTREE: - while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) - { - NEEDBITS(3) - s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; - DUMPBITS(3) - } - while (s->sub.trees.index < 19) - s->sub.trees.blens[border[s->sub.trees.index++]] = 0; - s->sub.trees.bb = 7; - t = zlib_fs_inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, - &s->sub.trees.tb, s->hufts, z); - if (t != Z_OK) - { - r = t; - if (r == Z_DATA_ERROR) - s->mode = B_BAD; - LEAVE - } - s->sub.trees.index = 0; - s->mode = DTREE; - case DTREE: - while (t = s->sub.trees.table, - s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) - { - inflate_huft *h; - uInt i, j, c; - - t = s->sub.trees.bb; - NEEDBITS(t) - h = s->sub.trees.tb + ((uInt)b & zlib_fs_inflate_mask[t]); - t = h->bits; - c = h->base; - if (c < 16) - { - DUMPBITS(t) - s->sub.trees.blens[s->sub.trees.index++] = c; - } - else /* c == 16..18 */ - { - i = c == 18 ? 7 : c - 14; - j = c == 18 ? 11 : 3; - NEEDBITS(t + i) - DUMPBITS(t) - j += (uInt)b & zlib_fs_inflate_mask[i]; - DUMPBITS(i) - i = s->sub.trees.index; - t = s->sub.trees.table; - if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || - (c == 16 && i < 1)) - { - s->mode = B_BAD; - z->msg = (char*)"invalid bit length repeat"; - r = Z_DATA_ERROR; - LEAVE - } - c = c == 16 ? s->sub.trees.blens[i - 1] : 0; - do { - s->sub.trees.blens[i++] = c; - } while (--j); - s->sub.trees.index = i; - } - } - s->sub.trees.tb = Z_NULL; - { - uInt bl, bd; - inflate_huft *tl, *td; - inflate_codes_statef *c; - - bl = 9; /* must be <= 9 for lookahead assumptions */ - bd = 6; /* must be <= 9 for lookahead assumptions */ - t = s->sub.trees.table; - t = zlib_fs_inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), - s->sub.trees.blens, &bl, &bd, &tl, &td, - s->hufts, z); - if (t != Z_OK) - { - if (t == (uInt)Z_DATA_ERROR) - s->mode = B_BAD; - r = t; - LEAVE - } - if ((c = zlib_fs_inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - s->sub.decode.codes = c; - } - s->mode = CODES; - case CODES: - UPDATE - if ((r = zlib_fs_inflate_codes(s, z, r)) != Z_STREAM_END) - return zlib_fs_inflate_flush(s, z, r); - r = Z_OK; - zlib_fs_inflate_codes_free(s->sub.decode.codes, z); - LOAD - if (!s->last) - { - s->mode = TYPE; - break; - } - s->mode = DRY; - case DRY: - FLUSH - if (s->read != s->write) - LEAVE - s->mode = B_DONE; - case B_DONE: - r = Z_STREAM_END; - LEAVE - case B_BAD: - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } -} - - -int zlib_fs_inflate_blocks_free(s, z) -inflate_blocks_statef *s; -z_streamp z; -{ - zlib_fs_inflate_blocks_reset(s, z, Z_NULL); - return Z_OK; -} - - -void zlib_fs_inflate_set_dictionary(s, d, n) -inflate_blocks_statef *s; -const Bytef *d; -uInt n; -{ - memcpy(s->window, d, n); - s->read = s->write = s->window + n; -} - - -/* Returns true if inflate is currently at the end of a block generated - * by Z_SYNC_FLUSH or Z_FULL_FLUSH. - * IN assertion: s != Z_NULL - */ -int zlib_fs_inflate_blocks_sync_point(s) -inflate_blocks_statef *s; -{ - return s->mode == LENS; -} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/infblock.h linux.19pre5-ac1/fs/inflate_fs/infblock.h --- linux.19p5/fs/inflate_fs/infblock.h Thu Apr 4 13:18:15 2002 +++ linux.19pre5-ac1/fs/inflate_fs/infblock.h Thu Jan 1 01:00:00 1970 @@ -1,44 +0,0 @@ -/* infblock.h -- header to use infblock.c - * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -#ifndef _INFBLOCK_H -#define _INFBLOCK_H - -struct inflate_blocks_state; -typedef struct inflate_blocks_state FAR inflate_blocks_statef; - -extern inflate_blocks_statef * zlib_fs_inflate_blocks_new OF(( - z_streamp z, - check_func c, /* check function */ - uInt w)); /* window size */ - -extern int zlib_fs_inflate_blocks OF(( - inflate_blocks_statef *, - z_streamp , - int)); /* initial return code */ - -extern void zlib_fs_inflate_blocks_reset OF(( - inflate_blocks_statef *, - z_streamp , - uLongf *)); /* check value on output */ - -extern int zlib_fs_inflate_blocks_free OF(( - inflate_blocks_statef *, - z_streamp)); - -extern void zlib_fs_inflate_set_dictionary OF(( - inflate_blocks_statef *s, - const Bytef *d, /* dictionary */ - uInt n)); /* dictionary length */ - -extern int zlib_fs_inflate_blocks_sync_point OF(( - inflate_blocks_statef *s)); - -#endif /* _INFBLOCK_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/infcodes.c linux.19pre5-ac1/fs/inflate_fs/infcodes.c --- linux.19p5/fs/inflate_fs/infcodes.c Thu Apr 4 13:18:15 2002 +++ linux.19pre5-ac1/fs/inflate_fs/infcodes.c Thu Jan 1 01:00:00 1970 @@ -1,204 +0,0 @@ -/* infcodes.c -- process literals and length/distance pairs - * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" -#include "infblock.h" -#include "infcodes.h" -#include "infutil.h" -#include "inffast.h" - -/* simplify the use of the inflate_huft type with some defines */ -#define exop word.what.Exop -#define bits word.what.Bits - -inflate_codes_statef *zlib_fs_inflate_codes_new(bl, bd, tl, td, z) -uInt bl, bd; -inflate_huft *tl; -inflate_huft *td; /* need separate declaration for Borland C++ */ -z_streamp z; -{ - inflate_codes_statef *c; - - c = &WS(z)->working_state; - { - c->mode = START; - c->lbits = (Byte)bl; - c->dbits = (Byte)bd; - c->ltree = tl; - c->dtree = td; - } - return c; -} - - -int zlib_fs_inflate_codes(s, z, r) -inflate_blocks_statef *s; -z_streamp z; -int r; -{ - uInt j; /* temporary storage */ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - Bytef *f; /* pointer to copy strings from */ - inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ - - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD - - /* process input and output based on current state */ - while (1) switch (c->mode) - { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - case START: /* x: set up for LEN */ -#ifndef SLOW - if (m >= 258 && n >= 10) - { - UPDATE - r = zlib_fs_inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); - LOAD - if (r != Z_OK) - { - c->mode = r == Z_STREAM_END ? WASH : BADCODE; - break; - } - } -#endif /* !SLOW */ - c->sub.code.need = c->lbits; - c->sub.code.tree = c->ltree; - c->mode = LEN; - case LEN: /* i: get length/literal/eob next */ - j = c->sub.code.need; - NEEDBITS(j) - t = c->sub.code.tree + ((uInt)b & zlib_fs_inflate_mask[j]); - DUMPBITS(t->bits) - e = (uInt)(t->exop); - if (e == 0) /* literal */ - { - c->sub.lit = t->base; - c->mode = LIT; - break; - } - if (e & 16) /* length */ - { - c->sub.copy.get = e & 15; - c->len = t->base; - c->mode = LENEXT; - break; - } - if ((e & 64) == 0) /* next table */ - { - c->sub.code.need = e; - c->sub.code.tree = t + t->base; - break; - } - if (e & 32) /* end of block */ - { - c->mode = WASH; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = (char*)"invalid literal/length code"; - r = Z_DATA_ERROR; - LEAVE - case LENEXT: /* i: getting length extra (have base) */ - j = c->sub.copy.get; - NEEDBITS(j) - c->len += (uInt)b & zlib_fs_inflate_mask[j]; - DUMPBITS(j) - c->sub.code.need = c->dbits; - c->sub.code.tree = c->dtree; - c->mode = DIST; - case DIST: /* i: get distance next */ - j = c->sub.code.need; - NEEDBITS(j) - t = c->sub.code.tree + ((uInt)b & zlib_fs_inflate_mask[j]); - DUMPBITS(t->bits) - e = (uInt)(t->exop); - if (e & 16) /* distance */ - { - c->sub.copy.get = e & 15; - c->sub.copy.dist = t->base; - c->mode = DISTEXT; - break; - } - if ((e & 64) == 0) /* next table */ - { - c->sub.code.need = e; - c->sub.code.tree = t + t->base; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = (char*)"invalid distance code"; - r = Z_DATA_ERROR; - LEAVE - case DISTEXT: /* i: getting distance extra */ - j = c->sub.copy.get; - NEEDBITS(j) - c->sub.copy.dist += (uInt)b & zlib_fs_inflate_mask[j]; - DUMPBITS(j) - c->mode = COPY; - case COPY: /* o: copying bytes in window, waiting for space */ -#ifndef __TURBOC__ /* Turbo C bug for following expression */ - f = (uInt)(q - s->window) < c->sub.copy.dist ? - s->end - (c->sub.copy.dist - (q - s->window)) : - q - c->sub.copy.dist; -#else - f = q - c->sub.copy.dist; - if ((uInt)(q - s->window) < c->sub.copy.dist) - f = s->end - (c->sub.copy.dist - (uInt)(q - s->window)); -#endif - while (c->len) - { - NEEDOUT - OUTBYTE(*f++) - if (f == s->end) - f = s->window; - c->len--; - } - c->mode = START; - break; - case LIT: /* o: got literal, waiting for output space */ - NEEDOUT - OUTBYTE(c->sub.lit) - c->mode = START; - break; - case WASH: /* o: got eob, possibly more output */ - if (k > 7) /* return unused byte, if any */ - { - k -= 8; - n++; - p--; /* can always return one */ - } - FLUSH - if (s->read != s->write) - LEAVE - c->mode = END; - case END: - r = Z_STREAM_END; - LEAVE - case BADCODE: /* x: got error */ - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } -#ifdef NEED_DUMMY_RETURN - return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ -#endif -} - - -void zlib_fs_inflate_codes_free(c, z) -inflate_codes_statef *c; -z_streamp z; -{ -} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/infcodes.h linux.19pre5-ac1/fs/inflate_fs/infcodes.h --- linux.19p5/fs/inflate_fs/infcodes.h Thu Apr 4 13:18:15 2002 +++ linux.19pre5-ac1/fs/inflate_fs/infcodes.h Thu Jan 1 01:00:00 1970 @@ -1,33 +0,0 @@ -/* infcodes.h -- header to use infcodes.c - * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -#ifndef _INFCODES_H -#define _INFCODES_H - -#include "infblock.h" - -struct inflate_codes_state; -typedef struct inflate_codes_state FAR inflate_codes_statef; - -extern inflate_codes_statef *zlib_fs_inflate_codes_new OF(( - uInt, uInt, - inflate_huft *, inflate_huft *, - z_streamp )); - -extern int zlib_fs_inflate_codes OF(( - inflate_blocks_statef *, - z_streamp , - int)); - -extern void zlib_fs_inflate_codes_free OF(( - inflate_codes_statef *, - z_streamp )); - -#endif /* _INFCODES_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/inffast.c linux.19pre5-ac1/fs/inflate_fs/inffast.c --- linux.19p5/fs/inflate_fs/inffast.c Thu Apr 4 13:18:15 2002 +++ linux.19pre5-ac1/fs/inflate_fs/inffast.c Thu Jan 1 01:00:00 1970 @@ -1,161 +0,0 @@ -/* inffast.c -- process literals and length/distance pairs fast - * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" -#include "infblock.h" -#include "infcodes.h" -#include "infutil.h" -#include "inffast.h" - -struct inflate_codes_state; - -/* simplify the use of the inflate_huft type with some defines */ -#define exop word.what.Exop -#define bits word.what.Bits - -/* macros for bit input with no checking and for returning unused bytes */ -#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3;} - -/* Called with number of bytes left to write in window at least 258 - (the maximum string length) and number of input bytes available - at least ten. The ten bytes are six bytes for the longest length/ - distance pair plus four bytes for overloading the bit buffer. */ - -int zlib_fs_inflate_fast(bl, bd, tl, td, s, z) -uInt bl, bd; -inflate_huft *tl; -inflate_huft *td; /* need separate declaration for Borland C++ */ -inflate_blocks_statef *s; -z_streamp z; -{ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - uInt ml; /* mask for literal/length tree */ - uInt md; /* mask for distance tree */ - uInt c; /* bytes to copy */ - uInt d; /* distance back to copy from */ - Bytef *r; /* copy source pointer */ - - /* load input, output, bit values */ - LOAD - - /* initialize masks */ - ml = zlib_fs_inflate_mask[bl]; - md = zlib_fs_inflate_mask[bd]; - - /* do until not enough input or output space for fast loop */ - do { /* assume called with m >= 258 && n >= 10 */ - /* get literal/length code */ - GRABBITS(20) /* max bits for literal/length code */ - if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) - { - DUMPBITS(t->bits) - *q++ = (Byte)t->base; - m--; - continue; - } - do { - DUMPBITS(t->bits) - if (e & 16) - { - /* get extra bits for length */ - e &= 15; - c = t->base + ((uInt)b & zlib_fs_inflate_mask[e]); - DUMPBITS(e) - - /* decode distance base of block to copy */ - GRABBITS(15); /* max bits for distance code */ - e = (t = td + ((uInt)b & md))->exop; - do { - DUMPBITS(t->bits) - if (e & 16) - { - /* get extra bits to add to distance base */ - e &= 15; - GRABBITS(e) /* get extra bits (up to 13) */ - d = t->base + ((uInt)b & zlib_fs_inflate_mask[e]); - DUMPBITS(e) - - /* do the copy */ - m -= c; - if ((uInt)(q - s->window) >= d) /* offset before dest */ - { /* just copy */ - r = q - d; - *q++ = *r++; c--; /* minimum count is three, */ - *q++ = *r++; c--; /* so unroll loop a little */ - } - else /* else offset after destination */ - { - e = d - (uInt)(q - s->window); /* bytes from offset to end */ - r = s->end - e; /* pointer to offset */ - if (c > e) /* if source crosses, */ - { - c -= e; /* copy to end of window */ - do { - *q++ = *r++; - } while (--e); - r = s->window; /* copy rest from start of window */ - } - } - do { /* copy all or what's left */ - *q++ = *r++; - } while (--c); - break; - } - else if ((e & 64) == 0) - { - t += t->base; - e = (t += ((uInt)b & zlib_fs_inflate_mask[e]))->exop; - } - else - { - z->msg = (char*)"invalid distance code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while (1); - break; - } - if ((e & 64) == 0) - { - t += t->base; - if ((e = (t += ((uInt)b & zlib_fs_inflate_mask[e]))->exop) == 0) - { - DUMPBITS(t->bits) - *q++ = (Byte)t->base; - m--; - break; - } - } - else if (e & 32) - { - UNGRAB - UPDATE - return Z_STREAM_END; - } - else - { - z->msg = (char*)"invalid literal/length code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while (1); - } while (m >= 258 && n >= 10); - - /* not enough input or output--restore pointers and return */ - UNGRAB - UPDATE - return Z_OK; -} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/inffast.h linux.19pre5-ac1/fs/inflate_fs/inffast.h --- linux.19p5/fs/inflate_fs/inffast.h Thu Apr 4 13:18:15 2002 +++ linux.19pre5-ac1/fs/inflate_fs/inffast.h Thu Jan 1 01:00:00 1970 @@ -1,17 +0,0 @@ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -extern int zlib_fs_inflate_fast OF(( - uInt, - uInt, - inflate_huft *, - inflate_huft *, - inflate_blocks_statef *, - z_streamp )); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/inffixed.h linux.19pre5-ac1/fs/inflate_fs/inffixed.h --- linux.19p5/fs/inflate_fs/inffixed.h Thu Apr 4 13:18:15 2002 +++ linux.19pre5-ac1/fs/inflate_fs/inffixed.h Thu Jan 1 01:00:00 1970 @@ -1,151 +0,0 @@ -/* inffixed.h -- table for decoding fixed codes - * Generated automatically by the maketree.c program - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -local uInt fixed_bl = 9; -local uInt fixed_bd = 5; -local inflate_huft fixed_tl[] = { - {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, - {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, - {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, - {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224}, - {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144}, - {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208}, - {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176}, - {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240}, - {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, - {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200}, - {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168}, - {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232}, - {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152}, - {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216}, - {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184}, - {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248}, - {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, - {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196}, - {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164}, - {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228}, - {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148}, - {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212}, - {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180}, - {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244}, - {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, - {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204}, - {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172}, - {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236}, - {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156}, - {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220}, - {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188}, - {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252}, - {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, - {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194}, - {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162}, - {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226}, - {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146}, - {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210}, - {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178}, - {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242}, - {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, - {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202}, - {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170}, - {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234}, - {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154}, - {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218}, - {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186}, - {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250}, - {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, - {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198}, - {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166}, - {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230}, - {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150}, - {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214}, - {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182}, - {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246}, - {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, - {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206}, - {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174}, - {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238}, - {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158}, - {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222}, - {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190}, - {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254}, - {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, - {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193}, - {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161}, - {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225}, - {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145}, - {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209}, - {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177}, - {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241}, - {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, - {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201}, - {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169}, - {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233}, - {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153}, - {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217}, - {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185}, - {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249}, - {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, - {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197}, - {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165}, - {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229}, - {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149}, - {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213}, - {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181}, - {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245}, - {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, - {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205}, - {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173}, - {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237}, - {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157}, - {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221}, - {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189}, - {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253}, - {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, - {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195}, - {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163}, - {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227}, - {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147}, - {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211}, - {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179}, - {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243}, - {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, - {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203}, - {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171}, - {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235}, - {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155}, - {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219}, - {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187}, - {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251}, - {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, - {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199}, - {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167}, - {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231}, - {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151}, - {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215}, - {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183}, - {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247}, - {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, - {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207}, - {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175}, - {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239}, - {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159}, - {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223}, - {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191}, - {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255} - }; -local inflate_huft fixed_td[] = { - {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097}, - {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385}, - {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193}, - {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577}, - {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145}, - {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577}, - {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289}, - {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577} - }; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/inflate.c linux.19pre5-ac1/fs/inflate_fs/inflate.c --- linux.19p5/fs/inflate_fs/inflate.c Thu Apr 4 13:18:15 2002 +++ linux.19pre5-ac1/fs/inflate_fs/inflate.c Thu Jan 1 01:00:00 1970 @@ -1,293 +0,0 @@ -/* inflate.c -- zlib interface to inflate modules - * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include -#include "zutil.h" -#include "infblock.h" -#include "infutil.h" - -int ZEXPORT zlib_fs_inflate_workspacesize(void) -{ - return sizeof(struct inflate_workspace); -} - - -int ZEXPORT zlib_fs_inflateReset(z) -z_streamp z; -{ - if (z == Z_NULL || z->state == Z_NULL || z->workspace == Z_NULL) - return Z_STREAM_ERROR; - z->total_in = z->total_out = 0; - z->msg = Z_NULL; - z->state->mode = z->state->nowrap ? BLOCKS : METHOD; - zlib_fs_inflate_blocks_reset(z->state->blocks, z, Z_NULL); - return Z_OK; -} - - -int ZEXPORT zlib_fs_inflateEnd(z) -z_streamp z; -{ - if (z == Z_NULL || z->state == Z_NULL || z->workspace == Z_NULL) - return Z_STREAM_ERROR; - if (z->state->blocks != Z_NULL) - zlib_fs_inflate_blocks_free(z->state->blocks, z); - z->state = Z_NULL; - return Z_OK; -} - - -int ZEXPORT zlib_fs_inflateInit2_(z, w, version, stream_size) -z_streamp z; -int w; -const char *version; -int stream_size; -{ - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != sizeof(z_stream) || z->workspace == Z_NULL) - return Z_VERSION_ERROR; - - /* initialize state */ - if (z == Z_NULL) - return Z_STREAM_ERROR; - z->msg = Z_NULL; - z->state = &WS(z)->internal_state; - z->state->blocks = Z_NULL; - - /* handle undocumented nowrap option (no zlib header or check) */ - z->state->nowrap = 0; - if (w < 0) - { - w = - w; - z->state->nowrap = 1; - } - - /* set window size */ - if (w < 8 || w > 15) - { - zlib_fs_inflateEnd(z); - return Z_STREAM_ERROR; - } - z->state->wbits = (uInt)w; - - /* create inflate_blocks state */ - if ((z->state->blocks = - zlib_fs_inflate_blocks_new(z, z->state->nowrap ? Z_NULL : zlib_fs_adler32, (uInt)1 << w)) - == Z_NULL) - { - zlib_fs_inflateEnd(z); - return Z_MEM_ERROR; - } - - /* reset state */ - zlib_fs_inflateReset(z); - return Z_OK; -} - - -int ZEXPORT zlib_fs_inflateInit_(z, version, stream_size) -z_streamp z; -const char *version; -int stream_size; -{ - return zlib_fs_inflateInit2_(z, DEF_WBITS, version, stream_size); -} - -#undef NEEDBYTE -#undef NEXTBYTE -#define NEEDBYTE {if(z->avail_in==0)return r;r=f;} -#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) - -int ZEXPORT zlib_fs_inflate(z, f) -z_streamp z; -int f; -{ - int r; - uInt b; - - if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL) - return Z_STREAM_ERROR; - f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; - r = Z_BUF_ERROR; - while (1) switch (z->state->mode) - { - case METHOD: - NEEDBYTE - if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) - { - z->state->mode = I_BAD; - z->msg = (char*)"unknown compression method"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - if ((z->state->sub.method >> 4) + 8 > z->state->wbits) - { - z->state->mode = I_BAD; - z->msg = (char*)"invalid window size"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - z->state->mode = FLAG; - case FLAG: - NEEDBYTE - b = NEXTBYTE; - if (((z->state->sub.method << 8) + b) % 31) - { - z->state->mode = I_BAD; - z->msg = (char*)"incorrect header check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - if (!(b & PRESET_DICT)) - { - z->state->mode = BLOCKS; - break; - } - z->state->mode = DICT4; - case DICT4: - NEEDBYTE - z->state->sub.check.need = (uLong)NEXTBYTE << 24; - z->state->mode = DICT3; - case DICT3: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 16; - z->state->mode = DICT2; - case DICT2: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 8; - z->state->mode = DICT1; - case DICT1: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE; - z->adler = z->state->sub.check.need; - z->state->mode = DICT0; - return Z_NEED_DICT; - case DICT0: - z->state->mode = I_BAD; - z->msg = (char*)"need dictionary"; - z->state->sub.marker = 0; /* can try inflateSync */ - return Z_STREAM_ERROR; - case BLOCKS: - r = zlib_fs_inflate_blocks(z->state->blocks, z, r); - if (r == Z_DATA_ERROR) - { - z->state->mode = I_BAD; - z->state->sub.marker = 0; /* can try inflateSync */ - break; - } - if (r == Z_OK) - r = f; - if (r != Z_STREAM_END) - return r; - r = f; - zlib_fs_inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); - if (z->state->nowrap) - { - z->state->mode = I_DONE; - break; - } - z->state->mode = CHECK4; - case CHECK4: - NEEDBYTE - z->state->sub.check.need = (uLong)NEXTBYTE << 24; - z->state->mode = CHECK3; - case CHECK3: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 16; - z->state->mode = CHECK2; - case CHECK2: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 8; - z->state->mode = CHECK1; - case CHECK1: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE; - - if (z->state->sub.check.was != z->state->sub.check.need) - { - z->state->mode = I_BAD; - z->msg = (char*)"incorrect data check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - z->state->mode = I_DONE; - case I_DONE: - return Z_STREAM_END; - case I_BAD: - return Z_DATA_ERROR; - default: - return Z_STREAM_ERROR; - } -#ifdef NEED_DUMMY_RETURN - return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ -#endif -} - - -int ZEXPORT zlib_fs_inflateSync(z) -z_streamp z; -{ - uInt n; /* number of bytes to look at */ - Bytef *p; /* pointer to bytes */ - uInt m; /* number of marker bytes found in a row */ - uLong r, w; /* temporaries to save total_in and total_out */ - - /* set up */ - if (z == Z_NULL || z->state == Z_NULL) - return Z_STREAM_ERROR; - if (z->state->mode != I_BAD) - { - z->state->mode = I_BAD; - z->state->sub.marker = 0; - } - if ((n = z->avail_in) == 0) - return Z_BUF_ERROR; - p = z->next_in; - m = z->state->sub.marker; - - /* search */ - while (n && m < 4) - { - static const Byte mark[4] = {0, 0, 0xff, 0xff}; - if (*p == mark[m]) - m++; - else if (*p) - m = 0; - else - m = 4 - m; - p++, n--; - } - - /* restore */ - z->total_in += p - z->next_in; - z->next_in = p; - z->avail_in = n; - z->state->sub.marker = m; - - /* return no joy or set up to restart on a new block */ - if (m != 4) - return Z_DATA_ERROR; - r = z->total_in; w = z->total_out; - zlib_fs_inflateReset(z); - z->total_in = r; z->total_out = w; - z->state->mode = BLOCKS; - return Z_OK; -} - - -/* Returns true if inflate is currently at the end of a block generated - * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP - * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH - * but removes the length bytes of the resulting empty stored block. When - * decompressing, PPP checks that at the end of input packet, inflate is - * waiting for these length bytes. - */ -int ZEXPORT zlib_fs_inflateSyncPoint(z) -z_streamp z; -{ - if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL) - return Z_STREAM_ERROR; - return zlib_fs_inflate_blocks_sync_point(z->state->blocks); -} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/inflate_syms.c linux.19pre5-ac1/fs/inflate_fs/inflate_syms.c --- linux.19p5/fs/inflate_fs/inflate_syms.c Thu Apr 4 13:18:15 2002 +++ linux.19pre5-ac1/fs/inflate_fs/inflate_syms.c Thu Jan 1 01:00:00 1970 @@ -1,22 +0,0 @@ -/* - * linux/fs/zlib/inflate_syms.c - * - * Exported symbols for the inflate functionality. - * - */ - -#include -#include - -#include - -EXPORT_SYMBOL(zlib_fs_inflate_workspacesize); -EXPORT_SYMBOL(zlib_fs_inflate); -EXPORT_SYMBOL(zlib_fs_inflateInit_); -EXPORT_SYMBOL(zlib_fs_inflateInit2_); -EXPORT_SYMBOL(zlib_fs_inflateEnd); -EXPORT_SYMBOL(zlib_fs_inflateSync); -EXPORT_SYMBOL(zlib_fs_inflateReset); -EXPORT_SYMBOL(zlib_fs_adler32); -EXPORT_SYMBOL(zlib_fs_inflateSyncPoint); -MODULE_LICENSE("GPL"); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/inftrees.c linux.19pre5-ac1/fs/inflate_fs/inftrees.c --- linux.19p5/fs/inflate_fs/inftrees.c Thu Apr 4 13:18:15 2002 +++ linux.19pre5-ac1/fs/inflate_fs/inftrees.c Thu Jan 1 01:00:00 1970 @@ -1,391 +0,0 @@ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" -#include "infutil.h" - -static const char inflate_copyright[] = - " inflate 1.1.3 Copyright 1995-1998 Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ -struct internal_state; - -/* simplify the use of the inflate_huft type with some defines */ -#define exop word.what.Exop -#define bits word.what.Bits - - -local int huft_build OF(( - uIntf *, /* code lengths in bits */ - uInt, /* number of codes */ - uInt, /* number of "simple" codes */ - const uIntf *, /* list of base values for non-simple codes */ - const uIntf *, /* list of extra bits for non-simple codes */ - inflate_huft * FAR*,/* result: starting table */ - uIntf *, /* maximum lookup bits (returns actual) */ - inflate_huft *, /* space for trees */ - uInt *, /* hufts used in space */ - uIntf * )); /* space for values */ - -/* Tables for deflate from PKZIP's appnote.txt. */ -local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - /* see note #13 above about 258 */ -local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */ -local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577}; -local const uInt cpdext[30] = { /* Extra bits for distance codes */ - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13}; - -/* - Huffman code decoding is performed using a multi-level table lookup. - The fastest way to decode is to simply build a lookup table whose - size is determined by the longest code. However, the time it takes - to build this table can also be a factor if the data being decoded - is not very long. The most common codes are necessarily the - shortest codes, so those codes dominate the decoding time, and hence - the speed. The idea is you can have a shorter table that decodes the - shorter, more probable codes, and then point to subsidiary tables for - the longer codes. The time it costs to decode the longer codes is - then traded against the time it takes to make longer tables. - - This results of this trade are in the variables lbits and dbits - below. lbits is the number of bits the first level table for literal/ - length codes can decode in one step, and dbits is the same thing for - the distance codes. Subsequent tables are also less than or equal to - those sizes. These values may be adjusted either when all of the - codes are shorter than that, in which case the longest code length in - bits is used, or when the shortest code is *longer* than the requested - table size, in which case the length of the shortest code in bits is - used. - - There are two different values for the two tables, since they code a - different number of possibilities each. The literal/length table - codes 286 possible values, or in a flat code, a little over eight - bits. The distance table codes 30 possible values, or a little less - than five bits, flat. The optimum values for speed end up being - about one bit more than those, so lbits is 8+1 and dbits is 5+1. - The optimum values may differ though from machine to machine, and - possibly even between compilers. Your mileage may vary. - */ - - -/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ -#define BMAX 15 /* maximum bit length of any code */ - -local int huft_build(b, n, s, d, e, t, m, hp, hn, v) -uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ -uInt n; /* number of codes (assumed <= 288) */ -uInt s; /* number of simple-valued codes (0..s-1) */ -const uIntf *d; /* list of base values for non-simple codes */ -const uIntf *e; /* list of extra bits for non-simple codes */ -inflate_huft * FAR *t; /* result: starting table */ -uIntf *m; /* maximum lookup bits, returns actual */ -inflate_huft *hp; /* space for trees */ -uInt *hn; /* hufts used in space */ -uIntf *v; /* working area: values in order of bit length */ -/* Given a list of code lengths and a maximum table size, make a set of - tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR - if the given code set is incomplete (the tables are still built in this - case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of - lengths), or Z_MEM_ERROR if not enough memory. */ -{ - - uInt a; /* counter for codes of length k */ - uInt c[BMAX+1]; /* bit length count table */ - uInt f; /* i repeats in table every f entries */ - int g; /* maximum code length */ - int h; /* table level */ - register uInt i; /* counter, current code */ - register uInt j; /* counter */ - register int k; /* number of bits in current code */ - int l; /* bits per table (returned in m) */ - uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */ - register uIntf *p; /* pointer into c[], b[], or v[] */ - inflate_huft *q; /* points to current table */ - struct inflate_huft_s r; /* table entry for structure assignment */ - inflate_huft *u[BMAX]; /* table stack */ - register int w; /* bits before this table == (l * h) */ - uInt x[BMAX+1]; /* bit offsets, then code stack */ - uIntf *xp; /* pointer into x */ - int y; /* number of dummy codes added */ - uInt z; /* number of entries in current table */ - - - /* Generate counts for each bit length */ - p = c; -#define C0 *p++ = 0; -#define C2 C0 C0 C0 C0 -#define C4 C2 C2 C2 C2 - C4 /* clear c[]--assume BMAX+1 is 16 */ - p = b; i = n; - do { - c[*p++]++; /* assume all entries <= BMAX */ - } while (--i); - if (c[0] == n) /* null input--all zero length codes */ - { - *t = (inflate_huft *)Z_NULL; - *m = 0; - return Z_OK; - } - - - /* Find minimum and maximum length, bound *m by those */ - l = *m; - for (j = 1; j <= BMAX; j++) - if (c[j]) - break; - k = j; /* minimum code length */ - if ((uInt)l < j) - l = j; - for (i = BMAX; i; i--) - if (c[i]) - break; - g = i; /* maximum code length */ - if ((uInt)l > i) - l = i; - *m = l; - - - /* Adjust last length count to fill out codes, if needed */ - for (y = 1 << j; j < i; j++, y <<= 1) - if ((y -= c[j]) < 0) - return Z_DATA_ERROR; - if ((y -= c[i]) < 0) - return Z_DATA_ERROR; - c[i] += y; - - - /* Generate starting offsets into the value table for each length */ - x[1] = j = 0; - p = c + 1; xp = x + 2; - while (--i) { /* note that i == g from above */ - *xp++ = (j += *p++); - } - - - /* Make a table of values in order of bit lengths */ - p = b; i = 0; - do { - if ((j = *p++) != 0) - v[x[j]++] = i; - } while (++i < n); - n = x[g]; /* set n to length of v */ - - - /* Generate the Huffman codes and for each, make the table entries */ - x[0] = i = 0; /* first Huffman code is zero */ - p = v; /* grab values in bit order */ - h = -1; /* no tables yet--level -1 */ - w = -l; /* bits decoded == (l * h) */ - u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ - q = (inflate_huft *)Z_NULL; /* ditto */ - z = 0; /* ditto */ - - /* go through the bit lengths (k already is bits in shortest code) */ - for (; k <= g; k++) - { - a = c[k]; - while (a--) - { - /* here i is the Huffman code of length k bits for value *p */ - /* make tables up to required level */ - while (k > w + l) - { - h++; - w += l; /* previous table always l bits */ - - /* compute minimum size table less than or equal to l bits */ - z = g - w; - z = z > (uInt)l ? l : z; /* table size upper limit */ - if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ - { /* too few codes for k-w bit table */ - f -= a + 1; /* deduct codes from patterns left */ - xp = c + k; - if (j < z) - while (++j < z) /* try smaller tables up to z bits */ - { - if ((f <<= 1) <= *++xp) - break; /* enough codes to use up j bits */ - f -= *xp; /* else deduct codes from patterns */ - } - } - z = 1 << j; /* table entries for j-bit table */ - - /* allocate new table */ - if (*hn + z > MANY) /* (note: doesn't matter for fixed) */ - return Z_MEM_ERROR; /* not enough memory */ - u[h] = q = hp + *hn; - *hn += z; - - /* connect to last table, if there is one */ - if (h) - { - x[h] = i; /* save pattern for backing up */ - r.bits = (Byte)l; /* bits to dump before this table */ - r.exop = (Byte)j; /* bits in this table */ - j = i >> (w - l); - r.base = (uInt)(q - u[h-1] - j); /* offset to this table */ - u[h-1][j] = r; /* connect to last table */ - } - else - *t = q; /* first table is returned result */ - } - - /* set up table entry in r */ - r.bits = (Byte)(k - w); - if (p >= v + n) - r.exop = 128 + 64; /* out of values--invalid code */ - else if (*p < s) - { - r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ - r.base = *p++; /* simple code is just the value */ - } - else - { - r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ - r.base = d[*p++ - s]; - } - - /* fill code-like entries with r */ - f = 1 << (k - w); - for (j = i >> w; j < z; j += f) - q[j] = r; - - /* backwards increment the k-bit code i */ - for (j = 1 << (k - 1); i & j; j >>= 1) - i ^= j; - i ^= j; - - /* backup over finished tables */ - mask = (1 << w) - 1; /* needed on HP, cc -O bug */ - while ((i & mask) != x[h]) - { - h--; /* don't need to update q */ - w -= l; - mask = (1 << w) - 1; - } - } - } - - - /* Return Z_BUF_ERROR if we were given an incomplete table */ - return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; -} - - -int zlib_fs_inflate_trees_bits(c, bb, tb, hp, z) -uIntf *c; /* 19 code lengths */ -uIntf *bb; /* bits tree desired/actual depth */ -inflate_huft * FAR *tb; /* bits tree result */ -inflate_huft *hp; /* space for trees */ -z_streamp z; /* for messages */ -{ - int r; - uInt hn = 0; /* hufts used in space */ - uIntf *v; /* work area for huft_build */ - - v = WS(z)->tree_work_area_1; - r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, - tb, bb, hp, &hn, v); - if (r == Z_DATA_ERROR) - z->msg = (char*)"oversubscribed dynamic bit lengths tree"; - else if (r == Z_BUF_ERROR || *bb == 0) - { - z->msg = (char*)"incomplete dynamic bit lengths tree"; - r = Z_DATA_ERROR; - } - return r; -} - -int zlib_fs_inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z) -uInt nl; /* number of literal/length codes */ -uInt nd; /* number of distance codes */ -uIntf *c; /* that many (total) code lengths */ -uIntf *bl; /* literal desired/actual bit depth */ -uIntf *bd; /* distance desired/actual bit depth */ -inflate_huft * FAR *tl; /* literal/length tree result */ -inflate_huft * FAR *td; /* distance tree result */ -inflate_huft *hp; /* space for trees */ -z_streamp z; /* for messages */ -{ - int r; - uInt hn = 0; /* hufts used in space */ - uIntf *v; /* work area for huft_build */ - - /* allocate work area */ - v = WS(z)->tree_work_area_2; - - /* build literal/length tree */ - r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v); - if (r != Z_OK || *bl == 0) - { - if (r == Z_DATA_ERROR) - z->msg = (char*)"oversubscribed literal/length tree"; - else if (r != Z_MEM_ERROR) - { - z->msg = (char*)"incomplete literal/length tree"; - r = Z_DATA_ERROR; - } - return r; - } - - /* build distance tree */ - r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v); - if (r != Z_OK || (*bd == 0 && nl > 257)) - { - if (r == Z_DATA_ERROR) - z->msg = (char*)"oversubscribed distance tree"; - else if (r == Z_BUF_ERROR) { -#ifdef PKZIP_BUG_WORKAROUND - r = Z_OK; - } -#else - z->msg = (char*)"incomplete distance tree"; - r = Z_DATA_ERROR; - } - else if (r != Z_MEM_ERROR) - { - z->msg = (char*)"empty distance tree with lengths"; - r = Z_DATA_ERROR; - } - return r; -#endif - } - - /* done */ - return Z_OK; -} - - -/* build fixed tables only once--keep them here */ -#include "inffixed.h" - - -int zlib_fs_inflate_trees_fixed(bl, bd, tl, td, z) -uIntf *bl; /* literal desired/actual bit depth */ -uIntf *bd; /* distance desired/actual bit depth */ -inflate_huft * FAR *tl; /* literal/length tree result */ -inflate_huft * FAR *td; /* distance tree result */ -z_streamp z; /* for memory allocation */ -{ - *bl = fixed_bl; - *bd = fixed_bd; - *tl = fixed_tl; - *td = fixed_td; - return Z_OK; -} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/inftrees.h linux.19pre5-ac1/fs/inflate_fs/inftrees.h --- linux.19p5/fs/inflate_fs/inftrees.h Thu Apr 4 13:18:15 2002 +++ linux.19pre5-ac1/fs/inflate_fs/inftrees.h Thu Jan 1 01:00:00 1970 @@ -1,63 +0,0 @@ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Huffman code lookup table entry--this entry is four bytes for machines - that have 16-bit pointers (e.g. PC's in the small or medium model). */ - -#ifndef _INFTREES_H -#define _INFTREES_H - -typedef struct inflate_huft_s FAR inflate_huft; - -struct inflate_huft_s { - union { - struct { - Byte Exop; /* number of extra bits or operation */ - Byte Bits; /* number of bits in this code or subcode */ - } what; - uInt pad; /* pad structure to a power of 2 (4 bytes for */ - } word; /* 16-bit, 8 bytes for 32-bit int's) */ - uInt base; /* literal, length base, distance base, - or table offset */ -}; - -/* Maximum size of dynamic tree. The maximum found in a long but non- - exhaustive search was 1004 huft structures (850 for length/literals - and 154 for distances, the latter actually the result of an - exhaustive search). The actual maximum is not known, but the - value below is more than safe. */ -#define MANY 1440 - -extern int zlib_fs_inflate_trees_bits OF(( - uIntf *, /* 19 code lengths */ - uIntf *, /* bits tree desired/actual depth */ - inflate_huft * FAR *, /* bits tree result */ - inflate_huft *, /* space for trees */ - z_streamp)); /* for messages */ - -extern int zlib_fs_inflate_trees_dynamic OF(( - uInt, /* number of literal/length codes */ - uInt, /* number of distance codes */ - uIntf *, /* that many (total) code lengths */ - uIntf *, /* literal desired/actual bit depth */ - uIntf *, /* distance desired/actual bit depth */ - inflate_huft * FAR *, /* literal/length tree result */ - inflate_huft * FAR *, /* distance tree result */ - inflate_huft *, /* space for trees */ - z_streamp)); /* for messages */ - -extern int zlib_fs_inflate_trees_fixed OF(( - uIntf *, /* literal desired/actual bit depth */ - uIntf *, /* distance desired/actual bit depth */ - inflate_huft * FAR *, /* literal/length tree result */ - inflate_huft * FAR *, /* distance tree result */ - z_streamp)); /* for memory allocation */ - -#endif /* _INFTREES_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/infutil.c linux.19pre5-ac1/fs/inflate_fs/infutil.c --- linux.19p5/fs/inflate_fs/infutil.c Thu Apr 4 13:18:15 2002 +++ linux.19pre5-ac1/fs/inflate_fs/infutil.c Thu Jan 1 01:00:00 1970 @@ -1,87 +0,0 @@ -/* inflate_util.c -- data and routines common to blocks and codes - * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "infblock.h" -#include "inftrees.h" -#include "infcodes.h" -#include "infutil.h" - -struct inflate_codes_state; - -/* And'ing with mask[n] masks the lower n bits */ -uInt zlib_fs_inflate_mask[17] = { - 0x0000, - 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, - 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff -}; - - -/* copy as much as possible from the sliding window to the output area */ -int zlib_fs_inflate_flush(s, z, r) -inflate_blocks_statef *s; -z_streamp z; -int r; -{ - uInt n; - Bytef *p; - Bytef *q; - - /* local copies of source and destination pointers */ - p = z->next_out; - q = s->read; - - /* compute number of bytes to copy as far as end of window */ - n = (uInt)((q <= s->write ? s->write : s->end) - q); - if (n > z->avail_out) n = z->avail_out; - if (n && r == Z_BUF_ERROR) r = Z_OK; - - /* update counters */ - z->avail_out -= n; - z->total_out += n; - - /* update check information */ - if (s->checkfn != Z_NULL) - z->adler = s->check = (*s->checkfn)(s->check, q, n); - - /* copy as far as end of window */ - memcpy(p, q, n); - p += n; - q += n; - - /* see if more to copy at beginning of window */ - if (q == s->end) - { - /* wrap pointers */ - q = s->window; - if (s->write == s->end) - s->write = s->window; - - /* compute bytes to copy */ - n = (uInt)(s->write - q); - if (n > z->avail_out) n = z->avail_out; - if (n && r == Z_BUF_ERROR) r = Z_OK; - - /* update counters */ - z->avail_out -= n; - z->total_out += n; - - /* update check information */ - if (s->checkfn != Z_NULL) - z->adler = s->check = (*s->checkfn)(s->check, q, n); - - /* copy */ - memcpy(p, q, n); - p += n; - q += n; - } - - /* update pointers */ - z->next_out = p; - s->read = q; - - /* done */ - return r; -} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/infutil.h linux.19pre5-ac1/fs/inflate_fs/infutil.h --- linux.19p5/fs/inflate_fs/infutil.h Thu Apr 4 13:18:15 2002 +++ linux.19pre5-ac1/fs/inflate_fs/infutil.h Thu Jan 1 01:00:00 1970 @@ -1,197 +0,0 @@ -/* infutil.h -- types and macros common to blocks and codes - * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -#ifndef _INFUTIL_H -#define _INFUTIL_H - -#include "zconf.h" -#include "inftrees.h" -#include "infcodes.h" - -typedef enum { - TYPE, /* get type bits (3, including end bit) */ - LENS, /* get lengths for stored */ - STORED, /* processing stored block */ - TABLE, /* get table lengths */ - BTREE, /* get bit lengths tree for a dynamic block */ - DTREE, /* get length, distance trees for a dynamic block */ - CODES, /* processing fixed or dynamic block */ - DRY, /* output remaining window bytes */ - B_DONE, /* finished last block, done */ - B_BAD} /* got a data error--stuck here */ -inflate_block_mode; - -/* inflate blocks semi-private state */ -struct inflate_blocks_state { - - /* mode */ - inflate_block_mode mode; /* current inflate_block mode */ - - /* mode dependent information */ - union { - uInt left; /* if STORED, bytes left to copy */ - struct { - uInt table; /* table lengths (14 bits) */ - uInt index; /* index into blens (or border) */ - uIntf *blens; /* bit lengths of codes */ - uInt bb; /* bit length tree depth */ - inflate_huft *tb; /* bit length decoding tree */ - } trees; /* if DTREE, decoding info for trees */ - struct { - inflate_codes_statef - *codes; - } decode; /* if CODES, current state */ - } sub; /* submode */ - uInt last; /* true if this block is the last block */ - - /* mode independent information */ - uInt bitk; /* bits in bit buffer */ - uLong bitb; /* bit buffer */ - inflate_huft *hufts; /* single malloc for tree space */ - Bytef *window; /* sliding window */ - Bytef *end; /* one byte after sliding window */ - Bytef *read; /* window read pointer */ - Bytef *write; /* window write pointer */ - check_func checkfn; /* check function */ - uLong check; /* check on output */ - -}; - - -/* defines for inflate input/output */ -/* update pointers and return */ -#define UPDBITS {s->bitb=b;s->bitk=k;} -#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} -#define UPDOUT {s->write=q;} -#define UPDATE {UPDBITS UPDIN UPDOUT} -#define LEAVE {UPDATE return zlib_fs_inflate_flush(s,z,r);} -/* get bytes and bits */ -#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} -#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} -#define NEXTBYTE (n--,*p++) -#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} -/* output bytes */ -#define WAVAIL (uInt)(qread?s->read-q-1:s->end-q) -#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} -#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} -#define FLUSH {UPDOUT r=zlib_fs_inflate_flush(s,z,r); LOADOUT} -#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} -#define OUTBYTE(a) {*q++=(Byte)(a);m--;} -/* load local pointers */ -#define LOAD {LOADIN LOADOUT} - -/* masks for lower bits (size given to avoid silly warnings with Visual C++) */ -extern uInt zlib_fs_inflate_mask[17]; - -/* copy as much as possible from the sliding window to the output area */ -extern int zlib_fs_inflate_flush OF(( - inflate_blocks_statef *, - z_streamp , - int)); - -/* inflate private state */ -typedef enum { - METHOD, /* waiting for method byte */ - FLAG, /* waiting for flag byte */ - DICT4, /* four dictionary check bytes to go */ - DICT3, /* three dictionary check bytes to go */ - DICT2, /* two dictionary check bytes to go */ - DICT1, /* one dictionary check byte to go */ - DICT0, /* waiting for inflateSetDictionary */ - BLOCKS, /* decompressing blocks */ - CHECK4, /* four check bytes to go */ - CHECK3, /* three check bytes to go */ - CHECK2, /* two check bytes to go */ - CHECK1, /* one check byte to go */ - I_DONE, /* finished check, done */ - I_BAD} /* got an error--stay here */ -inflate_mode; - -struct internal_state { - - /* mode */ - inflate_mode mode; /* current inflate mode */ - - /* mode dependent information */ - union { - uInt method; /* if FLAGS, method byte */ - struct { - uLong was; /* computed check value */ - uLong need; /* stream check value */ - } check; /* if CHECK, check values to compare */ - uInt marker; /* if BAD, inflateSync's marker bytes count */ - } sub; /* submode */ - - /* mode independent information */ - int nowrap; /* flag for no wrapper */ - uInt wbits; /* log2(window size) (8..15, defaults to 15) */ - inflate_blocks_statef - *blocks; /* current inflate_blocks state */ - -}; - -/* inflate codes private state */ -typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - START, /* x: set up for LEN */ - LEN, /* i: get length/literal/eob next */ - LENEXT, /* i: getting length extra (have base) */ - DIST, /* i: get distance next */ - DISTEXT, /* i: getting distance extra */ - COPY, /* o: copying bytes in window, waiting for space */ - LIT, /* o: got literal, waiting for output space */ - WASH, /* o: got eob, possibly still output waiting */ - END, /* x: got eob and all data flushed */ - BADCODE} /* x: got error */ -inflate_codes_mode; - -struct inflate_codes_state { - - /* mode */ - inflate_codes_mode mode; /* current inflate_codes mode */ - - /* mode dependent information */ - uInt len; - union { - struct { - inflate_huft *tree; /* pointer into tree */ - uInt need; /* bits needed */ - } code; /* if LEN or DIST, where in tree */ - uInt lit; /* if LIT, literal */ - struct { - uInt get; /* bits to get for extra */ - uInt dist; /* distance back to copy from */ - } copy; /* if EXT or COPY, where and how much */ - } sub; /* submode */ - - /* mode independent information */ - Byte lbits; /* ltree bits decoded per branch */ - Byte dbits; /* dtree bits decoder per branch */ - inflate_huft *ltree; /* literal/length/eob tree */ - inflate_huft *dtree; /* distance tree */ - -}; - -/* memory allocation for inflation */ - -struct inflate_workspace { - inflate_codes_statef working_state; - struct inflate_blocks_state working_blocks_state; - struct internal_state internal_state; - unsigned int tree_work_area_1[19]; - unsigned int tree_work_area_2[288]; - unsigned working_blens[258 + 0x1f + 0x1f]; - inflate_huft working_hufts[MANY]; - unsigned char working_window[1 << MAX_WBITS]; -}; - -#define WS(z) ((struct inflate_workspace *)(z->workspace)) - -#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/zconf.h linux.19pre5-ac1/fs/inflate_fs/zconf.h --- linux.19p5/fs/inflate_fs/zconf.h Thu Apr 4 13:18:15 2002 +++ linux.19pre5-ac1/fs/inflate_fs/zconf.h Thu Jan 1 01:00:00 1970 @@ -1,90 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-1998 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef _ZCONF_H -#define _ZCONF_H - -#if defined(__GNUC__) || defined(__386__) || defined(i386) -# ifndef __32BIT__ -# define __32BIT__ -# endif -#endif - -#if defined(__STDC__) || defined(__cplusplus) -# ifndef STDC -# define STDC -# endif -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# define MAX_MEM_LEVEL 9 -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef FAR -# define FAR -#endif - -typedef unsigned char Byte; /* 8 bits */ -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -typedef Byte FAR Bytef; -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -typedef void FAR *voidpf; -typedef void *voidp; - -#include /* for off_t */ -#include /* for SEEK_* and off_t */ -#define z_off_t off_t - -#endif /* _ZCONF_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/zutil.h linux.19pre5-ac1/fs/inflate_fs/zutil.h --- linux.19p5/fs/inflate_fs/zutil.h Thu Apr 4 13:18:15 2002 +++ linux.19pre5-ac1/fs/inflate_fs/zutil.h Thu Jan 1 01:00:00 1970 @@ -1,70 +0,0 @@ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-1998 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id: zutil.h,v 1.1 2000/01/01 03:32:23 davem Exp $ */ - -#ifndef _Z_UTIL_H -#define _Z_UTIL_H - -#include -#include -#include -#include - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - - /* common constants */ - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - - /* target dependencies */ - - /* Common defaults */ - -#ifndef OS_CODE -# define OS_CODE 0x03 /* assume Unix */ -#endif - - /* functions */ - -typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf, - uInt len)); - -#endif /* _Z_UTIL_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inode.c linux.19pre5-ac1/fs/inode.c --- linux.19p5/fs/inode.c Thu Apr 4 13:18:06 2002 +++ linux.19pre5-ac1/fs/inode.c Fri Mar 15 22:06:57 2002 @@ -247,15 +247,15 @@ static inline void sync_one(struct inode *inode, int sync) { - if (inode->i_state & I_LOCK) { + while (inode->i_state & I_LOCK) { __iget(inode); spin_unlock(&inode_lock); __wait_on_inode(inode); iput(inode); spin_lock(&inode_lock); - } else { - __sync_one(inode, sync); } + + __sync_one(inode, sync); } static inline void sync_list(struct list_head *head) @@ -725,8 +725,7 @@ count = inodes_stat.nr_unused / priority; prune_icache(count); - kmem_cache_shrink(inode_cachep); - return 0; + return kmem_cache_shrink_nr(inode_cachep); } /* @@ -778,6 +777,7 @@ atomic_set(&inode->i_writecount, 0); inode->i_size = 0; inode->i_blocks = 0; + inode->i_bytes = 0; inode->i_generation = 0; memset(&inode->i_dquot, 0, sizeof(inode->i_dquot)); inode->i_pipe = NULL; @@ -1152,7 +1152,7 @@ __get_free_pages(GFP_ATOMIC, order); } while (inode_hashtable == NULL && --order >= 0); - printk("Inode-cache hash table entries: %d (order: %ld, %ld bytes)\n", + printk(KERN_INFO "Inode cache hash table entries: %d (order: %ld, %ld bytes)\n", nr_hash, order, (PAGE_SIZE << order)); if (!inode_hashtable) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/ioctl.c linux.19pre5-ac1/fs/ioctl.c --- linux.19p5/fs/ioctl.c Thu Apr 4 13:18:06 2002 +++ linux.19pre5-ac1/fs/ioctl.c Mon Jan 28 19:55:51 2002 @@ -101,6 +101,16 @@ filp->f_flags &= ~FASYNC; break; + case FIOQSIZE: + if (S_ISDIR(filp->f_dentry->d_inode->i_mode) || + S_ISREG(filp->f_dentry->d_inode->i_mode) || + S_ISLNK(filp->f_dentry->d_inode->i_mode)) { + loff_t res = inode_get_bytes(filp->f_dentry->d_inode); + error = copy_to_user((loff_t *)arg, &res, sizeof(res)) ? -EFAULT : 0; + } + else + error = -ENOTTY; + break; default: error = -ENOTTY; if (S_ISREG(filp->f_dentry->d_inode->i_mode)) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/isofs/compress.c linux.19pre5-ac1/fs/isofs/compress.c --- linux.19p5/fs/isofs/compress.c Thu Apr 4 13:18:07 2002 +++ linux.19pre5-ac1/fs/isofs/compress.c Sat Mar 9 20:41:06 2002 @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include @@ -209,7 +209,7 @@ stream.workspace = zisofs_zlib_workspace; down(&zisofs_zlib_semaphore); - zerr = zlib_fs_inflateInit(&stream); + zerr = zlib_inflateInit(&stream); if ( zerr != Z_OK ) { if ( err && zerr == Z_MEM_ERROR ) err = -ENOMEM; @@ -250,7 +250,7 @@ } } ao = stream.avail_out; ai = stream.avail_in; - zerr = zlib_fs_inflate(&stream, Z_SYNC_FLUSH); + zerr = zlib_inflate(&stream, Z_SYNC_FLUSH); left_out = stream.avail_out; if ( zerr == Z_BUF_ERROR && stream.avail_in == 0 ) continue; @@ -291,7 +291,7 @@ fpage++; } } - zlib_fs_inflateEnd(&stream); + zlib_inflateEnd(&stream); z_eio: up(&zisofs_zlib_semaphore); @@ -339,7 +339,7 @@ return 0; } - zisofs_zlib_workspace = vmalloc(zlib_fs_inflate_workspacesize()); + zisofs_zlib_workspace = vmalloc(zlib_inflate_workspacesize()); if ( !zisofs_zlib_workspace ) return -ENOMEM; init_MUTEX(&zisofs_zlib_semaphore); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jbd/journal.c linux.19pre5-ac1/fs/jbd/journal.c --- linux.19p5/fs/jbd/journal.c Thu Apr 4 13:18:16 2002 +++ linux.19pre5-ac1/fs/jbd/journal.c Wed Feb 27 18:32:03 2002 @@ -460,8 +460,7 @@ printk (KERN_NOTICE __FUNCTION__ ": ENOMEM at get_unused_buffer_head, " "trying again.\n"); - current->policy |= SCHED_YIELD; - schedule(); + yield(); } } while (!new_bh); /* keep subsequent assertions sane */ @@ -1541,8 +1540,7 @@ last_warning = jiffies; } - current->policy |= SCHED_YIELD; - schedule(); + yield(); } } @@ -1600,8 +1598,7 @@ last_warning = jiffies; } while (ret == 0) { - current->policy |= SCHED_YIELD; - schedule(); + yield(); ret = kmem_cache_alloc(journal_head_cache, GFP_NOFS); } } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jbd/revoke.c linux.19pre5-ac1/fs/jbd/revoke.c --- linux.19p5/fs/jbd/revoke.c Thu Apr 4 13:18:16 2002 +++ linux.19pre5-ac1/fs/jbd/revoke.c Wed Feb 27 18:32:03 2002 @@ -137,8 +137,7 @@ if (!journal_oom_retry) return -ENOMEM; jbd_debug(1, "ENOMEM in " __FUNCTION__ ", retrying.\n"); - current->policy |= SCHED_YIELD; - schedule(); + yield(); goto repeat; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jbd/transaction.c linux.19pre5-ac1/fs/jbd/transaction.c --- linux.19p5/fs/jbd/transaction.c Thu Apr 4 13:18:16 2002 +++ linux.19pre5-ac1/fs/jbd/transaction.c Wed Feb 27 18:32:03 2002 @@ -1379,8 +1379,7 @@ do { old_handle_count = transaction->t_handle_count; set_current_state(TASK_RUNNING); - current->policy |= SCHED_YIELD; - schedule(); + yield(); } while (old_handle_count != transaction->t_handle_count); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jffs2/Makefile linux.19pre5-ac1/fs/jffs2/Makefile --- linux.19p5/fs/jffs2/Makefile Thu Apr 4 13:18:14 2002 +++ linux.19pre5-ac1/fs/jffs2/Makefile Sat Mar 9 20:41:06 2002 @@ -11,7 +11,7 @@ COMPR_OBJS := compr.o compr_rubin.o compr_rtime.o pushpull.o \ - compr_zlib.o zlib.o + compr_zlib.o JFFS2_OBJS := crc32.o dir.o file.o ioctl.o nodelist.o malloc.o \ read.o nodemgmt.o readinode.o super.o write.o scan.o gc.o \ symlink.o build.o erase.o background.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jffs2/background.c linux.19pre5-ac1/fs/jffs2/background.c --- linux.19p5/fs/jffs2/background.c Thu Apr 4 13:18:14 2002 +++ linux.19pre5-ac1/fs/jffs2/background.c Wed Feb 27 18:32:03 2002 @@ -106,9 +106,6 @@ sprintf(current->comm, "jffs2_gcd_mtd%d", c->mtd->index); - /* FIXME in the 2.2 backport */ - current->nice = 10; - for (;;) { spin_lock_irq(¤t->sigmask_lock); siginitsetinv (¤t->blocked, sigmask(SIGHUP) | sigmask(SIGKILL) | sigmask(SIGSTOP) | sigmask(SIGCONT)); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jffs2/compr_zlib.c linux.19pre5-ac1/fs/jffs2/compr_zlib.c --- linux.19p5/fs/jffs2/compr_zlib.c Thu Apr 4 13:18:14 2002 +++ linux.19pre5-ac1/fs/jffs2/compr_zlib.c Sat Mar 9 20:41:06 2002 @@ -1,7 +1,7 @@ /* * JFFS2 -- Journalling Flash File System, Version 2. * - * Copyright (C) 2001 Red Hat, Inc. + * Copyright (C) 2001, 2002 Red Hat, Inc. * * Created by David Woodhouse * @@ -31,42 +31,22 @@ * provisions above, a recipient may use your version of this file * under either the RHEPL or the GPL. * - * $Id: compr_zlib.c,v 1.8 2001/09/20 15:28:31 dwmw2 Exp $ + * $Id: compr_zlib.c,v 1.15 2002/03/04 09:35:48 dwmw2 Exp $ * */ -#include "zlib.h" +#ifndef __KERNEL__ +#error "The userspace support got too messy and was removed. Update your mkfs.jffs2" +#endif -#ifdef __KERNEL__ +#include #include #include /* for min() */ #include #include +#include #include "nodelist.h" -static void *zalloc(void *opaque, unsigned nr, unsigned size) -{ - /* How much does it request? Should we use vmalloc? Or be dynamic? */ - return kmalloc(nr * size, GFP_KERNEL); -} - -static void zfree(void *opaque, void *addr) -{ - kfree(addr); -} -#else -#define min(x,y) ((x)<(y)?(x):(y)) -#ifndef D1 -#define D1(x) -#endif -#define KERN_DEBUG -#define KERN_NOTICE -#define KERN_WARNING -#define printk printf -#include -#include -#endif - /* Plan: call deflate() with avail_in == *sourcelen, avail_out = *dstlen - 12 and flush == Z_FINISH. If it doesn't manage to finish, call it again with @@ -76,8 +56,37 @@ */ #define STREAM_END_SPACE 12 +static DECLARE_MUTEX(deflate_sem); +static DECLARE_MUTEX(inflate_sem); +static void *deflate_workspace; +static void *inflate_workspace; + +int __init jffs2_zlib_init(void) +{ + deflate_workspace = vmalloc(zlib_deflate_workspacesize()); + if (!deflate_workspace) { + printk("Failed to allocate %d bytes for deflate workspace\n", zlib_deflate_workspacesize()); + return -ENOMEM; + } + D1(printk("Allocated %d bytes for deflate workspace\n", zlib_deflate_workspacesize())); + inflate_workspace = vmalloc(zlib_inflate_workspacesize()); + if (!inflate_workspace) { + printk("Failed to allocate %d bytes for inflate workspace\n", zlib_inflate_workspacesize()); + vfree(deflate_workspace); + return -ENOMEM; + } + D1(printk("Allocated %d bytes for inflate workspace\n", zlib_inflate_workspacesize())); + return 0; +} + +void __exit jffs2_zlib_exit(void) +{ + vfree(deflate_workspace); + vfree(inflate_workspace); +} + int zlib_compress(unsigned char *data_in, unsigned char *cpage_out, - __u32 *sourcelen, __u32 *dstlen) + uint32_t *sourcelen, uint32_t *dstlen) { z_stream strm; int ret; @@ -85,18 +94,15 @@ if (*dstlen <= STREAM_END_SPACE) return -1; -#ifdef __KERNEL__ - strm.zalloc = zalloc; - strm.zfree = zfree; -#else - strm.zalloc = (void *)0; - strm.zfree = (void *)0; -#endif + down(&deflate_sem); + strm.workspace = deflate_workspace; - if (Z_OK != deflateInit(&strm, 3)) { + if (Z_OK != zlib_deflateInit(&strm, 3)) { printk(KERN_WARNING "deflateInit failed\n"); + up(&deflate_sem); return -1; } + strm.next_in = data_in; strm.total_in = 0; @@ -108,52 +114,49 @@ strm.avail_in = min((unsigned)(*sourcelen-strm.total_in), strm.avail_out); D1(printk(KERN_DEBUG "calling deflate with avail_in %d, avail_out %d\n", strm.avail_in, strm.avail_out)); - ret = deflate(&strm, Z_PARTIAL_FLUSH); + ret = zlib_deflate(&strm, Z_PARTIAL_FLUSH); D1(printk(KERN_DEBUG "deflate returned with avail_in %d, avail_out %d, total_in %ld, total_out %ld\n", strm.avail_in, strm.avail_out, strm.total_in, strm.total_out)); if (ret != Z_OK) { D1(printk(KERN_DEBUG "deflate in loop returned %d\n", ret)); - deflateEnd(&strm); + zlib_deflateEnd(&strm); + up(&deflate_sem); return -1; } } strm.avail_out += STREAM_END_SPACE; strm.avail_in = 0; - ret = deflate(&strm, Z_FINISH); + ret = zlib_deflate(&strm, Z_FINISH); + zlib_deflateEnd(&strm); + up(&deflate_sem); if (ret != Z_STREAM_END) { D1(printk(KERN_DEBUG "final deflate returned %d\n", ret)); - deflateEnd(&strm); return -1; } - deflateEnd(&strm); - D1(printk(KERN_DEBUG "zlib compressed %ld bytes into %ld\n", strm.total_in, strm.total_out)); + D1(printk(KERN_DEBUG "zlib compressed %ld bytes into %ld\n", + strm.total_in, strm.total_out)); if (strm.total_out >= strm.total_in) return -1; - *dstlen = strm.total_out; *sourcelen = strm.total_in; return 0; } void zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, - __u32 srclen, __u32 destlen) + uint32_t srclen, uint32_t destlen) { z_stream strm; int ret; -#ifdef __KERNEL__ - strm.zalloc = zalloc; - strm.zfree = zfree; -#else - strm.zalloc = (void *)0; - strm.zfree = (void *)0; -#endif + down(&inflate_sem); + strm.workspace = inflate_workspace; - if (Z_OK != inflateInit(&strm)) { + if (Z_OK != zlib_inflateInit(&strm)) { printk(KERN_WARNING "inflateInit failed\n"); + up(&inflate_sem); return; } strm.next_in = data_in; @@ -164,10 +167,11 @@ strm.avail_out = destlen; strm.total_out = 0; - while((ret = inflate(&strm, Z_FINISH)) == Z_OK) + while((ret = zlib_inflate(&strm, Z_FINISH)) == Z_OK) ; if (ret != Z_STREAM_END) { printk(KERN_NOTICE "inflate returned %d\n", ret); } - inflateEnd(&strm); + zlib_inflateEnd(&strm); + up(&inflate_sem); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jffs2/nodelist.h linux.19pre5-ac1/fs/jffs2/nodelist.h --- linux.19p5/fs/jffs2/nodelist.h Thu Apr 4 13:21:14 2002 +++ linux.19pre5-ac1/fs/jffs2/nodelist.h Thu Apr 4 16:04:06 2002 @@ -32,6 +32,7 @@ * under either the RHEPL or the GPL. * * $Id: nodelist.h,v 1.46.2.1 2002/02/23 14:04:44 dwmw2 Exp $ + * + zlib_init calls from v1.65 * */ @@ -349,3 +350,7 @@ void jffs2_erase_pending_blocks(struct jffs2_sb_info *c); void jffs2_mark_erased_blocks(struct jffs2_sb_info *c); void jffs2_erase_pending_trigger(struct jffs2_sb_info *c); + +/* compr_zlib.c */ +int jffs2_zlib_init(void); +void jffs2_zlib_exit(void); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jffs2/super.c linux.19pre5-ac1/fs/jffs2/super.c --- linux.19p5/fs/jffs2/super.c Thu Apr 4 13:21:14 2002 +++ linux.19pre5-ac1/fs/jffs2/super.c Thu Apr 4 14:38:00 2002 @@ -31,7 +31,8 @@ * provisions above, a recipient may use your version of this file * under either the RHEPL or the GPL. * - * $Id: super.c,v 1.48.2.2 2002/03/12 15:36:43 dwmw2 Exp $ + * $Id: super.c,v 1.48.2.1 2002/02/23 14:13:34 dwmw2 Exp $ + * + zlib_init calls from v1.56 * */ @@ -361,6 +362,11 @@ } #endif + ret = jffs2_zlib_init(); + if (ret) { + printk(KERN_ERR "JFFS2 error: Failed to initialise zlib workspaces\n"); + return ret; + } ret = jffs2_create_slab_caches(); if (ret) { printk(KERN_ERR "JFFS2 error: Failed to initialise slab caches\n"); @@ -377,6 +383,7 @@ static void __exit exit_jffs2_fs(void) { jffs2_destroy_slab_caches(); + jffs2_zlib_exit(); unregister_filesystem(&jffs2_fs_type); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jffs2/zlib.c linux.19pre5-ac1/fs/jffs2/zlib.c --- linux.19p5/fs/jffs2/zlib.c Thu Apr 4 13:21:14 2002 +++ linux.19pre5-ac1/fs/jffs2/zlib.c Thu Jan 1 01:00:00 1970 @@ -1,5376 +0,0 @@ -/* - * This file is derived from various .h and .c files from the zlib-1.0.4 - * distribution by Jean-loup Gailly and Mark Adler, with some additions - * by Paul Mackerras to aid in implementing Deflate compression and - * decompression for PPP packets. See zlib.h for conditions of - * distribution and use. - * - * Changes that have been made include: - * - added Z_PACKET_FLUSH (see zlib.h for details) - * - added inflateIncomp and deflateOutputPending - * - allow strm->next_out to be NULL, meaning discard the output - * - * $Id: zlib.c,v 1.3 1997/12/23 10:47:42 paulus Exp $ - */ - -/* - * ==FILEVERSION 20020318== - * - * This marker is used by the Linux installation script to determine - * whether an up-to-date version of this file is already installed. - */ - -#define NO_DUMMY_DECL -#define NO_ZCFUNCS -#define MY_ZCALLOC - -#if defined(__FreeBSD__) && (defined(KERNEL) || defined(_KERNEL)) -#define inflate inflate_ppp /* FreeBSD already has an inflate :-( */ -#endif - - -/* +++ zutil.h */ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-1996 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* From: zutil.h,v 1.16 1996/07/24 13:41:13 me Exp $ */ - -#ifndef _Z_UTIL_H -#define _Z_UTIL_H - -#include "zlib.h" - -#if defined(KERNEL) || defined(_KERNEL) -/* Assume this is a *BSD or SVR4 kernel */ -#include -#include -#include -# define HAVE_MEMCPY -# define memcpy(d, s, n) bcopy((s), (d), (n)) -# define memset(d, v, n) bzero((d), (n)) -# define memcmp bcmp - -#else -#if defined(__KERNEL__) -/* Assume this is a Linux kernel */ -#include -#define HAVE_MEMCPY - -#else /* not kernel */ - -#if defined(MSDOS)||defined(VMS)||defined(CRAY)||defined(WIN32)||defined(RISCOS) -# include -# include -#else - extern int errno; -#endif -#ifdef STDC -# include -# include -#endif -#endif /* __KERNEL__ */ -#endif /* _KERNEL || KERNEL */ - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ -/* (size given to avoid silly warnings with Visual C++) */ - -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] - -#define ERR_RETURN(strm,err) \ - return (strm->msg = (char*)ERR_MSG(err), (err)) -/* To be used only when the state is known to be valid */ - - /* common constants */ - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - - /* target dependencies */ - -#ifdef MSDOS -# define OS_CODE 0x00 -# ifdef __TURBOC__ -# include -# else /* MSC or DJGPP */ -# include -# endif -#endif - -#ifdef OS2 -# define OS_CODE 0x06 -#endif - -#ifdef WIN32 /* Window 95 & Windows NT */ -# define OS_CODE 0x0b -#endif - -#if defined(VAXC) || defined(VMS) -# define OS_CODE 0x02 -# define FOPEN(name, mode) \ - fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") -#endif - -#ifdef AMIGA -# define OS_CODE 0x01 -#endif - -#if defined(ATARI) || defined(atarist) -# define OS_CODE 0x05 -#endif - -#ifdef MACOS -# define OS_CODE 0x07 -#endif - -#ifdef __50SERIES /* Prime/PRIMOS */ -# define OS_CODE 0x0F -#endif - -#ifdef TOPS20 -# define OS_CODE 0x0a -#endif - -#if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ -#endif - - /* Common defaults */ - -#ifndef OS_CODE -# define OS_CODE 0x03 /* assume Unix */ -#endif - -#ifndef FOPEN -# define FOPEN(name, mode) fopen((name), (mode)) -#endif - - /* functions */ - -#ifdef HAVE_STRERROR - extern char *strerror OF((int)); -# define zstrerror(errnum) strerror(errnum) -#else -# define zstrerror(errnum) "" -#endif - -#if defined(pyr) -# define NO_MEMCPY -#endif -#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(_MSC_VER) - /* Use our own functions for small and medium model with MSC <= 5.0. - * You may have to use the same strategy for Borland C (untested). - */ -# define NO_MEMCPY -#endif -#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) -# define HAVE_MEMCPY -#endif -#ifdef HAVE_MEMCPY -# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ -# define zmemcpy _fmemcpy -# define zmemcmp _fmemcmp -# define zmemzero(dest, len) _fmemset(dest, 0, len) -# else -# define zmemcpy memcpy -# define zmemcmp memcmp -# define zmemzero(dest, len) memset(dest, 0, len) -# endif -#else - extern void zmemcpy OF((Bytef* dest, Bytef* source, uInt len)); - extern int zmemcmp OF((Bytef* s1, Bytef* s2, uInt len)); - extern void zmemzero OF((Bytef* dest, uInt len)); -#endif - -/* Diagnostic functions */ -#ifdef DEBUG_ZLIB -# include -# ifndef verbose -# define verbose 0 -# endif - extern void z_error OF((char *m)); -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) fprintf x -# define Tracev(x) {if (verbose) fprintf x ;} -# define Tracevv(x) {if (verbose>1) fprintf x ;} -# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} -# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - - -typedef uLong (*check_func) OF((uLong check, const Bytef *buf, uInt len)); - -voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); -void zcfree OF((voidpf opaque, voidpf ptr)); - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} - -#endif /* _Z_UTIL_H */ -/* --- zutil.h */ - -/* +++ deflate.h */ -/* deflate.h -- internal compression state - * Copyright (C) 1995-1996 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* From: deflate.h,v 1.10 1996/07/02 12:41:00 me Exp $ */ - -#ifndef _DEFLATE_H -#define _DEFLATE_H - -/* #include "zutil.h" */ - -/* =========================================================================== - * Internal compression state. - */ - -#define LENGTH_CODES 29 -/* number of length codes, not counting the special END_BLOCK code */ - -#define LITERALS 256 -/* number of literal bytes 0..255 */ - -#define L_CODES (LITERALS+1+LENGTH_CODES) -/* number of Literal or Length codes, including the END_BLOCK code */ - -#define D_CODES 30 -/* number of distance codes */ - -#define BL_CODES 19 -/* number of codes used to transfer the bit lengths */ - -#define HEAP_SIZE (2*L_CODES+1) -/* maximum heap size */ - -#define MAX_BITS 15 -/* All codes must not exceed MAX_BITS bits */ - -#define INIT_STATE 42 -#define BUSY_STATE 113 -#define FINISH_STATE 666 -/* Stream status */ - - -/* Data structure describing a single value and its code string. */ -typedef struct ct_data_s { - union { - ush freq; /* frequency count */ - ush code; /* bit string */ - } fc; - union { - ush dad; /* father node in Huffman tree */ - ush len; /* length of bit string */ - } dl; -} FAR ct_data; - -#define Freq fc.freq -#define Code fc.code -#define Dad dl.dad -#define Len dl.len - -typedef struct static_tree_desc_s static_tree_desc; - -typedef struct tree_desc_s { - ct_data *dyn_tree; /* the dynamic tree */ - int max_code; /* largest code with non zero frequency */ - static_tree_desc *stat_desc; /* the corresponding static tree */ -} FAR tree_desc; - -typedef ush Pos; -typedef Pos FAR Posf; -typedef unsigned IPos; - -/* A Pos is an index in the character window. We use short instead of int to - * save space in the various tables. IPos is used only for parameter passing. - */ - -typedef struct deflate_state { - z_streamp strm; /* pointer back to this zlib stream */ - int status; /* as the name implies */ - Bytef *pending_buf; /* output still pending */ - ulg pending_buf_size; /* size of pending_buf */ - Bytef *pending_out; /* next pending byte to output to the stream */ - int pending; /* nb of bytes in the pending buffer */ - int noheader; /* suppress zlib header and adler32 */ - Byte data_type; /* UNKNOWN, BINARY or ASCII */ - Byte method; /* STORED (for zip only) or DEFLATED */ - int last_flush; /* value of flush param for previous deflate call */ - - /* used by deflate.c: */ - - uInt w_size; /* LZ77 window size (32K by default) */ - uInt w_bits; /* log2(w_size) (8..16) */ - uInt w_mask; /* w_size - 1 */ - - Bytef *window; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. Also, it limits - * the window size to 64K, which is quite useful on MSDOS. - * To do: use the user input buffer as sliding window. - */ - - ulg window_size; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - Posf *prev; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - Posf *head; /* Heads of the hash chains or NIL. */ - - uInt ins_h; /* hash index of string to be inserted */ - uInt hash_size; /* number of elements in hash table */ - uInt hash_bits; /* log2(hash_size) */ - uInt hash_mask; /* hash_size-1 */ - - uInt hash_shift; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - long block_start; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - uInt match_length; /* length of best match */ - IPos prev_match; /* previous match */ - int match_available; /* set if previous match exists */ - uInt strstart; /* start of string to insert */ - uInt match_start; /* start of matching string */ - uInt lookahead; /* number of valid bytes ahead in window */ - - uInt prev_length; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - uInt max_chain_length; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - uInt max_lazy_match; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ -# define max_insert_length max_lazy_match - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - int level; /* compression level (1..9) */ - int strategy; /* favor or force Huffman coding*/ - - uInt good_match; - /* Use a faster search when the previous match is longer than this */ - - int nice_match; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - /* Didn't use ct_data typedef below to supress compiler warning */ - struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - struct tree_desc_s l_desc; /* desc. for literal tree */ - struct tree_desc_s d_desc; /* desc. for distance tree */ - struct tree_desc_s bl_desc; /* desc. for bit length tree */ - - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - int heap_len; /* number of elements in the heap */ - int heap_max; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - uch depth[2*L_CODES+1]; - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - uchf *l_buf; /* buffer for literals or lengths */ - - uInt lit_bufsize; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - uInt last_lit; /* running index in l_buf */ - - ushf *d_buf; - /* Buffer for distances. To simplify the code, d_buf and l_buf have - * the same number of elements. To use different lengths, an extra flag - * array would be necessary. - */ - - ulg opt_len; /* bit length of current block with optimal trees */ - ulg static_len; /* bit length of current block with static trees */ - ulg compressed_len; /* total bit length of compressed file */ - uInt matches; /* number of string matches in current block */ - int last_eob_len; /* bit length of EOB code for last block */ - -#ifdef DEBUG_ZLIB - ulg bits_sent; /* bit length of the compressed data */ -#endif - - ush bi_buf; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - int bi_valid; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - -} FAR deflate_state; - -/* Output a byte on the stream. - * IN assertion: there is enough room in pending_buf. - */ -#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} - - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) -/* In order to simplify the code, particularly on 16 bit machines, match - * distances are limited to MAX_DIST instead of WSIZE. - */ - - /* in trees.c */ -void _tr_init OF((deflate_state *s)); -int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); -ulg _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, - int eof)); -void _tr_align OF((deflate_state *s)); -void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, - int eof)); -void _tr_stored_type_only OF((deflate_state *)); - -#endif -/* --- deflate.h */ - -/* +++ deflate.c */ -/* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-1996 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process depends on being able to identify portions - * of the input text which are identical to earlier input (within a - * sliding window trailing behind the input currently being processed). - * - * The most straightforward technique turns out to be the fastest for - * most input files: try all possible matches and select the longest. - * The key feature of this algorithm is that insertions into the string - * dictionary are very simple and thus fast, and deletions are avoided - * completely. Insertions are performed at each input character, whereas - * string matches are performed only when the previous match ends. So it - * is preferable to spend more time in matches to allow very fast string - * insertions and avoid deletions. The matching algorithm for small - * strings is inspired from that of Rabin & Karp. A brute force approach - * is used to find longer strings when a small match has been found. - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze - * (by Leonid Broukhis). - * A previous version of this file used a more sophisticated algorithm - * (by Fiala and Greene) which is guaranteed to run in linear amortized - * time, but has a larger average cost, uses more memory and is patented. - * However the F&G algorithm may be faster for some highly redundant - * files if the parameter max_chain_length (described below) is too large. - * - * ACKNOWLEDGEMENTS - * - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and - * I found it in 'freeze' written by Leonid Broukhis. - * Thanks to many people for bug reports and testing. - * - * REFERENCES - * - * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". - * Available in ftp://ds.internic.net/rfc/rfc1951.txt - * - * A description of the Rabin and Karp algorithm is given in the book - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. - * - * Fiala,E.R., and Greene,D.H. - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 - * - */ - -/* From: deflate.c,v 1.15 1996/07/24 13:40:58 me Exp $ */ - -/* #include "deflate.h" */ - -char deflate_copyright[] = " deflate 1.0.4 Copyright 1995-1996 Jean-loup Gailly "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* =========================================================================== - * Function prototypes. - */ -typedef enum { - need_more, /* block not completed, need more input or more output */ - block_done, /* block flush performed */ - finish_started, /* finish started, need only more output at next deflate */ - finish_done /* finish done, accept no more input or output */ -} block_state; - -typedef block_state (*compress_func) OF((deflate_state *s, int flush)); -/* Compression function. Returns the block state after the call. */ - -local void fill_window OF((deflate_state *s)); -local block_state deflate_stored OF((deflate_state *s, int flush)); -local block_state deflate_fast OF((deflate_state *s, int flush)); -local block_state deflate_slow OF((deflate_state *s, int flush)); -local void lm_init OF((deflate_state *s)); -local void putShortMSB OF((deflate_state *s, uInt b)); -local void flush_pending OF((z_streamp strm)); -local int read_buf OF((z_streamp strm, charf *buf, unsigned size)); -#ifdef ASMV - void match_init OF((void)); /* asm code initialization */ - uInt longest_match OF((deflate_state *s, IPos cur_match)); -#else -local uInt longest_match OF((deflate_state *s, IPos cur_match)); -#endif - -#ifdef DEBUG_ZLIB -local void check_match OF((deflate_state *s, IPos start, IPos match, - int length)); -#endif - -/* =========================================================================== - * Local data - */ - -#define NIL 0 -/* Tail of hash chains */ - -#ifndef TOO_FAR -# define TOO_FAR 4096 -#endif -/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -typedef struct config_s { - ush good_length; /* reduce lazy search above this match length */ - ush max_lazy; /* do not perform lazy search above this match length */ - ush nice_length; /* quit search above this match length */ - ush max_chain; - compress_func func; -} config; - -local config configuration_table[10] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */ -/* 2 */ {4, 5, 16, 8, deflate_fast}, -/* 3 */ {4, 6, 32, 32, deflate_fast}, - -/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ -/* 5 */ {8, 16, 32, 32, deflate_slow}, -/* 6 */ {8, 16, 128, 128, deflate_slow}, -/* 7 */ {8, 32, 128, 256, deflate_slow}, -/* 8 */ {32, 128, 258, 1024, deflate_slow}, -/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */ - -/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 - * For deflate_fast() (levels <= 3) good is ignored and lazy has a different - * meaning. - */ - -#define EQUAL 0 -/* result of memcmp for equal strings */ - -#ifndef NO_DUMMY_DECL -struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ -#endif - -/* =========================================================================== - * Update a hash value with the given input byte - * IN assertion: all calls to to UPDATE_HASH are made with consecutive - * input characters, so that a running hash key can be computed from the - * previous key instead of complete recalculation each time. - */ -#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) - - -/* =========================================================================== - * Insert string str in the dictionary and set match_head to the previous head - * of the hash chain (the most recent string with same hash key). Return - * the previous length of the hash chain. - * IN assertion: all calls to to INSERT_STRING are made with consecutive - * input characters and the first MIN_MATCH bytes of str are valid - * (except for the last MIN_MATCH-1 bytes of the input file). - */ -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) - -/* =========================================================================== - * Initialize the hash table (avoiding 64K overflow for 16 bit systems). - * prev[] will be initialized on the fly. - */ -#define CLEAR_HASH(s) \ - s->head[s->hash_size-1] = NIL; \ - zmemzero((charf *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); - -/* ========================================================================= */ -int deflateInit_(strm, level, version, stream_size) - z_streamp strm; - int level; - const char *version; - int stream_size; -{ - return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY, version, stream_size); - /* To do: ignore strm->next_in if we use it as window */ -} - -/* ========================================================================= */ -int deflateInit2_(strm, level, method, windowBits, memLevel, strategy, - version, stream_size) - z_streamp strm; - int level; - int method; - int windowBits; - int memLevel; - int strategy; - const char *version; - int stream_size; -{ - deflate_state *s; - int noheader = 0; - static char* my_version = ZLIB_VERSION; - - ushf *overlay; - /* We overlay pending_buf and d_buf+l_buf. This works since the average - * output size for (length,distance) codes is <= 24 bits. - */ - - if (version == Z_NULL || version[0] != my_version[0] || - stream_size != sizeof(z_stream)) { - return Z_VERSION_ERROR; - } - if (strm == Z_NULL) return Z_STREAM_ERROR; - - strm->msg = Z_NULL; -#ifndef NO_ZCFUNCS - if (strm->zalloc == Z_NULL) { - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; - } - if (strm->zfree == Z_NULL) strm->zfree = zcfree; -#endif - - if (level == Z_DEFAULT_COMPRESSION) level = 6; - - if (windowBits < 0) { /* undocumented feature: suppress zlib header */ - noheader = 1; - windowBits = -windowBits; - } - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || - windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_HUFFMAN_ONLY) { - return Z_STREAM_ERROR; - } - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); - if (s == Z_NULL) return Z_MEM_ERROR; - strm->state = (struct internal_state FAR *)s; - s->strm = strm; - - s->noheader = noheader; - s->w_bits = windowBits; - s->w_size = 1 << s->w_bits; - s->w_mask = s->w_size - 1; - - s->hash_bits = memLevel + 7; - s->hash_size = 1 << s->hash_bits; - s->hash_mask = s->hash_size - 1; - s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); - - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); - - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); - s->pending_buf = (uchf *) overlay; - s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); - - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || - s->pending_buf == Z_NULL) { - strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); - deflateEnd (strm); - return Z_MEM_ERROR; - } - s->d_buf = overlay + s->lit_bufsize/sizeof(ush); - s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; - - s->level = level; - s->strategy = strategy; - s->method = (Byte)method; - - return deflateReset(strm); -} - -/* ========================================================================= */ -int deflateSetDictionary (strm, dictionary, dictLength) - z_streamp strm; - const Bytef *dictionary; - uInt dictLength; -{ - deflate_state *s; - uInt length = dictLength; - uInt n; - IPos hash_head = 0; - - if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) - return Z_STREAM_ERROR; - - s = (deflate_state *) strm->state; - if (s->status != INIT_STATE) return Z_STREAM_ERROR; - - strm->adler = adler32(strm->adler, dictionary, dictLength); - - if (length < MIN_MATCH) return Z_OK; - if (length > MAX_DIST(s)) { - length = MAX_DIST(s); -#ifndef USE_DICT_HEAD - dictionary += dictLength - length; /* use the tail of the dictionary */ -#endif - } - zmemcpy((charf *)s->window, dictionary, length); - s->strstart = length; - s->block_start = (long)length; - - /* Insert all strings in the hash table (except for the last two bytes). - * s->lookahead stays null, so s->ins_h will be recomputed at the next - * call of fill_window. - */ - s->ins_h = s->window[0]; - UPDATE_HASH(s, s->ins_h, s->window[1]); - for (n = 0; n <= length - MIN_MATCH; n++) { - INSERT_STRING(s, n, hash_head); - } - if (hash_head) hash_head = 0; /* to make compiler happy */ - return Z_OK; -} - -/* ========================================================================= */ -int deflateReset (strm) - z_streamp strm; -{ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR; - - strm->total_in = strm->total_out = 0; - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ - strm->data_type = Z_UNKNOWN; - - s = (deflate_state *)strm->state; - s->pending = 0; - s->pending_out = s->pending_buf; - - if (s->noheader < 0) { - s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */ - } - s->status = s->noheader ? BUSY_STATE : INIT_STATE; - strm->adler = 1; - s->last_flush = Z_NO_FLUSH; - - _tr_init(s); - lm_init(s); - - return Z_OK; -} - -/* ========================================================================= */ -int deflateParams(strm, level, strategy) - z_streamp strm; - int level; - int strategy; -{ - deflate_state *s; - compress_func func; - int err = Z_OK; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = (deflate_state *) strm->state; - - if (level == Z_DEFAULT_COMPRESSION) { - level = 6; - } - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { - return Z_STREAM_ERROR; - } - func = configuration_table[s->level].func; - - if (func != configuration_table[level].func && strm->total_in != 0) { - /* Flush the last buffer: */ - err = deflate(strm, Z_PARTIAL_FLUSH); - } - if (s->level != level) { - s->level = level; - s->max_lazy_match = configuration_table[level].max_lazy; - s->good_match = configuration_table[level].good_length; - s->nice_match = configuration_table[level].nice_length; - s->max_chain_length = configuration_table[level].max_chain; - } - s->strategy = strategy; - return err; -} - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -local void putShortMSB (s, b) - deflate_state *s; - uInt b; -{ - put_byte(s, (Byte)(b >> 8)); - put_byte(s, (Byte)(b & 0xff)); -} - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output goes - * through this function so some applications may wish to modify it - * to avoid allocating a large strm->next_out buffer and copying into it. - * (See also read_buf()). - */ -local void flush_pending(strm) - z_streamp strm; -{ - deflate_state *s = (deflate_state *) strm->state; - unsigned len = s->pending; - - if (len > strm->avail_out) len = strm->avail_out; - if (len == 0) return; - - if (strm->next_out != Z_NULL) { - zmemcpy(strm->next_out, s->pending_out, len); - strm->next_out += len; - } - s->pending_out += len; - strm->total_out += len; - strm->avail_out -= len; - s->pending -= len; - if (s->pending == 0) { - s->pending_out = s->pending_buf; - } -} - -/* ========================================================================= */ -int deflate (strm, flush) - z_streamp strm; - int flush; -{ - int old_flush; /* value of flush param for previous deflate call */ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - flush > Z_FINISH || flush < 0) { - return Z_STREAM_ERROR; - } - s = (deflate_state *) strm->state; - - if ((strm->next_in == Z_NULL && strm->avail_in != 0) || - (s->status == FINISH_STATE && flush != Z_FINISH)) { - ERR_RETURN(strm, Z_STREAM_ERROR); - } - if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - - s->strm = strm; /* just in case */ - old_flush = s->last_flush; - s->last_flush = flush; - - /* Write the zlib header */ - if (s->status == INIT_STATE) { - - uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; - uInt level_flags = (s->level-1) >> 1; - - if (level_flags > 3) level_flags = 3; - header |= (level_flags << 6); - if (s->strstart != 0) header |= PRESET_DICT; - header += 31 - (header % 31); - - s->status = BUSY_STATE; - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s->strstart != 0) { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - strm->adler = 1L; - } - - /* Flush as much pending output as possible */ - if (s->pending != 0) { - flush_pending(strm); - if (strm->avail_out == 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s->last_flush = -1; - return Z_OK; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUFF_ERROR. - */ - } else if (strm->avail_in == 0 && flush <= old_flush && - flush != Z_FINISH) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* User must not provide more input after the first FINISH: */ - if (s->status == FINISH_STATE && strm->avail_in != 0) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* Start a new block or continue the current one. - */ - if (strm->avail_in != 0 || s->lookahead != 0 || - (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { - block_state bstate; - - bstate = (*(configuration_table[s->level].func))(s, flush); - - if (bstate == finish_started || bstate == finish_done) { - s->status = FINISH_STATE; - } - if (bstate == need_more || bstate == finish_started) { - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ - } - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate == block_done) { - if (flush == Z_PARTIAL_FLUSH) { - _tr_align(s); - } else if (flush == Z_PACKET_FLUSH) { - /* Output just the 3-bit `stored' block type value, - but not a zero length. */ - _tr_stored_type_only(s); - } else { /* FULL_FLUSH or SYNC_FLUSH */ - _tr_stored_block(s, (char*)0, 0L, 0); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush == Z_FULL_FLUSH) { - CLEAR_HASH(s); /* forget history */ - } - } - flush_pending(strm); - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK; - } - } - } - Assert(strm->avail_out > 0, "bug2"); - - if (flush != Z_FINISH) return Z_OK; - if (s->noheader) return Z_STREAM_END; - - /* Write the zlib trailer (adler32) */ - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - s->noheader = -1; /* write the trailer only once! */ - return s->pending != 0 ? Z_OK : Z_STREAM_END; -} - -/* ========================================================================= */ -int deflateEnd (strm) - z_streamp strm; -{ - int status; - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = (deflate_state *) strm->state; - - status = s->status; - if (status != INIT_STATE && status != BUSY_STATE && - status != FINISH_STATE) { - return Z_STREAM_ERROR; - } - - /* Deallocate in reverse order of allocations: */ - TRY_FREE(strm, s->pending_buf); - TRY_FREE(strm, s->head); - TRY_FREE(strm, s->prev); - TRY_FREE(strm, s->window); - - ZFREE(strm, s); - strm->state = Z_NULL; - - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -} - -/* ========================================================================= - * Copy the source state to the destination state. - */ -int deflateCopy (dest, source) - z_streamp dest; - z_streamp source; -{ - deflate_state *ds; - deflate_state *ss; - ushf *overlay; - - if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) - return Z_STREAM_ERROR; - ss = (deflate_state *) source->state; - - *dest = *source; - - ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); - if (ds == Z_NULL) return Z_MEM_ERROR; - dest->state = (struct internal_state FAR *) ds; - *ds = *ss; - ds->strm = dest; - - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); - ds->pending_buf = (uchf *) overlay; - - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || - ds->pending_buf == Z_NULL) { - deflateEnd (dest); - return Z_MEM_ERROR; - } - /* ??? following zmemcpy doesn't work for 16-bit MSDOS */ - zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); - zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); - zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); - - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); - ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); - ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; - - ds->l_desc.dyn_tree = ds->dyn_ltree; - ds->d_desc.dyn_tree = ds->dyn_dtree; - ds->bl_desc.dyn_tree = ds->bl_tree; - - return Z_OK; -} - -/* =========================================================================== - * Return the number of bytes of output which are immediately available - * for output from the decompressor. - */ -int deflateOutputPending (strm) - z_streamp strm; -{ - if (strm == Z_NULL || strm->state == Z_NULL) return 0; - - return ((deflate_state *)(strm->state))->pending; -} - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->next_in buffer and copying from it. - * (See also flush_pending()). - */ -local int read_buf(strm, buf, size) - z_streamp strm; - charf *buf; - unsigned size; -{ - unsigned len = strm->avail_in; - - if (len > size) len = size; - if (len == 0) return 0; - - strm->avail_in -= len; - - if (!((deflate_state *)(strm->state))->noheader) { - strm->adler = adler32(strm->adler, strm->next_in, len); - } - zmemcpy(buf, strm->next_in, len); - strm->next_in += len; - strm->total_in += len; - - return (int)len; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init (s) - deflate_state *s; -{ - s->window_size = (ulg)2L*s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; -#ifdef ASMV - match_init(); /* initialize the asm code */ -#endif -} - -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ -#ifndef ASMV -/* For 80x86 and 680x0, an optimized version will be provided in match.asm or - * match.S. The code will be functionally equivalent. - */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - unsigned chain_length = s->max_chain_length;/* max hash chain length */ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - int best_len = s->prev_length; /* best match length so far */ - int nice_match = s->nice_match; /* stop if match long enough */ - IPos limit = s->strstart > (IPos)MAX_DIST(s) ? - s->strstart - (IPos)MAX_DIST(s) : NIL; - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - Posf *prev = s->prev; - uInt wmask = s->w_mask; - -#ifdef UNALIGNED_OK - /* Compare two bytes at a time. Note: this is not always beneficial. - * Try with and without -DUNALIGNED_OK to check. - */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - register ush scan_start = *(ushf*)scan; - register ush scan_end = *(ushf*)(scan+best_len-1); -#else - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - register Byte scan_end1 = scan[best_len-1]; - register Byte scan_end = scan[best_len]; -#endif - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s->prev_length >= s->good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2: - */ -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) - /* This code assumes sizeof(unsigned short) == 2. Do not use - * UNALIGNED_OK if your compiler uses a different size. - */ - if (*(ushf*)(match+best_len-1) != scan_end || - *(ushf*)match != scan_start) continue; - - /* It is not necessary to compare scan[2] and match[2] since they are - * always equal when the other bytes match, given that the hash keys - * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at - * strstart+3, +5, ... up to strstart+257. We check for insufficient - * lookahead only every 4th comparison; the 128th check will be made - * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is - * necessary to put more guard bytes at the end of the window, or - * to check more often for insufficient lookahead. - */ - Assert(scan[2] == match[2], "scan[2]?"); - scan++, match++; - do { - } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - scan < strend); - /* The funny "do {}" generates better code on most compilers */ - - /* Here, scan <= window+strstart+257 */ - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - if (*scan == *match) scan++; - - len = (MAX_MATCH - 1) - (int)(strend-scan); - scan = strend - (MAX_MATCH-1); - -#else /* UNALIGNED_OK */ - - if (match[best_len] != scan_end || - match[best_len-1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match++; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - -#endif /* UNALIGNED_OK */ - - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= nice_match) break; -#ifdef UNALIGNED_OK - scan_end = *(ushf*)(scan+best_len-1); -#else - scan_end1 = scan[best_len-1]; - scan_end = scan[best_len]; -#endif - } - } while ((cur_match = prev[cur_match & wmask]) > limit - && --chain_length != 0); - - if ((uInt)best_len <= s->lookahead) return best_len; - return s->lookahead; -} -#endif /* ASMV */ - -#ifdef DEBUG_ZLIB -/* =========================================================================== - * Check that the match at match_start is indeed a match. - */ -local void check_match(s, start, match, length) - deflate_state *s; - IPos start, match; - int length; -{ - /* check that the match is indeed a match */ - if (zmemcmp((charf *)s->window + match, - (charf *)s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); - do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); - z_error("invalid match"); - } - if (z_verbose > 1) { - fprintf(stderr,"\\[%d,%d]", start-match, length); - do { putc(s->window[start++], stderr); } while (--length != 0); - } -} -#else -# define check_match(s, start, match, length) -#endif - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -local void fill_window(s) - deflate_state *s; -{ - register unsigned n, m; - register Posf *p; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; - - do { - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); - - /* Deal with !@#$% 64K limit: */ - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if strstart == 0 - * and lookahead == 1 (input done one byte at time) - */ - more--; - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - } else if (s->strstart >= wsize+MAX_DIST(s)) { - - zmemcpy((charf *)s->window, (charf *)s->window+wsize, - (unsigned)wsize); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - - /* Slide the hash table (could be avoided with 32 bit values - at the expense of memory usage). We slide even when level == 0 - to keep the hash table consistent if we switch back to level > 0 - later. (Using level 0 permanently is not an optimal usage of - zlib, so we don't care about this pathological case.) - */ - n = s->hash_size; - p = &s->head[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - } while (--n); - - n = wsize; - p = &s->prev[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); - more += wsize; - } - if (s->strm->avail_in == 0) return; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, (charf *)s->window + s->strstart + s->lookahead, - more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead >= MIN_MATCH) { - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); -} - -/* =========================================================================== - * Flush the current block, with given end-of-file flag. - * IN assertion: strstart is set to the end of the current match. - */ -#define FLUSH_BLOCK_ONLY(s, eof) { \ - _tr_flush_block(s, (s->block_start >= 0L ? \ - (charf *)&s->window[(unsigned)s->block_start] : \ - (charf *)Z_NULL), \ - (ulg)((long)s->strstart - s->block_start), \ - (eof)); \ - s->block_start = s->strstart; \ - flush_pending(s->strm); \ - Tracev((stderr,"[FLUSH]")); \ -} - -/* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, eof) { \ - FLUSH_BLOCK_ONLY(s, eof); \ - if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ -} - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * This function does not insert new strings in the dictionary since - * uncompressible data is probably not useful. This function is used - * only for the level=0 compression option. - * NOTE: this function should be optimized to avoid extra copying from - * window to pending_buf. - */ -local block_state deflate_stored(s, flush) - deflate_state *s; - int flush; -{ - /* Stored blocks are limited to 0xffff bytes, pending_buf is limited - * to pending_buf_size, and each stored block has a 5 byte header: - */ - ulg max_block_size = 0xffff; - ulg max_start; - - if (max_block_size > s->pending_buf_size - 5) { - max_block_size = s->pending_buf_size - 5; - } - - /* Copy as much as possible from input to output: */ - for (;;) { - /* Fill the window as much as possible: */ - if (s->lookahead <= 1) { - - Assert(s->strstart < s->w_size+MAX_DIST(s) || - s->block_start >= (long)s->w_size, "slide too late"); - - fill_window(s); - if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; - - if (s->lookahead == 0) break; /* flush the current block */ - } - Assert(s->block_start >= 0L, "block gone"); - - s->strstart += s->lookahead; - s->lookahead = 0; - - /* Emit a stored block if pending_buf will be full: */ - max_start = s->block_start + max_block_size; - if (s->strstart == 0 || (ulg)s->strstart >= max_start) { - /* strstart == 0 is possible when wraparound on 16-bit machine */ - s->lookahead = (uInt)(s->strstart - max_start); - s->strstart = (uInt)max_start; - FLUSH_BLOCK(s, 0); - } - /* Flush if we may have to slide, otherwise block_start may become - * negative and the data will be gone: - */ - if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { - FLUSH_BLOCK(s, 0); - } - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -local block_state deflate_fast(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head = NIL; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - if (s->strategy != Z_HUFFMAN_ONLY) { - s->match_length = longest_match (s, hash_head); - } - /* longest_match() sets match_start */ - } - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->match_start, s->match_length); - - bflush = _tr_tally(s, s->strstart - s->match_start, - s->match_length - MIN_MATCH); - - s->lookahead -= s->match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ - if (s->match_length <= s->max_insert_length && - s->lookahead >= MIN_MATCH) { - s->match_length--; /* string at strstart already in hash table */ - do { - s->strstart++; - INSERT_STRING(s, s->strstart, hash_head); - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s->match_length != 0); - s->strstart++; - } else { - s->strstart += s->match_length; - s->match_length = 0; - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - bflush = _tr_tally (s, 0, s->window[s->strstart]); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -local block_state deflate_slow(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head = NIL; /* head of hash chain */ - int bflush; /* set if current block must be flushed */ - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - */ - s->prev_length = s->match_length, s->prev_match = s->match_start; - s->match_length = MIN_MATCH-1; - - if (hash_head != NIL && s->prev_length < s->max_lazy_match && - s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - if (s->strategy != Z_HUFFMAN_ONLY) { - s->match_length = longest_match (s, hash_head); - } - /* longest_match() sets match_start */ - - if (s->match_length <= 5 && (s->strategy == Z_FILTERED || - (s->match_length == MIN_MATCH && - s->strstart - s->match_start > TOO_FAR))) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s->match_length = MIN_MATCH-1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - check_match(s, s->strstart-1, s->prev_match, s->prev_length); - - bflush = _tr_tally(s, s->strstart -1 - s->prev_match, - s->prev_length - MIN_MATCH); - - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s->lookahead -= s->prev_length-1; - s->prev_length -= 2; - do { - if (++s->strstart <= max_insert) { - INSERT_STRING(s, s->strstart, hash_head); - } - } while (--s->prev_length != 0); - s->match_available = 0; - s->match_length = MIN_MATCH-1; - s->strstart++; - - if (bflush) FLUSH_BLOCK(s, 0); - - } else if (s->match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - Tracevv((stderr,"%c", s->window[s->strstart-1])); - if (_tr_tally (s, 0, s->window[s->strstart-1])) { - FLUSH_BLOCK_ONLY(s, 0); - } - s->strstart++; - s->lookahead--; - if (s->strm->avail_out == 0) return need_more; - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s->match_available = 1; - s->strstart++; - s->lookahead--; - } - } - Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s->match_available) { - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally (s, 0, s->window[s->strstart-1]); - s->match_available = 0; - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} -/* --- deflate.c */ - -/* +++ trees.c */ -/* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-1996 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process uses several Huffman trees. The more - * common source values are represented by shorter bit sequences. - * - * Each code tree is stored in a compressed form which is itself - * a Huffman encoding of the lengths of all the code strings (in - * ascending order by source values). The actual code strings are - * reconstructed from the lengths in the inflate process, as described - * in the deflate specification. - * - * REFERENCES - * - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc - * - * Storer, James A. - * Data Compression: Methods and Theory, pp. 49-50. - * Computer Science Press, 1988. ISBN 0-7167-8156-5. - * - * Sedgewick, R. - * Algorithms, p290. - * Addison-Wesley, 1983. ISBN 0-201-06672-6. - */ - -/* From: trees.c,v 1.11 1996/07/24 13:41:06 me Exp $ */ - -/* #include "deflate.h" */ - -#ifdef DEBUG_ZLIB -# include -#endif - -/* =========================================================================== - * Constants - */ - -#define MAX_BL_BITS 7 -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -#define END_BLOCK 256 -/* end of block literal code */ - -#define REP_3_6 16 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -#define REPZ_3_10 17 -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -#define REPZ_11_138 18 -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -local int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; - -local int extra_dbits[D_CODES] /* extra bits for each distance code */ - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -local int extra_blbits[BL_CODES]/* extra bits for each bit length code */ - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -local uch bl_order[BL_CODES] - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -#define Buf_size (8 * 2*sizeof(char)) -/* Number of bits used within bi_buf. (bi_buf might be implemented on - * more than 16 bits on some systems.) - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -local ct_data static_ltree[L_CODES+2]; -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -local ct_data static_dtree[D_CODES]; -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -local uch dist_code[512]; -/* distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -local uch length_code[MAX_MATCH-MIN_MATCH+1]; -/* length code for each normalized match length (0 == MIN_MATCH) */ - -local int base_length[LENGTH_CODES]; -/* First normalized length for each code (0 = MIN_MATCH) */ - -local int base_dist[D_CODES]; -/* First normalized distance for each code (0 = distance of 1) */ - -struct static_tree_desc_s { - ct_data *static_tree; /* static tree or NULL */ - intf *extra_bits; /* extra bits for each code or NULL */ - int extra_base; /* base index for extra_bits */ - int elems; /* max number of elements in the tree */ - int max_length; /* max bit length for the codes */ -}; - -local static_tree_desc static_l_desc = -{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; - -local static_tree_desc static_d_desc = -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; - -local static_tree_desc static_bl_desc = -{(ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; - -/* =========================================================================== - * Local (static) routines in this file. - */ - -local void tr_static_init OF((void)); -local void init_block OF((deflate_state *s)); -local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); -local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); -local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); -local void build_tree OF((deflate_state *s, tree_desc *desc)); -local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local int build_bl_tree OF((deflate_state *s)); -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, - int blcodes)); -local void compress_block OF((deflate_state *s, ct_data *ltree, - ct_data *dtree)); -local void set_data_type OF((deflate_state *s)); -local unsigned bi_reverse OF((unsigned value, int length)); -local void bi_windup OF((deflate_state *s)); -local void bi_flush OF((deflate_state *s)); -local void copy_block OF((deflate_state *s, charf *buf, unsigned len, - int header)); - -#ifndef DEBUG_ZLIB -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) - /* Send a code of the given tree. c and tree must not have side effects */ - -#else /* DEBUG_ZLIB */ -# define send_code(s, c, tree) \ - { if (verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ - send_bits(s, tree[c].Code, tree[c].Len); } -#endif - -#define d_code(dist) \ - ((dist) < 256 ? dist_code[dist] : dist_code[256+((dist)>>7)]) -/* Mapping from a distance to a distance code. dist is the distance - 1 and - * must not have side effects. dist_code[256] and dist_code[257] are never - * used. - */ - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -#ifdef DEBUG_ZLIB -local void send_bits OF((deflate_state *s, int value, int length)); - -local void send_bits(s, value, length) - deflate_state *s; - int value; /* value to send */ - int length; /* number of bits */ -{ - Tracevv((stderr," l %2d v %4x ", length, value)); - Assert(length > 0 && length <= 15, "invalid length"); - s->bits_sent += (ulg)length; - - /* If not enough room in bi_buf, use (valid) bits from bi_buf and - * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) - * unused bits in value. - */ - if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (value << s->bi_valid); - put_short(s, s->bi_buf); - s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); - s->bi_valid += length - Buf_size; - } else { - s->bi_buf |= value << s->bi_valid; - s->bi_valid += length; - } -} -#else /* !DEBUG_ZLIB */ - -#define send_bits(s, value, length) \ -{ int len = length;\ - if (s->bi_valid > (int)Buf_size - len) {\ - int val = value;\ - s->bi_buf |= (val << s->bi_valid);\ - put_short(s, s->bi_buf);\ - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ - s->bi_valid += len - Buf_size;\ - } else {\ - s->bi_buf |= (value) << s->bi_valid;\ - s->bi_valid += len;\ - }\ -} -#endif /* DEBUG_ZLIB */ - - -#define MAX(a,b) (a >= b ? a : b) -/* the arguments must not have side effects */ - -/* =========================================================================== - * Initialize the various 'constant' tables. In a multi-threaded environment, - * this function may be called by two threads concurrently, but this is - * harmless since both invocations do exactly the same thing. - */ -local void tr_static_init() -{ - static int static_init_done = 0; - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - if (static_init_done) return; - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - base_length[code] = length; - for (n = 0; n < (1< dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { - dist_code[256 + dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse((unsigned)n, 5); - } - static_init_done = 1; -} - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -void _tr_init(s) - deflate_state *s; -{ - tr_static_init(); - - s->compressed_len = 0L; - - s->l_desc.dyn_tree = s->dyn_ltree; - s->l_desc.stat_desc = &static_l_desc; - - s->d_desc.dyn_tree = s->dyn_dtree; - s->d_desc.stat_desc = &static_d_desc; - - s->bl_desc.dyn_tree = s->bl_tree; - s->bl_desc.stat_desc = &static_bl_desc; - - s->bi_buf = 0; - s->bi_valid = 0; - s->last_eob_len = 8; /* enough lookahead for inflate */ -#ifdef DEBUG_ZLIB - s->bits_sent = 0L; -#endif - - /* Initialize the first block of the first file: */ - init_block(s); -} - -/* =========================================================================== - * Initialize a new block. - */ -local void init_block(s) - deflate_state *s; -{ - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->last_lit = s->matches = 0; -} - -#define SMALLEST 1 -/* Index within the heap array of least frequent node in the Huffman tree */ - - -/* =========================================================================== - * Remove the smallest element from the heap and recreate the heap with - * one less element. Updates heap and heap_len. - */ -#define pqremove(s, tree, top) \ -{\ - top = s->heap[SMALLEST]; \ - s->heap[SMALLEST] = s->heap[s->heap_len--]; \ - pqdownheap(s, tree, SMALLEST); \ -} - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -#define smaller(tree, n, m, depth) \ - (tree[n].Freq < tree[m].Freq || \ - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -local void pqdownheap(s, tree, k) - deflate_state *s; - ct_data *tree; /* the tree to restore */ - int k; /* node to move down */ -{ - int v = s->heap[k]; - int j = k << 1; /* left son of k */ - while (j <= s->heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s->heap_len && - smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s->heap[j], s->depth)) break; - - /* Exchange v with the smallest son */ - s->heap[k] = s->heap[j]; k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s->heap[k] = v; -} - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -local void gen_bitlen(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ - ct_data *tree = desc->dyn_tree; - int max_code = desc->max_code; - ct_data *stree = desc->stat_desc->static_tree; - intf *extra = desc->stat_desc->extra_bits; - int base = desc->stat_desc->extra_base; - int max_length = desc->stat_desc->max_length; - int h; /* heap index */ - int n, m; /* iterate over the tree elements */ - int bits; /* bit length */ - int xbits; /* extra bits */ - ush f; /* frequency */ - int overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ - - for (h = s->heap_max+1; h < HEAP_SIZE; h++) { - n = s->heap[h]; - bits = tree[tree[n].Dad].Len + 1; - if (bits > max_length) bits = max_length, overflow++; - tree[n].Len = (ush)bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) continue; /* not a leaf node */ - - s->bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n-base]; - f = tree[n].Freq; - s->opt_len += (ulg)f * (bits + xbits); - if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); - } - if (overflow == 0) return; - - Trace((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length-1; - while (s->bl_count[bits] == 0) bits--; - s->bl_count[bits]--; /* move one leaf down the tree */ - s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ - s->bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits != 0; bits--) { - n = s->bl_count[bits]; - while (n != 0) { - m = s->heap[--h]; - if (m > max_code) continue; - if (tree[m].Len != (unsigned) bits) { - Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s->opt_len += ((long)bits - (long)tree[m].Len) - *(long)tree[m].Freq; - tree[m].Len = (ush)bits; - } - n--; - } - } -} - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes (tree, max_code, bl_count) - ct_data *tree; /* the tree to decorate */ - int max_code; /* largest code with non zero frequency */ - ushf *bl_count; /* number of codes at each bit length */ -{ - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - ush code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - next_code[bits] = code = (code + bl_count[bits-1]) << 1; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; - ct_data *stree = desc->stat_desc->static_tree; - int elems = desc->stat_desc->elems; - int n, m; /* iterate over heap elements */ - int max_code = -1; /* largest code with non zero frequency */ - int node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s->heap_len = 0, s->heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n].Freq != 0) { - s->heap[++(s->heap_len)] = max_code = n; - s->depth[n] = 0; - } else { - tree[n].Len = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s->heap_len < 2) { - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); - tree[node].Freq = 1; - s->depth[node] = 0; - s->opt_len--; if (stree) s->static_len -= stree[node].Len; - /* node is 0 or 1 so it does not have extra bits */ - } - desc->max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - pqremove(s, tree, n); /* n = node of least frequency */ - m = s->heap[SMALLEST]; /* m = node of next least frequency */ - - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ - s->heap[--(s->heap_max)] = m; - - /* Create a new node father of n and m */ - tree[node].Freq = tree[n].Freq + tree[m].Freq; - s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1); - tree[n].Dad = tree[m].Dad = (ush)node; -#ifdef DUMP_BL_TREE - if (tree == s->bl_tree) { - fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); - } -#endif - /* and insert the new node in the heap */ - s->heap[SMALLEST] = node++; - pqdownheap(s, tree, SMALLEST); - - } while (s->heap_len >= 2); - - s->heap[--(s->heap_max)] = s->heap[SMALLEST]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, (tree_desc *)desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes ((ct_data *)tree, max_code, s->bl_count); -} - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -local void scan_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - if (nextlen == 0) max_count = 138, min_count = 3; - tree[max_code+1].Len = (ush)0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - s->bl_tree[curlen].Freq += count; - } else if (curlen != 0) { - if (curlen != prevlen) s->bl_tree[curlen].Freq++; - s->bl_tree[REP_3_6].Freq++; - } else if (count <= 10) { - s->bl_tree[REPZ_3_10].Freq++; - } else { - s->bl_tree[REPZ_11_138].Freq++; - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -local void send_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen == 0) max_count = 138, min_count = 3; - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { send_code(s, curlen, s->bl_tree); } while (--count != 0); - - } else if (curlen != 0) { - if (curlen != prevlen) { - send_code(s, curlen, s->bl_tree); count--; - } - Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); - - } else { - send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -local int build_bl_tree(s) - deflate_state *s; -{ - int max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, (tree_desc *)(&(s->bl_desc))); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { - if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; - } - /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3*(max_blindex+1) + 5+5+4; - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - s->opt_len, s->static_len)); - - return max_blindex; -} - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -local void send_all_trees(s, lcodes, dcodes, blcodes) - deflate_state *s; - int lcodes, dcodes, blcodes; /* number of codes for each tree */ -{ - int rank; /* index in bl_order */ - - Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - "too many codes"); - Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes-1, 5); - send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); - } - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -} - -/* =========================================================================== - * Send a stored block - */ -void _tr_stored_block(s, buf, stored_len, eof) - deflate_state *s; - charf *buf; /* input block */ - ulg stored_len; /* length of input block */ - int eof; /* true if this is the last block for a file */ -{ - send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ - s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; - s->compressed_len += (stored_len + 4) << 3; - - copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ -} - -/* Send just the `stored block' type code without any length bytes or data. - */ -void _tr_stored_type_only(s) - deflate_state *s; -{ - send_bits(s, (STORED_BLOCK << 1), 3); - bi_windup(s); - s->compressed_len = (s->compressed_len + 3) & ~7L; -} - - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - * The current inflate code requires 9 bits of lookahead. If the - * last two codes for the previous block (real code plus EOB) were coded - * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode - * the last real code. In this case we send two empty static blocks instead - * of one. (There are no problems if the previous block is stored or fixed.) - * To simplify the code, we assume the worst case of last real code encoded - * on one bit only. - */ -void _tr_align(s) - deflate_state *s; -{ - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ - bi_flush(s); - /* Of the 10 bits for the empty block, we have already sent - * (10 - bi_valid) bits. The lookahead for the last real code (before - * the EOB of the previous block) was thus at least one plus the length - * of the EOB plus what we have just sent of the empty static block. - */ - if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); - s->compressed_len += 10L; - bi_flush(s); - } - s->last_eob_len = 7; -} - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and output the encoded block to the zip file. This function - * returns the total compressed length for the file so far. - */ -ulg _tr_flush_block(s, buf, stored_len, eof) - deflate_state *s; - charf *buf; /* input block, or NULL if too old */ - ulg stored_len; /* length of input block */ - int eof; /* true if this is the last block for a file */ -{ - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - int max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s->level > 0) { - - /* Check if the file is ascii or binary */ - if (s->data_type == Z_UNKNOWN) set_data_type(s); - - /* Construct the literal and distance trees */ - build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - - build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute first the block length in bytes*/ - opt_lenb = (s->opt_len+3+7)>>3; - static_lenb = (s->static_len+3+7)>>3; - - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - s->last_lit)); - - if (static_lenb <= opt_lenb) opt_lenb = static_lenb; - - } else { - Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - - /* If compression failed and this is the first and last block, - * and if the .zip file can be seeked (to rewrite the local header), - * the whole file is transformed into a stored file: - */ -#ifdef STORED_FILE_OK -# ifdef FORCE_STORED_FILE - if (eof && s->compressed_len == 0L) { /* force stored file */ -# else - if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) { -# endif - /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */ - if (buf == (charf*)0) error ("block vanished"); - - copy_block(s, buf, (unsigned)stored_len, 0); /* without header */ - s->compressed_len = stored_len << 3; - s->method = STORED; - } else -#endif /* STORED_FILE_OK */ - -#ifdef FORCE_STORED - if (buf != (char*)0) { /* force stored block */ -#else - if (stored_len+4 <= opt_lenb && buf != (char*)0) { - /* 4: two words for the lengths */ -#endif - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block(s, buf, stored_len, eof); - -#ifdef FORCE_STATIC - } else if (static_lenb >= 0) { /* force static trees */ -#else - } else if (static_lenb == opt_lenb) { -#endif - send_bits(s, (STATIC_TREES<<1)+eof, 3); - compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); - s->compressed_len += 3 + s->static_len; - } else { - send_bits(s, (DYN_TREES<<1)+eof, 3); - send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, - max_blindex+1); - compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); - s->compressed_len += 3 + s->opt_len; - } - Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - init_block(s); - - if (eof) { - bi_windup(s); - s->compressed_len += 7; /* align on byte boundary */ - } - Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - s->compressed_len-7*eof)); - - return s->compressed_len >> 3; -} - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -int _tr_tally (s, dist, lc) - deflate_state *s; - unsigned dist; /* distance of matched string */ - unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ -{ - s->d_buf[s->last_lit] = (ush)dist; - s->l_buf[s->last_lit++] = (uch)lc; - if (dist == 0) { - /* lc is the unmatched char */ - s->dyn_ltree[lc].Freq++; - } else { - s->matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - Assert((ush)dist < (ush)MAX_DIST(s) && - (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s->dyn_ltree[length_code[lc]+LITERALS+1].Freq++; - s->dyn_dtree[d_code(dist)].Freq++; - } - - /* Try to guess if it is profitable to stop the current block here */ - if (s->level > 2 && (s->last_lit & 0xfff) == 0) { - /* Compute an upper bound for the compressed length */ - ulg out_length = (ulg)s->last_lit*8L; - ulg in_length = (ulg)((long)s->strstart - s->block_start); - int dcode; - for (dcode = 0; dcode < D_CODES; dcode++) { - out_length += (ulg)s->dyn_dtree[dcode].Freq * - (5L+extra_dbits[dcode]); - } - out_length >>= 3; - Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", - s->last_lit, in_length, out_length, - 100L - out_length*100L/in_length)); - if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; - } - return (s->last_lit == s->lit_bufsize-1); - /* We avoid equality with lit_bufsize because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ -} - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block(s, ltree, dtree) - deflate_state *s; - ct_data *ltree; /* literal tree */ - ct_data *dtree; /* distance tree */ -{ - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned lx = 0; /* running index in l_buf */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->last_lit != 0) do { - dist = s->d_buf[lx]; - lc = s->l_buf[lx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = length_code[lc]; - send_code(s, code+LITERALS+1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ - Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow"); - - } while (lx < s->last_lit); - - send_code(s, END_BLOCK, ltree); - s->last_eob_len = ltree[END_BLOCK].Len; -} - -/* =========================================================================== - * Set the data type to ASCII or BINARY, using a crude approximation: - * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. - * IN assertion: the fields freq of dyn_ltree are set and the total of all - * frequencies does not exceed 64K (to fit in an int on 16 bit machines). - */ -local void set_data_type(s) - deflate_state *s; -{ - int n = 0; - unsigned ascii_freq = 0; - unsigned bin_freq = 0; - while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; - while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; - while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; - s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse(code, len) - unsigned code; /* the value to invert */ - int len; /* its bit length */ -{ - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush(s) - deflate_state *s; -{ - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -local void bi_windup(s) - deflate_state *s; -{ - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef DEBUG_ZLIB - s->bits_sent = (s->bits_sent+7) & ~7; -#endif -} - -/* =========================================================================== - * Copy a stored block, storing first the length and its - * one's complement if requested. - */ -local void copy_block(s, buf, len, header) - deflate_state *s; - charf *buf; /* the input data */ - unsigned len; /* its length */ - int header; /* true if block header must be written */ -{ - bi_windup(s); /* align on byte boundary */ - s->last_eob_len = 8; /* enough lookahead for inflate */ - - if (header) { - put_short(s, (ush)len); - put_short(s, (ush)~len); -#ifdef DEBUG_ZLIB - s->bits_sent += 2*16; -#endif - } -#ifdef DEBUG_ZLIB - s->bits_sent += (ulg)len<<3; -#endif - /* bundle up the put_byte(s, *buf++) calls */ - zmemcpy(&s->pending_buf[s->pending], buf, len); - s->pending += len; -} -/* --- trees.c */ - -/* +++ inflate.c */ -/* inflate.c -- zlib interface to inflate modules - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* #include "zutil.h" */ - -/* +++ infblock.h */ -/* infblock.h -- header to use infblock.c - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -struct inflate_blocks_state; -typedef struct inflate_blocks_state FAR inflate_blocks_statef; - -extern inflate_blocks_statef * inflate_blocks_new OF(( - z_streamp z, - check_func c, /* check function */ - uInt w)); /* window size */ - -extern int inflate_blocks OF(( - inflate_blocks_statef *, - z_streamp , - int)); /* initial return code */ - -extern void inflate_blocks_reset OF(( - inflate_blocks_statef *, - z_streamp , - uLongf *)); /* check value on output */ - -extern int inflate_blocks_free OF(( - inflate_blocks_statef *, - z_streamp , - uLongf *)); /* check value on output */ - -extern void inflate_set_dictionary OF(( - inflate_blocks_statef *s, - const Bytef *d, /* dictionary */ - uInt n)); /* dictionary length */ - -extern int inflate_addhistory OF(( - inflate_blocks_statef *, - z_streamp)); - -extern int inflate_packet_flush OF(( - inflate_blocks_statef *)); -/* --- infblock.h */ - -#ifndef NO_DUMMY_DECL -struct inflate_blocks_state {int dummy;}; /* for buggy compilers */ -#endif - -/* inflate private state */ -struct internal_state { - - /* mode */ - enum { - METHOD, /* waiting for method byte */ - FLAG, /* waiting for flag byte */ - DICT4, /* four dictionary check bytes to go */ - DICT3, /* three dictionary check bytes to go */ - DICT2, /* two dictionary check bytes to go */ - DICT1, /* one dictionary check byte to go */ - DICT0, /* waiting for inflateSetDictionary */ - BLOCKS, /* decompressing blocks */ - CHECK4, /* four check bytes to go */ - CHECK3, /* three check bytes to go */ - CHECK2, /* two check bytes to go */ - CHECK1, /* one check byte to go */ - DONE, /* finished check, done */ - BAD} /* got an error--stay here */ - mode; /* current inflate mode */ - - /* mode dependent information */ - union { - uInt method; /* if FLAGS, method byte */ - struct { - uLong was; /* computed check value */ - uLong need; /* stream check value */ - } check; /* if CHECK, check values to compare */ - uInt marker; /* if BAD, inflateSync's marker bytes count */ - } sub; /* submode */ - - /* mode independent information */ - int nowrap; /* flag for no wrapper */ - uInt wbits; /* log2(window size) (8..15, defaults to 15) */ - inflate_blocks_statef - *blocks; /* current inflate_blocks state */ - -}; - - -int inflateReset(z) -z_streamp z; -{ - uLong c; - - if (z == Z_NULL || z->state == Z_NULL) - return Z_STREAM_ERROR; - z->total_in = z->total_out = 0; - z->msg = Z_NULL; - z->state->mode = z->state->nowrap ? BLOCKS : METHOD; - inflate_blocks_reset(z->state->blocks, z, &c); - Trace((stderr, "inflate: reset\n")); - return Z_OK; -} - - -int inflateEnd(z) -z_streamp z; -{ - uLong c; - - if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) - return Z_STREAM_ERROR; - if (z->state->blocks != Z_NULL) - inflate_blocks_free(z->state->blocks, z, &c); - ZFREE(z, z->state); - z->state = Z_NULL; - Trace((stderr, "inflate: end\n")); - return Z_OK; -} - - -int inflateInit2_(z, w, version, stream_size) -z_streamp z; -int w; -const char *version; -int stream_size; -{ - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != sizeof(z_stream)) - return Z_VERSION_ERROR; - - /* initialize state */ - if (z == Z_NULL) - return Z_STREAM_ERROR; - z->msg = Z_NULL; -#ifndef NO_ZCFUNCS - if (z->zalloc == Z_NULL) - { - z->zalloc = zcalloc; - z->opaque = (voidpf)0; - } - if (z->zfree == Z_NULL) z->zfree = zcfree; -#endif - if ((z->state = (struct internal_state FAR *) - ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) - return Z_MEM_ERROR; - z->state->blocks = Z_NULL; - - /* handle undocumented nowrap option (no zlib header or check) */ - z->state->nowrap = 0; - if (w < 0) - { - w = - w; - z->state->nowrap = 1; - } - - /* set window size */ - if (w < 8 || w > 15) - { - inflateEnd(z); - return Z_STREAM_ERROR; - } - z->state->wbits = (uInt)w; - - /* create inflate_blocks state */ - if ((z->state->blocks = - inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) - == Z_NULL) - { - inflateEnd(z); - return Z_MEM_ERROR; - } - Trace((stderr, "inflate: allocated\n")); - - /* reset state */ - inflateReset(z); - return Z_OK; -} - - -int inflateInit_(z, version, stream_size) -z_streamp z; -const char *version; -int stream_size; -{ - return inflateInit2_(z, DEF_WBITS, version, stream_size); -} - - -#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;} -#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) - -int inflate(z, f) -z_streamp z; -int f; -{ - int r; - uInt b; - - if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL || f < 0) - return Z_STREAM_ERROR; - r = Z_BUF_ERROR; - while (1) switch (z->state->mode) - { - case METHOD: - NEEDBYTE - if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) - { - z->state->mode = BAD; - z->msg = (char*)"unknown compression method"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - if ((z->state->sub.method >> 4) + 8 > z->state->wbits) - { - z->state->mode = BAD; - z->msg = (char*)"invalid window size"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - z->state->mode = FLAG; - case FLAG: - NEEDBYTE - b = NEXTBYTE; - if (((z->state->sub.method << 8) + b) % 31) - { - z->state->mode = BAD; - z->msg = (char*)"incorrect header check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - Trace((stderr, "inflate: zlib header ok\n")); - if (!(b & PRESET_DICT)) - { - z->state->mode = BLOCKS; - break; - } - z->state->mode = DICT4; - case DICT4: - NEEDBYTE - z->state->sub.check.need = (uLong)NEXTBYTE << 24; - z->state->mode = DICT3; - case DICT3: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 16; - z->state->mode = DICT2; - case DICT2: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 8; - z->state->mode = DICT1; - case DICT1: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE; - z->adler = z->state->sub.check.need; - z->state->mode = DICT0; - return Z_NEED_DICT; - case DICT0: - z->state->mode = BAD; - z->msg = (char*)"need dictionary"; - z->state->sub.marker = 0; /* can try inflateSync */ - return Z_STREAM_ERROR; - case BLOCKS: - r = inflate_blocks(z->state->blocks, z, r); - if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0) - r = inflate_packet_flush(z->state->blocks); - if (r == Z_DATA_ERROR) - { - z->state->mode = BAD; - z->state->sub.marker = 0; /* can try inflateSync */ - break; - } - if (r != Z_STREAM_END) - return r; - r = Z_OK; - inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); - if (z->state->nowrap) - { - z->state->mode = DONE; - break; - } - z->state->mode = CHECK4; - case CHECK4: - NEEDBYTE - z->state->sub.check.need = (uLong)NEXTBYTE << 24; - z->state->mode = CHECK3; - case CHECK3: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 16; - z->state->mode = CHECK2; - case CHECK2: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 8; - z->state->mode = CHECK1; - case CHECK1: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE; - - if (z->state->sub.check.was != z->state->sub.check.need) - { - z->state->mode = BAD; - z->msg = (char*)"incorrect data check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - Trace((stderr, "inflate: zlib check ok\n")); - z->state->mode = DONE; - case DONE: - return Z_STREAM_END; - case BAD: - return Z_DATA_ERROR; - default: - return Z_STREAM_ERROR; - } - - empty: - if (f != Z_PACKET_FLUSH) - return r; - z->state->mode = BAD; - z->msg = (char *)"need more for packet flush"; - z->state->sub.marker = 0; /* can try inflateSync */ - return Z_DATA_ERROR; -} - - -int inflateSetDictionary(z, dictionary, dictLength) -z_streamp z; -const Bytef *dictionary; -uInt dictLength; -{ - uInt length = dictLength; - - if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0) - return Z_STREAM_ERROR; - - if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR; - z->adler = 1L; - - if (length >= ((uInt)1<state->wbits)) - { - length = (1<state->wbits)-1; - dictionary += dictLength - length; - } - inflate_set_dictionary(z->state->blocks, dictionary, length); - z->state->mode = BLOCKS; - return Z_OK; -} - -/* - * This subroutine adds the data at next_in/avail_in to the output history - * without performing any output. The output buffer must be "caught up"; - * i.e. no pending output (hence s->read equals s->write), and the state must - * be BLOCKS (i.e. we should be willing to see the start of a series of - * BLOCKS). On exit, the output will also be caught up, and the checksum - * will have been updated if need be. - */ - -int inflateIncomp(z) -z_stream *z; -{ - if (z->state->mode != BLOCKS) - return Z_DATA_ERROR; - return inflate_addhistory(z->state->blocks, z); -} - - -int inflateSync(z) -z_streamp z; -{ - uInt n; /* number of bytes to look at */ - Bytef *p; /* pointer to bytes */ - uInt m; /* number of marker bytes found in a row */ - uLong r, w; /* temporaries to save total_in and total_out */ - - /* set up */ - if (z == Z_NULL || z->state == Z_NULL) - return Z_STREAM_ERROR; - if (z->state->mode != BAD) - { - z->state->mode = BAD; - z->state->sub.marker = 0; - } - if ((n = z->avail_in) == 0) - return Z_BUF_ERROR; - p = z->next_in; - m = z->state->sub.marker; - - /* search */ - while (n && m < 4) - { - if (*p == (Byte)(m < 2 ? 0 : 0xff)) - m++; - else if (*p) - m = 0; - else - m = 4 - m; - p++, n--; - } - - /* restore */ - z->total_in += p - z->next_in; - z->next_in = p; - z->avail_in = n; - z->state->sub.marker = m; - - /* return no joy or set up to restart on a new block */ - if (m != 4) - return Z_DATA_ERROR; - r = z->total_in; w = z->total_out; - inflateReset(z); - z->total_in = r; z->total_out = w; - z->state->mode = BLOCKS; - return Z_OK; -} - -#undef NEEDBYTE -#undef NEXTBYTE -/* --- inflate.c */ - -/* +++ infblock.c */ -/* infblock.c -- interpret and process block types to last block - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* #include "zutil.h" */ -/* #include "infblock.h" */ - -/* +++ inftrees.h */ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Huffman code lookup table entry--this entry is four bytes for machines - that have 16-bit pointers (e.g. PC's in the small or medium model). */ - -typedef struct inflate_huft_s FAR inflate_huft; - -struct inflate_huft_s { - union { - struct { - Byte Exop; /* number of extra bits or operation */ - Byte Bits; /* number of bits in this code or subcode */ - } what; - Bytef *pad; /* pad structure to a power of 2 (4 bytes for */ - } word; /* 16-bit, 8 bytes for 32-bit machines) */ - union { - uInt Base; /* literal, length base, or distance base */ - inflate_huft *Next; /* pointer to next level of table */ - } more; -}; - -#ifdef DEBUG_ZLIB - extern uInt inflate_hufts; -#endif - -extern int inflate_trees_bits OF(( - uIntf *, /* 19 code lengths */ - uIntf *, /* bits tree desired/actual depth */ - inflate_huft * FAR *, /* bits tree result */ - z_streamp )); /* for zalloc, zfree functions */ - -extern int inflate_trees_dynamic OF(( - uInt, /* number of literal/length codes */ - uInt, /* number of distance codes */ - uIntf *, /* that many (total) code lengths */ - uIntf *, /* literal desired/actual bit depth */ - uIntf *, /* distance desired/actual bit depth */ - inflate_huft * FAR *, /* literal/length tree result */ - inflate_huft * FAR *, /* distance tree result */ - z_streamp )); /* for zalloc, zfree functions */ - -extern int inflate_trees_fixed OF(( - uIntf *, /* literal desired/actual bit depth */ - uIntf *, /* distance desired/actual bit depth */ - inflate_huft * FAR *, /* literal/length tree result */ - inflate_huft * FAR *)); /* distance tree result */ - -extern int inflate_trees_free OF(( - inflate_huft *, /* tables to free */ - z_streamp )); /* for zfree function */ - -/* --- inftrees.h */ - -/* +++ infcodes.h */ -/* infcodes.h -- header to use infcodes.c - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -struct inflate_codes_state; -typedef struct inflate_codes_state FAR inflate_codes_statef; - -extern inflate_codes_statef *inflate_codes_new OF(( - uInt, uInt, - inflate_huft *, inflate_huft *, - z_streamp )); - -extern int inflate_codes OF(( - inflate_blocks_statef *, - z_streamp , - int)); - -extern void inflate_codes_free OF(( - inflate_codes_statef *, - z_streamp )); - -/* --- infcodes.h */ - -/* +++ infutil.h */ -/* infutil.h -- types and macros common to blocks and codes - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -#ifndef _INFUTIL_H -#define _INFUTIL_H - -typedef enum { - TYPE, /* get type bits (3, including end bit) */ - LENS, /* get lengths for stored */ - STORED, /* processing stored block */ - TABLE, /* get table lengths */ - BTREE, /* get bit lengths tree for a dynamic block */ - DTREE, /* get length, distance trees for a dynamic block */ - CODES, /* processing fixed or dynamic block */ - DRY, /* output remaining window bytes */ - DONEB, /* finished last block, done */ - BADB} /* got a data error--stuck here */ -inflate_block_mode; - -/* inflate blocks semi-private state */ -struct inflate_blocks_state { - - /* mode */ - inflate_block_mode mode; /* current inflate_block mode */ - - /* mode dependent information */ - union { - uInt left; /* if STORED, bytes left to copy */ - struct { - uInt table; /* table lengths (14 bits) */ - uInt index; /* index into blens (or border) */ - uIntf *blens; /* bit lengths of codes */ - uInt bb; /* bit length tree depth */ - inflate_huft *tb; /* bit length decoding tree */ - } trees; /* if DTREE, decoding info for trees */ - struct { - inflate_huft *tl; - inflate_huft *td; /* trees to free */ - inflate_codes_statef - *codes; - } decode; /* if CODES, current state */ - } sub; /* submode */ - uInt last; /* true if this block is the last block */ - - /* mode independent information */ - uInt bitk; /* bits in bit buffer */ - uLong bitb; /* bit buffer */ - Bytef *window; /* sliding window */ - Bytef *end; /* one byte after sliding window */ - Bytef *read; /* window read pointer */ - Bytef *write; /* window write pointer */ - check_func checkfn; /* check function */ - uLong check; /* check on output */ - -}; - - -/* defines for inflate input/output */ -/* update pointers and return */ -#define UPDBITS {s->bitb=b;s->bitk=k;} -#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} -#define UPDOUT {s->write=q;} -#define UPDATE {UPDBITS UPDIN UPDOUT} -#define LEAVE {UPDATE return inflate_flush(s,z,r);} -/* get bytes and bits */ -#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} -#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} -#define NEXTBYTE (n--,*p++) -#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} -/* output bytes */ -#define WAVAIL (uInt)(qread?s->read-q-1:s->end-q) -#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} -#define WWRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} -#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} -#define NEEDOUT {if(m==0){WWRAP if(m==0){FLUSH WWRAP if(m==0) LEAVE}}r=Z_OK;} -#define OUTBYTE(a) {*q++=(Byte)(a);m--;} -/* load local pointers */ -#define LOAD {LOADIN LOADOUT} - -/* masks for lower bits (size given to avoid silly warnings with Visual C++) */ -extern uInt inflate_mask[17]; - -/* copy as much as possible from the sliding window to the output area */ -extern int inflate_flush OF(( - inflate_blocks_statef *, - z_streamp , - int)); - -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - -#endif -/* --- infutil.h */ - -#ifndef NO_DUMMY_DECL -struct inflate_codes_state {int dummy;}; /* for buggy compilers */ -#endif - -/* Table for deflate from PKZIP's appnote.txt. */ -local const uInt border[] = { /* Order of the bit length code lengths */ - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - -/* - Notes beyond the 1.93a appnote.txt: - - 1. Distance pointers never point before the beginning of the output - stream. - 2. Distance pointers can point back across blocks, up to 32k away. - 3. There is an implied maximum of 7 bits for the bit length table and - 15 bits for the actual data. - 4. If only one code exists, then it is encoded using one bit. (Zero - would be more efficient, but perhaps a little confusing.) If two - codes exist, they are coded using one bit each (0 and 1). - 5. There is no way of sending zero distance codes--a dummy must be - sent if there are none. (History: a pre 2.0 version of PKZIP would - store blocks with no distance codes, but this was discovered to be - too harsh a criterion.) Valid only for 1.93a. 2.04c does allow - zero distance codes, which is sent as one code of zero bits in - length. - 6. There are up to 286 literal/length codes. Code 256 represents the - end-of-block. Note however that the static length tree defines - 288 codes just to fill out the Huffman codes. Codes 286 and 287 - cannot be used though, since there is no length base or extra bits - defined for them. Similarily, there are up to 30 distance codes. - However, static trees define 32 codes (all 5 bits) to fill out the - Huffman codes, but the last two had better not show up in the data. - 7. Unzip can check dynamic Huffman blocks for complete code sets. - The exception is that a single code would not be complete (see #4). - 8. The five bits following the block type is really the number of - literal codes sent minus 257. - 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits - (1+6+6). Therefore, to output three times the length, you output - three codes (1+1+1), whereas to output four times the same length, - you only need two codes (1+3). Hmm. - 10. In the tree reconstruction algorithm, Code = Code + Increment - only if BitLength(i) is not zero. (Pretty obvious.) - 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) - 12. Note: length code 284 can represent 227-258, but length code 285 - really is 258. The last length deserves its own, short code - since it gets used a lot in very redundant files. The length - 258 is special since 258 - 3 (the min match length) is 255. - 13. The literal/length and distance code bit lengths are read as a - single stream of lengths. It is possible (and advantageous) for - a repeat code (16, 17, or 18) to go across the boundary between - the two sets of lengths. - */ - - -void inflate_blocks_reset(s, z, c) -inflate_blocks_statef *s; -z_streamp z; -uLongf *c; -{ - if (s->checkfn != Z_NULL) - *c = s->check; - if (s->mode == BTREE || s->mode == DTREE) - ZFREE(z, s->sub.trees.blens); - if (s->mode == CODES) - { - inflate_codes_free(s->sub.decode.codes, z); - inflate_trees_free(s->sub.decode.td, z); - inflate_trees_free(s->sub.decode.tl, z); - } - s->mode = TYPE; - s->bitk = 0; - s->bitb = 0; - s->read = s->write = s->window; - if (s->checkfn != Z_NULL) - z->adler = s->check = (*s->checkfn)(0L, Z_NULL, 0); - Trace((stderr, "inflate: blocks reset\n")); -} - - -inflate_blocks_statef *inflate_blocks_new(z, c, w) -z_streamp z; -check_func c; -uInt w; -{ - inflate_blocks_statef *s; - - if ((s = (inflate_blocks_statef *)ZALLOC - (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) - return s; - if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) - { - ZFREE(z, s); - return Z_NULL; - } - s->end = s->window + w; - s->checkfn = c; - s->mode = TYPE; - Trace((stderr, "inflate: blocks allocated\n")); - inflate_blocks_reset(s, z, &s->check); - return s; -} - - -#ifdef DEBUG_ZLIB - extern uInt inflate_hufts; -#endif -int inflate_blocks(s, z, r) -inflate_blocks_statef *s; -z_streamp z; -int r; -{ - uInt t; /* temporary storage */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD - - /* process input based on current state */ - while (1) switch (s->mode) - { - case TYPE: - NEEDBITS(3) - t = (uInt)b & 7; - s->last = t & 1; - switch (t >> 1) - { - case 0: /* stored */ - Trace((stderr, "inflate: stored block%s\n", - s->last ? " (last)" : "")); - DUMPBITS(3) - t = k & 7; /* go to byte boundary */ - DUMPBITS(t) - s->mode = LENS; /* get length of stored block */ - break; - case 1: /* fixed */ - Trace((stderr, "inflate: fixed codes block%s\n", - s->last ? " (last)" : "")); - { - uInt bl, bd; - inflate_huft *tl, *td; - - inflate_trees_fixed(&bl, &bd, &tl, &td); - s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); - if (s->sub.decode.codes == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - s->sub.decode.tl = Z_NULL; /* don't try to free these */ - s->sub.decode.td = Z_NULL; - } - DUMPBITS(3) - s->mode = CODES; - break; - case 2: /* dynamic */ - Trace((stderr, "inflate: dynamic codes block%s\n", - s->last ? " (last)" : "")); - DUMPBITS(3) - s->mode = TABLE; - break; - case 3: /* illegal */ - DUMPBITS(3) - s->mode = BADB; - z->msg = (char*)"invalid block type"; - r = Z_DATA_ERROR; - LEAVE - } - break; - case LENS: - NEEDBITS(32) - if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) - { - s->mode = BADB; - z->msg = (char*)"invalid stored block lengths"; - r = Z_DATA_ERROR; - LEAVE - } - s->sub.left = (uInt)b & 0xffff; - b = k = 0; /* dump bits */ - Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); - s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); - break; - case STORED: - if (n == 0) - LEAVE - NEEDOUT - t = s->sub.left; - if (t > n) t = n; - if (t > m) t = m; - zmemcpy(q, p, t); - p += t; n -= t; - q += t; m -= t; - if ((s->sub.left -= t) != 0) - break; - Tracev((stderr, "inflate: stored end, %lu total out\n", - z->total_out + (q >= s->read ? q - s->read : - (s->end - s->read) + (q - s->window)))); - s->mode = s->last ? DRY : TYPE; - break; - case TABLE: - NEEDBITS(14) - s->sub.trees.table = t = (uInt)b & 0x3fff; -#ifndef PKZIP_BUG_WORKAROUND - if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) - { - s->mode = BADB; - z->msg = (char*)"too many length or distance symbols"; - r = Z_DATA_ERROR; - LEAVE - } -#endif - t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); - if (t < 19) - t = 19; - if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - DUMPBITS(14) - s->sub.trees.index = 0; - Tracev((stderr, "inflate: table sizes ok\n")); - s->mode = BTREE; - case BTREE: - while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) - { - NEEDBITS(3) - s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; - DUMPBITS(3) - } - while (s->sub.trees.index < 19) - s->sub.trees.blens[border[s->sub.trees.index++]] = 0; - s->sub.trees.bb = 7; - t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, - &s->sub.trees.tb, z); - if (t != Z_OK) - { - r = t; - if (r == Z_DATA_ERROR) - { - ZFREE(z, s->sub.trees.blens); - s->mode = BADB; - } - LEAVE - } - s->sub.trees.index = 0; - Tracev((stderr, "inflate: bits tree ok\n")); - s->mode = DTREE; - case DTREE: - while (t = s->sub.trees.table, - s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) - { - inflate_huft *h; - uInt i, j, c; - - t = s->sub.trees.bb; - NEEDBITS(t) - h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); - t = h->word.what.Bits; - c = h->more.Base; - if (c < 16) - { - DUMPBITS(t) - s->sub.trees.blens[s->sub.trees.index++] = c; - } - else /* c == 16..18 */ - { - i = c == 18 ? 7 : c - 14; - j = c == 18 ? 11 : 3; - NEEDBITS(t + i) - DUMPBITS(t) - j += (uInt)b & inflate_mask[i]; - DUMPBITS(i) - i = s->sub.trees.index; - t = s->sub.trees.table; - if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || - (c == 16 && i < 1)) - { - inflate_trees_free(s->sub.trees.tb, z); - ZFREE(z, s->sub.trees.blens); - s->mode = BADB; - z->msg = (char*)"invalid bit length repeat"; - r = Z_DATA_ERROR; - LEAVE - } - c = c == 16 ? s->sub.trees.blens[i - 1] : 0; - do { - s->sub.trees.blens[i++] = c; - } while (--j); - s->sub.trees.index = i; - } - } - inflate_trees_free(s->sub.trees.tb, z); - s->sub.trees.tb = Z_NULL; - { - uInt bl, bd; - inflate_huft *tl, *td; - inflate_codes_statef *c; - - bl = 9; /* must be <= 9 for lookahead assumptions */ - bd = 6; /* must be <= 9 for lookahead assumptions */ - t = s->sub.trees.table; -#ifdef DEBUG_ZLIB - inflate_hufts = 0; -#endif - t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), - s->sub.trees.blens, &bl, &bd, &tl, &td, z); - if (t != Z_OK) - { - if (t == (uInt)Z_DATA_ERROR) - { - ZFREE(z, s->sub.trees.blens); - s->mode = BADB; - } - r = t; - LEAVE - } - Tracev((stderr, "inflate: trees ok, %d * %d bytes used\n", - inflate_hufts, sizeof(inflate_huft))); - if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) - { - inflate_trees_free(td, z); - inflate_trees_free(tl, z); - r = Z_MEM_ERROR; - LEAVE - } - ZFREE(z, s->sub.trees.blens); - s->sub.decode.codes = c; - s->sub.decode.tl = tl; - s->sub.decode.td = td; - } - s->mode = CODES; - case CODES: - UPDATE - if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) - return inflate_flush(s, z, r); - r = Z_OK; - inflate_codes_free(s->sub.decode.codes, z); - inflate_trees_free(s->sub.decode.td, z); - inflate_trees_free(s->sub.decode.tl, z); - LOAD - Tracev((stderr, "inflate: codes end, %lu total out\n", - z->total_out + (q >= s->read ? q - s->read : - (s->end - s->read) + (q - s->window)))); - if (!s->last) - { - s->mode = TYPE; - break; - } - if (k > 7) /* return unused byte, if any */ - { - Assert(k < 16, "inflate_codes grabbed too many bytes") - k -= 8; - n++; - p--; /* can always return one */ - } - s->mode = DRY; - case DRY: - FLUSH - if (s->read != s->write) - LEAVE - s->mode = DONEB; - case DONEB: - r = Z_STREAM_END; - LEAVE - case BADB: - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } -} - - -int inflate_blocks_free(s, z, c) -inflate_blocks_statef *s; -z_streamp z; -uLongf *c; -{ - inflate_blocks_reset(s, z, c); - ZFREE(z, s->window); - ZFREE(z, s); - Trace((stderr, "inflate: blocks freed\n")); - return Z_OK; -} - - -void inflate_set_dictionary(s, d, n) -inflate_blocks_statef *s; -const Bytef *d; -uInt n; -{ - zmemcpy((charf *)s->window, d, n); - s->read = s->write = s->window + n; -} - -/* - * This subroutine adds the data at next_in/avail_in to the output history - * without performing any output. The output buffer must be "caught up"; - * i.e. no pending output (hence s->read equals s->write), and the state must - * be BLOCKS (i.e. we should be willing to see the start of a series of - * BLOCKS). On exit, the output will also be caught up, and the checksum - * will have been updated if need be. - */ -int inflate_addhistory(s, z) -inflate_blocks_statef *s; -z_stream *z; -{ - uLong b; /* bit buffer */ /* NOT USED HERE */ - uInt k; /* bits in bit buffer */ /* NOT USED HERE */ - uInt t; /* temporary storage */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - - if (s->read != s->write) - return Z_STREAM_ERROR; - if (s->mode != TYPE) - return Z_DATA_ERROR; - - /* we're ready to rock */ - LOAD - /* while there is input ready, copy to output buffer, moving - * pointers as needed. - */ - while (n) { - t = n; /* how many to do */ - /* is there room until end of buffer? */ - if (t > m) t = m; - /* update check information */ - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(s->check, q, t); - zmemcpy(q, p, t); - q += t; - p += t; - n -= t; - z->total_out += t; - s->read = q; /* drag read pointer forward */ -/* WWRAP */ /* expand WWRAP macro by hand to handle s->read */ - if (q == s->end) { - s->read = q = s->window; - m = WAVAIL; - } - } - UPDATE - return Z_OK; -} - - -/* - * At the end of a Deflate-compressed PPP packet, we expect to have seen - * a `stored' block type value but not the (zero) length bytes. - */ -int inflate_packet_flush(s) - inflate_blocks_statef *s; -{ - if (s->mode != LENS) - return Z_DATA_ERROR; - s->mode = TYPE; - return Z_OK; -} -/* --- infblock.c */ - -/* +++ inftrees.c */ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* #include "zutil.h" */ -/* #include "inftrees.h" */ - -char inflate_copyright[] = " inflate 1.0.4 Copyright 1995-1996 Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - - -local int huft_build OF(( - uIntf *, /* code lengths in bits */ - uInt, /* number of codes */ - uInt, /* number of "simple" codes */ - const uIntf *, /* list of base values for non-simple codes */ - const uIntf *, /* list of extra bits for non-simple codes */ - inflate_huft * FAR*,/* result: starting table */ - uIntf *, /* maximum lookup bits (returns actual) */ - z_streamp )); /* for zalloc function */ - -local voidpf falloc OF(( - voidpf, /* opaque pointer (not used) */ - uInt, /* number of items */ - uInt)); /* size of item */ - -/* Tables for deflate from PKZIP's appnote.txt. */ -local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - /* see note #13 above about 258 */ -local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */ -local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577}; -local const uInt cpdext[30] = { /* Extra bits for distance codes */ - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13}; - -/* - Huffman code decoding is performed using a multi-level table lookup. - The fastest way to decode is to simply build a lookup table whose - size is determined by the longest code. However, the time it takes - to build this table can also be a factor if the data being decoded - is not very long. The most common codes are necessarily the - shortest codes, so those codes dominate the decoding time, and hence - the speed. The idea is you can have a shorter table that decodes the - shorter, more probable codes, and then point to subsidiary tables for - the longer codes. The time it costs to decode the longer codes is - then traded against the time it takes to make longer tables. - - This results of this trade are in the variables lbits and dbits - below. lbits is the number of bits the first level table for literal/ - length codes can decode in one step, and dbits is the same thing for - the distance codes. Subsequent tables are also less than or equal to - those sizes. These values may be adjusted either when all of the - codes are shorter than that, in which case the longest code length in - bits is used, or when the shortest code is *longer* than the requested - table size, in which case the length of the shortest code in bits is - used. - - There are two different values for the two tables, since they code a - different number of possibilities each. The literal/length table - codes 286 possible values, or in a flat code, a little over eight - bits. The distance table codes 30 possible values, or a little less - than five bits, flat. The optimum values for speed end up being - about one bit more than those, so lbits is 8+1 and dbits is 5+1. - The optimum values may differ though from machine to machine, and - possibly even between compilers. Your mileage may vary. - */ - - -/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ -#define BMAX 15 /* maximum bit length of any code */ -#define N_MAX 288 /* maximum number of codes in any set */ - -#ifdef DEBUG_ZLIB - uInt inflate_hufts; -#endif - -local int huft_build(b, n, s, d, e, t, m, zs) -uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ -uInt n; /* number of codes (assumed <= N_MAX) */ -uInt s; /* number of simple-valued codes (0..s-1) */ -const uIntf *d; /* list of base values for non-simple codes */ -const uIntf *e; /* list of extra bits for non-simple codes */ -inflate_huft * FAR *t; /* result: starting table */ -uIntf *m; /* maximum lookup bits, returns actual */ -z_streamp zs; /* for zalloc function */ -/* Given a list of code lengths and a maximum table size, make a set of - tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR - if the given code set is incomplete (the tables are still built in this - case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of - lengths), or Z_MEM_ERROR if not enough memory. */ -{ - - uInt a; /* counter for codes of length k */ - uInt c[BMAX+1]; /* bit length count table */ - uInt f; /* i repeats in table every f entries */ - int g; /* maximum code length */ - int h; /* table level */ - register uInt i; /* counter, current code */ - register uInt j; /* counter */ - register int k; /* number of bits in current code */ - int l; /* bits per table (returned in m) */ - register uIntf *p; /* pointer into c[], b[], or v[] */ - inflate_huft *q; /* points to current table */ - struct inflate_huft_s r; /* table entry for structure assignment */ - inflate_huft *u[BMAX]; /* table stack */ - uInt v[N_MAX]; /* values in order of bit length */ - register int w; /* bits before this table == (l * h) */ - uInt x[BMAX+1]; /* bit offsets, then code stack */ - uIntf *xp; /* pointer into x */ - int y; /* number of dummy codes added */ - uInt z; /* number of entries in current table */ - - - /* Generate counts for each bit length */ - p = c; -#define C0 *p++ = 0; -#define C2 C0 C0 C0 C0 -#define C4 C2 C2 C2 C2 - C4 /* clear c[]--assume BMAX+1 is 16 */ - p = b; i = n; - do { - c[*p++]++; /* assume all entries <= BMAX */ - } while (--i); - if (c[0] == n) /* null input--all zero length codes */ - { - *t = (inflate_huft *)Z_NULL; - *m = 0; - return Z_OK; - } - - - /* Find minimum and maximum length, bound *m by those */ - l = *m; - for (j = 1; j <= BMAX; j++) - if (c[j]) - break; - k = j; /* minimum code length */ - if ((uInt)l < j) - l = j; - for (i = BMAX; i; i--) - if (c[i]) - break; - g = i; /* maximum code length */ - if ((uInt)l > i) - l = i; - *m = l; - - - /* Adjust last length count to fill out codes, if needed */ - for (y = 1 << j; j < i; j++, y <<= 1) - if ((y -= c[j]) < 0) - return Z_DATA_ERROR; - if ((y -= c[i]) < 0) - return Z_DATA_ERROR; - c[i] += y; - - - /* Generate starting offsets into the value table for each length */ - x[1] = j = 0; - p = c + 1; xp = x + 2; - while (--i) { /* note that i == g from above */ - *xp++ = (j += *p++); - } - - - /* Make a table of values in order of bit lengths */ - p = b; i = 0; - do { - if ((j = *p++) != 0) - v[x[j]++] = i; - } while (++i < n); - n = x[g]; /* set n to length of v */ - - - /* Generate the Huffman codes and for each, make the table entries */ - x[0] = i = 0; /* first Huffman code is zero */ - p = v; /* grab values in bit order */ - h = -1; /* no tables yet--level -1 */ - w = -l; /* bits decoded == (l * h) */ - u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ - q = (inflate_huft *)Z_NULL; /* ditto */ - z = 0; /* ditto */ - - /* go through the bit lengths (k already is bits in shortest code) */ - for (; k <= g; k++) - { - a = c[k]; - while (a--) - { - /* here i is the Huffman code of length k bits for value *p */ - /* make tables up to required level */ - while (k > w + l) - { - h++; - w += l; /* previous table always l bits */ - - /* compute minimum size table less than or equal to l bits */ - z = g - w; - z = z > (uInt)l ? l : z; /* table size upper limit */ - if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ - { /* too few codes for k-w bit table */ - f -= a + 1; /* deduct codes from patterns left */ - xp = c + k; - if (j < z) - while (++j < z) /* try smaller tables up to z bits */ - { - if ((f <<= 1) <= *++xp) - break; /* enough codes to use up j bits */ - f -= *xp; /* else deduct codes from patterns */ - } - } - z = 1 << j; /* table entries for j-bit table */ - - /* allocate and link in new table */ - if ((q = (inflate_huft *)ZALLOC - (zs,z + 1,sizeof(inflate_huft))) == Z_NULL) - { - if (h) - inflate_trees_free(u[0], zs); - return Z_MEM_ERROR; /* not enough memory */ - } -#ifdef DEBUG_ZLIB - inflate_hufts += z + 1; -#endif - *t = q + 1; /* link to list for huft_free() */ - *(t = &(q->next)) = Z_NULL; - u[h] = ++q; /* table starts after link */ - - /* connect to last table, if there is one */ - if (h) - { - x[h] = i; /* save pattern for backing up */ - r.bits = (Byte)l; /* bits to dump before this table */ - r.exop = (Byte)j; /* bits in this table */ - r.next = q; /* pointer to this table */ - j = i >> (w - l); /* (get around Turbo C bug) */ - u[h-1][j] = r; /* connect to last table */ - } - } - - /* set up table entry in r */ - r.bits = (Byte)(k - w); - if (p >= v + n) - r.exop = 128 + 64; /* out of values--invalid code */ - else if (*p < s) - { - r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ - r.base = *p++; /* simple code is just the value */ - } - else - { - r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ - r.base = d[*p++ - s]; - } - - /* fill code-like entries with r */ - f = 1 << (k - w); - for (j = i >> w; j < z; j += f) - q[j] = r; - - /* backwards increment the k-bit code i */ - for (j = 1 << (k - 1); i & j; j >>= 1) - i ^= j; - i ^= j; - - /* backup over finished tables */ - while ((i & ((1 << w) - 1)) != x[h]) - { - h--; /* don't need to update q */ - w -= l; - } - } - } - - - /* Return Z_BUF_ERROR if we were given an incomplete table */ - return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; -} - - -int inflate_trees_bits(c, bb, tb, z) -uIntf *c; /* 19 code lengths */ -uIntf *bb; /* bits tree desired/actual depth */ -inflate_huft * FAR *tb; /* bits tree result */ -z_streamp z; /* for zfree function */ -{ - int r; - - r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z); - if (r == Z_DATA_ERROR) - z->msg = (char*)"oversubscribed dynamic bit lengths tree"; - else if (r == Z_BUF_ERROR || *bb == 0) - { - inflate_trees_free(*tb, z); - z->msg = (char*)"incomplete dynamic bit lengths tree"; - r = Z_DATA_ERROR; - } - return r; -} - - -int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z) -uInt nl; /* number of literal/length codes */ -uInt nd; /* number of distance codes */ -uIntf *c; /* that many (total) code lengths */ -uIntf *bl; /* literal desired/actual bit depth */ -uIntf *bd; /* distance desired/actual bit depth */ -inflate_huft * FAR *tl; /* literal/length tree result */ -inflate_huft * FAR *td; /* distance tree result */ -z_streamp z; /* for zfree function */ -{ - int r; - - /* build literal/length tree */ - r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z); - if (r != Z_OK || *bl == 0) - { - if (r == Z_DATA_ERROR) - z->msg = (char*)"oversubscribed literal/length tree"; - else if (r != Z_MEM_ERROR) - { - inflate_trees_free(*tl, z); - z->msg = (char*)"incomplete literal/length tree"; - r = Z_DATA_ERROR; - } - return r; - } - - /* build distance tree */ - r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z); - if (r != Z_OK || (*bd == 0 && nl > 257)) - { - if (r == Z_DATA_ERROR) - z->msg = (char*)"oversubscribed distance tree"; - else if (r == Z_BUF_ERROR) { -#ifdef PKZIP_BUG_WORKAROUND - r = Z_OK; - } -#else - inflate_trees_free(*td, z); - z->msg = (char*)"incomplete distance tree"; - r = Z_DATA_ERROR; - } - else if (r != Z_MEM_ERROR) - { - z->msg = (char*)"empty distance tree with lengths"; - r = Z_DATA_ERROR; - } - inflate_trees_free(*tl, z); - return r; -#endif - } - - /* done */ - return Z_OK; -} - - -/* build fixed tables only once--keep them here */ -local int fixed_built = 0; -#define FIXEDH 530 /* number of hufts used by fixed tables */ -local inflate_huft fixed_mem[FIXEDH]; -local uInt fixed_bl; -local uInt fixed_bd; -local inflate_huft *fixed_tl; -local inflate_huft *fixed_td; - - -local voidpf falloc(q, n, s) -voidpf q; /* opaque pointer */ -uInt n; /* number of items */ -uInt s; /* size of item */ -{ - Assert(s == sizeof(inflate_huft) && n <= *(intf *)q, - "inflate_trees falloc overflow"); - *(intf *)q -= n+s-s; /* s-s to avoid warning */ - return (voidpf)(fixed_mem + *(intf *)q); -} - - -int inflate_trees_fixed(bl, bd, tl, td) -uIntf *bl; /* literal desired/actual bit depth */ -uIntf *bd; /* distance desired/actual bit depth */ -inflate_huft * FAR *tl; /* literal/length tree result */ -inflate_huft * FAR *td; /* distance tree result */ -{ - /* build fixed tables if not already (multiple overlapped executions ok) */ - if (!fixed_built) - { - int k; /* temporary variable */ - unsigned c[288]; /* length list for huft_build */ - z_stream z; /* for falloc function */ - int f = FIXEDH; /* number of hufts left in fixed_mem */ - - /* set up fake z_stream for memory routines */ - z.zalloc = falloc; - z.zfree = Z_NULL; - z.opaque = (voidpf)&f; - - /* literal table */ - for (k = 0; k < 144; k++) - c[k] = 8; - for (; k < 256; k++) - c[k] = 9; - for (; k < 280; k++) - c[k] = 7; - for (; k < 288; k++) - c[k] = 8; - fixed_bl = 7; - huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z); - - /* distance table */ - for (k = 0; k < 30; k++) - c[k] = 5; - fixed_bd = 5; - huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z); - - /* done */ - Assert(f == 0, "invalid build of fixed tables"); - fixed_built = 1; - } - *bl = fixed_bl; - *bd = fixed_bd; - *tl = fixed_tl; - *td = fixed_td; - return Z_OK; -} - - -int inflate_trees_free(t, z) -inflate_huft *t; /* table to free */ -z_streamp z; /* for zfree function */ -/* Free the malloc'ed tables built by huft_build(), which makes a linked - list of the tables it made, with the links in a dummy first entry of - each table. */ -{ - register inflate_huft *p, *q, *r; - - /* Reverse linked list */ - p = Z_NULL; - q = t; - while (q != Z_NULL) - { - r = (q - 1)->next; - (q - 1)->next = p; - p = q; - q = r; - } - /* Go through linked list, freeing from the malloced (t[-1]) address. */ - while (p != Z_NULL) - { - q = (--p)->next; - ZFREE(z,p); - p = q; - } - return Z_OK; -} -/* --- inftrees.c */ - -/* +++ infcodes.c */ -/* infcodes.c -- process literals and length/distance pairs - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* #include "zutil.h" */ -/* #include "inftrees.h" */ -/* #include "infblock.h" */ -/* #include "infcodes.h" */ -/* #include "infutil.h" */ - -/* +++ inffast.h */ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -extern int inflate_fast OF(( - uInt, - uInt, - inflate_huft *, - inflate_huft *, - inflate_blocks_statef *, - z_streamp )); -/* --- inffast.h */ - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - -/* inflate codes private state */ -struct inflate_codes_state { - - /* mode */ - enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - START, /* x: set up for LEN */ - LEN, /* i: get length/literal/eob next */ - LENEXT, /* i: getting length extra (have base) */ - DIST, /* i: get distance next */ - DISTEXT, /* i: getting distance extra */ - COPY, /* o: copying bytes in window, waiting for space */ - LIT, /* o: got literal, waiting for output space */ - WASH, /* o: got eob, possibly still output waiting */ - END, /* x: got eob and all data flushed */ - BADCODE} /* x: got error */ - mode; /* current inflate_codes mode */ - - /* mode dependent information */ - uInt len; - union { - struct { - inflate_huft *tree; /* pointer into tree */ - uInt need; /* bits needed */ - } code; /* if LEN or DIST, where in tree */ - uInt lit; /* if LIT, literal */ - struct { - uInt get; /* bits to get for extra */ - uInt dist; /* distance back to copy from */ - } copy; /* if EXT or COPY, where and how much */ - } sub; /* submode */ - - /* mode independent information */ - Byte lbits; /* ltree bits decoded per branch */ - Byte dbits; /* dtree bits decoder per branch */ - inflate_huft *ltree; /* literal/length/eob tree */ - inflate_huft *dtree; /* distance tree */ - -}; - - -inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) -uInt bl, bd; -inflate_huft *tl; -inflate_huft *td; /* need separate declaration for Borland C++ */ -z_streamp z; -{ - inflate_codes_statef *c; - - if ((c = (inflate_codes_statef *) - ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) - { - c->mode = START; - c->lbits = (Byte)bl; - c->dbits = (Byte)bd; - c->ltree = tl; - c->dtree = td; - Tracev((stderr, "inflate: codes new\n")); - } - return c; -} - - -int inflate_codes(s, z, r) -inflate_blocks_statef *s; -z_streamp z; -int r; -{ - uInt j; /* temporary storage */ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - Bytef *f; /* pointer to copy strings from */ - inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ - - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD - - /* process input and output based on current state */ - while (1) switch (c->mode) - { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - case START: /* x: set up for LEN */ -#ifndef SLOW - if (m >= 258 && n >= 10) - { - UPDATE - r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); - LOAD - if (r != Z_OK) - { - c->mode = r == Z_STREAM_END ? WASH : BADCODE; - break; - } - } -#endif /* !SLOW */ - c->sub.code.need = c->lbits; - c->sub.code.tree = c->ltree; - c->mode = LEN; - case LEN: /* i: get length/literal/eob next */ - j = c->sub.code.need; - NEEDBITS(j) - t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); - DUMPBITS(t->bits) - e = (uInt)(t->exop); - if (e == 0) /* literal */ - { - c->sub.lit = t->base; - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", t->base)); - c->mode = LIT; - break; - } - if (e & 16) /* length */ - { - c->sub.copy.get = e & 15; - c->len = t->base; - c->mode = LENEXT; - break; - } - if ((e & 64) == 0) /* next table */ - { - c->sub.code.need = e; - c->sub.code.tree = t->next; - break; - } - if (e & 32) /* end of block */ - { - Tracevv((stderr, "inflate: end of block\n")); - c->mode = WASH; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = (char*)"invalid literal/length code"; - r = Z_DATA_ERROR; - LEAVE - case LENEXT: /* i: getting length extra (have base) */ - j = c->sub.copy.get; - NEEDBITS(j) - c->len += (uInt)b & inflate_mask[j]; - DUMPBITS(j) - c->sub.code.need = c->dbits; - c->sub.code.tree = c->dtree; - Tracevv((stderr, "inflate: length %u\n", c->len)); - c->mode = DIST; - case DIST: /* i: get distance next */ - j = c->sub.code.need; - NEEDBITS(j) - t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); - DUMPBITS(t->bits) - e = (uInt)(t->exop); - if (e & 16) /* distance */ - { - c->sub.copy.get = e & 15; - c->sub.copy.dist = t->base; - c->mode = DISTEXT; - break; - } - if ((e & 64) == 0) /* next table */ - { - c->sub.code.need = e; - c->sub.code.tree = t->next; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = (char*)"invalid distance code"; - r = Z_DATA_ERROR; - LEAVE - case DISTEXT: /* i: getting distance extra */ - j = c->sub.copy.get; - NEEDBITS(j) - c->sub.copy.dist += (uInt)b & inflate_mask[j]; - DUMPBITS(j) - Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); - c->mode = COPY; - case COPY: /* o: copying bytes in window, waiting for space */ -#ifndef __TURBOC__ /* Turbo C bug for following expression */ - f = (uInt)(q - s->window) < c->sub.copy.dist ? - s->end - (c->sub.copy.dist - (q - s->window)) : - q - c->sub.copy.dist; -#else - f = q - c->sub.copy.dist; - if ((uInt)(q - s->window) < c->sub.copy.dist) - f = s->end - (c->sub.copy.dist - (uInt)(q - s->window)); -#endif - while (c->len) - { - NEEDOUT - OUTBYTE(*f++) - if (f == s->end) - f = s->window; - c->len--; - } - c->mode = START; - break; - case LIT: /* o: got literal, waiting for output space */ - NEEDOUT - OUTBYTE(c->sub.lit) - c->mode = START; - break; - case WASH: /* o: got eob, possibly more output */ - FLUSH - if (s->read != s->write) - LEAVE - c->mode = END; - case END: - r = Z_STREAM_END; - LEAVE - case BADCODE: /* x: got error */ - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } -} - - -void inflate_codes_free(c, z) -inflate_codes_statef *c; -z_streamp z; -{ - ZFREE(z, c); - Tracev((stderr, "inflate: codes free\n")); -} -/* --- infcodes.c */ - -/* +++ infutil.c */ -/* inflate_util.c -- data and routines common to blocks and codes - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* #include "zutil.h" */ -/* #include "infblock.h" */ -/* #include "inftrees.h" */ -/* #include "infcodes.h" */ -/* #include "infutil.h" */ - -#ifndef NO_DUMMY_DECL -struct inflate_codes_state {int dummy;}; /* for buggy compilers */ -#endif - -/* And'ing with mask[n] masks the lower n bits */ -uInt inflate_mask[17] = { - 0x0000, - 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, - 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff -}; - - -/* copy as much as possible from the sliding window to the output area */ -int inflate_flush(s, z, r) -inflate_blocks_statef *s; -z_streamp z; -int r; -{ - uInt n; - Bytef *p; - Bytef *q; - - /* local copies of source and destination pointers */ - p = z->next_out; - q = s->read; - - /* compute number of bytes to copy as far as end of window */ - n = (uInt)((q <= s->write ? s->write : s->end) - q); - if (n > z->avail_out) n = z->avail_out; - if (n && r == Z_BUF_ERROR) r = Z_OK; - - /* update counters */ - z->avail_out -= n; - z->total_out += n; - - /* update check information */ - if (s->checkfn != Z_NULL) - z->adler = s->check = (*s->checkfn)(s->check, q, n); - - /* copy as far as end of window */ - if (p != Z_NULL) { - zmemcpy(p, q, n); - p += n; - } - q += n; - - /* see if more to copy at beginning of window */ - if (q == s->end) - { - /* wrap pointers */ - q = s->window; - if (s->write == s->end) - s->write = s->window; - - /* compute bytes to copy */ - n = (uInt)(s->write - q); - if (n > z->avail_out) n = z->avail_out; - if (n && r == Z_BUF_ERROR) r = Z_OK; - - /* update counters */ - z->avail_out -= n; - z->total_out += n; - - /* update check information */ - if (s->checkfn != Z_NULL) - z->adler = s->check = (*s->checkfn)(s->check, q, n); - - /* copy */ - if (p != Z_NULL) { - zmemcpy(p, q, n); - p += n; - } - q += n; - } - - /* update pointers */ - z->next_out = p; - s->read = q; - - /* done */ - return r; -} -/* --- infutil.c */ - -/* +++ inffast.c */ -/* inffast.c -- process literals and length/distance pairs fast - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* #include "zutil.h" */ -/* #include "inftrees.h" */ -/* #include "infblock.h" */ -/* #include "infcodes.h" */ -/* #include "infutil.h" */ -/* #include "inffast.h" */ - -#ifndef NO_DUMMY_DECL -struct inflate_codes_state {int dummy;}; /* for buggy compilers */ -#endif - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - -/* macros for bit input with no checking and for returning unused bytes */ -#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<>3);p-=c;k&=7;} - -/* Called with number of bytes left to write in window at least 258 - (the maximum string length) and number of input bytes available - at least ten. The ten bytes are six bytes for the longest length/ - distance pair plus four bytes for overloading the bit buffer. */ - -int inflate_fast(bl, bd, tl, td, s, z) -uInt bl, bd; -inflate_huft *tl; -inflate_huft *td; /* need separate declaration for Borland C++ */ -inflate_blocks_statef *s; -z_streamp z; -{ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - uInt ml; /* mask for literal/length tree */ - uInt md; /* mask for distance tree */ - uInt c; /* bytes to copy */ - uInt d; /* distance back to copy from */ - Bytef *r; /* copy source pointer */ - - /* load input, output, bit values */ - LOAD - - /* initialize masks */ - ml = inflate_mask[bl]; - md = inflate_mask[bd]; - - /* do until not enough input or output space for fast loop */ - do { /* assume called with m >= 258 && n >= 10 */ - /* get literal/length code */ - GRABBITS(20) /* max bits for literal/length code */ - if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) - { - DUMPBITS(t->bits) - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base)); - *q++ = (Byte)t->base; - m--; - continue; - } - do { - DUMPBITS(t->bits) - if (e & 16) - { - /* get extra bits for length */ - e &= 15; - c = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e) - Tracevv((stderr, "inflate: * length %u\n", c)); - - /* decode distance base of block to copy */ - GRABBITS(15); /* max bits for distance code */ - e = (t = td + ((uInt)b & md))->exop; - do { - DUMPBITS(t->bits) - if (e & 16) - { - /* get extra bits to add to distance base */ - e &= 15; - GRABBITS(e) /* get extra bits (up to 13) */ - d = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e) - Tracevv((stderr, "inflate: * distance %u\n", d)); - - /* do the copy */ - m -= c; - if ((uInt)(q - s->window) >= d) /* offset before dest */ - { /* just copy */ - r = q - d; - *q++ = *r++; c--; /* minimum count is three, */ - *q++ = *r++; c--; /* so unroll loop a little */ - } - else /* else offset after destination */ - { - e = d - (uInt)(q - s->window); /* bytes from offset to end */ - r = s->end - e; /* pointer to offset */ - if (c > e) /* if source crosses, */ - { - c -= e; /* copy to end of window */ - do { - *q++ = *r++; - } while (--e); - r = s->window; /* copy rest from start of window */ - } - } - do { /* copy all or what's left */ - *q++ = *r++; - } while (--c); - break; - } - else if ((e & 64) == 0) - e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop; - else - { - z->msg = (char*)"invalid distance code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while (1); - break; - } - if ((e & 64) == 0) - { - if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0) - { - DUMPBITS(t->bits) - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base)); - *q++ = (Byte)t->base; - m--; - break; - } - } - else if (e & 32) - { - Tracevv((stderr, "inflate: * end of block\n")); - UNGRAB - UPDATE - return Z_STREAM_END; - } - else - { - z->msg = (char*)"invalid literal/length code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while (1); - } while (m >= 258 && n >= 10); - - /* not enough input or output--restore pointers and return */ - UNGRAB - UPDATE - return Z_OK; -} -/* --- inffast.c */ - -/* +++ zutil.c */ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-1996 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: zutil.c,v 1.17 1996/07/24 13:41:12 me Exp $ */ - -/* #include "zutil.h" */ - -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - -#ifndef STDC -extern void exit OF((int)); -#endif - -const char *z_errmsg[10] = { -"need dictionary", /* Z_NEED_DICT 2 */ -"stream end", /* Z_STREAM_END 1 */ -"", /* Z_OK 0 */ -"file error", /* Z_ERRNO (-1) */ -"stream error", /* Z_STREAM_ERROR (-2) */ -"data error", /* Z_DATA_ERROR (-3) */ -"insufficient memory", /* Z_MEM_ERROR (-4) */ -"buffer error", /* Z_BUF_ERROR (-5) */ -"incompatible version",/* Z_VERSION_ERROR (-6) */ -""}; - - -const char *zlibVersion() -{ - return ZLIB_VERSION; -} - -#ifdef DEBUG_ZLIB -void z_error (m) - char *m; -{ - fprintf(stderr, "%s\n", m); - exit(1); -} -#endif - -#ifndef HAVE_MEMCPY - -void zmemcpy(dest, source, len) - Bytef* dest; - Bytef* source; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = *source++; /* ??? to be unrolled */ - } while (--len != 0); -} - -int zmemcmp(s1, s2, len) - Bytef* s1; - Bytef* s2; - uInt len; -{ - uInt j; - - for (j = 0; j < len; j++) { - if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; - } - return 0; -} - -void zmemzero(dest, len) - Bytef* dest; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = 0; /* ??? to be unrolled */ - } while (--len != 0); -} -#endif - -#ifdef __TURBOC__ -#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__) -/* Small and medium model in Turbo C are for now limited to near allocation - * with reduced MAX_WBITS and MAX_MEM_LEVEL - */ -# define MY_ZCALLOC - -/* Turbo C malloc() does not allow dynamic allocation of 64K bytes - * and farmalloc(64K) returns a pointer with an offset of 8, so we - * must fix the pointer. Warning: the pointer must be put back to its - * original form in order to free it, use zcfree(). - */ - -#define MAX_PTR 10 -/* 10*64K = 640K */ - -local int next_ptr = 0; - -typedef struct ptr_table_s { - voidpf org_ptr; - voidpf new_ptr; -} ptr_table; - -local ptr_table table[MAX_PTR]; -/* This table is used to remember the original form of pointers - * to large buffers (64K). Such pointers are normalized with a zero offset. - * Since MSDOS is not a preemptive multitasking OS, this table is not - * protected from concurrent access. This hack doesn't work anyway on - * a protected system like OS/2. Use Microsoft C instead. - */ - -voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - voidpf buf = opaque; /* just to make some compilers happy */ - ulg bsize = (ulg)items*size; - - /* If we allocate less than 65520 bytes, we assume that farmalloc - * will return a usable pointer which doesn't have to be normalized. - */ - if (bsize < 65520L) { - buf = farmalloc(bsize); - if (*(ush*)&buf != 0) return buf; - } else { - buf = farmalloc(bsize + 16L); - } - if (buf == NULL || next_ptr >= MAX_PTR) return NULL; - table[next_ptr].org_ptr = buf; - - /* Normalize the pointer to seg:0 */ - *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; - *(ush*)&buf = 0; - table[next_ptr++].new_ptr = buf; - return buf; -} - -void zcfree (voidpf opaque, voidpf ptr) -{ - int n; - if (*(ush*)&ptr != 0) { /* object < 64K */ - farfree(ptr); - return; - } - /* Find the original pointer */ - for (n = 0; n < next_ptr; n++) { - if (ptr != table[n].new_ptr) continue; - - farfree(table[n].org_ptr); - while (++n < next_ptr) { - table[n-1] = table[n]; - } - next_ptr--; - return; - } - ptr = opaque; /* just to make some compilers happy */ - Assert(0, "zcfree: ptr not found"); -} -#endif -#endif /* __TURBOC__ */ - - -#if defined(M_I86) && !defined(__32BIT__) -/* Microsoft C in 16-bit mode */ - -# define MY_ZCALLOC - -#if (!defined(_MSC_VER) || (_MSC_VER < 600)) -# define _halloc halloc -# define _hfree hfree -#endif - -voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - return _halloc((long)items, size); -} - -void zcfree (voidpf opaque, voidpf ptr) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - _hfree(ptr); -} - -#endif /* MSC */ - - -#ifndef MY_ZCALLOC /* Any system without a special alloc function */ - -#ifndef STDC -extern voidp calloc OF((uInt items, uInt size)); -extern void free OF((voidpf ptr)); -#endif - -voidpf zcalloc (opaque, items, size) - voidpf opaque; - unsigned items; - unsigned size; -{ - if (opaque) items += size - size; /* make compiler happy */ - return (voidpf)calloc(items, size); -} - -void zcfree (opaque, ptr) - voidpf opaque; - voidpf ptr; -{ - free(ptr); - if (opaque) return; /* make compiler happy */ -} - -#endif /* MY_ZCALLOC */ -/* --- zutil.c */ - -/* +++ adler32.c */ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: adler32.c,v 1.10 1996/05/22 11:52:18 me Exp $ */ - -/* #include "zlib.h" */ - -#define BASE 65521L /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - -/* ========================================================================= */ -uLong adler32(adler, buf, len) - uLong adler; - const Bytef *buf; - uInt len; -{ - unsigned long s1 = adler & 0xffff; - unsigned long s2 = (adler >> 16) & 0xffff; - int k; - - if (buf == Z_NULL) return 1L; - - while (len > 0) { - k = len < NMAX ? len : NMAX; - len -= k; - while (k >= 16) { - DO16(buf); - buf += 16; - k -= 16; - } - if (k != 0) do { - s1 += *buf++; - s2 += s1; - } while (--k); - s1 %= BASE; - s2 %= BASE; - } - return (s2 << 16) | s1; -} -/* --- adler32.c */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jffs2/zlib.h linux.19pre5-ac1/fs/jffs2/zlib.h --- linux.19p5/fs/jffs2/zlib.h Thu Apr 4 13:18:15 2002 +++ linux.19pre5-ac1/fs/jffs2/zlib.h Thu Jan 1 01:00:00 1970 @@ -1,1010 +0,0 @@ -/* $Id: zlib.h,v 1.2 1997/12/23 10:47:44 paulus Exp $ */ - -/* - * This file is derived from zlib.h and zconf.h from the zlib-1.0.4 - * distribution by Jean-loup Gailly and Mark Adler, with some additions - * by Paul Mackerras to aid in implementing Deflate compression and - * decompression for PPP packets. - */ - -/* - * ==FILEVERSION 971127== - * - * This marker is used by the Linux installation script to determine - * whether an up-to-date version of this file is already installed. - */ - - -/* +++ zlib.h */ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.0.4, Jul 24th, 1996. - - Copyright (C) 1995-1996 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - gzip@prep.ai.mit.edu madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt - (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). -*/ - -#ifndef _ZLIB_H -#define _ZLIB_H - -#ifdef __cplusplus -extern "C" { -#endif - - -/* +++ zconf.h */ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-1996 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: zconf.h,v 1.20 1996/07/02 15:09:28 me Exp $ */ - -#ifndef _ZCONF_H -#define _ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - */ -#ifdef Z_PREFIX -# define deflateInit_ z_deflateInit_ -# define deflate z_deflate -# define deflateEnd z_deflateEnd -# define inflateInit_ z_inflateInit_ -# define inflate z_inflate -# define inflateEnd z_inflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateSetDictionary z_deflateSetDictionary -# define deflateCopy z_deflateCopy -# define deflateReset z_deflateReset -# define deflateParams z_deflateParams -# define inflateInit2_ z_inflateInit2_ -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateReset z_inflateReset -# define compress z_compress -# define uncompress z_uncompress -# define adler32 z_adler32 -# define crc32 z_crc32 -# define get_crc_table z_get_crc_table - -# define Byte z_Byte -# define uInt z_uInt -# define uLong z_uLong -# define Bytef z_Bytef -# define charf z_charf -# define intf z_intf -# define uIntf z_uIntf -# define uLongf z_uLongf -# define voidpf z_voidpf -# define voidp z_voidp -#endif - -#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) -# define WIN32 -#endif -#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) -# ifndef __32BIT__ -# define __32BIT__ -# endif -#endif -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#if defined(MSDOS) && !defined(__32BIT__) -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) -# define STDC -#endif -#if (defined(__STDC__) || defined(__cplusplus)) && !defined(STDC) -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const -# endif -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2 */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - 1 << (windowBits+2) + 1 << (memLevel+9) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR __far -# else -# define FAR far -# endif -#endif -#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) -# ifndef __32BIT__ -# define SMALL_MEDIUM -# define FAR __far -# endif -#endif -#ifndef FAR -# define FAR -#endif - -typedef unsigned char Byte; /* 8 bits */ -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#if defined(__BORLANDC__) && defined(SMALL_MEDIUM) - /* Borland C/C++ ignores FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - - -/* Compile with -DZLIB_DLL for Windows DLL support */ -#if (defined(_WINDOWS) || defined(WINDOWS)) && defined(ZLIB_DLL) -# include -# define EXPORT WINAPI -#else -# define EXPORT -#endif - -#endif /* _ZCONF_H */ -/* --- zconf.h */ - -#define ZLIB_VERSION "1.0.4P" - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed - data. This version of the library supports only one compression method - (deflation) but other algorithms may be added later and will have the same - stream interface. - - For compression the application must provide the output buffer and - may optionally provide the input buffer for optimization. For decompression, - the application must provide the input buffer and may optionally provide - the output buffer for optimization. - - Compression can be done in a single step if the buffers are large - enough (for example if an input file is mmap'ed), or can be done by - repeated calls of the compression function. In the latter case, the - application must provide more input and/or consume the output - (providing more output space) before each call. - - The library does not install any signal handler. It is recommended to - add at least a handler for SIGSEGV when decompressing; the library checks - the consistency of the input data whenever possible but may go nuts - for some forms of corrupted input. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); - -struct internal_state; - -typedef struct z_stream_s { - Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total nb of input bytes read so far */ - - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total nb of bytes output so far */ - - char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: ascii or binary */ - uLong adler; /* adler32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - The application must update next_in and avail_in when avail_in has - dropped to zero. It must update next_out and avail_out when avail_out - has dropped to zero. The application must initialize zalloc, zfree and - opaque before calling the init function. All other fields are set by the - compression library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this - if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, - pointers returned by zalloc for objects of exactly 65536 bytes *must* - have their offset normalized to zero. The default allocation function - provided by this library ensures this (see zutil.c). To reduce memory - requirements and avoid any allocation of 64K objects, at the expense of - compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or - progress reports. After compression, total_in holds the total size of - the uncompressed data and may be saved for use in the decompressor - (particularly if the decompressor wants to decompress everything in - a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_PACKET_FLUSH 2 -#define Z_SYNC_FLUSH 3 -#define Z_FULL_FLUSH 4 -#define Z_FINISH 5 -/* Allowed flush values; see deflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative - * values are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_ASCII 1 -#define Z_UNKNOWN 2 -/* Possible values of the data_type field */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - /* basic functions */ - -extern const char * EXPORT zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is - not compatible with the zlib.h header file used by the application. - This check is automatically made by deflateInit and inflateInit. - */ - -/* -extern int EXPORT deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. - If zalloc and zfree are set to Z_NULL, deflateInit updates them to - use default allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at - all (the input data is simply copied a block at a time). - Z_DEFAULT_COMPRESSION requests a default compromise between speed and - compression (currently equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if level is not a valid compression level, - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). - msg is set to null if there is no error message. deflateInit does not - perform any compression: this will be done by deflate(). -*/ - - -extern int EXPORT deflate OF((z_streamp strm, int flush)); -/* - Performs one or both of the following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). - Some output may be provided even if flush is not set. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating avail_in or avail_out accordingly; avail_out - should never be zero before the call. The application can consume the - compressed output when it wants, for example when the output buffer is full - (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK - and with zero avail_out, it must be called again after making room in the - output buffer because there might be more output pending. - - If the parameter flush is set to Z_PARTIAL_FLUSH, the current compression - block is terminated and flushed to the output buffer so that the - decompressor can get all input data available so far. For method 9, a future - variant on method 8, the current block will be flushed but not terminated. - Z_SYNC_FLUSH has the same effect as partial flush except that the compressed - output is byte aligned (the compressor can clear its internal bit buffer) - and the current block is always terminated; this can be useful if the - compressor has to be restarted from scratch after an interruption (in which - case the internal state of the compressor may be lost). - If flush is set to Z_FULL_FLUSH, the compression block is terminated, a - special marker is output and the compression dictionary is discarded; this - is useful to allow the decompressor to synchronize if one compressed block - has been damaged (see inflateSync below). Flushing degrades compression and - so should be used only when necessary. Using Z_FULL_FLUSH too often can - seriously degrade the compression. If deflate returns with avail_out == 0, - this function must be called again with the same value of the flush - parameter and more output space (updated avail_out), until the flush is - complete (deflate returns with non-zero avail_out). - - If the parameter flush is set to Z_PACKET_FLUSH, the compression - block is terminated, and a zero-length stored block is output, - omitting the length bytes (the effect of this is that the 3-bit type - code 000 for a stored block is output, and the output is then - byte-aligned). This is designed for use at the end of a PPP packet. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there - was enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the - stream are deflateReset or deflateEnd. - - Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least - 0.1% larger than avail_in plus 12 bytes. If deflate does not return - Z_STREAM_END, then it must be called again as described above. - - deflate() may update data_type if it can make a good guess about - the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered - binary. This field is only for information purposes and does not affect - the compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible. -*/ - - -extern int EXPORT deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, - msg may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -extern int EXPORT inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - zalloc, zfree and opaque must be initialized before by the caller. If - zalloc and zfree are set to Z_NULL, inflateInit updates them to use default - allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_VERSION_ERROR if the zlib library version is incompatible - with the version assumed by the caller. msg is set to null if there is no - error message. inflateInit does not perform any decompression: this will be - done by inflate(). -*/ - - -extern int EXPORT inflate OF((z_streamp strm, int flush)); -/* - Performs one or both of the following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing - will resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there - is no more input data or no more space in the output buffer (see below - about the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating the next_* and avail_* values accordingly. - The application can consume the uncompressed output when it wants, for - example when the output buffer is full (avail_out == 0), or after each - call of inflate(). If inflate returns Z_OK and with zero avail_out, it - must be called again after making room in the output buffer because there - might be more output pending. - - If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH, - inflate flushes as much output as possible to the output buffer. The - flushing behavior of inflate is not specified for values of the flush - parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the - current implementation actually flushes as much output as possible - anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data - has been consumed, it is expecting to see the length field of a stored - block; if not, it returns Z_DATA_ERROR. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step - (a single call of inflate), the parameter flush should be set to - Z_FINISH. In this case all pending input is processed and all pending - output is flushed; avail_out must be large enough to hold all the - uncompressed data. (The size of the uncompressed data may have been saved - by the compressor for this purpose.) The next operation on this stream must - be inflateEnd to deallocate the decompression state. The use of Z_FINISH - is never required, but can be used to inform inflate that a faster routine - may be used for the single inflate() call. - - inflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if the end of the - compressed data has been reached and all uncompressed output has been - produced, Z_NEED_DICT if a preset dictionary is needed at this point (see - inflateSetDictionary below), Z_DATA_ERROR if the input data was corrupted, - Z_STREAM_ERROR if the stream structure was inconsistent (for example if - next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, - Z_BUF_ERROR if no progress is possible or if there was not enough room in - the output buffer when Z_FINISH is used. In the Z_DATA_ERROR case, the - application may then call inflateSync to look for a good compression block. - In the Z_NEED_DICT case, strm->adler is set to the Adler32 value of the - dictionary chosen by the compressor. -*/ - - -extern int EXPORT inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -extern int EXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by - the caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. (Method 9 will allow a 64K history buffer and - partial block flushes.) - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library (the value 16 will be allowed for method 9). Larger - values of this parameter result in better compression at the expense of - memory usage. The default value is 15 if deflateInit is used instead. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but - is slow and reduces compression ratio; memLevel=9 uses maximum memory - for optimal speed. The default value is 8. See zconf.h for total memory - usage as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match). Filtered data consists mostly of small values with a - somewhat random distribution. In this case, the compression algorithm is - tuned to compress them better. The effect of Z_FILTERED is to force more - Huffman coding and less string matching; it is somewhat intermediate - between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects - the compression ratio but not the correctness of the compressed output even - if it is not set appropriately. - - If next_in is not null, the library will use this buffer to hold also - some history information; the buffer must either hold the entire input - data, or have at least 1<<(windowBits+1) bytes and be writable. If next_in - is null, the library will allocate its own history buffer (and leave next_in - null). next_out need not be provided here but must be provided by the - application for the next call of deflate(). - - If the history buffer is provided by the application, next_in must - must never be changed by the application since the compressor maintains - information inside this buffer from call to call; the application - must provide more input only by increasing avail_in. next_in is always - reset by the library in this case. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was - not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as - an invalid method). msg is set to null if there is no error message. - deflateInit2 does not perform any compression: this will be done by - deflate(). -*/ - -extern int EXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the compression dictionary (history buffer) from the given - byte sequence without producing any compressed output. This function must - be called immediately after deflateInit or deflateInit2, before any call - of deflate. The compressor and decompressor must use exactly the same - dictionary (see inflateSetDictionary). - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and - can be predicted with good accuracy; the data can then be compressed better - than with the default empty dictionary. In this version of the library, - only the last 32K bytes of the dictionary are used. - Upon return of this function, strm->adler is set to the Adler32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The Adler32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state - is inconsistent (for example if deflate has already been called for this - stream). deflateSetDictionary does not perform any compression: this will - be done by deflate(). -*/ - -extern int EXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. If - the source stream is using an application-supplied history buffer, a new - buffer is allocated for the destination stream. The compressed output - buffer is always application-supplied. It's the responsibility of the - application to provide the correct values of next_out and avail_out for the - next call of deflate. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and - can consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being NULL). msg is left unchanged in both source and - destination. -*/ - -extern int EXPORT deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, - but does not free and reallocate all the internal compression state. - The stream will keep the same compression level and any other attributes - that may have been set by deflateInit2. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - -extern int EXPORT deflateParams OF((z_streamp strm, int level, int strategy)); -/* - Dynamically update the compression level and compression strategy. - This can be used to switch between compression and straight copy of - the input data, or to switch to a different kind of input data requiring - a different strategy. If the compression level is changed, the input - available so far is compressed with the old level (and may be flushed); - the new level will take effect only at the next call of deflate(). - - Before the call of deflateParams, the stream state must be set as for - a call of deflate(), since the currently available input may have to - be compressed and flushed. In particular, strm->avail_out must be non-zero. - - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR - if strm->avail_out was zero. -*/ - -extern int EXPORT deflateOutputPending OF((z_streamp strm)); -/* - Returns the number of bytes of output which are immediately - available from the compressor (i.e. without any further input - or flush). -*/ - -/* -extern int EXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with more compression options. The - fields next_out, zalloc, zfree and opaque must be initialized before by - the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library (the value 16 will be allowed soon). The - default value is 15 if inflateInit is used instead. If a compressed stream - with a larger window size is given as input, inflate() will return with - the error code Z_DATA_ERROR instead of trying to allocate a larger window. - - If next_out is not null, the library will use this buffer for the history - buffer; the buffer must either be large enough to hold the entire output - data, or have at least 1<> 16) )); \ +}) + +#if (defined(__KERNEL__) && defined(__LITTLE_ENDIAN)) || (defined(__BYTE_ORDER) && (__BYTE_ORDER == __LITTLE_ENDIAN)) + #define __cpu_to_le24(x) ((__u32)(x)) + #define __le24_to_cpu(x) ((__u32)(x)) +#else + #define __cpu_to_le24(x) __swab24(x) + #define __le24_to_cpu(x) __swab24(x) +#endif + +#ifdef __KERNEL__ + #define cpu_to_le24 __cpu_to_le24 + #define le24_to_cpu __le24_to_cpu +#endif + +#endif /* !_H_ENDIAN24 */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/file.c linux.19pre5-ac1/fs/jfs/file.c --- linux.19p5/fs/jfs/file.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/file.c Thu Feb 14 20:46:53 2002 @@ -0,0 +1,102 @@ +/* + * + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include "jfs_incore.h" +#include "jfs_txnmgr.h" +#include "jfs_debug.h" + + +extern int jfs_commit_inode(struct inode *, int); + +int jfs_fsync(struct file *file, struct dentry *dentry, int datasync) +{ + struct inode *inode = dentry->d_inode; + int rc = 0; + + rc = fsync_inode_data_buffers(inode); + + if (!(inode->i_state & I_DIRTY)) + return rc; + if (datasync || !(inode->i_state & I_DIRTY_DATASYNC)) + return rc; + + IWRITE_LOCK(inode); + rc |= jfs_commit_inode(inode, 1); + IWRITE_UNLOCK(inode); + + return rc ? -EIO : 0; +} + +struct file_operations jfs_file_operations = { + open: generic_file_open, + llseek: generic_file_llseek, + write: generic_file_write, + read: generic_file_read, + mmap: generic_file_mmap, + fsync: jfs_fsync, +}; + +/* + * Guts of jfs_truncate. Called with locks already held. Can be called + * with directory for truncating directory index table. + */ +void jfs_truncate_nolock(struct inode *ip, loff_t length) +{ + loff_t newsize; + tid_t tid; + + ASSERT(length >= 0); + + if (test_cflag(COMMIT_Nolink, ip)) { + xtTruncate(0, ip, length, COMMIT_WMAP); + return; + } + + do { + tid = txBegin(ip->i_sb, 0); + + newsize = xtTruncate(tid, ip, length, + COMMIT_TRUNCATE | COMMIT_PWMAP); + if (newsize < 0) { + txEnd(tid); + break; + } + + ip->i_mtime = ip->i_ctime = CURRENT_TIME; + mark_inode_dirty(ip); + + txCommit(tid, 1, &ip, 0); + txEnd(tid); + } while (newsize > length); /* Truncate isn't always atomic */ +} + +static void jfs_truncate(struct inode *ip) +{ + jFYI(1, ("jfs_truncate: size = 0x%lx\n", (ulong) ip->i_size)); + + IWRITE_LOCK(ip); + jfs_truncate_nolock(ip, ip->i_size); + IWRITE_UNLOCK(ip); +} + +struct inode_operations jfs_file_inode_operations = { + truncate: jfs_truncate, +}; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/inode.c linux.19pre5-ac1/fs/jfs/inode.c --- linux.19p5/fs/jfs/inode.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/inode.c Thu Feb 14 20:46:53 2002 @@ -0,0 +1,325 @@ +/* + * + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include "jfs_incore.h" +#include "jfs_filsys.h" +#include "jfs_imap.h" +#include "jfs_extent.h" +#include "jfs_unicode.h" +#include "jfs_debug.h" + + +extern struct inode_operations jfs_dir_inode_operations; +extern struct inode_operations jfs_file_inode_operations; +extern struct inode_operations jfs_symlink_inode_operations; +extern struct file_operations jfs_dir_operations; +extern struct file_operations jfs_file_operations; +struct address_space_operations jfs_aops; +extern int freeZeroLink(struct inode *); + +void jfs_put_inode(struct inode *inode) +{ + jFYI(1, ("In jfs_put_inode, inode = 0x%p\n", inode)); +} + +void jfs_read_inode(struct inode *inode) +{ + int rc; + + rc = alloc_jfs_inode(inode); + if (rc) { + printk(__FUNCTION__ ": failed."); + goto bad_inode; + } + jFYI(1, ("In jfs_read_inode, inode = 0x%p\n", inode)); + + if (diRead(inode)) + goto bad_inode_free; + + if (S_ISREG(inode->i_mode)) { + inode->i_op = &jfs_file_inode_operations; + inode->i_fop = &jfs_file_operations; + inode->i_mapping->a_ops = &jfs_aops; + } else if (S_ISDIR(inode->i_mode)) { + inode->i_op = &jfs_dir_inode_operations; + inode->i_fop = &jfs_dir_operations; + inode->i_mapping->a_ops = &jfs_aops; + inode->i_mapping->gfp_mask = GFP_NOFS; + } else if (S_ISLNK(inode->i_mode)) { + if (inode->i_size > IDATASIZE) { + inode->i_op = &page_symlink_inode_operations; + inode->i_mapping->a_ops = &jfs_aops; + } else + inode->i_op = &jfs_symlink_inode_operations; + } else { + init_special_inode(inode, inode->i_mode, + kdev_t_to_nr(inode->i_rdev)); + } + + return; + + bad_inode_free: + free_jfs_inode(inode); + bad_inode: + make_bad_inode(inode); +} + +/* This define is from fs/open.c */ +#define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m)) + +/* + * Workhorse of both fsync & write_inode + */ +int jfs_commit_inode(struct inode *inode, int wait) +{ + int rc = 0; + tid_t tid; + static int noisy = 5; + + jFYI(1, ("In jfs_commit_inode, inode = 0x%p\n", inode)); + + /* + * Don't commit if inode has been committed since last being + * marked dirty, or if it has been deleted. + */ + if (test_cflag(COMMIT_Nolink, inode) || + !test_cflag(COMMIT_Dirty, inode)) + return 0; + + if (isReadOnly(inode)) { + /* kernel allows writes to devices on read-only + * partitions and may think inode is dirty + */ + if (!special_file(inode->i_mode) && noisy) { + jERROR(1, ("jfs_commit_inode(0x%p) called on " + "read-only volume\n", inode)); + jERROR(1, ("Is remount racy?\n")); + noisy--; + } + return 0; + } + + tid = txBegin(inode->i_sb, COMMIT_INODE); + rc = txCommit(tid, 1, &inode, wait ? COMMIT_SYNC : 0); + txEnd(tid); + return -rc; +} + +void jfs_write_inode(struct inode *inode, int wait) +{ + /* + * If COMMIT_DIRTY is not set, the inode isn't really dirty. + * It has been committed since the last change, but was still + * on the dirty inode list + */ + if (test_cflag(COMMIT_Nolink, inode) || + !test_cflag(COMMIT_Dirty, inode)) + return; + + IWRITE_LOCK(inode); + + if (jfs_commit_inode(inode, wait)) { + jERROR(1, ("jfs_write_inode: jfs_commit_inode failed!\n")); + } + + IWRITE_UNLOCK(inode); +} + +void jfs_delete_inode(struct inode *inode) +{ + jFYI(1, ("In jfs_delete_inode, inode = 0x%p\n", inode)); + + IWRITE_LOCK(inode); + if (test_cflag(COMMIT_Freewmap, inode)) + freeZeroLink(inode); + + diFree(inode); + IWRITE_UNLOCK(inode); + + clear_inode(inode); +} + +void jfs_dirty_inode(struct inode *inode) +{ + static int noisy = 5; + + if (isReadOnly(inode)) { + if (!special_file(inode->i_mode) && noisy) { + /* kernel allows writes to devices on read-only + * partitions and may try to mark inode dirty + */ + jERROR(1, ("jfs_dirty_inode called on " + "read-only volume\n")); + jERROR(1, ("Is remount racy?\n")); + noisy--; + } + return; + } + + set_cflag(COMMIT_Dirty, inode); +} + +static int jfs_get_block(struct inode *ip, long lblock, + struct buffer_head *bh_result, int create) +{ + s64 lblock64 = lblock; + int no_size_check = 0; + int rc = 0; + int take_locks; + xad_t xad; + s64 xaddr; + int xflag; + s32 xlen; + + /* + * If this is a special inode (imap, dmap) or directory, + * the lock should already be taken + */ + take_locks = ((JFS_IP(ip)->fileset != AGGREGATE_I) && + !S_ISDIR(ip->i_mode)); + /* + * Take appropriate lock on inode + */ + if (take_locks) { + if (create) + IWRITE_LOCK(ip); + else + IREAD_LOCK(ip); + } + + /* + * A directory's "data" is the inode index table, but i_size is the + * size of the d-tree, so don't check the offset against i_size + */ + if (S_ISDIR(ip->i_mode)) + no_size_check = 1; + + if ((no_size_check || + ((lblock64 << ip->i_sb->s_blocksize_bits) < ip->i_size)) && + (xtLookup + (ip, lblock64, 1, &xflag, &xaddr, &xlen, no_size_check) + == 0) && xlen) { + if (xflag & XAD_NOTRECORDED) { + if (!create) + /* + * Allocated but not recorded, read treats + * this as a hole + */ + goto unlock; +#ifdef _JFS_4K + XADoffset(&xad, lblock64); + XADlength(&xad, xlen); + XADaddress(&xad, xaddr); +#else /* _JFS_4K */ + /* + * As long as block size = 4K, this isn't a problem. + * We should mark the whole page not ABNR, but how + * will we know to mark the other blocks BH_New? + */ + BUG(); +#endif /* _JFS_4K */ + rc = extRecord(ip, &xad); + if (rc) + goto unlock; + bh_result->b_state |= (1UL << BH_New); + } + + bh_result->b_dev = ip->i_dev; + bh_result->b_blocknr = xaddr; + bh_result->b_state |= (1UL << BH_Mapped); + goto unlock; + } + if (!create) + goto unlock; + + /* + * Allocate a new block + */ +#ifdef _JFS_4K + if ((rc = + extHint(ip, lblock64 << ip->i_sb->s_blocksize_bits, &xad))) + goto unlock; + rc = extAlloc(ip, 1, lblock64, &xad, FALSE); + if (rc) + goto unlock; + + bh_result->b_dev = ip->i_dev; + bh_result->b_blocknr = addressXAD(&xad); + bh_result->b_state |= ((1UL << BH_Mapped) | (1UL << BH_New)); + +#else /* _JFS_4K */ + /* + * We need to do whatever it takes to keep all but the last buffers + * in 4K pages - see jfs_write.c + */ + BUG(); +#endif /* _JFS_4K */ + + unlock: + /* + * Release lock on inode + */ + if (take_locks) { + if (create) + IWRITE_UNLOCK(ip); + else + IREAD_UNLOCK(ip); + } + return -rc; +} + +static int jfs_writepage(struct page *page) +{ + return block_write_full_page(page, jfs_get_block); +} + +static int jfs_readpage(struct file *file, struct page *page) +{ + return block_read_full_page(page, jfs_get_block); +} + +static int jfs_prepare_write(struct file *file, + struct page *page, unsigned from, unsigned to) +{ + return block_prepare_write(page, from, to, jfs_get_block); +} + +static int jfs_bmap(struct address_space *mapping, long block) +{ + return generic_block_bmap(mapping, block, jfs_get_block); +} + +static int jfs_direct_IO(int rw, struct inode *inode, struct kiobuf *iobuf, + unsigned long blocknr, int blocksize) +{ + return generic_direct_IO(rw, inode, iobuf, blocknr, + blocksize, jfs_get_block); +} + +struct address_space_operations jfs_aops = { + readpage: jfs_readpage, + writepage: jfs_writepage, + sync_page: block_sync_page, + prepare_write: jfs_prepare_write, + commit_write: generic_commit_write, + bmap: jfs_bmap, + direct_IO: jfs_direct_IO, +}; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_btree.h linux.19pre5-ac1/fs/jfs/jfs_btree.h --- linux.19p5/fs/jfs/jfs_btree.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_btree.h Thu Feb 14 20:46:53 2002 @@ -0,0 +1,163 @@ +/* + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef _H_JFS_BTREE +#define _H_JFS_BTREE +/* + * jfs_btree.h: B+-tree + * + * JFS B+-tree (dtree and xtree) common definitions + */ + +/* + * basic btree page - btpage_t + */ +typedef struct { + s64 next; /* 8: right sibling bn */ + s64 prev; /* 8: left sibling bn */ + + u8 flag; /* 1: */ + u8 rsrvd[7]; /* 7: type specific */ + s64 self; /* 8: self address */ + + u8 entry[4064]; /* 4064: */ +} btpage_t; /* (4096) */ + +/* btpaget_t flag */ +#define BT_TYPE 0x07 /* B+-tree index */ +#define BT_ROOT 0x01 /* root page */ +#define BT_LEAF 0x02 /* leaf page */ +#define BT_INTERNAL 0x04 /* internal page */ +#define BT_RIGHTMOST 0x10 /* rightmost page */ +#define BT_LEFTMOST 0x20 /* leftmost page */ +#define BT_SWAPPED 0x80 /* used by fsck for endian swapping */ + +/* btorder (in inode) */ +#define BT_RANDOM 0x0000 +#define BT_SEQUENTIAL 0x0001 +#define BT_LOOKUP 0x0010 +#define BT_INSERT 0x0020 +#define BT_DELETE 0x0040 + +/* + * btree page buffer cache access + */ +#define BT_IS_ROOT(MP) (((MP)->xflag & COMMIT_PAGE) == 0) + +/* get page from buffer page */ +#define BT_PAGE(IP, MP, TYPE, ROOT)\ + (BT_IS_ROOT(MP) ? (TYPE *)&JFS_IP(IP)->ROOT : (TYPE *)(MP)->data) + +/* get the page buffer and the page for specified block address */ +#define BT_GETPAGE(IP, BN, MP, TYPE, SIZE, P, RC, ROOT)\ +{\ + if ((BN) == 0)\ + {\ + MP = (metapage_t *)&JFS_IP(IP)->bxflag;\ + P = (TYPE *)&JFS_IP(IP)->ROOT;\ + RC = 0;\ + jEVENT(0,("%d BT_GETPAGE returning root\n", __LINE__));\ + }\ + else\ + {\ + jEVENT(0,("%d BT_GETPAGE reading block %d\n", __LINE__,\ + (int)BN));\ + MP = read_metapage((IP), BN, SIZE, 1);\ + if (MP) {\ + RC = 0;\ + P = (MP)->data;\ + } else {\ + P = NULL;\ + jERROR(1,("bread failed!\n"));\ + RC = EIO;\ + }\ + }\ +} + +#define BT_MARK_DIRTY(MP, IP)\ +{\ + if (BT_IS_ROOT(MP))\ + mark_inode_dirty(IP);\ + else\ + mark_metapage_dirty(MP);\ +} + +/* put the page buffer */ +#define BT_PUTPAGE(MP)\ +{\ + if (! BT_IS_ROOT(MP)) \ + release_metapage(MP); \ +} + + +/* + * btree traversal stack + * + * record the path traversed during the search; + * top frame record the leaf page/entry selected. + */ +#define MAXTREEHEIGHT 8 +typedef struct btframe { /* stack frame */ + s64 bn; /* 8: */ + s16 index; /* 2: */ + s16 lastindex; /* 2: */ + struct metapage *mp; /* 4: */ +} btframe_t; /* (16) */ + +typedef struct btstack { + btframe_t *top; /* 4: */ + int nsplit; /* 4: */ + btframe_t stack[MAXTREEHEIGHT]; +} btstack_t; + +#define BT_CLR(btstack)\ + (btstack)->top = (btstack)->stack + +#define BT_PUSH(BTSTACK, BN, INDEX)\ +{\ + (BTSTACK)->top->bn = BN;\ + (BTSTACK)->top->index = INDEX;\ + ++(BTSTACK)->top;\ + assert((BTSTACK)->top != &((BTSTACK)->stack[MAXTREEHEIGHT]));\ +} + +#define BT_POP(btstack)\ + ( (btstack)->top == (btstack)->stack ? NULL : --(btstack)->top ) + +#define BT_STACK(btstack)\ + ( (btstack)->top == (btstack)->stack ? NULL : (btstack)->top ) + +/* retrieve search results */ +#define BT_GETSEARCH(IP, LEAF, BN, MP, TYPE, P, INDEX, ROOT)\ +{\ + BN = (LEAF)->bn;\ + MP = (LEAF)->mp;\ + if (BN)\ + P = (TYPE *)MP->data;\ + else\ + P = (TYPE *)&JFS_IP(IP)->ROOT;\ + INDEX = (LEAF)->index;\ +} + +/* put the page buffer of search */ +#define BT_PUTSEARCH(BTSTACK)\ +{\ + if (! BT_IS_ROOT((BTSTACK)->top->mp))\ + release_metapage((BTSTACK)->top->mp);\ +} +#endif /* _H_JFS_BTREE */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_debug.c linux.19pre5-ac1/fs/jfs/jfs_debug.c --- linux.19p5/fs/jfs/jfs_debug.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_debug.c Thu Feb 14 20:46:53 2002 @@ -0,0 +1,145 @@ +/* + * + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include "jfs_incore.h" +#include "jfs_filsys.h" +#include "jfs_debug.h" + +#ifdef CONFIG_JFS_DEBUG +void dump_mem(char *label, void *data, int length) +{ + int i, j; + int *intptr = data; + char *charptr = data; + char buf[10], line[80]; + + printk("%s: dump of %d bytes of data at 0x%p\n\n", label, length, + data); + for (i = 0; i < length; i += 16) { + line[0] = 0; + for (j = 0; (j < 4) && (i + j * 4 < length); j++) { + sprintf(buf, " %08x", intptr[i / 4 + j]); + strcat(line, buf); + } + buf[0] = ' '; + buf[2] = 0; + for (j = 0; (j < 16) && (i + j < length); j++) { + buf[1] = + isprint(charptr[i + j]) ? charptr[i + j] : '.'; + strcat(line, buf); + } + printk("%s\n", line); + } +} + +#ifdef CONFIG_PROC_FS +static int loglevel_read(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len; + + len = sprintf(page, "%d\n", jfsloglevel); + + len -= off; + *start = page + off; + + if (len > count) + len = count; + else + *eof = 1; + + if (len < 0) + len = 0; + + return len; +} + +static int loglevel_write(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + char c; + + if (get_user(c, buffer)) + return -EFAULT; + + /* yes, I know this is an ASCIIism. --hch */ + if (c < '0' || c > '9') + return -EINVAL; + jfsloglevel = c - '0'; + return count; +} + + +extern read_proc_t jfs_txanchor_read; +#ifdef CONFIG_JFS_STATISTICS +extern read_proc_t jfs_lmstats_read; +extern read_proc_t jfs_xtstat_read; +extern read_proc_t jfs_mpstat_read; +#endif +static struct proc_dir_entry *base; + +static struct { + const char *name; + read_proc_t *read_fn; + write_proc_t *write_fn; +} Entries[] = { + { "TxAnchor", jfs_txanchor_read, }, +#ifdef CONFIG_JFS_STATISTICS + { "lmstats", jfs_lmstats_read, }, + { "xtstat", jfs_xtstat_read, }, + { "mpstat", jfs_mpstat_read, }, +#endif + { "loglevel", loglevel_read, loglevel_write } +}; +#define NPROCENT (sizeof(Entries)/sizeof(Entries[0])) + +void jfs_proc_init(void) +{ + int i; + + if (!(base = proc_mkdir("jfs", proc_root_fs))) + return; + base->owner = THIS_MODULE; + + for (i = 0; i < NPROCENT; i++) { + struct proc_dir_entry *p; + if ((p = create_proc_entry(Entries[i].name, 0, base))) { + p->read_proc = Entries[i].read_fn; + p->write_proc = Entries[i].write_fn; + } + } +} + +void jfs_proc_clean(void) +{ + int i; + + if (base) { + for (i = 0; i < NPROCENT; i++) + remove_proc_entry(Entries[i].name, base); + remove_proc_entry("jfs", base); + } +} + +#endif /* CONFIG_PROC_FS */ +#endif /* CONFIG_JFS_DEBUG */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_debug.h linux.19pre5-ac1/fs/jfs/jfs_debug.h --- linux.19p5/fs/jfs/jfs_debug.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_debug.h Tue Mar 26 20:32:19 2002 @@ -0,0 +1,96 @@ +/* + * + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ +#ifndef _H_JFS_DEBUG +#define _H_JFS_DEBUG + +/* + * jfs_debug.h + * + * global debug message, data structure/macro definitions + * under control of CONFIG_JFS_DEBUG, CONFIG_JFS_STATISTICS; + */ + +/* + * assert with traditional printf/panic + */ +#ifdef CONFIG_KERNEL_ASSERTS +/* kgdb stuff */ +#define assert(p) KERNEL_ASSERT(#p, p) +#else +#define assert(p) {\ +if (!(p))\ + {\ + printk("assert(%s)\n",#p);\ + BUG();\ + }\ +} +#endif + +/* + * debug ON + * -------- + */ +#ifdef CONFIG_JFS_DEBUG +#define ASSERT(p) assert(p) + +/* dump memory contents */ +extern void dump_mem(char *label, void *data, int length); +extern int jfsloglevel; + +/* information message: e.g., configuration, major event */ +#define jFYI(button, prspec) \ + do { if (button && jfsloglevel > 1) printk prspec; } while (0) + +/* error event message: e.g., i/o error */ +extern int jfsERROR; +#define jERROR(button, prspec) \ + do { if (button && jfsloglevel > 0) { printk prspec; } } while (0) + +/* debug event message: */ +#define jEVENT(button,prspec) \ + do { if (button) printk prspec; } while (0) + +/* + * debug OFF + * --------- + */ +#else /* CONFIG_JFS_DEBUG */ +#define dump_mem(label,data,length) +#define ASSERT(p) +#define jEVENT(button,prspec) +#define jERROR(button,prspec) +#define jFYI(button,prspec) +#endif /* CONFIG_JFS_DEBUG */ + +/* + * statistics + * ---------- + */ +#ifdef CONFIG_JFS_STATISTICS +#define INCREMENT(x) ((x)++) +#define DECREMENT(x) ((x)--) +#define HIGHWATERMARK(x,y) ((x) = max((x), (y))) +#else +#define INCREMENT(x) +#define DECREMENT(x) +#define HIGHWATERMARK(x,y) +#endif /* CONFIG_JFS_STATISTICS */ + +#endif /* _H_JFS_DEBUG */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_defragfs.h linux.19pre5-ac1/fs/jfs/jfs_defragfs.h --- linux.19p5/fs/jfs/jfs_defragfs.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_defragfs.h Thu Feb 14 20:46:53 2002 @@ -0,0 +1,55 @@ +/* + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef _H_JFS_DEFRAGFS +#define _H_JFS_DEFRAGFS + +/* + * jfs_defragfs.h + */ +/* + * defragfs parameter list + */ +typedef struct { + uint flag; /* 4: */ + u8 dev; /* 1: */ + u8 pad[3]; /* 3: */ + s32 fileset; /* 4: */ + u32 inostamp; /* 4: */ + u32 ino; /* 4: */ + u32 gen; /* 4: */ + s64 xoff; /* 8: */ + s64 old_xaddr; /* 8: */ + s64 new_xaddr; /* 8: */ + s32 xlen; /* 4: */ +} defragfs_t; /* (52) */ + +/* plist flag */ +#define DEFRAGFS_SYNC 0x80000000 +#define DEFRAGFS_COMMIT 0x40000000 +#define DEFRAGFS_RELOCATE 0x10000000 + +#define INODE_TYPE 0x0000F000 /* IFREG or IFDIR */ + +#define EXTENT_TYPE 0x000000ff +#define DTPAGE 0x00000001 +#define XTPAGE 0x00000002 +#define DATAEXT 0x00000004 +#define EAEXT 0x00000008 + +#endif /* _H_JFS_DEFRAGFS */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_dinode.h linux.19pre5-ac1/fs/jfs/jfs_dinode.h --- linux.19p5/fs/jfs/jfs_dinode.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_dinode.h Thu Feb 14 20:46:53 2002 @@ -0,0 +1,157 @@ +/* + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _H_JFS_DINODE +#define _H_JFS_DINODE + +/* + * jfs_dinode.h: on-disk inode manager + * + */ + +#define INODESLOTSIZE 128 +#define L2INODESLOTSIZE 7 +#define log2INODESIZE 9 /* log2(bytes per dinode) */ + + +/* + * on-disk inode (dinode_t): 512 bytes + * + * note: align 64-bit fields on 8-byte boundary. + */ +struct dinode { + /* + * I. base area (128 bytes) + * ------------------------ + * + * define generic/POSIX attributes + */ + u32 di_inostamp; /* 4: stamp to show inode belongs to fileset */ + s32 di_fileset; /* 4: fileset number */ + u32 di_number; /* 4: inode number, aka file serial number */ + u32 di_gen; /* 4: inode generation number */ + + pxd_t di_ixpxd; /* 8: inode extent descriptor */ + + s64 di_size; /* 8: size */ + s64 di_nblocks; /* 8: number of blocks allocated */ + + u32 di_nlink; /* 4: number of links to the object */ + + u32 di_uid; /* 4: user id of owner */ + u32 di_gid; /* 4: group id of owner */ + + u32 di_mode; /* 4: attribute, format and permission */ + + struct timestruc_t di_atime; /* 8: time last data accessed */ + struct timestruc_t di_ctime; /* 8: time last status changed */ + struct timestruc_t di_mtime; /* 8: time last data modified */ + struct timestruc_t di_otime; /* 8: time created */ + + dxd_t di_acl; /* 16: acl descriptor */ + + dxd_t di_ea; /* 16: ea descriptor */ + + u32 di_next_index; /* 4: Next available dir_table index */ + + s32 di_acltype; /* 4: Type of ACL */ + + /* + * Extension Areas. + * + * Historically, the inode was partitioned into 4 128-byte areas, + * the last 3 being defined as unions which could have multiple + * uses. The first 96 bytes had been completely unused until + * an index table was added to the directory. It is now more + * useful to describe the last 3/4 of the inode as a single + * union. We would probably be better off redesigning the + * entire structure from scratch, but we don't want to break + * commonality with OS/2's JFS at this time. + */ + union { + struct { + /* + * This table contains the information needed to + * find a directory entry from a 32-bit index. + * If the index is small enough, the table is inline, + * otherwise, an x-tree root overlays this table + */ + dir_table_slot_t _table[12]; /* 96: inline */ + + dtroot_t _dtroot; /* 288: dtree root */ + } _dir; /* (384) */ +#define di_dirtable u._dir._table +#define di_dtroot u._dir._dtroot +#define di_parent di_dtroot.header.idotdot +#define di_DASD di_dtroot.header.DASD + + struct { + union { + u8 _data[96]; /* 96: unused */ + struct { + void *_imap; /* 4: unused */ + u32 _gengen; /* 4: generator */ + } _imap; + } _u1; /* 96: */ +#define di_gengen u._file._u1._imap._gengen + + union { + xtpage_t _xtroot; + struct { + u8 unused[16]; /* 16: */ + dxd_t _dxd; /* 16: */ + union { + u32 _rdev; /* 4: */ + u8 _fastsymlink[128]; + } _u; + u8 _inlineea[128]; + } _special; + } _u2; + } _file; +#define di_xtroot u._file._u2._xtroot +#define di_dxd u._file._u2._special._dxd +#define di_btroot di_xtroot +#define di_inlinedata u._file._u2._special._u +#define di_rdev u._file._u2._special._u._rdev +#define di_fastsymlink u._file._u2._special._u._fastsymlink +#define di_inlineea u._file._u2._special._inlineea + } u; +}; + +typedef struct dinode dinode_t; + + +/* extended mode bits (on-disk inode di_mode) */ +#define IFJOURNAL 0x00010000 /* journalled file */ +#define ISPARSE 0x00020000 /* sparse file enabled */ +#define INLINEEA 0x00040000 /* inline EA area free */ +#define ISWAPFILE 0x00800000 /* file open for pager swap space */ + +/* more extended mode bits: attributes for OS/2 */ +#define IREADONLY 0x02000000 /* no write access to file */ +#define IARCHIVE 0x40000000 /* file archive bit */ +#define ISYSTEM 0x08000000 /* system file */ +#define IHIDDEN 0x04000000 /* hidden file */ +#define IRASH 0x4E000000 /* mask for changeable attributes */ +#define INEWNAME 0x80000000 /* non-8.3 filename format */ +#define IDIRECTORY 0x20000000 /* directory (shadow of real bit) */ +#define ATTRSHIFT 25 /* bits to shift to move attribute + specification to mode position */ + +#endif /*_H_JFS_DINODE */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_dmap.c linux.19pre5-ac1/fs/jfs/jfs_dmap.c --- linux.19p5/fs/jfs/jfs_dmap.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_dmap.c Thu Feb 14 20:46:53 2002 @@ -0,0 +1,4189 @@ +/* + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + * + * + * MODULE_NAME: jfs_dmap.c + * + * COMPONENT_NAME: sysjfs + * + * FUNCTION: block allocation map manager + * +*/ + +/* + * Change History : + * + */ + +#include +#include "jfs_incore.h" +#include "jfs_dmap.h" +#include "jfs_imap.h" +#include "jfs_lock.h" +#include "jfs_metapage.h" +#include "jfs_debug.h" + +/* + * Debug code for double-checking block map + */ +/* #define _JFS_DEBUG_DMAP 1 */ + +#ifdef _JFS_DEBUG_DMAP +#define DBINITMAP(size,ipbmap,results) \ + DBinitmap(size,ipbmap,results) +#define DBALLOC(dbmap,mapsize,blkno,nblocks) \ + DBAlloc(dbmap,mapsize,blkno,nblocks) +#define DBFREE(dbmap,mapsize,blkno,nblocks) \ + DBFree(dbmap,mapsize,blkno,nblocks) +#define DBALLOCCK(dbmap,mapsize,blkno,nblocks) \ + DBAllocCK(dbmap,mapsize,blkno,nblocks) +#define DBFREECK(dbmap,mapsize,blkno,nblocks) \ + DBFreeCK(dbmap,mapsize,blkno,nblocks) + +static void DBinitmap(s64, struct inode *, u32 **); +static void DBAlloc(uint *, s64, s64, s64); +static void DBFree(uint *, s64, s64, s64); +static void DBAllocCK(uint *, s64, s64, s64); +static void DBFreeCK(uint *, s64, s64, s64); +#else +#define DBINITMAP(size,ipbmap,results) +#define DBALLOC(dbmap, mapsize, blkno, nblocks) +#define DBFREE(dbmap, mapsize, blkno, nblocks) +#define DBALLOCCK(dbmap, mapsize, blkno, nblocks) +#define DBFREECK(dbmap, mapsize, blkno, nblocks) +#endif /* _JFS_DEBUG_DMAP */ + +/* + * SERIALIZATION of the Block Allocation Map. + * + * the working state of the block allocation map is accessed in + * two directions: + * + * 1) allocation and free requests that start at the dmap + * level and move up through the dmap control pages (i.e. + * the vast majority of requests). + * + * 2) allocation requests that start at dmap control page + * level and work down towards the dmaps. + * + * the serialization scheme used here is as follows. + * + * requests which start at the bottom are serialized against each + * other through buffers and each requests holds onto its buffers + * as it works it way up from a single dmap to the required level + * of dmap control page. + * requests that start at the top are serialized against each other + * and request that start from the bottom by the multiple read/single + * write inode lock of the bmap inode. requests starting at the top + * take this lock in write mode while request starting at the bottom + * take the lock in read mode. a single top-down request may proceed + * exclusively while multiple bottoms-up requests may proceed + * simultaneously (under the protection of busy buffers). + * + * in addition to information found in dmaps and dmap control pages, + * the working state of the block allocation map also includes read/ + * write information maintained in the bmap descriptor (i.e. total + * free block count, allocation group level free block counts). + * a single exclusive lock (BMAP_LOCK) is used to guard this information + * in the face of multiple-bottoms up requests. + * (lock ordering: IREAD_LOCK, BMAP_LOCK); + * + * accesses to the persistent state of the block allocation map (limited + * to the persistent bitmaps in dmaps) is guarded by (busy) buffers. + */ + +#define BMAP_LOCK_INIT(bmp) init_MUTEX(&bmp->db_bmaplock) +#define BMAP_LOCK(bmp) down(&bmp->db_bmaplock) +#define BMAP_UNLOCK(bmp) up(&bmp->db_bmaplock) + +/* + * forward references + */ +static void dbAllocBits(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks); +static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval); +static void dbBackSplit(dmtree_t * tp, int leafno); +static void dbJoin(dmtree_t * tp, int leafno, int newval); +static void dbAdjTree(dmtree_t * tp, int leafno, int newval); +static int dbAdjCtl(bmap_t * bmp, s64 blkno, int newval, int alloc, + int level); +static int dbAllocAny(bmap_t * bmp, s64 nblocks, int l2nb, s64 * results); +static int dbAllocNext(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks); +static int dbAllocNear(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks, + int l2nb, s64 * results); +static int dbAllocDmap(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks); +static int dbAllocDmapLev(bmap_t * bmp, dmap_t * dp, int nblocks, int l2nb, + s64 * results); +static int dbAllocAG(bmap_t * bmp, int agno, s64 nblocks, int l2nb, + s64 * results); +static int dbAllocCtl(bmap_t * bmp, s64 nblocks, int l2nb, s64 blkno, + s64 * results); +int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks); +static int dbFindBits(u32 word, int l2nb); +static int dbFindCtl(bmap_t * bmp, int l2nb, int level, s64 * blkno); +static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx); +static void dbFreeBits(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks); +static int dbFreeDmap(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks); +static int dbMaxBud(u8 * cp); +s64 dbMapFileSizeToMapSize(struct inode *ipbmap); +int blkstol2(s64 nb); +void fsDirty(void); + +int cntlz(u32 value); +int cnttz(u32 word); + +static int dbAllocDmapBU(bmap_t * bmp, dmap_t * dp, s64 blkno, + int nblocks); +static int dbInitDmap(dmap_t * dp, s64 blkno, int nblocks); +static int dbInitDmapTree(dmap_t * dp); +static int dbInitTree(dmaptree_t * dtp); +static int dbInitDmapCtl(dmapctl_t * dcp, int level, int i); +static int dbGetL2AGSize(s64 nblocks); + +/* + * buddy table + * + * table used for determining buddy sizes within characters of + * dmap bitmap words. the characters themselves serve as indexes + * into the table, with the table elements yielding the maximum + * binary buddy of free bits within the character. + */ +signed char budtab[256] = { + 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -1 +}; + + +/* + * NAME: dbMount() + * + * FUNCTION: initializate the block allocation map. + * + * memory is allocated for the in-core bmap descriptor and + * the in-core descriptor is initialized from disk. + * + * PARAMETERS: + * ipbmap - pointer to in-core inode for the block map. + * + * RETURN VALUES: + * 0 - success + * ENOMEM - insufficient memory + * EIO - i/o error + */ +int dbMount(struct inode *ipbmap) +{ + bmap_t *bmp; + dbmap_t *dbmp_le; + metapage_t *mp; + int i; + + /* + * allocate/initialize the in-memory bmap descriptor + */ + /* allocate memory for the in-memory bmap descriptor */ + bmp = kmalloc(sizeof(bmap_t), GFP_KERNEL); + if (bmp == NULL) + return (ENOMEM); + + /* read the on-disk bmap descriptor. */ + mp = read_metapage(ipbmap, + BMAPBLKNO << JFS_SBI(ipbmap->i_sb)->l2nbperpage, + PSIZE, 0); + if (mp == NULL) { + kfree(bmp); + return (EIO); + } + + /* copy the on-disk bmap descriptor to its in-memory version. */ + dbmp_le = (dbmap_t *) mp->data; + bmp->db_mapsize = le64_to_cpu(dbmp_le->dn_mapsize); + bmp->db_nfree = le64_to_cpu(dbmp_le->dn_nfree); + bmp->db_l2nbperpage = le32_to_cpu(dbmp_le->dn_l2nbperpage); + bmp->db_numag = le32_to_cpu(dbmp_le->dn_numag); + bmp->db_maxlevel = le32_to_cpu(dbmp_le->dn_maxlevel); + bmp->db_maxag = le32_to_cpu(dbmp_le->dn_maxag); + bmp->db_agpref = le32_to_cpu(dbmp_le->dn_agpref); + bmp->db_aglevel = le32_to_cpu(dbmp_le->dn_aglevel); + bmp->db_agheigth = le32_to_cpu(dbmp_le->dn_agheigth); + bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth); + bmp->db_agstart = le32_to_cpu(dbmp_le->dn_agstart); + bmp->db_agl2size = le32_to_cpu(dbmp_le->dn_agl2size); + for (i = 0; i < MAXAG; i++) + bmp->db_agfree[i] = le64_to_cpu(dbmp_le->dn_agfree[i]); + bmp->db_agsize = le64_to_cpu(dbmp_le->dn_agsize); + bmp->db_maxfreebud = dbmp_le->dn_maxfreebud; + + /* release the buffer. */ + release_metapage(mp); + + /* bind the bmap inode and the bmap descriptor to each other. */ + bmp->db_ipbmap = ipbmap; + JFS_SBI(ipbmap->i_sb)->bmap = bmp; + + DBINITMAP(bmp->db_mapsize, ipbmap, &bmp->db_DBmap); + + /* + * allocate/initialize the bmap lock + */ + BMAP_LOCK_INIT(bmp); + + return (0); +} + + +/* + * NAME: dbUnmount() + * + * FUNCTION: terminate the block allocation map in preparation for + * file system unmount. + * + * the in-core bmap descriptor is written to disk and + * the memory for this descriptor is freed. + * + * PARAMETERS: + * ipbmap - pointer to in-core inode for the block map. + * + * RETURN VALUES: + * 0 - success + * EIO - i/o error + */ +int dbUnmount(struct inode *ipbmap, int mounterror) +{ + bmap_t *bmp = JFS_SBI(ipbmap->i_sb)->bmap; + + if (!(mounterror || isReadOnly(ipbmap))) + dbSync(ipbmap); + + /* + * Invalidate the page cache buffers + */ + truncate_inode_pages(ipbmap->i_mapping, 0); + + /* free the memory for the in-memory bmap. */ + kfree(bmp); + + return (0); +} + +/* + * dbSync() + */ +int dbSync(struct inode *ipbmap) +{ + dbmap_t *dbmp_le; + bmap_t *bmp = JFS_SBI(ipbmap->i_sb)->bmap; + metapage_t *mp; + int i; + + /* + * write bmap global control page + */ + /* get the buffer for the on-disk bmap descriptor. */ + mp = read_metapage(ipbmap, + BMAPBLKNO << JFS_SBI(ipbmap->i_sb)->l2nbperpage, + PSIZE, 0); + if (mp == NULL) { + jERROR(1,("dbSync: read_metapage failed!\n")); + return (EIO); + } + /* copy the in-memory version of the bmap to the on-disk version */ + dbmp_le = (dbmap_t *) mp->data; + dbmp_le->dn_mapsize = cpu_to_le64(bmp->db_mapsize); + dbmp_le->dn_nfree = cpu_to_le64(bmp->db_nfree); + dbmp_le->dn_l2nbperpage = cpu_to_le32(bmp->db_l2nbperpage); + dbmp_le->dn_numag = cpu_to_le32(bmp->db_numag); + dbmp_le->dn_maxlevel = cpu_to_le32(bmp->db_maxlevel); + dbmp_le->dn_maxag = cpu_to_le32(bmp->db_maxag); + dbmp_le->dn_agpref = cpu_to_le32(bmp->db_agpref); + dbmp_le->dn_aglevel = cpu_to_le32(bmp->db_aglevel); + dbmp_le->dn_agheigth = cpu_to_le32(bmp->db_agheigth); + dbmp_le->dn_agwidth = cpu_to_le32(bmp->db_agwidth); + dbmp_le->dn_agstart = cpu_to_le32(bmp->db_agstart); + dbmp_le->dn_agl2size = cpu_to_le32(bmp->db_agl2size); + for (i = 0; i < MAXAG; i++) + dbmp_le->dn_agfree[i] = cpu_to_le64(bmp->db_agfree[i]); + dbmp_le->dn_agsize = cpu_to_le64(bmp->db_agsize); + dbmp_le->dn_maxfreebud = bmp->db_maxfreebud; + + /* write the buffer */ + write_metapage(mp); + + /* + * write out dirty pages of bmap + */ + fsync_inode_data_buffers(ipbmap); + + ipbmap->i_state |= I_DIRTY; + diWriteSpecial(ipbmap); + + return (0); +} + + +/* + * NAME: dbFree() + * + * FUNCTION: free the specified block range from the working block + * allocation map. + * + * the blocks will be free from the working map one dmap + * at a time. + * + * PARAMETERS: + * ip - pointer to in-core inode; + * blkno - starting block number to be freed. + * nblocks - number of blocks to be freed. + * + * RETURN VALUES: + * 0 - success + * EIO - i/o error + */ +int dbFree(struct inode *ip, s64 blkno, s64 nblocks) +{ + metapage_t *mp; + dmap_t *dp; + int nb, rc; + s64 lblkno, rem; + struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap; + bmap_t *bmp = JFS_SBI(ip->i_sb)->bmap; + + IREAD_LOCK(ipbmap); + + /* block to be freed better be within the mapsize. */ + assert(blkno + nblocks <= bmp->db_mapsize); + + /* + * free the blocks a dmap at a time. + */ + mp = NULL; + for (rem = nblocks; rem > 0; rem -= nb, blkno += nb) { + /* release previous dmap if any */ + if (mp) { + write_metapage(mp); + } + + /* get the buffer for the current dmap. */ + lblkno = BLKTODMAP(blkno, bmp->db_l2nbperpage); + mp = read_metapage(ipbmap, lblkno, PSIZE, 0); + if (mp == NULL) { + IREAD_UNLOCK(ipbmap); + return (EIO); + } + dp = (dmap_t *) mp->data; + + /* determine the number of blocks to be freed from + * this dmap. + */ + nb = min(rem, BPERDMAP - (blkno & (BPERDMAP - 1))); + + DBALLOCCK(bmp->db_DBmap, bmp->db_mapsize, blkno, nb); + + /* free the blocks. */ + if ((rc = dbFreeDmap(bmp, dp, blkno, nb))) { + release_metapage(mp); + IREAD_UNLOCK(ipbmap); + return (rc); + } + + DBFREE(bmp->db_DBmap, bmp->db_mapsize, blkno, nb); + } + + /* write the last buffer. */ + write_metapage(mp); + + IREAD_UNLOCK(ipbmap); + + return (0); +} + + +/* + * NAME: dbUpdatePMap() + * + * FUNCTION: update the allocation state (free or allocate) of the + * specified block range in the persistent block allocation map. + * + * the blocks will be updated in the persistent map one + * dmap at a time. + * + * PARAMETERS: + * ipbmap - pointer to in-core inode for the block map. + * free - TRUE if block range is to be freed from the persistent + * map; FALSE if it is to be allocated. + * blkno - starting block number of the range. + * nblocks - number of contiguous blocks in the range. + * tblk - transaction block; + * + * RETURN VALUES: + * 0 - success + * EIO - i/o error + */ +int +dbUpdatePMap(struct inode *ipbmap, + int free, s64 blkno, s64 nblocks, tblock_t * tblk) +{ + int nblks, dbitno, wbitno, rbits; + int word, nbits, nwords; + bmap_t *bmp = JFS_SBI(ipbmap->i_sb)->bmap; + s64 lblkno, rem, lastlblkno; + u32 mask; + dmap_t *dp; + metapage_t *mp; + log_t *log; + int lsn, difft, diffp; + + /* the blocks better be within the mapsize. */ + assert(blkno + nblocks <= bmp->db_mapsize); + + /* compute delta of transaction lsn from log syncpt */ + lsn = tblk->lsn; + log = (log_t *) JFS_SBI(tblk->sb)->log; + logdiff(difft, lsn, log); + + /* + * update the block state a dmap at a time. + */ + mp = NULL; + lastlblkno = 0; + for (rem = nblocks; rem > 0; rem -= nblks, blkno += nblks) { + /* get the buffer for the current dmap. */ + lblkno = BLKTODMAP(blkno, bmp->db_l2nbperpage); + if (lblkno != lastlblkno) { + if (mp) { + write_metapage(mp); + } + + mp = read_metapage(bmp->db_ipbmap, lblkno, PSIZE, + 0); + if (mp == NULL) + return (EIO); + } + dp = (dmap_t *) mp->data; + + /* determine the bit number and word within the dmap of + * the starting block. also determine how many blocks + * are to be updated within this dmap. + */ + dbitno = blkno & (BPERDMAP - 1); + word = dbitno >> L2DBWORD; + nblks = min(rem, (s64)BPERDMAP - dbitno); + + /* update the bits of the dmap words. the first and last + * words may only have a subset of their bits updated. if + * this is the case, we'll work against that word (i.e. + * partial first and/or last) only in a single pass. a + * single pass will also be used to update all words that + * are to have all their bits updated. + */ + for (rbits = nblks; rbits > 0; + rbits -= nbits, dbitno += nbits) { + /* determine the bit number within the word and + * the number of bits within the word. + */ + wbitno = dbitno & (DBWORD - 1); + nbits = min(rbits, DBWORD - wbitno); + + /* check if only part of the word is to be updated. */ + if (nbits < DBWORD) { + /* update (free or allocate) the bits + * in this word. + */ + mask = + (ONES << (DBWORD - nbits) >> wbitno); + if (free) + dp->pmap[word] &= + cpu_to_le32(~mask); + else + dp->pmap[word] |= + cpu_to_le32(mask); + + word += 1; + } else { + /* one or more words are to have all + * their bits updated. determine how + * many words and how many bits. + */ + nwords = rbits >> L2DBWORD; + nbits = nwords << L2DBWORD; + + /* update (free or allocate) the bits + * in these words. + */ + if (free) + memset(&dp->pmap[word], 0, + nwords * 4); + else + memset(&dp->pmap[word], (int) ONES, + nwords * 4); + + word += nwords; + } + } + + /* + * update dmap lsn + */ + if (lblkno == lastlblkno) + continue; + + lastlblkno = lblkno; + + if (mp->lsn != 0) { + /* inherit older/smaller lsn */ + logdiff(diffp, mp->lsn, log); + if (difft < diffp) { + mp->lsn = lsn; + + /* move bp after tblock in logsync list */ + LOGSYNC_LOCK(log); + list_del(&mp->synclist); + list_add(&mp->synclist, &tblk->synclist); + LOGSYNC_UNLOCK(log); + } + + /* inherit younger/larger clsn */ + LOGSYNC_LOCK(log); + logdiff(difft, tblk->clsn, log); + logdiff(diffp, mp->clsn, log); + if (difft > diffp) + mp->clsn = tblk->clsn; + LOGSYNC_UNLOCK(log); + } else { + mp->log = log; + mp->lsn = lsn; + + /* insert bp after tblock in logsync list */ + LOGSYNC_LOCK(log); + + log->count++; + list_add(&mp->synclist, &tblk->synclist); + + mp->clsn = tblk->clsn; + LOGSYNC_UNLOCK(log); + } + } + + /* write the last buffer. */ + if (mp) { + write_metapage(mp); + } + + return (0); +} + + +/* + * NAME: dbNextAG() + * + * FUNCTION: find the preferred allocation group for new allocations. + * + * we try to keep the trailing (rightmost) allocation groups + * free for large allocations. we try to do this by targeting + * new inode allocations towards the leftmost or 'active' + * allocation groups while keeping the rightmost or 'inactive' + * allocation groups free. once the active allocation groups + * have dropped to a certain percentage of free space, we add + * the leftmost inactive allocation group to the active set. + * + * within the active allocation groups, we maintain a preferred + * allocation group which consists of a group with at least + * average free space over the active set. it is the preferred + * group that we target new inode allocation towards. the + * tie-in between inode allocation and block allocation occurs + * as we allocate the first (data) block of an inode and specify + * the inode (block) as the allocation hint for this block. + * + * PARAMETERS: + * ipbmap - pointer to in-core inode for the block map. + * + * RETURN VALUES: + * the preferred allocation group number. + * + * note: only called by dbAlloc(); + */ +int dbNextAG(struct inode *ipbmap) +{ + s64 avgfree, inactfree, actfree, rem; + int actags, inactags, l2agsize; + bmap_t *bmp = JFS_SBI(ipbmap->i_sb)->bmap; + + BMAP_LOCK(bmp); + + /* determine the number of active allocation groups (i.e. + * the number of allocation groups up to and including + * the rightmost allocation group with blocks allocated + * in it. + */ + actags = bmp->db_maxag + 1; + assert(actags <= bmp->db_numag); + + /* get the number of inactive allocation groups (i.e. the + * number of allocation group following the rightmost group + * with allocation in it. + */ + inactags = bmp->db_numag - actags; + + /* determine how many blocks are in the inactive allocation + * groups. in doing this, we must account for the fact that + * the rightmost group might be a partial group (i.e. file + * system size is not a multiple of the group size). + */ + l2agsize = bmp->db_agl2size; + rem = bmp->db_mapsize & (bmp->db_agsize - 1); + inactfree = (inactags + && rem) ? ((inactags - 1) << l2agsize) + + rem : inactags << l2agsize; + + /* now determine how many free blocks are in the active + * allocation groups plus the average number of free blocks + * within the active ags. + */ + actfree = bmp->db_nfree - inactfree; + avgfree = (u32) actfree / (u32) actags; + + /* check if not all of the allocation groups are active. + */ + if (actags < bmp->db_numag) { + /* not all of the allocation groups are active. determine + * if we should extend the active set by 1 (i.e. add the + * group following the current active set). we do so if + * the number of free blocks within the active set is less + * than the allocation group set and average free within + * the active set is less than 60%. we activate a new group + * by setting the allocation group preference to the new + * group. + */ + if (actfree < bmp->db_agsize && + ((avgfree * 100) >> l2agsize) < 60) + bmp->db_agpref = actags; + } else { + /* all allocation groups are in the active set. check if + * the preferred allocation group has average free space. + * if not, re-establish the preferred group as the leftmost + * group with average free space. + */ + if (bmp->db_agfree[bmp->db_agpref] < avgfree) { + for (bmp->db_agpref = 0; bmp->db_agpref < actags; + bmp->db_agpref++) { + if (bmp->db_agfree[bmp->db_agpref] <= + avgfree) + break; + } + assert(bmp->db_agpref < bmp->db_numag); + } + } + + BMAP_UNLOCK(bmp); + + /* return the preferred group. + */ + return (bmp->db_agpref); +} + + +/* + * NAME: dbAlloc() + * + * FUNCTION: attempt to allocate a specified number of contiguous free + * blocks from the working allocation block map. + * + * the block allocation policy uses hints and a multi-step + * approach. + * + * for allocation requests smaller than the number of blocks + * per dmap, we first try to allocate the new blocks + * immediately following the hint. if these blocks are not + * available, we try to allocate blocks near the hint. if + * no blocks near the hint are available, we next try to + * allocate within the same dmap as contains the hint. + * + * if no blocks are available in the dmap or the allocation + * request is larger than the dmap size, we try to allocate + * within the same allocation group as contains the hint. if + * this does not succeed, we finally try to allocate anywhere + * within the aggregate. + * + * we also try to allocate anywhere within the aggregate for + * for allocation requests larger than the allocation group + * size or requests that specify no hint value. + * + * PARAMETERS: + * ip - pointer to in-core inode; + * hint - allocation hint. + * nblocks - number of contiguous blocks in the range. + * results - on successful return, set to the starting block number + * of the newly allocated contiguous range. + * + * RETURN VALUES: + * 0 - success + * ENOSPC - insufficient disk resources + * EIO - i/o error + */ +int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results) +{ + int rc, agno; + struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap; + bmap_t *bmp; + metapage_t *mp; + s64 lblkno, blkno; + dmap_t *dp; + int l2nb; + s64 mapSize; + + /* assert that nblocks is valid */ + assert(nblocks > 0); + +#ifdef _STILL_TO_PORT + /* DASD limit check F226941 */ + if (OVER_LIMIT(ip, nblocks)) + return ENOSPC; +#endif /* _STILL_TO_PORT */ + + /* get the log2 number of blocks to be allocated. + * if the number of blocks is not a log2 multiple, + * it will be rounded up to the next log2 multiple. + */ + l2nb = BLKSTOL2(nblocks); + + bmp = JFS_SBI(ip->i_sb)->bmap; + +//retry: /* serialize w.r.t.extendfs() */ + mapSize = bmp->db_mapsize; + + /* the hint should be within the map */ + assert(hint < mapSize); + + /* if no hint was specified or the number of blocks to be + * allocated is greater than the allocation group size, try + * to allocate anywhere. + */ + if (hint == 0 || l2nb > bmp->db_agl2size) { + IWRITE_LOCK(ipbmap); + + rc = dbAllocAny(bmp, nblocks, l2nb, results); + if (rc == 0) { + DBALLOC(bmp->db_DBmap, bmp->db_mapsize, *results, + nblocks); + } + + IWRITE_UNLOCK(ipbmap); + return (rc); + } + + /* we would like to allocate close to the hint. adjust the + * hint to the block following the hint since the allocators + * will start looking for free space starting at this point. + * if the hint was the last block of the file system, try to + * allocate in the same allocation group as the hint. + */ + blkno = hint + 1; + if (blkno >= bmp->db_mapsize) { + blkno--; + goto tryag; + } + + /* check if blkno crosses over into a new allocation group. + * if so, check if we should allow allocations within this + * allocation group. we try to keep the trailing (rightmost) + * allocation groups of the file system free for large + * allocations and may want to prevent this allocation from + * spilling over into this space. + */ + if ((blkno & (bmp->db_agsize - 1)) == 0) { + /* check if the AG is beyond the rightmost AG with + * allocations in it. if so, call dbNextAG() to + * determine if the allocation should be allowed + * to proceed within this AG or should be targeted + * to another AG. + */ + agno = blkno >> bmp->db_agl2size; + if (agno > bmp->db_maxag) { + agno = dbNextAG(ipbmap); + blkno = (s64) agno << bmp->db_agl2size; + goto tryag; + } + } + + /* check if the allocation request size can be satisfied from a + * single dmap. if so, try to allocate from the dmap containing + * the hint using a tiered strategy. + */ + if (nblocks <= BPERDMAP) { + IREAD_LOCK(ipbmap); + + /* get the buffer for the dmap containing the hint. + */ + lblkno = BLKTODMAP(blkno, bmp->db_l2nbperpage); + mp = read_metapage(ipbmap, lblkno, PSIZE, 0); + if (mp == NULL) { + IREAD_UNLOCK(ipbmap); + return (EIO); + } + dp = (dmap_t *) mp->data; + + /* first, try to satisfy the allocation request with the + * blocks beginning at the hint. + */ + if ((rc = + dbAllocNext(bmp, dp, blkno, + (int) nblocks)) != ENOSPC) { + if (rc == 0) { + *results = blkno; + DBALLOC(bmp->db_DBmap, bmp->db_mapsize, + *results, nblocks); + write_metapage(mp); + } else { + assert(rc == EIO); + release_metapage(mp); + } + + IREAD_UNLOCK(ipbmap); + return (rc); + } + + /* next, try to satisfy the allocation request with blocks + * near the hint. + */ + if ((rc = + dbAllocNear(bmp, dp, blkno, (int) nblocks, l2nb, + results)) + != ENOSPC) { + if (rc == 0) { + DBALLOC(bmp->db_DBmap, bmp->db_mapsize, + *results, nblocks); + mark_metapage_dirty(mp); + } + release_metapage(mp); + + IREAD_UNLOCK(ipbmap); + return (rc); + } + + /* try to satisfy the allocation request with blocks within + * the same allocation group as the hint. + */ + if ((rc = + dbAllocDmapLev(bmp, dp, (int) nblocks, l2nb, results)) + != ENOSPC) { + if (rc == 0) { + DBALLOC(bmp->db_DBmap, bmp->db_mapsize, + *results, nblocks); + mark_metapage_dirty(mp); + } + release_metapage(mp); + + IREAD_UNLOCK(ipbmap); + return (rc); + } + + release_metapage(mp); + IREAD_UNLOCK(ipbmap); + } + + tryag: + IWRITE_LOCK(ipbmap); + + /* determine the allocation group number of the hint and try to + * allocate within this allocation group. if that fails, try to + * allocate anywhere in the map. + */ + agno = blkno >> bmp->db_agl2size; + if ((rc = dbAllocAG(bmp, agno, nblocks, l2nb, results)) == ENOSPC) + rc = dbAllocAny(bmp, nblocks, l2nb, results); + if (rc == 0) { + DBALLOC(bmp->db_DBmap, bmp->db_mapsize, *results, nblocks); + } + + IWRITE_UNLOCK(ipbmap); + + return (rc); +} + + +/* + * NAME: dbAllocExact() + * + * FUNCTION: try to allocate the requested extent; + * + * PARAMETERS: + * ip - pointer to in-core inode; + * blkno - extent address; + * nblocks - extent length; + * + * RETURN VALUES: + * 0 - success + * ENOSPC - insufficient disk resources + * EIO - i/o error + */ +int dbAllocExact(struct inode *ip, s64 blkno, int nblocks) +{ + int rc; + struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap; + bmap_t *bmp = JFS_SBI(ip->i_sb)->bmap; + dmap_t *dp; + s64 lblkno; + metapage_t *mp; + + IREAD_LOCK(ipbmap); + + /* + * validate extent request: + * + * note: defragfs policy: + * max 64 blocks will be moved. + * allocation request size must be satisfied from a single dmap. + */ + if (nblocks <= 0 || nblocks > BPERDMAP || blkno >= bmp->db_mapsize) { + IREAD_UNLOCK(ipbmap); + return EINVAL; + } + + if (nblocks > ((s64) 1 << bmp->db_maxfreebud)) { + /* the free space is no longer available */ + IREAD_UNLOCK(ipbmap); + return ENOSPC; + } + + /* read in the dmap covering the extent */ + lblkno = BLKTODMAP(blkno, bmp->db_l2nbperpage); + mp = read_metapage(ipbmap, lblkno, PSIZE, 0); + if (mp == NULL) { + IREAD_UNLOCK(ipbmap); + return (EIO); + } + dp = (dmap_t *) mp->data; + + /* try to allocate the requested extent */ + rc = dbAllocNext(bmp, dp, blkno, nblocks); + + IREAD_UNLOCK(ipbmap); + + if (rc == 0) { + DBALLOC(bmp->db_DBmap, bmp->db_mapsize, blkno, nblocks); + mark_metapage_dirty(mp); + } + release_metapage(mp); + + return (rc); +} + + +/* + * NAME: dbReAlloc() + * + * FUNCTION: attempt to extend a current allocation by a specified + * number of blocks. + * + * this routine attempts to satisfy the allocation request + * by first trying to extend the existing allocation in + * place by allocating the additional blocks as the blocks + * immediately following the current allocation. if these + * blocks are not available, this routine will attempt to + * allocate a new set of contiguous blocks large enough + * to cover the existing allocation plus the additional + * number of blocks required. + * + * PARAMETERS: + * ip - pointer to in-core inode requiring allocation. + * blkno - starting block of the current allocation. + * nblocks - number of contiguous blocks within the current + * allocation. + * addnblocks - number of blocks to add to the allocation. + * results - on successful return, set to the starting block number + * of the existing allocation if the existing allocation + * was extended in place or to a newly allocated contiguous + * range if the existing allocation could not be extended + * in place. + * + * RETURN VALUES: + * 0 - success + * ENOSPC - insufficient disk resources + * EIO - i/o error + */ +int +dbReAlloc(struct inode *ip, + s64 blkno, s64 nblocks, s64 addnblocks, s64 * results) +{ + int rc; + + /* try to extend the allocation in place. + */ + if ((rc = dbExtend(ip, blkno, nblocks, addnblocks)) == 0) { + *results = blkno; + return (0); + } else { + if (rc != ENOSPC) + return (rc); + } + + /* could not extend the allocation in place, so allocate a + * new set of blocks for the entire request (i.e. try to get + * a range of contiguous blocks large enough to cover the + * existing allocation plus the additional blocks.) + */ + return (dbAlloc + (ip, blkno + nblocks - 1, addnblocks + nblocks, results)); +} + + +/* + * NAME: dbExtend() + * + * FUNCTION: attempt to extend a current allocation by a specified + * number of blocks. + * + * this routine attempts to satisfy the allocation request + * by first trying to extend the existing allocation in + * place by allocating the additional blocks as the blocks + * immediately following the current allocation. + * + * PARAMETERS: + * ip - pointer to in-core inode requiring allocation. + * blkno - starting block of the current allocation. + * nblocks - number of contiguous blocks within the current + * allocation. + * addnblocks - number of blocks to add to the allocation. + * + * RETURN VALUES: + * 0 - success + * ENOSPC - insufficient disk resources + * EIO - i/o error + */ +int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks) +{ + struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb); + s64 lblkno, lastblkno, extblkno; + uint rel_block; + metapage_t *mp; + dmap_t *dp; + int rc; + struct inode *ipbmap = sbi->ipbmap; + bmap_t *bmp; + + /* + * We don't want a non-aligned extent to cross a page boundary + */ + if (((rel_block = blkno & (sbi->nbperpage - 1))) && + (rel_block + nblocks + addnblocks > sbi->nbperpage)) + return (ENOSPC); + + /* get the last block of the current allocation */ + lastblkno = blkno + nblocks - 1; + + /* determine the block number of the block following + * the existing allocation. + */ + extblkno = lastblkno + 1; + + IREAD_LOCK(ipbmap); + + /* better be within the file system */ + bmp = sbi->bmap; + assert(lastblkno >= 0 && lastblkno < bmp->db_mapsize); + + /* we'll attempt to extend the current allocation in place by + * allocating the additional blocks as the blocks immediately + * following the current allocation. we only try to extend the + * current allocation in place if the number of additional blocks + * can fit into a dmap, the last block of the current allocation + * is not the last block of the file system, and the start of the + * inplace extension is not on an allocation group boundry. + */ + if (addnblocks > BPERDMAP || extblkno >= bmp->db_mapsize || + (extblkno & (bmp->db_agsize - 1)) == 0) { + IREAD_UNLOCK(ipbmap); + return (ENOSPC); + } + + /* get the buffer for the dmap containing the first block + * of the extension. + */ + lblkno = BLKTODMAP(extblkno, bmp->db_l2nbperpage); + mp = read_metapage(ipbmap, lblkno, PSIZE, 0); + if (mp == NULL) { + IREAD_UNLOCK(ipbmap); + return (EIO); + } + + DBALLOCCK(bmp->db_DBmap, bmp->db_mapsize, blkno, nblocks); + dp = (dmap_t *) mp->data; + + /* try to allocate the blocks immediately following the + * current allocation. + */ + rc = dbAllocNext(bmp, dp, extblkno, (int) addnblocks); + + IREAD_UNLOCK(ipbmap); + + /* were we successful ? */ + if (rc == 0) { + DBALLOC(bmp->db_DBmap, bmp->db_mapsize, extblkno, + addnblocks); + write_metapage(mp); + } else { + /* we were not successful */ + release_metapage(mp); + assert(rc == ENOSPC || rc == EIO); + } + + return (rc); +} + + +/* + * NAME: dbAllocNext() + * + * FUNCTION: attempt to allocate the blocks of the specified block + * range within a dmap. + * + * PARAMETERS: + * bmp - pointer to bmap descriptor + * dp - pointer to dmap. + * blkno - starting block number of the range. + * nblocks - number of contiguous free blocks of the range. + * + * RETURN VALUES: + * 0 - success + * ENOSPC - insufficient disk resources + * EIO - i/o error + * + * serialization: IREAD_LOCK(ipbmap) held on entry/exit; + */ +static int dbAllocNext(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks) +{ + int dbitno, word, rembits, nb, nwords, wbitno, nw; + int l2size; + s8 *leaf; + u32 mask; + + /* pick up a pointer to the leaves of the dmap tree. + */ + leaf = dp->tree.stree + le32_to_cpu(dp->tree.leafidx); + + /* determine the bit number and word within the dmap of the + * starting block. + */ + dbitno = blkno & (BPERDMAP - 1); + word = dbitno >> L2DBWORD; + + /* check if the specified block range is contained within + * this dmap. + */ + if (dbitno + nblocks > BPERDMAP) + return (ENOSPC); + + /* check if the starting leaf indicates that anything + * is free. + */ + if (leaf[word] == NOFREE) + return (ENOSPC); + + /* check the dmaps words corresponding to block range to see + * if the block range is free. not all bits of the first and + * last words may be contained within the block range. if this + * is the case, we'll work against those words (i.e. partial first + * and/or last) on an individual basis (a single pass) and examine + * the actual bits to determine if they are free. a single pass + * will be used for all dmap words fully contained within the + * specified range. within this pass, the leaves of the dmap + * tree will be examined to determine if the blocks are free. a + * single leaf may describe the free space of multiple dmap + * words, so we may visit only a subset of the actual leaves + * corresponding to the dmap words of the block range. + */ + for (rembits = nblocks; rembits > 0; rembits -= nb, dbitno += nb) { + /* determine the bit number within the word and + * the number of bits within the word. + */ + wbitno = dbitno & (DBWORD - 1); + nb = min(rembits, DBWORD - wbitno); + + /* check if only part of the word is to be examined. + */ + if (nb < DBWORD) { + /* check if the bits are free. + */ + mask = (ONES << (DBWORD - nb) >> wbitno); + if ((mask & ~le32_to_cpu(dp->wmap[word])) != mask) + return (ENOSPC); + + word += 1; + } else { + /* one or more dmap words are fully contained + * within the block range. determine how many + * words and how many bits. + */ + nwords = rembits >> L2DBWORD; + nb = nwords << L2DBWORD; + + /* now examine the appropriate leaves to determine + * if the blocks are free. + */ + while (nwords > 0) { + /* does the leaf describe any free space ? + */ + if (leaf[word] < BUDMIN) + return (ENOSPC); + + /* determine the l2 number of bits provided + * by this leaf. + */ + l2size = + min((int)leaf[word], NLSTOL2BSZ(nwords)); + + /* determine how many words were handled. + */ + nw = BUDSIZE(l2size, BUDMIN); + + nwords -= nw; + word += nw; + } + } + } + + /* allocate the blocks. + */ + return (dbAllocDmap(bmp, dp, blkno, nblocks)); +} + + +/* + * NAME: dbAllocNear() + * + * FUNCTION: attempt to allocate a number of contiguous free blocks near + * a specified block (hint) within a dmap. + * + * starting with the dmap leaf that covers the hint, we'll + * check the next four contiguous leaves for sufficient free + * space. if sufficient free space is found, we'll allocate + * the desired free space. + * + * PARAMETERS: + * bmp - pointer to bmap descriptor + * dp - pointer to dmap. + * blkno - block number to allocate near. + * nblocks - actual number of contiguous free blocks desired. + * l2nb - log2 number of contiguous free blocks desired. + * results - on successful return, set to the starting block number + * of the newly allocated range. + * + * RETURN VALUES: + * 0 - success + * ENOSPC - insufficient disk resources + * EIO - i/o error + * + * serialization: IREAD_LOCK(ipbmap) held on entry/exit; + */ +static int +dbAllocNear(bmap_t * bmp, + dmap_t * dp, s64 blkno, int nblocks, int l2nb, s64 * results) +{ + int word, lword, rc; + s8 *leaf = dp->tree.stree + le32_to_cpu(dp->tree.leafidx); + + /* determine the word within the dmap that holds the hint + * (i.e. blkno). also, determine the last word in the dmap + * that we'll include in our examination. + */ + word = (blkno & (BPERDMAP - 1)) >> L2DBWORD; + lword = min(word + 4, LPERDMAP); + + /* examine the leaves for sufficient free space. + */ + for (; word < lword; word++) { + /* does the leaf describe sufficient free space ? + */ + if (leaf[word] < l2nb) + continue; + + /* determine the block number within the file system + * of the first block described by this dmap word. + */ + blkno = le64_to_cpu(dp->start) + (word << L2DBWORD); + + /* if not all bits of the dmap word are free, get the + * starting bit number within the dmap word of the required + * string of free bits and adjust the block number with the + * value. + */ + if (leaf[word] < BUDMIN) + blkno += + dbFindBits(le32_to_cpu(dp->wmap[word]), l2nb); + + /* allocate the blocks. + */ + if ((rc = dbAllocDmap(bmp, dp, blkno, nblocks)) == 0) + *results = blkno; + + return (rc); + } + + return (ENOSPC); +} + + +/* + * NAME: dbAllocAG() + * + * FUNCTION: attempt to allocate the specified number of contiguous + * free blocks within the specified allocation group. + * + * unless the allocation group size is equal to the number + * of blocks per dmap, the dmap control pages will be used to + * find the required free space, if available. we start the + * search at the highest dmap control page level which + * distinctly describes the allocation group's free space + * (i.e. the highest level at which the allocation group's + * free space is not mixed in with that of any other group). + * in addition, we start the search within this level at a + * height of the dmapctl dmtree at which the nodes distinctly + * describe the allocation group's free space. at this height, + * the allocation group's free space may be represented by 1 + * or two sub-trees, depending on the allocation group size. + * we search the top nodes of these subtrees left to right for + * sufficient free space. if sufficient free space is found, + * the subtree is searched to find the leftmost leaf that + * has free space. once we have made it to the leaf, we + * move the search to the next lower level dmap control page + * corresponding to this leaf. we continue down the dmap control + * pages until we find the dmap that contains or starts the + * sufficient free space and we allocate at this dmap. + * + * if the allocation group size is equal to the dmap size, + * we'll start at the dmap corresponding to the allocation + * group and attempt the allocation at this level. + * + * the dmap control page search is also not performed if the + * allocation group is completely free and we go to the first + * dmap of the allocation group to do the allocation. this is + * done because the allocation group may be part (not the first + * part) of a larger binary buddy system, causing the dmap + * control pages to indicate no free space (NOFREE) within + * the allocation group. + * + * PARAMETERS: + * bmp - pointer to bmap descriptor + * agno - allocation group number. + * nblocks - actual number of contiguous free blocks desired. + * l2nb - log2 number of contiguous free blocks desired. + * results - on successful return, set to the starting block number + * of the newly allocated range. + * + * RETURN VALUES: + * 0 - success + * ENOSPC - insufficient disk resources + * EIO - i/o error + * + * note: IWRITE_LOCK(ipmap) held on entry/exit; + */ +static int +dbAllocAG(bmap_t * bmp, int agno, s64 nblocks, int l2nb, s64 * results) +{ + metapage_t *mp; + dmapctl_t *dcp; + int rc, ti, i, k, m, n, agperlev; + s64 blkno, lblkno; + int budmin; + + /* allocation request should not be for more than the + * allocation group size. + */ + assert(l2nb <= bmp->db_agl2size); + + /* determine the starting block number of the allocation + * group. + */ + blkno = (s64) agno << bmp->db_agl2size; + + /* check if the allocation group size is the minimum allocation + * group size or if the allocation group is completely free. if + * the allocation group size is the minimum size of BPERDMAP (i.e. + * 1 dmap), there is no need to search the dmap control page (below) + * that fully describes the allocation group since the allocation + * group is already fully described by a dmap. in this case, we + * just call dbAllocCtl() to search the dmap tree and allocate the + * required space if available. + * + * if the allocation group is completely free, dbAllocCtl() is + * also called to allocate the required space. this is done for + * two reasons. first, it makes no sense searching the dmap control + * pages for free space when we know that free space exists. second, + * the dmap control pages may indicate that the allocation group + * has no free space if the allocation group is part (not the first + * part) of a larger binary buddy system. + */ + if (bmp->db_agsize == BPERDMAP + || bmp->db_agfree[agno] == bmp->db_agsize) { + rc = dbAllocCtl(bmp, nblocks, l2nb, blkno, results); + /* assert(!(rc == ENOSPC && bmp->db_agfree[agno] == bmp->db_agsize)); */ + if ((rc == ENOSPC) && + (bmp->db_agfree[agno] == bmp->db_agsize)) { + jERROR(1, + ("dbAllocAG: removed assert, but still need to debug here\nblkno = 0x%Lx, nblocks = 0x%Lx\n", + (unsigned long long) blkno, + (unsigned long long) nblocks)); + } + return (rc); + } + + /* the buffer for the dmap control page that fully describes the + * allocation group. + */ + lblkno = BLKTOCTL(blkno, bmp->db_l2nbperpage, bmp->db_aglevel); + mp = read_metapage(bmp->db_ipbmap, lblkno, PSIZE, 0); + if (mp == NULL) + return (EIO); + dcp = (dmapctl_t *) mp->data; + budmin = dcp->budmin; + + /* search the subtree(s) of the dmap control page that describes + * the allocation group, looking for sufficient free space. to begin, + * determine how many allocation groups are represented in a dmap + * control page at the control page level (i.e. L0, L1, L2) that + * fully describes an allocation group. next, determine the starting + * tree index of this allocation group within the control page. + */ + agperlev = + (1 << (L2LPERCTL - (bmp->db_agheigth << 1))) / bmp->db_agwidth; + ti = bmp->db_agstart + bmp->db_agwidth * (agno & (agperlev - 1)); + + /* dmap control page trees fan-out by 4 and a single allocation + * group may be described by 1 or 2 subtrees within the ag level + * dmap control page, depending upon the ag size. examine the ag's + * subtrees for sufficient free space, starting with the leftmost + * subtree. + */ + for (i = 0; i < bmp->db_agwidth; i++, ti++) { + /* is there sufficient free space ? + */ + if (l2nb > dcp->stree[ti]) + continue; + + /* sufficient free space found in a subtree. now search down + * the subtree to find the leftmost leaf that describes this + * free space. + */ + for (k = bmp->db_agheigth; k > 0; k--) { + for (n = 0, m = (ti << 2) + 1; n < 4; n++) { + if (l2nb <= dcp->stree[m + n]) { + ti = m + n; + break; + } + } + assert(n < 4); + } + + /* determine the block number within the file system + * that corresponds to this leaf. + */ + if (bmp->db_aglevel == 2) + blkno = 0; + else if (bmp->db_aglevel == 1) + blkno &= ~(MAXL1SIZE - 1); + else /* bmp->db_aglevel == 0 */ + blkno &= ~(MAXL0SIZE - 1); + + blkno += + ((s64) (ti - le32_to_cpu(dcp->leafidx))) << budmin; + + /* release the buffer in preparation for going down + * the next level of dmap control pages. + */ + release_metapage(mp); + + /* check if we need to continue to search down the lower + * level dmap control pages. we need to if the number of + * blocks required is less than maximum number of blocks + * described at the next lower level. + */ + if (l2nb < budmin) { + + /* search the lower level dmap control pages to get + * the starting block number of the the dmap that + * contains or starts off the free space. + */ + if ((rc = + dbFindCtl(bmp, l2nb, bmp->db_aglevel - 1, + &blkno))) { + assert(rc != ENOSPC); + return (rc); + } + } + + /* allocate the blocks. + */ + rc = dbAllocCtl(bmp, nblocks, l2nb, blkno, results); + assert(rc != ENOSPC); + return (rc); + } + + /* no space in the allocation group. release the buffer and + * return ENOSPC. + */ + release_metapage(mp); + + return (ENOSPC); +} + + +/* + * NAME: dbAllocAny() + * + * FUNCTION: attempt to allocate the specified number of contiguous + * free blocks anywhere in the file system. + * + * dbAllocAny() attempts to find the sufficient free space by + * searching down the dmap control pages, starting with the + * highest level (i.e. L0, L1, L2) control page. if free space + * large enough to satisfy the desired free space is found, the + * desired free space is allocated. + * + * PARAMETERS: + * bmp - pointer to bmap descriptor + * nblocks - actual number of contiguous free blocks desired. + * l2nb - log2 number of contiguous free blocks desired. + * results - on successful return, set to the starting block number + * of the newly allocated range. + * + * RETURN VALUES: + * 0 - success + * ENOSPC - insufficient disk resources + * EIO - i/o error + * + * serialization: IWRITE_LOCK(ipbmap) held on entry/exit; + */ +static int dbAllocAny(bmap_t * bmp, s64 nblocks, int l2nb, s64 * results) +{ + int rc; + s64 blkno = 0; + + /* starting with the top level dmap control page, search + * down the dmap control levels for sufficient free space. + * if free space is found, dbFindCtl() returns the starting + * block number of the dmap that contains or starts off the + * range of free space. + */ + if ((rc = dbFindCtl(bmp, l2nb, bmp->db_maxlevel, &blkno))) + return (rc); + + /* allocate the blocks. + */ + rc = dbAllocCtl(bmp, nblocks, l2nb, blkno, results); + assert(rc != ENOSPC); + return (rc); +} + + +/* + * NAME: dbFindCtl() + * + * FUNCTION: starting at a specified dmap control page level and block + * number, search down the dmap control levels for a range of + * contiguous free blocks large enough to satisfy an allocation + * request for the specified number of free blocks. + * + * if sufficient contiguous free blocks are found, this routine + * returns the starting block number within a dmap page that + * contains or starts a range of contiqious free blocks that + * is sufficient in size. + * + * PARAMETERS: + * bmp - pointer to bmap descriptor + * level - starting dmap control page level. + * l2nb - log2 number of contiguous free blocks desired. + * *blkno - on entry, starting block number for conducting the search. + * on successful return, the first block within a dmap page + * that contains or starts a range of contiguous free blocks. + * + * RETURN VALUES: + * 0 - success + * ENOSPC - insufficient disk resources + * EIO - i/o error + * + * serialization: IWRITE_LOCK(ipbmap) held on entry/exit; + */ +static int dbFindCtl(bmap_t * bmp, int l2nb, int level, s64 * blkno) +{ + int rc, leafidx, lev; + s64 b, lblkno; + dmapctl_t *dcp; + int budmin; + metapage_t *mp; + + /* starting at the specified dmap control page level and block + * number, search down the dmap control levels for the starting + * block number of a dmap page that contains or starts off + * sufficient free blocks. + */ + for (lev = level, b = *blkno; lev >= 0; lev--) { + /* get the buffer of the dmap control page for the block + * number and level (i.e. L0, L1, L2). + */ + lblkno = BLKTOCTL(b, bmp->db_l2nbperpage, lev); + mp = read_metapage(bmp->db_ipbmap, lblkno, PSIZE, 0); + if (mp == NULL) + return (EIO); + dcp = (dmapctl_t *) mp->data; + budmin = dcp->budmin; + + /* search the tree within the dmap control page for + * sufficent free space. if sufficient free space is found, + * dbFindLeaf() returns the index of the leaf at which + * free space was found. + */ + rc = dbFindLeaf((dmtree_t *) dcp, l2nb, &leafidx); + + /* release the buffer. + */ + release_metapage(mp); + + /* space found ? + */ + if (rc) { + assert(lev == level); + return (ENOSPC); + } + + /* adjust the block number to reflect the location within + * the dmap control page (i.e. the leaf) at which free + * space was found. + */ + b += (((s64) leafidx) << budmin); + + /* we stop the search at this dmap control page level if + * the number of blocks required is greater than or equal + * to the maximum number of blocks described at the next + * (lower) level. + */ + if (l2nb >= budmin) + break; + } + + *blkno = b; + return (0); +} + + +/* + * NAME: dbAllocCtl() + * + * FUNCTION: attempt to allocate a specified number of contiguous + * blocks starting within a specific dmap. + * + * this routine is called by higher level routines that search + * the dmap control pages above the actual dmaps for contiguous + * free space. the result of successful searches by these + * routines are the starting block numbers within dmaps, with + * the dmaps themselves containing the desired contiguous free + * space or starting a contiguous free space of desired size + * that is made up of the blocks of one or more dmaps. these + * calls should not fail due to insufficent resources. + * + * this routine is called in some cases where it is not known + * whether it will fail due to insufficient resources. more + * specifically, this occurs when allocating from an allocation + * group whose size is equal to the number of blocks per dmap. + * in this case, the dmap control pages are not examined prior + * to calling this routine (to save pathlength) and the call + * might fail. + * + * for a request size that fits within a dmap, this routine relies + * upon the dmap's dmtree to find the requested contiguous free + * space. for request sizes that are larger than a dmap, the + * requested free space will start at the first block of the + * first dmap (i.e. blkno). + * + * PARAMETERS: + * bmp - pointer to bmap descriptor + * nblocks - actual number of contiguous free blocks to allocate. + * l2nb - log2 number of contiguous free blocks to allocate. + * blkno - starting block number of the dmap to start the allocation + * from. + * results - on successful return, set to the starting block number + * of the newly allocated range. + * + * RETURN VALUES: + * 0 - success + * ENOSPC - insufficient disk resources + * EIO - i/o error + * + * serialization: IWRITE_LOCK(ipbmap) held on entry/exit; + */ +static int +dbAllocCtl(bmap_t * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results) +{ + int rc, nb; + s64 b, lblkno, n; + metapage_t *mp; + dmap_t *dp; + + /* check if the allocation request is confined to a single dmap. + */ + if (l2nb <= L2BPERDMAP) { + /* get the buffer for the dmap. + */ + lblkno = BLKTODMAP(blkno, bmp->db_l2nbperpage); + mp = read_metapage(bmp->db_ipbmap, lblkno, PSIZE, 0); + if (mp == NULL) + return (EIO); + dp = (dmap_t *) mp->data; + + /* try to allocate the blocks. + */ + rc = dbAllocDmapLev(bmp, dp, (int) nblocks, l2nb, results); + if (rc == 0) + mark_metapage_dirty(mp); + + release_metapage(mp); + + return (rc); + } + + /* allocation request involving multiple dmaps. it must start on + * a dmap boundary. + */ + assert((blkno & (BPERDMAP - 1)) == 0); + + /* allocate the blocks dmap by dmap. + */ + for (n = nblocks, b = blkno; n > 0; n -= nb, b += nb) { + /* get the buffer for the dmap. + */ + lblkno = BLKTODMAP(b, bmp->db_l2nbperpage); + mp = read_metapage(bmp->db_ipbmap, lblkno, PSIZE, 0); + if (mp == NULL) { + rc = EIO; + goto backout; + } + dp = (dmap_t *) mp->data; + + /* the dmap better be all free. + */ + assert(dp->tree.stree[ROOT] == L2BPERDMAP); + + /* determine how many blocks to allocate from this dmap. + */ + nb = min(n, (s64)BPERDMAP); + + /* allocate the blocks from the dmap. + */ + if ((rc = dbAllocDmap(bmp, dp, b, nb))) { + release_metapage(mp); + goto backout; + } + + /* write the buffer. + */ + write_metapage(mp); + } + + /* set the results (starting block number) and return. + */ + *results = blkno; + return (0); + + /* something failed in handling an allocation request involving + * multiple dmaps. we'll try to clean up by backing out any + * allocation that has already happened for this request. if + * we fail in backing out the allocation, we'll mark the file + * system to indicate that blocks have been leaked. + */ + backout: + + /* try to backout the allocations dmap by dmap. + */ + for (n = nblocks - n, b = blkno; n > 0; + n -= BPERDMAP, b += BPERDMAP) { + /* get the buffer for this dmap. + */ + lblkno = BLKTODMAP(b, bmp->db_l2nbperpage); + mp = read_metapage(bmp->db_ipbmap, lblkno, PSIZE, 0); + if (mp == NULL) { + /* could not back out. mark the file system + * to indicate that we have leaked blocks. + */ + fsDirty(); /* !!! */ + jERROR(1, + ("dbAllocCtl: I/O Error: Block Leakage.\n")); + continue; + } + dp = (dmap_t *) mp->data; + + /* free the blocks is this dmap. + */ + if (dbFreeDmap(bmp, dp, b, BPERDMAP)) { + /* could not back out. mark the file system + * to indicate that we have leaked blocks. + */ + release_metapage(mp); + fsDirty(); /* !!! */ + jERROR(1, ("dbAllocCtl: Block Leakage.\n")); + continue; + } + + /* write the buffer. + */ + write_metapage(mp); + } + + return (rc); +} + + +/* + * NAME: dbAllocDmapLev() + * + * FUNCTION: attempt to allocate a specified number of contiguous blocks + * from a specified dmap. + * + * this routine checks if the contiguous blocks are available. + * if so, nblocks of blocks are allocated; otherwise, ENOSPC is + * returned. + * + * PARAMETERS: + * mp - pointer to bmap descriptor + * dp - pointer to dmap to attempt to allocate blocks from. + * l2nb - log2 number of contiguous block desired. + * nblocks - actual number of contiguous block desired. + * results - on successful return, set to the starting block number + * of the newly allocated range. + * + * RETURN VALUES: + * 0 - success + * ENOSPC - insufficient disk resources + * EIO - i/o error + * + * serialization: IREAD_LOCK(ipbmap), e.g., from dbAlloc(), or + * IWRITE_LOCK(ipbmap), e.g., dbAllocCtl(), held on entry/exit; + */ +static int +dbAllocDmapLev(bmap_t * bmp, + dmap_t * dp, int nblocks, int l2nb, s64 * results) +{ + s64 blkno; + int leafidx, rc; + + /* can't be more than a dmaps worth of blocks */ + assert(l2nb <= L2BPERDMAP); + + /* search the tree within the dmap page for sufficient + * free space. if sufficient free space is found, dbFindLeaf() + * returns the index of the leaf at which free space was found. + */ + if (dbFindLeaf((dmtree_t *) & dp->tree, l2nb, &leafidx)) + return (ENOSPC); + + /* determine the block number within the file system corresponding + * to the leaf at which free space was found. + */ + blkno = le64_to_cpu(dp->start) + (leafidx << L2DBWORD); + + /* if not all bits of the dmap word are free, get the starting + * bit number within the dmap word of the required string of free + * bits and adjust the block number with this value. + */ + if (dp->tree.stree[leafidx + LEAFIND] < BUDMIN) + blkno += dbFindBits(le32_to_cpu(dp->wmap[leafidx]), l2nb); + + /* allocate the blocks */ + if ((rc = dbAllocDmap(bmp, dp, blkno, nblocks)) == 0) + *results = blkno; + + return (rc); +} + + +/* + * NAME: dbAllocDmap() + * + * FUNCTION: adjust the disk allocation map to reflect the allocation + * of a specified block range within a dmap. + * + * this routine allocates the specified blocks from the dmap + * through a call to dbAllocBits(). if the allocation of the + * block range causes the maximum string of free blocks within + * the dmap to change (i.e. the value of the root of the dmap's + * dmtree), this routine will cause this change to be reflected + * up through the appropriate levels of the dmap control pages + * by a call to dbAdjCtl() for the L0 dmap control page that + * covers this dmap. + * + * PARAMETERS: + * bmp - pointer to bmap descriptor + * dp - pointer to dmap to allocate the block range from. + * blkno - starting block number of the block to be allocated. + * nblocks - number of blocks to be allocated. + * + * RETURN VALUES: + * 0 - success + * EIO - i/o error + * + * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit; + */ +static int dbAllocDmap(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks) +{ + s8 oldroot; + int rc; + + /* save the current value of the root (i.e. maximum free string) + * of the dmap tree. + */ + oldroot = dp->tree.stree[ROOT]; + + /* allocate the specified (blocks) bits */ + dbAllocBits(bmp, dp, blkno, nblocks); + + /* if the root has not changed, done. */ + if (dp->tree.stree[ROOT] == oldroot) + return (0); + + /* root changed. bubble the change up to the dmap control pages. + * if the adjustment of the upper level control pages fails, + * backout the bit allocation (thus making everything consistent). + */ + if ((rc = dbAdjCtl(bmp, blkno, dp->tree.stree[ROOT], 1, 0))) + dbFreeBits(bmp, dp, blkno, nblocks); + + return (rc); +} + + +/* + * NAME: dbFreeDmap() + * + * FUNCTION: adjust the disk allocation map to reflect the allocation + * of a specified block range within a dmap. + * + * this routine frees the specified blocks from the dmap through + * a call to dbFreeBits(). if the deallocation of the block range + * causes the maximum string of free blocks within the dmap to + * change (i.e. the value of the root of the dmap's dmtree), this + * routine will cause this change to be reflected up through the + * appropriate levels of the dmap control pages by a call to + * dbAdjCtl() for the L0 dmap control page that covers this dmap. + * + * PARAMETERS: + * bmp - pointer to bmap descriptor + * dp - pointer to dmap to free the block range from. + * blkno - starting block number of the block to be freed. + * nblocks - number of blocks to be freed. + * + * RETURN VALUES: + * 0 - success + * EIO - i/o error + * + * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit; + */ +static int dbFreeDmap(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks) +{ + s8 oldroot; + int rc, word; + + /* save the current value of the root (i.e. maximum free string) + * of the dmap tree. + */ + oldroot = dp->tree.stree[ROOT]; + + /* free the specified (blocks) bits */ + dbFreeBits(bmp, dp, blkno, nblocks); + + /* if the root has not changed, done. */ + if (dp->tree.stree[ROOT] == oldroot) + return (0); + + /* root changed. bubble the change up to the dmap control pages. + * if the adjustment of the upper level control pages fails, + * backout the deallocation. + */ + if ((rc = dbAdjCtl(bmp, blkno, dp->tree.stree[ROOT], 0, 0))) { + word = (blkno & (BPERDMAP - 1)) >> L2DBWORD; + + /* as part of backing out the deallocation, we will have + * to back split the dmap tree if the deallocation caused + * the freed blocks to become part of a larger binary buddy + * system. + */ + if (dp->tree.stree[word] == NOFREE) + dbBackSplit((dmtree_t *) & dp->tree, word); + + dbAllocBits(bmp, dp, blkno, nblocks); + } + + return (rc); +} + + +/* + * NAME: dbAllocBits() + * + * FUNCTION: allocate a specified block range from a dmap. + * + * this routine updates the dmap to reflect the working + * state allocation of the specified block range. it directly + * updates the bits of the working map and causes the adjustment + * of the binary buddy system described by the dmap's dmtree + * leaves to reflect the bits allocated. it also causes the + * dmap's dmtree, as a whole, to reflect the allocated range. + * + * PARAMETERS: + * bmp - pointer to bmap descriptor + * dp - pointer to dmap to allocate bits from. + * blkno - starting block number of the bits to be allocated. + * nblocks - number of bits to be allocated. + * + * RETURN VALUES: none + * + * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit; + */ +static void dbAllocBits(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks) +{ + int dbitno, word, rembits, nb, nwords, wbitno, nw, agno; + dmtree_t *tp = (dmtree_t *) & dp->tree; + int size; + s8 *leaf; + + /* pick up a pointer to the leaves of the dmap tree */ + leaf = dp->tree.stree + LEAFIND; + + /* determine the bit number and word within the dmap of the + * starting block. + */ + dbitno = blkno & (BPERDMAP - 1); + word = dbitno >> L2DBWORD; + + /* block range better be within the dmap */ + assert(dbitno + nblocks <= BPERDMAP); + + /* allocate the bits of the dmap's words corresponding to the block + * range. not all bits of the first and last words may be contained + * within the block range. if this is the case, we'll work against + * those words (i.e. partial first and/or last) on an individual basis + * (a single pass), allocating the bits of interest by hand and + * updating the leaf corresponding to the dmap word. a single pass + * will be used for all dmap words fully contained within the + * specified range. within this pass, the bits of all fully contained + * dmap words will be marked as free in a single shot and the leaves + * will be updated. a single leaf may describe the free space of + * multiple dmap words, so we may update only a subset of the actual + * leaves corresponding to the dmap words of the block range. + */ + for (rembits = nblocks; rembits > 0; rembits -= nb, dbitno += nb) { + /* determine the bit number within the word and + * the number of bits within the word. + */ + wbitno = dbitno & (DBWORD - 1); + nb = min(rembits, DBWORD - wbitno); + + /* check if only part of a word is to be allocated. + */ + if (nb < DBWORD) { + /* allocate (set to 1) the appropriate bits within + * this dmap word. + */ + dp->wmap[word] |= cpu_to_le32(ONES << (DBWORD - nb) + >> wbitno); + + /* update the leaf for this dmap word. in addition + * to setting the leaf value to the binary buddy max + * of the updated dmap word, dbSplit() will split + * the binary system of the leaves if need be. + */ + dbSplit(tp, word, BUDMIN, + dbMaxBud((u8 *) & dp->wmap[word])); + + word += 1; + } else { + /* one or more dmap words are fully contained + * within the block range. determine how many + * words and allocate (set to 1) the bits of these + * words. + */ + nwords = rembits >> L2DBWORD; + memset(&dp->wmap[word], (int) ONES, nwords * 4); + + /* determine how many bits. + */ + nb = nwords << L2DBWORD; + + /* now update the appropriate leaves to reflect + * the allocated words. + */ + for (; nwords > 0; nwords -= nw) { + assert(leaf[word] >= BUDMIN); + + /* determine what the leaf value should be + * updated to as the minimum of the l2 number + * of bits being allocated and the l2 number + * of bits currently described by this leaf. + */ + size = min((int)leaf[word], NLSTOL2BSZ(nwords)); + + /* update the leaf to reflect the allocation. + * in addition to setting the leaf value to + * NOFREE, dbSplit() will split the binary + * system of the leaves to reflect the current + * allocation (size). + */ + dbSplit(tp, word, size, NOFREE); + + /* get the number of dmap words handled */ + nw = BUDSIZE(size, BUDMIN); + word += nw; + } + } + } + + /* update the free count for this dmap */ + dp->nfree = cpu_to_le32(le32_to_cpu(dp->nfree) - nblocks); + + BMAP_LOCK(bmp); + + /* if this allocation group is completely free, + * update the maximum allocation group number if this allocation + * group is the new max. + */ + agno = blkno >> bmp->db_agl2size; + if (agno > bmp->db_maxag) + bmp->db_maxag = agno; + + /* update the free count for the allocation group and map */ + bmp->db_agfree[agno] -= nblocks; + bmp->db_nfree -= nblocks; + + BMAP_UNLOCK(bmp); +} + + +/* + * NAME: dbFreeBits() + * + * FUNCTION: free a specified block range from a dmap. + * + * this routine updates the dmap to reflect the working + * state allocation of the specified block range. it directly + * updates the bits of the working map and causes the adjustment + * of the binary buddy system described by the dmap's dmtree + * leaves to reflect the bits freed. it also causes the dmap's + * dmtree, as a whole, to reflect the deallocated range. + * + * PARAMETERS: + * bmp - pointer to bmap descriptor + * dp - pointer to dmap to free bits from. + * blkno - starting block number of the bits to be freed. + * nblocks - number of bits to be freed. + * + * RETURN VALUES: none + * + * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit; + */ +static void dbFreeBits(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks) +{ + int dbitno, word, rembits, nb, nwords, wbitno, nw, agno; + dmtree_t *tp = (dmtree_t *) & dp->tree; + int size; + + /* determine the bit number and word within the dmap of the + * starting block. + */ + dbitno = blkno & (BPERDMAP - 1); + word = dbitno >> L2DBWORD; + + /* block range better be within the dmap. + */ + assert(dbitno + nblocks <= BPERDMAP); + + /* free the bits of the dmaps words corresponding to the block range. + * not all bits of the first and last words may be contained within + * the block range. if this is the case, we'll work against those + * words (i.e. partial first and/or last) on an individual basis + * (a single pass), freeing the bits of interest by hand and updating + * the leaf corresponding to the dmap word. a single pass will be used + * for all dmap words fully contained within the specified range. + * within this pass, the bits of all fully contained dmap words will + * be marked as free in a single shot and the leaves will be updated. a + * single leaf may describe the free space of multiple dmap words, + * so we may update only a subset of the actual leaves corresponding + * to the dmap words of the block range. + * + * dbJoin() is used to update leaf values and will join the binary + * buddy system of the leaves if the new leaf values indicate this + * should be done. + */ + for (rembits = nblocks; rembits > 0; rembits -= nb, dbitno += nb) { + /* determine the bit number within the word and + * the number of bits within the word. + */ + wbitno = dbitno & (DBWORD - 1); + nb = min(rembits, DBWORD - wbitno); + + /* check if only part of a word is to be freed. + */ + if (nb < DBWORD) { + /* free (zero) the appropriate bits within this + * dmap word. + */ + dp->wmap[word] &= + cpu_to_le32(~(ONES << (DBWORD - nb) + >> wbitno)); + + /* update the leaf for this dmap word. + */ + dbJoin(tp, word, + dbMaxBud((u8 *) & dp->wmap[word])); + + word += 1; + } else { + /* one or more dmap words are fully contained + * within the block range. determine how many + * words and free (zero) the bits of these words. + */ + nwords = rembits >> L2DBWORD; + memset(&dp->wmap[word], 0, nwords * 4); + + /* determine how many bits. + */ + nb = nwords << L2DBWORD; + + /* now update the appropriate leaves to reflect + * the freed words. + */ + for (; nwords > 0; nwords -= nw) { + /* determine what the leaf value should be + * updated to as the minimum of the l2 number + * of bits being freed and the l2 (max) number + * of bits that can be described by this leaf. + */ + size = + min(LITOL2BSZ + (word, L2LPERDMAP, BUDMIN), + NLSTOL2BSZ(nwords)); + + /* update the leaf. + */ + dbJoin(tp, word, size); + + /* get the number of dmap words handled. + */ + nw = BUDSIZE(size, BUDMIN); + word += nw; + } + } + } + + /* update the free count for this dmap. + */ + dp->nfree = cpu_to_le32(le32_to_cpu(dp->nfree) + nblocks); + + BMAP_LOCK(bmp); + + /* update the free count for the allocation group and + * map. + */ + agno = blkno >> bmp->db_agl2size; + bmp->db_nfree += nblocks; + bmp->db_agfree[agno] += nblocks; + + /* check if this allocation group is not completely free and + * if it is currently the maximum (rightmost) allocation group. + * if so, establish the new maximum allocation group number by + * searching left for the first allocation group with allocation. + */ + if ((bmp->db_agfree[agno] == bmp->db_agsize + && agno == bmp->db_maxag) || (agno == bmp->db_numag - 1 + && bmp->db_agfree[agno] == + (bmp-> db_mapsize & + (BPERDMAP - 1)))) { + while (bmp->db_maxag > 0) { + bmp->db_maxag -= 1; + if (bmp->db_agfree[bmp->db_maxag] != + bmp->db_agsize) + break; + } + + /* re-establish the allocation group preference if the + * current preference is right of the maximum allocation + * group. + */ + if (bmp->db_agpref > bmp->db_maxag) + bmp->db_agpref = bmp->db_maxag; + } + + BMAP_UNLOCK(bmp); +} + + +/* + * NAME: dbAdjCtl() + * + * FUNCTION: adjust a dmap control page at a specified level to reflect + * the change in a lower level dmap or dmap control page's + * maximum string of free blocks (i.e. a change in the root + * of the lower level object's dmtree) due to the allocation + * or deallocation of a range of blocks with a single dmap. + * + * on entry, this routine is provided with the new value of + * the lower level dmap or dmap control page root and the + * starting block number of the block range whose allocation + * or deallocation resulted in the root change. this range + * is respresented by a single leaf of the current dmapctl + * and the leaf will be updated with this value, possibly + * causing a binary buddy system within the leaves to be + * split or joined. the update may also cause the dmapctl's + * dmtree to be updated. + * + * if the adjustment of the dmap control page, itself, causes its + * root to change, this change will be bubbled up to the next dmap + * control level by a recursive call to this routine, specifying + * the new root value and the next dmap control page level to + * be adjusted. + * PARAMETERS: + * bmp - pointer to bmap descriptor + * blkno - the first block of a block range within a dmap. it is + * the allocation or deallocation of this block range that + * requires the dmap control page to be adjusted. + * newval - the new value of the lower level dmap or dmap control + * page root. + * alloc - TRUE if adjustment is due to an allocation. + * level - current level of dmap control page (i.e. L0, L1, L2) to + * be adjusted. + * + * RETURN VALUES: + * 0 - success + * EIO - i/o error + * + * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit; + */ +static int +dbAdjCtl(bmap_t * bmp, s64 blkno, int newval, int alloc, int level) +{ + metapage_t *mp; + s8 oldroot; + int oldval; + s64 lblkno; + dmapctl_t *dcp; + int rc, leafno, ti; + + /* get the buffer for the dmap control page for the specified + * block number and control page level. + */ + lblkno = BLKTOCTL(blkno, bmp->db_l2nbperpage, level); + mp = read_metapage(bmp->db_ipbmap, lblkno, PSIZE, 0); + if (mp == NULL) + return (EIO); + dcp = (dmapctl_t *) mp->data; + + /* determine the leaf number corresponding to the block and + * the index within the dmap control tree. + */ + leafno = BLKTOCTLLEAF(blkno, dcp->budmin); + ti = leafno + le32_to_cpu(dcp->leafidx); + + /* save the current leaf value and the current root level (i.e. + * maximum l2 free string described by this dmapctl). + */ + oldval = dcp->stree[ti]; + oldroot = dcp->stree[ROOT]; + + /* check if this is a control page update for an allocation. + * if so, update the leaf to reflect the new leaf value using + * dbSplit(); otherwise (deallocation), use dbJoin() to udpate + * the leaf with the new value. in addition to updating the + * leaf, dbSplit() will also split the binary buddy system of + * the leaves, if required, and bubble new values within the + * dmapctl tree, if required. similarly, dbJoin() will join + * the binary buddy system of leaves and bubble new values up + * the dmapctl tree as required by the new leaf value. + */ + if (alloc) { + /* check if we are in the middle of a binary buddy + * system. this happens when we are performing the + * first allocation out of an allocation group that + * is part (not the first part) of a larger binary + * buddy system. if we are in the middle, back split + * the system prior to calling dbSplit() which assumes + * that it is at the front of a binary buddy system. + */ + if (oldval == NOFREE) { + dbBackSplit((dmtree_t *) dcp, leafno); + oldval = dcp->stree[ti]; + } + dbSplit((dmtree_t *) dcp, leafno, dcp->budmin, newval); + } else { + dbJoin((dmtree_t *) dcp, leafno, newval); + } + + /* check if the root of the current dmap control page changed due + * to the update and if the current dmap control page is not at + * the current top level (i.e. L0, L1, L2) of the map. if so (i.e. + * root changed and this is not the top level), call this routine + * again (recursion) for the next higher level of the mapping to + * reflect the change in root for the current dmap control page. + */ + if (dcp->stree[ROOT] != oldroot) { + /* are we below the top level of the map. if so, + * bubble the root up to the next higher level. + */ + if (level < bmp->db_maxlevel) { + /* bubble up the new root of this dmap control page to + * the next level. + */ + if ((rc = + dbAdjCtl(bmp, blkno, dcp->stree[ROOT], alloc, + level + 1))) { + /* something went wrong in bubbling up the new + * root value, so backout the changes to the + * current dmap control page. + */ + if (alloc) { + dbJoin((dmtree_t *) dcp, leafno, + oldval); + } else { + /* the dbJoin() above might have + * caused a larger binary buddy system + * to form and we may now be in the + * middle of it. if this is the case, + * back split the buddies. + */ + if (dcp->stree[ti] == NOFREE) + dbBackSplit((dmtree_t *) + dcp, leafno); + dbSplit((dmtree_t *) dcp, leafno, + dcp->budmin, oldval); + } + + /* release the buffer and return the error. + */ + release_metapage(mp); + return (rc); + } + } else { + /* we're at the top level of the map. update + * the bmap control page to reflect the size + * of the maximum free buddy system. + */ + assert(level == bmp->db_maxlevel); + assert(bmp->db_maxfreebud == oldroot); + bmp->db_maxfreebud = dcp->stree[ROOT]; + } + } + + /* write the buffer. + */ + write_metapage(mp); + + return (0); +} + + +/* + * NAME: dbSplit() + * + * FUNCTION: update the leaf of a dmtree with a new value, splitting + * the leaf from the binary buddy system of the dmtree's + * leaves, as required. + * + * PARAMETERS: + * tp - pointer to the tree containing the leaf. + * leafno - the number of the leaf to be updated. + * splitsz - the size the binary buddy system starting at the leaf + * must be split to, specified as the log2 number of blocks. + * newval - the new value for the leaf. + * + * RETURN VALUES: none + * + * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit; + */ +static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval) +{ + int budsz; + int cursz; + s8 *leaf = tp->dmt_stree + le32_to_cpu(tp->dmt_leafidx); + + /* check if the leaf needs to be split. + */ + if (leaf[leafno] > tp->dmt_budmin) { + /* the split occurs by cutting the buddy system in half + * at the specified leaf until we reach the specified + * size. pick up the starting split size (current size + * - 1 in l2) and the corresponding buddy size. + */ + cursz = leaf[leafno] - 1; + budsz = BUDSIZE(cursz, tp->dmt_budmin); + + /* split until we reach the specified size. + */ + while (cursz >= splitsz) { + /* update the buddy's leaf with its new value. + */ + dbAdjTree(tp, leafno ^ budsz, cursz); + + /* on to the next size and buddy. + */ + cursz -= 1; + budsz >>= 1; + } + } + + /* adjust the dmap tree to reflect the specified leaf's new + * value. + */ + dbAdjTree(tp, leafno, newval); +} + + +/* + * NAME: dbBackSplit() + * + * FUNCTION: back split the binary buddy system of dmtree leaves + * that hold a specified leaf until the specified leaf + * starts its own binary buddy system. + * + * the allocators typically perform allocations at the start + * of binary buddy systems and dbSplit() is used to accomplish + * any required splits. in some cases, however, allocation + * may occur in the middle of a binary system and requires a + * back split, with the split proceeding out from the middle of + * the system (less efficient) rather than the start of the + * system (more efficient). the cases in which a back split + * is required are rare and are limited to the first allocation + * within an allocation group which is a part (not first part) + * of a larger binary buddy system and a few exception cases + * in which a previous join operation must be backed out. + * + * PARAMETERS: + * tp - pointer to the tree containing the leaf. + * leafno - the number of the leaf to be updated. + * + * RETURN VALUES: none + * + * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit; + */ +static void dbBackSplit(dmtree_t * tp, int leafno) +{ + int budsz, bud, w, bsz, size; + int cursz; + s8 *leaf = tp->dmt_stree + le32_to_cpu(tp->dmt_leafidx); + + /* leaf should be part (not first part) of a binary + * buddy system. + */ + assert(leaf[leafno] == NOFREE); + + /* the back split is accomplished by iteratively finding the leaf + * that starts the buddy system that contains the specified leaf and + * splitting that system in two. this iteration continues until + * the specified leaf becomes the start of a buddy system. + * + * determine maximum possible l2 size for the specified leaf. + */ + size = + LITOL2BSZ(leafno, le32_to_cpu(tp->dmt_l2nleafs), + tp->dmt_budmin); + + /* determine the number of leaves covered by this size. this + * is the buddy size that we will start with as we search for + * the buddy system that contains the specified leaf. + */ + budsz = BUDSIZE(size, tp->dmt_budmin); + + /* back split. + */ + while (leaf[leafno] == NOFREE) { + /* find the leftmost buddy leaf. + */ + for (w = leafno, bsz = budsz;; bsz <<= 1, + w = (w < bud) ? w : bud) { + assert(bsz < le32_to_cpu(tp->dmt_nleafs)); + + /* determine the buddy. + */ + bud = w ^ bsz; + + /* check if this buddy is the start of the system. + */ + if (leaf[bud] != NOFREE) { + /* split the leaf at the start of the + * system in two. + */ + cursz = leaf[bud] - 1; + dbSplit(tp, bud, cursz, cursz); + break; + } + } + } + + assert(leaf[leafno] == size); +} + + +/* + * NAME: dbJoin() + * + * FUNCTION: update the leaf of a dmtree with a new value, joining + * the leaf with other leaves of the dmtree into a multi-leaf + * binary buddy system, as required. + * + * PARAMETERS: + * tp - pointer to the tree containing the leaf. + * leafno - the number of the leaf to be updated. + * newval - the new value for the leaf. + * + * RETURN VALUES: none + */ +static void dbJoin(dmtree_t * tp, int leafno, int newval) +{ + int budsz, buddy; + s8 *leaf; + + /* can the new leaf value require a join with other leaves ? + */ + if (newval >= tp->dmt_budmin) { + /* pickup a pointer to the leaves of the tree. + */ + leaf = tp->dmt_stree + le32_to_cpu(tp->dmt_leafidx); + + /* try to join the specified leaf into a large binary + * buddy system. the join proceeds by attempting to join + * the specified leafno with its buddy (leaf) at new value. + * if the join occurs, we attempt to join the left leaf + * of the joined buddies with its buddy at new value + 1. + * we continue to join until we find a buddy that cannot be + * joined (does not have a value equal to the size of the + * last join) or until all leaves have been joined into a + * single system. + * + * get the buddy size (number of words covered) of + * the new value. + */ + budsz = BUDSIZE(newval, tp->dmt_budmin); + + /* try to join. + */ + while (budsz < le32_to_cpu(tp->dmt_nleafs)) { + /* get the buddy leaf. + */ + buddy = leafno ^ budsz; + + /* if the leaf's new value is greater than its + * buddy's value, we join no more. + */ + if (newval > leaf[buddy]) + break; + + assert(newval == leaf[buddy]); + + /* check which (leafno or buddy) is the left buddy. + * the left buddy gets to claim the blocks resulting + * from the join while the right gets to claim none. + * the left buddy is also eligable to participate in + * a join at the next higher level while the right + * is not. + * + */ + if (leafno < buddy) { + /* leafno is the left buddy. + */ + dbAdjTree(tp, buddy, NOFREE); + } else { + /* buddy is the left buddy and becomes + * leafno. + */ + dbAdjTree(tp, leafno, NOFREE); + leafno = buddy; + } + + /* on to try the next join. + */ + newval += 1; + budsz <<= 1; + } + } + + /* update the leaf value. + */ + dbAdjTree(tp, leafno, newval); +} + + +/* + * NAME: dbAdjTree() + * + * FUNCTION: update a leaf of a dmtree with a new value, adjusting + * the dmtree, as required, to reflect the new leaf value. + * the combination of any buddies must already be done before + * this is called. + * + * PARAMETERS: + * tp - pointer to the tree to be adjusted. + * leafno - the number of the leaf to be updated. + * newval - the new value for the leaf. + * + * RETURN VALUES: none + */ +static void dbAdjTree(dmtree_t * tp, int leafno, int newval) +{ + int lp, pp, k; + int max; + + /* pick up the index of the leaf for this leafno. + */ + lp = leafno + le32_to_cpu(tp->dmt_leafidx); + + /* is the current value the same as the old value ? if so, + * there is nothing to do. + */ + if (tp->dmt_stree[lp] == newval) + return; + + /* set the new value. + */ + tp->dmt_stree[lp] = newval; + + /* bubble the new value up the tree as required. + */ + for (k = 0; k < le32_to_cpu(tp->dmt_height); k++) { + /* get the index of the first leaf of the 4 leaf + * group containing the specified leaf (leafno). + */ + lp = ((lp - 1) & ~0x03) + 1; + + /* get the index of the parent of this 4 leaf group. + */ + pp = (lp - 1) >> 2; + + /* determine the maximum of the 4 leaves. + */ + max = TREEMAX(&tp->dmt_stree[lp]); + + /* if the maximum of the 4 is the same as the + * parent's value, we're done. + */ + if (tp->dmt_stree[pp] == max) + break; + + /* parent gets new value. + */ + tp->dmt_stree[pp] = max; + + /* parent becomes leaf for next go-round. + */ + lp = pp; + } +} + + +/* + * NAME: dbFindLeaf() + * + * FUNCTION: search a dmtree_t for sufficient free blocks, returning + * the index of a leaf describing the free blocks if + * sufficient free blocks are found. + * + * the search starts at the top of the dmtree_t tree and + * proceeds down the tree to the leftmost leaf with sufficient + * free space. + * + * PARAMETERS: + * tp - pointer to the tree to be searched. + * l2nb - log2 number of free blocks to search for. + * leafidx - return pointer to be set to the index of the leaf + * describing at least l2nb free blocks if sufficient + * free blocks are found. + * + * RETURN VALUES: + * 0 - success + * ENOSPC - insufficient free blocks. + */ +static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx) +{ + int ti, n = 0, k, x = 0; + + /* first check the root of the tree to see if there is + * sufficient free space. + */ + if (l2nb > tp->dmt_stree[ROOT]) + return (ENOSPC); + + /* sufficient free space available. now search down the tree + * starting at the next level for the leftmost leaf that + * describes sufficient free space. + */ + for (k = le32_to_cpu(tp->dmt_height), ti = 1; + k > 0; k--, ti = ((ti + n) << 2) + 1) { + /* search the four nodes at this level, starting from + * the left. + */ + for (x = ti, n = 0; n < 4; n++) { + /* sufficient free space found. move to the next + * level (or quit if this is the last level). + */ + if (l2nb <= tp->dmt_stree[x + n]) + break; + } + + /* better have found something since the higher + * levels of the tree said it was here. + */ + assert(n < 4); + } + + /* set the return to the leftmost leaf describing sufficient + * free space. + */ + *leafidx = x + n - le32_to_cpu(tp->dmt_leafidx); + + return (0); +} + + +/* + * NAME: dbFindBits() + * + * FUNCTION: find a specified number of binary buddy free bits within a + * dmap bitmap word value. + * + * this routine searches the bitmap value for (1 << l2nb) free + * bits at (1 << l2nb) alignments within the value. + * + * PARAMETERS: + * word - dmap bitmap word value. + * l2nb - number of free bits specified as a log2 number. + * + * RETURN VALUES: + * starting bit number of free bits. + */ +static int dbFindBits(u32 word, int l2nb) +{ + int bitno, nb; + u32 mask; + + /* get the number of bits. + */ + nb = 1 << l2nb; + assert(nb <= DBWORD); + + /* complement the word so we can use a mask (i.e. 0s represent + * free bits) and compute the mask. + */ + word = ~word; + mask = ONES << (DBWORD - nb); + + /* scan the word for nb free bits at nb alignments. + */ + for (bitno = 0; mask != 0; bitno += nb, mask >>= nb) { + if ((mask & word) == mask) + break; + } + + ASSERT(bitno < 32); + + /* return the bit number. + */ + return (bitno); +} + + +/* + * NAME: dbMaxBud(u8 *cp) + * + * FUNCTION: determine the largest binary buddy string of free + * bits within 32-bits of the map. + * + * PARAMETERS: + * cp - pointer to the 32-bit value. + * + * RETURN VALUES: + * largest binary buddy of free bits within a dmap word. + */ +static int dbMaxBud(u8 * cp) +{ + signed char tmp1, tmp2; + + /* check if the wmap word is all free. if so, the + * free buddy size is BUDMIN. + */ + if (*((uint *) cp) == 0) + return (BUDMIN); + + /* check if the wmap word is half free. if so, the + * free buddy size is BUDMIN-1. + */ + if (*((u16 *) cp) == 0 || *((u16 *) cp + 1) == 0) + return (BUDMIN - 1); + + /* not all free or half free. determine the free buddy + * size thru table lookup using quarters of the wmap word. + */ + tmp1 = max(budtab[cp[2]], budtab[cp[3]]); + tmp2 = max(budtab[cp[0]], budtab[cp[1]]); + return (max(tmp1, tmp2)); +} + + +/* + * NAME: cnttz(uint word) + * + * FUNCTION: determine the number of trailing zeros within a 32-bit + * value. + * + * PARAMETERS: + * value - 32-bit value to be examined. + * + * RETURN VALUES: + * count of trailing zeros + */ +int cnttz(u32 word) +{ + int n; + + for (n = 0; n < 32; n++, word >>= 1) { + if (word & 0x01) + break; + } + + return (n); +} + + +/* + * NAME: cntlz(u32 value) + * + * FUNCTION: determine the number of leading zeros within a 32-bit + * value. + * + * PARAMETERS: + * value - 32-bit value to be examined. + * + * RETURN VALUES: + * count of leading zeros + */ +int cntlz(u32 value) +{ + int n; + + for (n = 0; n < 32; n++, value <<= 1) { + if (value & HIGHORDER) + break; + } + return (n); +} + + +/* + * NAME: blkstol2(s64 nb) + * + * FUNCTION: convert a block count to its log2 value. if the block + * count is not a l2 multiple, it is rounded up to the next + * larger l2 multiple. + * + * PARAMETERS: + * nb - number of blocks + * + * RETURN VALUES: + * log2 number of blocks + */ +int blkstol2(s64 nb) +{ + int l2nb; + s64 mask; /* meant to be signed */ + + mask = (s64) 1 << (64 - 1); + + /* count the leading bits. + */ + for (l2nb = 0; l2nb < 64; l2nb++, mask >>= 1) { + /* leading bit found. + */ + if (nb & mask) { + /* determine the l2 value. + */ + l2nb = (64 - 1) - l2nb; + + /* check if we need to round up. + */ + if (~mask & nb) + l2nb++; + + return (l2nb); + } + } + assert(0); + return 0; /* fix compiler warning */ +} + + +/* + * NAME: fsDirty() + * + * FUNCTION: xxx + * + * PARAMETERS: + * ipmnt - mount inode + * + * RETURN VALUES: + * none + */ +void fsDirty() +{ + printk("fsDirty(): bye-bye\n"); + assert(0); +} + + +/* + * NAME: dbAllocBottomUp() + * + * FUNCTION: alloc the specified block range from the working block + * allocation map. + * + * the blocks will be alloc from the working map one dmap + * at a time. + * + * PARAMETERS: + * ip - pointer to in-core inode; + * blkno - starting block number to be freed. + * nblocks - number of blocks to be freed. + * + * RETURN VALUES: + * 0 - success + * EIO - i/o error + */ +int dbAllocBottomUp(struct inode *ip, s64 blkno, s64 nblocks) +{ + metapage_t *mp; + dmap_t *dp; + int nb, rc; + s64 lblkno, rem; + struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap; + bmap_t *bmp = JFS_SBI(ip->i_sb)->bmap; + + IREAD_LOCK(ipbmap); + + /* block to be allocated better be within the mapsize. */ + ASSERT(nblocks <= bmp->db_mapsize - blkno); + + /* + * allocate the blocks a dmap at a time. + */ + mp = NULL; + for (rem = nblocks; rem > 0; rem -= nb, blkno += nb) { + /* release previous dmap if any */ + if (mp) { + write_metapage(mp); + } + + /* get the buffer for the current dmap. */ + lblkno = BLKTODMAP(blkno, bmp->db_l2nbperpage); + mp = read_metapage(ipbmap, lblkno, PSIZE, 0); + if (mp == NULL) { + IREAD_UNLOCK(ipbmap); + return (EIO); + } + dp = (dmap_t *) mp->data; + + /* determine the number of blocks to be allocated from + * this dmap. + */ + nb = min(rem, BPERDMAP - (blkno & (BPERDMAP - 1))); + + DBFREECK(bmp->db_DBmap, bmp->db_mapsize, blkno, nb); + + /* allocate the blocks. */ + if ((rc = dbAllocDmapBU(bmp, dp, blkno, nb))) { + release_metapage(mp); + IREAD_UNLOCK(ipbmap); + return (rc); + } + + DBALLOC(bmp->db_DBmap, bmp->db_mapsize, blkno, nb); + } + + /* write the last buffer. */ + write_metapage(mp); + + IREAD_UNLOCK(ipbmap); + + return (0); +} + + +static int dbAllocDmapBU(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks) +{ + int rc; + int dbitno, word, rembits, nb, nwords, wbitno, agno; + s8 oldroot, *leaf; + dmaptree_t *tp = (dmaptree_t *) & dp->tree; + + /* save the current value of the root (i.e. maximum free string) + * of the dmap tree. + */ + oldroot = tp->stree[ROOT]; + + /* pick up a pointer to the leaves of the dmap tree */ + leaf = tp->stree + LEAFIND; + + /* determine the bit number and word within the dmap of the + * starting block. + */ + dbitno = blkno & (BPERDMAP - 1); + word = dbitno >> L2DBWORD; + + /* block range better be within the dmap */ + assert(dbitno + nblocks <= BPERDMAP); + + /* allocate the bits of the dmap's words corresponding to the block + * range. not all bits of the first and last words may be contained + * within the block range. if this is the case, we'll work against + * those words (i.e. partial first and/or last) on an individual basis + * (a single pass), allocating the bits of interest by hand and + * updating the leaf corresponding to the dmap word. a single pass + * will be used for all dmap words fully contained within the + * specified range. within this pass, the bits of all fully contained + * dmap words will be marked as free in a single shot and the leaves + * will be updated. a single leaf may describe the free space of + * multiple dmap words, so we may update only a subset of the actual + * leaves corresponding to the dmap words of the block range. + */ + for (rembits = nblocks; rembits > 0; rembits -= nb, dbitno += nb) { + /* determine the bit number within the word and + * the number of bits within the word. + */ + wbitno = dbitno & (DBWORD - 1); + nb = min(rembits, DBWORD - wbitno); + + /* check if only part of a word is to be allocated. + */ + if (nb < DBWORD) { + /* allocate (set to 1) the appropriate bits within + * this dmap word. + */ + dp->wmap[word] |= cpu_to_le32(ONES << (DBWORD - nb) + >> wbitno); + + word += 1; + } else { + /* one or more dmap words are fully contained + * within the block range. determine how many + * words and allocate (set to 1) the bits of these + * words. + */ + nwords = rembits >> L2DBWORD; + memset(&dp->wmap[word], (int) ONES, nwords * 4); + + /* determine how many bits */ + nb = nwords << L2DBWORD; + } + } + + /* update the free count for this dmap */ + dp->nfree = cpu_to_le32(le32_to_cpu(dp->nfree) - nblocks); + + /* reconstruct summary tree */ + dbInitDmapTree(dp); + + BMAP_LOCK(bmp); + + /* if this allocation group is completely free, + * update the highest active allocation group number + * if this allocation group is the new max. + */ + agno = blkno >> bmp->db_agl2size; + if (agno > bmp->db_maxag) + bmp->db_maxag = agno; + + /* update the free count for the allocation group and map */ + bmp->db_agfree[agno] -= nblocks; + bmp->db_nfree -= nblocks; + + BMAP_UNLOCK(bmp); + + /* if the root has not changed, done. */ + if (tp->stree[ROOT] == oldroot) + return (0); + + /* root changed. bubble the change up to the dmap control pages. + * if the adjustment of the upper level control pages fails, + * backout the bit allocation (thus making everything consistent). + */ + if ((rc = dbAdjCtl(bmp, blkno, tp->stree[ROOT], 1, 0))) + dbFreeBits(bmp, dp, blkno, nblocks); + + return (rc); +} + + +/* + * NAME: dbExtendFS() + * + * FUNCTION: extend bmap from blkno for nblocks; + * dbExtendFS() updates bmap ready for dbAllocBottomUp(); + * + * L2 + * | + * L1---------------------------------L1 + * | | + * L0---------L0---------L0 L0---------L0---------L0 + * | | | | | | + * d0,...,dn d0,...,dn d0,...,dn d0,...,dn d0,...,dn d0,.,dm; + * L2L1L0d0,...,dnL0d0,...,dnL0d0,...,dnL1L0d0,...,dnL0d0,...,dnL0d0,..dm + * + * <---old---><----------------------------extend-----------------------> + */ +int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks) +{ + struct jfs_sb_info *sbi = JFS_SBI(ipbmap->i_sb); + int nbperpage = sbi->nbperpage; + int i, i0 = TRUE, j, j0 = TRUE, k, n; + s64 newsize; + s64 p; + metapage_t *mp, *l2mp, *l1mp, *l0mp; + dmapctl_t *l2dcp, *l1dcp, *l0dcp; + dmap_t *dp; + s8 *l0leaf, *l1leaf, *l2leaf; + bmap_t *bmp = sbi->bmap; + int agno, l2agsize, oldl2agsize; + s64 ag_rem; + + newsize = blkno + nblocks; + + jEVENT(0, ("dbExtendFS: blkno:%Ld nblocks:%Ld newsize:%Ld\n", + (long long) blkno, (long long) nblocks, + (long long) newsize)); + + /* + * initialize bmap control page. + * + * all the data in bmap control page should exclude + * the mkfs hidden dmap page. + */ + + /* update mapsize */ + bmp->db_mapsize = newsize; + bmp->db_maxlevel = BMAPSZTOLEV(bmp->db_mapsize); + + /* compute new AG size */ + l2agsize = dbGetL2AGSize(newsize); + oldl2agsize = bmp->db_agl2size; + + bmp->db_agl2size = l2agsize; + bmp->db_agsize = 1 << l2agsize; + + /* compute new number of AG */ + agno = bmp->db_numag; + bmp->db_numag = newsize >> l2agsize; + bmp->db_numag += ((u32) newsize % (u32) bmp->db_agsize) ? 1 : 0; + + /* + * reconfigure db_agfree[] + * from old AG configuration to new AG configuration; + * + * coalesce contiguous k (newAGSize/oldAGSize) AGs; + * i.e., (AGi, ..., AGj) where i = k*n and j = k*(n+1) - 1 to AGn; + * note: new AG size = old AG size * (2**x). + */ + if (l2agsize == oldl2agsize) + goto extend; + k = 1 << (l2agsize - oldl2agsize); + ag_rem = bmp->db_agfree[0]; /* save agfree[0] */ + for (i = 0, n = 0; i < agno; n++) { + bmp->db_agfree[n] = 0; /* init collection point */ + + /* coalesce cotiguous k AGs; */ + for (j = 0; j < k && i < agno; j++, i++) { + /* merge AGi to AGn */ + bmp->db_agfree[n] += bmp->db_agfree[i]; + } + } + bmp->db_agfree[0] += ag_rem; /* restore agfree[0] */ + + for (; n < MAXAG; n++) + bmp->db_agfree[n] = 0; + + /* + * update highest active ag number + */ + + bmp->db_maxag = bmp->db_maxag / k; + + /* + * extend bmap + * + * update bit maps and corresponding level control pages; + * global control page db_nfree, db_agfree[agno], db_maxfreebud; + */ + extend: + /* get L2 page */ + p = BMAPBLKNO + nbperpage; /* L2 page */ + l2mp = read_metapage(ipbmap, p, PSIZE, 0); + assert(l2mp); + l2dcp = (dmapctl_t *) l2mp->data; + + /* compute start L1 */ + k = blkno >> L2MAXL1SIZE; + l2leaf = l2dcp->stree + CTLLEAFIND + k; + p = BLKTOL1(blkno, sbi->l2nbperpage); /* L1 page */ + + /* + * extend each L1 in L2 + */ + for (; k < LPERCTL; k++, p += nbperpage) { + /* get L1 page */ + if (j0) { + /* read in L1 page: (blkno & (MAXL1SIZE - 1)) */ + l1mp = read_metapage(ipbmap, p, PSIZE, 0); + if (l1mp == NULL) + goto errout; + l1dcp = (dmapctl_t *) l1mp->data; + + /* compute start L0 */ + j = (blkno & (MAXL1SIZE - 1)) >> L2MAXL0SIZE; + l1leaf = l1dcp->stree + CTLLEAFIND + j; + p = BLKTOL0(blkno, sbi->l2nbperpage); + j0 = FALSE; + } else { + /* assign/init L1 page */ + l1mp = get_metapage(ipbmap, p, PSIZE, 0); + if (l1mp == NULL) + goto errout; + + l1dcp = (dmapctl_t *) l1mp->data; + + /* compute start L0 */ + j = 0; + l1leaf = l1dcp->stree + CTLLEAFIND; + p += nbperpage; /* 1st L0 of L1.k */ + } + + /* + * extend each L0 in L1 + */ + for (; j < LPERCTL; j++) { + /* get L0 page */ + if (i0) { + /* read in L0 page: (blkno & (MAXL0SIZE - 1)) */ + + l0mp = read_metapage(ipbmap, p, PSIZE, 0); + if (l0mp == NULL) + goto errout; + l0dcp = (dmapctl_t *) l0mp->data; + + /* compute start dmap */ + i = (blkno & (MAXL0SIZE - 1)) >> + L2BPERDMAP; + l0leaf = l0dcp->stree + CTLLEAFIND + i; + p = BLKTODMAP(blkno, + sbi->l2nbperpage); + i0 = FALSE; + } else { + /* assign/init L0 page */ + l0mp = get_metapage(ipbmap, p, PSIZE, 0); + if (l0mp == NULL) + goto errout; + + l0dcp = (dmapctl_t *) l0mp->data; + + /* compute start dmap */ + i = 0; + l0leaf = l0dcp->stree + CTLLEAFIND; + p += nbperpage; /* 1st dmap of L0.j */ + } + + /* + * extend each dmap in L0 + */ + for (; i < LPERCTL; i++) { + /* + * reconstruct the dmap page, and + * initialize corresponding parent L0 leaf + */ + if ((n = blkno & (BPERDMAP - 1))) { + /* read in dmap page: */ + mp = read_metapage(ipbmap, p, + PSIZE, 0); + if (mp == NULL) + goto errout; + n = min(nblocks, (s64)BPERDMAP - n); + } else { + /* assign/init dmap page */ + mp = read_metapage(ipbmap, p, + PSIZE, 0); + if (mp == NULL) + goto errout; + + n = min(nblocks, (s64)BPERDMAP); + } + + dp = (dmap_t *) mp->data; + *l0leaf = dbInitDmap(dp, blkno, n); + + bmp->db_nfree += n; + agno = le64_to_cpu(dp->start) >> l2agsize; + bmp->db_agfree[agno] += n; + + write_metapage(mp); + + l0leaf++; + p += nbperpage; + + blkno += n; + nblocks -= n; + if (nblocks == 0) + break; + } /* for each dmap in a L0 */ + + /* + * build current L0 page from its leaves, and + * initialize corresponding parent L1 leaf + */ + *l1leaf = dbInitDmapCtl(l0dcp, 0, ++i); + write_metapage(l0mp); + + if (nblocks) + l1leaf++; /* continue for next L0 */ + else { + /* more than 1 L0 ? */ + if (j > 0) + break; /* build L1 page */ + else { + /* summarize in global bmap page */ + bmp->db_maxfreebud = *l1leaf; + release_metapage(l1mp); + release_metapage(l2mp); + goto finalize; + } + } + } /* for each L0 in a L1 */ + + /* + * build current L1 page from its leaves, and + * initialize corresponding parent L2 leaf + */ + *l2leaf = dbInitDmapCtl(l1dcp, 1, ++j); + write_metapage(l1mp); + + if (nblocks) + l2leaf++; /* continue for next L1 */ + else { + /* more than 1 L1 ? */ + if (k > 0) + break; /* build L2 page */ + else { + /* summarize in global bmap page */ + bmp->db_maxfreebud = *l2leaf; + release_metapage(l2mp); + goto finalize; + } + } + } /* for each L1 in a L2 */ + + assert(0); + + /* + * finalize bmap control page + */ + finalize: + + return 0; + + errout: + return EIO; +} + + +/* + * dbFinalizeBmap() + */ +void dbFinalizeBmap(struct inode *ipbmap) +{ + bmap_t *bmp = JFS_SBI(ipbmap->i_sb)->bmap; + int actags, inactags, l2nl; + s64 ag_rem, actfree, inactfree, avgfree; + int i, n; + + /* + * finalize bmap control page + */ +//finalize: + /* + * compute db_agpref: preferred ag to allocate from + * (the leftmost ag with average free space in it); + */ +//agpref: + /* get the number of active ags and inacitve ags */ + actags = bmp->db_maxag + 1; + inactags = bmp->db_numag - actags; + ag_rem = bmp->db_mapsize & (bmp->db_agsize - 1); /* ??? */ + + /* determine how many blocks are in the inactive allocation + * groups. in doing this, we must account for the fact that + * the rightmost group might be a partial group (i.e. file + * system size is not a multiple of the group size). + */ + inactfree = (inactags && ag_rem) ? + ((inactags - 1) << bmp->db_agl2size) + ag_rem + : inactags << bmp->db_agl2size; + + /* determine how many free blocks are in the active + * allocation groups plus the average number of free blocks + * within the active ags. + */ + actfree = bmp->db_nfree - inactfree; + avgfree = (u32) actfree / (u32) actags; + + /* if the preferred allocation group has not average free space. + * re-establish the preferred group as the leftmost + * group with average free space. + */ + if (bmp->db_agfree[bmp->db_agpref] < avgfree) { + for (bmp->db_agpref = 0; bmp->db_agpref < actags; + bmp->db_agpref++) { + if (bmp->db_agfree[bmp->db_agpref] >= avgfree) + break; + } + assert(bmp->db_agpref < bmp->db_numag); + } + + /* + * compute db_aglevel, db_agheigth, db_width, db_agstart: + * an ag is covered in aglevel dmapctl summary tree, + * at agheight level height (from leaf) with agwidth number of nodes + * each, which starts at agstart index node of the smmary tree node + * array; + */ + bmp->db_aglevel = BMAPSZTOLEV(bmp->db_agsize); + l2nl = + bmp->db_agl2size - (L2BPERDMAP + bmp->db_aglevel * L2LPERCTL); + bmp->db_agheigth = l2nl >> 1; + bmp->db_agwidth = 1 << (l2nl - (bmp->db_agheigth << 1)); + for (i = 5 - bmp->db_agheigth, bmp->db_agstart = 0, n = 1; i > 0; + i--) { + bmp->db_agstart += n; + n <<= 2; + } + +/* +printk("bmap: agpref:%d aglevel:%d agheigth:%d agwidth:%d\n", + bmp->db_agpref, bmp->db_aglevel, bmp->db_agheigth, bmp->db_agwidth); +*/ +} + + +/* + * NAME: dbInitDmap()/ujfs_idmap_page() + * + * FUNCTION: initialize working/persistent bitmap of the dmap page + * for the specified number of blocks: + * + * at entry, the bitmaps had been initialized as free (ZEROS); + * The number of blocks will only account for the actually + * existing blocks. Blocks which don't actually exist in + * the aggregate will be marked as allocated (ONES); + * + * PARAMETERS: + * dp - pointer to page of map + * nblocks - number of blocks this page + * + * RETURNS: NONE + */ +static int dbInitDmap(dmap_t * dp, s64 Blkno, int nblocks) +{ + int blkno, w, b, r, nw, nb, i; +/* +printk("sbh_dmap: in dbInitDmap blkno:%Ld nblocks:%ld\n", Blkno, nblocks); +*/ + + /* starting block number within the dmap */ + blkno = Blkno & (BPERDMAP - 1); + + if (blkno == 0) { + dp->nblocks = dp->nfree = cpu_to_le32(nblocks); + dp->start = cpu_to_le64(Blkno); + + if (nblocks == BPERDMAP) { + memset(&dp->wmap[0], 0, LPERDMAP * 4); + memset(&dp->pmap[0], 0, LPERDMAP * 4); + goto initTree; + } + } else { + dp->nblocks = + cpu_to_le32(le32_to_cpu(dp->nblocks) + nblocks); + dp->nfree = cpu_to_le32(le32_to_cpu(dp->nfree) + nblocks); + } + + /* word number containing start block number */ + w = blkno >> L2DBWORD; + + /* + * free the bits corresponding to the block range (ZEROS): + * note: not all bits of the first and last words may be contained + * within the block range. + */ + for (r = nblocks; r > 0; r -= nb, blkno += nb) { + /* number of bits preceding range to be freed in the word */ + b = blkno & (DBWORD - 1); + /* number of bits to free in the word */ + nb = min(r, DBWORD - b); + + /* is partial word to be freed ? */ + if (nb < DBWORD) { + /* free (set to 0) from the bitmap word */ + dp->wmap[w] &= cpu_to_le32(~(ONES << (DBWORD - nb) + >> b)); + dp->pmap[w] &= cpu_to_le32(~(ONES << (DBWORD - nb) + >> b)); + + /* skip the word freed */ + w++; + } else { + /* free (set to 0) contiguous bitmap words */ + nw = r >> L2DBWORD; + memset(&dp->wmap[w], 0, nw * 4); + memset(&dp->pmap[w], 0, nw * 4); + + /* skip the words freed */ + nb = nw << L2DBWORD; + w += nw; + } + } + + /* + * mark bits following the range to be freed (non-existing + * blocks) as allocated (ONES) + */ +/* +printk("sbh_dmap: in dbInitDmap, preparing to mark unbacked, blkno:%ld nblocks:%ld\n", + blkno, nblocks); +*/ + + if (blkno == BPERDMAP) + goto initTree; + + /* the first word beyond the end of existing blocks */ + w = blkno >> L2DBWORD; + + /* does nblocks fall on a 32-bit boundary ? */ + b = blkno & (DBWORD - 1); +/* +printk("sbh_dmap: in dbInitDmap, b:%ld w:%ld mask: %lx\n", b, w, (ONES>>b)); +*/ + if (b) { + /* mark a partial word allocated */ + dp->wmap[w] = dp->pmap[w] = cpu_to_le32(ONES >> b); + w++; + } + + /* set the rest of the words in the page to allocated (ONES) */ + for (i = w; i < LPERDMAP; i++) + dp->pmap[i] = dp->wmap[i] = ONES; + + /* + * init tree + */ + initTree: + return (dbInitDmapTree(dp)); +} + + +/* + * NAME: dbInitDmapTree()/ujfs_complete_dmap() + * + * FUNCTION: initialize summary tree of the specified dmap: + * + * at entry, bitmap of the dmap has been initialized; + * + * PARAMETERS: + * dp - dmap to complete + * blkno - starting block number for this dmap + * treemax - will be filled in with max free for this dmap + * + * RETURNS: max free string at the root of the tree + */ +static int dbInitDmapTree(dmap_t * dp) +{ + dmaptree_t *tp; + s8 *cp; + int i; + + /* init fixed info of tree */ + tp = &dp->tree; + tp->nleafs = cpu_to_le32(LPERDMAP); + tp->l2nleafs = cpu_to_le32(L2LPERDMAP); + tp->leafidx = cpu_to_le32(LEAFIND); + tp->height = cpu_to_le32(4); + tp->budmin = BUDMIN; + + /* init each leaf from corresponding wmap word: + * note: leaf is set to NOFREE(-1) if all blocks of corresponding + * bitmap word are allocated. + */ + cp = tp->stree + le32_to_cpu(tp->leafidx); + for (i = 0; i < LPERDMAP; i++) + *cp++ = dbMaxBud((u8 *) & dp->wmap[i]); + + /* build the dmap's binary buddy summary tree */ + return (dbInitTree(tp)); +} + + +/* + * NAME: dbInitTree()/ujfs_adjtree() + * + * FUNCTION: initialize binary buddy summary tree of a dmap or dmapctl. + * + * at entry, the leaves of the tree has been initialized + * from corresponding bitmap word or root of summary tree + * of the child control page; + * configure binary buddy system at the leaf level, then + * bubble up the values of the leaf nodes up the tree. + * + * PARAMETERS: + * cp - Pointer to the root of the tree + * l2leaves- Number of leaf nodes as a power of 2 + * l2min - Number of blocks that can be covered by a leaf + * as a power of 2 + * + * RETURNS: max free string at the root of the tree + */ +static int dbInitTree(dmaptree_t * dtp) +{ + int l2max, l2free, bsize, nextb, i; + int child, parent, nparent; + s8 *tp, *cp, *cp1; + + tp = dtp->stree; + + /* Determine the maximum free string possible for the leaves */ + l2max = le32_to_cpu(dtp->l2nleafs) + dtp->budmin; + + /* + * configure the leaf levevl into binary buddy system + * + * Try to combine buddies starting with a buddy size of 1 + * (i.e. two leaves). At a buddy size of 1 two buddy leaves + * can be combined if both buddies have a maximum free of l2min; + * the combination will result in the left-most buddy leaf having + * a maximum free of l2min+1. + * After processing all buddies for a given size, process buddies + * at the next higher buddy size (i.e. current size * 2) and + * the next maximum free (current free + 1). + * This continues until the maximum possible buddy combination + * yields maximum free. + */ + for (l2free = dtp->budmin, bsize = 1; l2free < l2max; + l2free++, bsize = nextb) { + /* get next buddy size == current buddy pair size */ + nextb = bsize << 1; + + /* scan each adjacent buddy pair at current buddy size */ + for (i = 0, cp = tp + le32_to_cpu(dtp->leafidx); + i < le32_to_cpu(dtp->nleafs); + i += nextb, cp += nextb) { + /* coalesce if both adjacent buddies are max free */ + if (*cp == l2free && *(cp + bsize) == l2free) { + *cp = l2free + 1; /* left take right */ + *(cp + bsize) = -1; /* right give left */ + } + } + } + + /* + * bubble summary information of leaves up the tree. + * + * Starting at the leaf node level, the four nodes described by + * the higher level parent node are compared for a maximum free and + * this maximum becomes the value of the parent node. + * when all lower level nodes are processed in this fashion then + * move up to the next level (parent becomes a lower level node) and + * continue the process for that level. + */ + for (child = le32_to_cpu(dtp->leafidx), + nparent = le32_to_cpu(dtp->nleafs) >> 2; + nparent > 0; nparent >>= 2, child = parent) { + /* get index of 1st node of parent level */ + parent = (child - 1) >> 2; + + /* set the value of the parent node as the maximum + * of the four nodes of the current level. + */ + for (i = 0, cp = tp + child, cp1 = tp + parent; + i < nparent; i++, cp += 4, cp1++) + *cp1 = TREEMAX(cp); + } + + return (*tp); +} + + +/* + * dbInitDmapCtl() + * + * function: initialize dmapctl page + */ +static int dbInitDmapCtl(dmapctl_t * dcp, int level, int i) +{ /* start leaf index not covered by range */ + s8 *cp; + + dcp->nleafs = cpu_to_le32(LPERCTL); + dcp->l2nleafs = cpu_to_le32(L2LPERCTL); + dcp->leafidx = cpu_to_le32(CTLLEAFIND); + dcp->height = cpu_to_le32(5); + dcp->budmin = L2BPERDMAP + L2LPERCTL * level; + + /* + * initialize the leaves of current level that were not covered + * by the specified input block range (i.e. the leaves have no + * low level dmapctl or dmap). + */ + cp = &dcp->stree[CTLLEAFIND + i]; + for (; i < LPERCTL; i++) + *cp++ = NOFREE; + + /* build the dmap's binary buddy summary tree */ + return (dbInitTree((dmaptree_t *) dcp)); +} + + +/* + * NAME: dbGetL2AGSize()/ujfs_getagl2size() + * + * FUNCTION: Determine log2(allocation group size) from aggregate size + * + * PARAMETERS: + * nblocks - Number of blocks in aggregate + * + * RETURNS: log2(allocation group size) in aggregate blocks + */ +static int dbGetL2AGSize(s64 nblocks) +{ + s64 sz; + s64 m; + int l2sz; + + if (nblocks < BPERDMAP * MAXAG) + return (L2BPERDMAP); + + /* round up aggregate size to power of 2 */ + m = ((u64) 1 << (64 - 1)); + for (l2sz = 64; l2sz >= 0; l2sz--, m >>= 1) { + if (m & nblocks) + break; + } + + sz = (s64) 1 << l2sz; + if (sz < nblocks) + l2sz += 1; + + /* agsize = roundupSize/max_number_of_ag */ + return (l2sz - L2MAXAG); +} + + +/* + * NAME: dbMapFileSizeToMapSize() + * + * FUNCTION: compute number of blocks the block allocation map file + * can cover from the map file size; + * + * RETURNS: Number of blocks which can be covered by this block map file; + */ + +/* + * maximum number of map pages at each level including control pages + */ +#define MAXL0PAGES (1 + LPERCTL) +#define MAXL1PAGES (1 + LPERCTL * MAXL0PAGES) +#define MAXL2PAGES (1 + LPERCTL * MAXL1PAGES) + +/* + * convert number of map pages to the zero origin top dmapctl level + */ +#define BMAPPGTOLEV(npages) \ + (((npages) <= 3 + MAXL0PAGES) ? 0 \ + : ((npages) <= 2 + MAXL1PAGES) ? 1 : 2) + +s64 dbMapFileSizeToMapSize(struct inode * ipbmap) +{ + struct super_block *sb = ipbmap->i_sb; + s64 nblocks; + s64 npages, ndmaps; + int level, i; + int complete, factor; + + nblocks = ipbmap->i_size >> JFS_SBI(sb)->l2bsize; + npages = nblocks >> JFS_SBI(sb)->l2nbperpage; + level = BMAPPGTOLEV(npages); + + /* At each level, accumulate the number of dmap pages covered by + * the number of full child levels below it; + * repeat for the last incomplete child level. + */ + ndmaps = 0; + npages--; /* skip the first global control page */ + /* skip higher level control pages above top level covered by map */ + npages -= (2 - level); + npages--; /* skip top level's control page */ + for (i = level; i >= 0; i--) { + factor = + (i == 2) ? MAXL1PAGES : ((i == 1) ? MAXL0PAGES : 1); + complete = (u32) npages / factor; + ndmaps += complete * ((i == 2) ? LPERCTL * LPERCTL + : ((i == 1) ? LPERCTL : 1)); + + /* pages in last/incomplete child */ + npages = (u32) npages % factor; + /* skip incomplete child's level control page */ + npages--; + } + + /* convert the number of dmaps into the number of blocks + * which can be covered by the dmaps; + */ + nblocks = ndmaps << L2BPERDMAP; + + return (nblocks); +} + + +#ifdef _JFS_DEBUG_DMAP +/* + * DBinitmap() + */ +static void DBinitmap(s64 size, struct inode *ipbmap, u32 ** results) +{ + int npages; + u32 *dbmap, *d; + int n; + s64 lblkno, cur_block; + dmap_t *dp; + metapage_t *mp; + + npages = size / 32768; + npages += (size % 32768) ? 1 : 0; + + dbmap = (u32 *) xmalloc(npages * 4096, L2PSIZE, kernel_heap); + if (dbmap == NULL) + assert(0); + + for (n = 0, d = dbmap; n < npages; n++, d += 1024) + bzero(d, 4096); + + /* Need to initialize from disk map pages + */ + for (d = dbmap, cur_block = 0; cur_block < size; + cur_block += BPERDMAP, d += LPERDMAP) { + lblkno = BLKTODMAP(cur_block, + JFS_SBI(ipbmap->i_sb)->bmap-> + db_l2nbperpage); + mp = read_metapage(ipbmap, lblkno, PSIZE, 0); + if (mp == NULL) { + assert(0); + } + dp = (dmap_t *) mp->data; + + for (n = 0; n < LPERDMAP; n++) + d[n] = le32_to_cpu(dp->wmap[n]); + + release_metapage(mp); + } + + *results = dbmap; +} + + +/* + * DBAlloc() + */ +void DBAlloc(uint * dbmap, s64 mapsize, s64 blkno, s64 nblocks) +{ + int word, nb, bitno; + u32 mask; + + assert(blkno > 0 && blkno < mapsize); + assert(nblocks > 0 && nblocks <= mapsize); + + assert(blkno + nblocks <= mapsize); + + dbmap += (blkno / 32); + while (nblocks > 0) { + bitno = blkno & (32 - 1); + nb = min(nblocks, 32 - bitno); + + mask = (0xffffffff << (32 - nb) >> bitno); + assert((mask & *dbmap) == 0); + *dbmap |= mask; + + dbmap++; + blkno += nb; + nblocks -= nb; + } +} + + +/* + * DBFree() + */ +static void DBFree(uint * dbmap, s64 mapsize, s64 blkno, s64 nblocks) +{ + int word, nb, bitno; + u32 mask; + + assert(blkno > 0 && blkno < mapsize); + assert(nblocks > 0 && nblocks <= mapsize); + + assert(blkno + nblocks <= mapsize); + + dbmap += (blkno / 32); + while (nblocks > 0) { + bitno = blkno & (32 - 1); + nb = min(nblocks, 32 - bitno); + + mask = (0xffffffff << (32 - nb) >> bitno); + assert((mask & *dbmap) == mask); + *dbmap &= ~mask; + + dbmap++; + blkno += nb; + nblocks -= nb; + } +} + + +/* + * DBAllocCK() + */ +static void DBAllocCK(uint * dbmap, s64 mapsize, s64 blkno, s64 nblocks) +{ + int word, nb, bitno; + u32 mask; + + assert(blkno > 0 && blkno < mapsize); + assert(nblocks > 0 && nblocks <= mapsize); + + assert(blkno + nblocks <= mapsize); + + dbmap += (blkno / 32); + while (nblocks > 0) { + bitno = blkno & (32 - 1); + nb = min(nblocks, 32 - bitno); + + mask = (0xffffffff << (32 - nb) >> bitno); + assert((mask & *dbmap) == mask); + + dbmap++; + blkno += nb; + nblocks -= nb; + } +} + + +/* + * DBFreeCK() + */ +static void DBFreeCK(uint * dbmap, s64 mapsize, s64 blkno, s64 nblocks) +{ + int word, nb, bitno; + u32 mask; + + assert(blkno > 0 && blkno < mapsize); + assert(nblocks > 0 && nblocks <= mapsize); + + assert(blkno + nblocks <= mapsize); + + dbmap += (blkno / 32); + while (nblocks > 0) { + bitno = blkno & (32 - 1); + nb = min(nblocks, 32 - bitno); + + mask = (0xffffffff << (32 - nb) >> bitno); + assert((mask & *dbmap) == 0); + + dbmap++; + blkno += nb; + nblocks -= nb; + } +} + + +/* + * dbPrtMap() + */ +static void dbPrtMap(bmap_t * bmp) +{ + printk(" mapsize: %d%d\n", bmp->db_mapsize); + printk(" nfree: %d%d\n", bmp->db_nfree); + printk(" numag: %d\n", bmp->db_numag); + printk(" agsize: %d%d\n", bmp->db_agsize); + printk(" agl2size: %d\n", bmp->db_agl2size); + printk(" agwidth: %d\n", bmp->db_agwidth); + printk(" agstart: %d\n", bmp->db_agstart); + printk(" agheigth: %d\n", bmp->db_agheigth); + printk(" aglevel: %d\n", bmp->db_aglevel); + printk(" maxlevel: %d\n", bmp->db_maxlevel); + printk(" maxag: %d\n", bmp->db_maxag); + printk(" agpref: %d\n", bmp->db_agpref); + printk(" l2nbppg: %d\n", bmp->db_l2nbperpage); +} + + +/* + * dbPrtCtl() + */ +static void dbPrtCtl(dmapctl_t * dcp) +{ + int i, j, n; + + printk(" height: %08x\n", le32_to_cpu(dcp->height)); + printk(" leafidx: %08x\n", le32_to_cpu(dcp->leafidx)); + printk(" budmin: %08x\n", dcp->budmin); + printk(" nleafs: %08x\n", le32_to_cpu(dcp->nleafs)); + printk(" l2nleafs: %08x\n", le32_to_cpu(dcp->l2nleafs)); + + printk("\n Tree:\n"); + for (i = 0; i < CTLLEAFIND; i += 8) { + n = min(8, CTLLEAFIND - i); + + for (j = 0; j < n; j++) + printf(" [%03x]: %02x", i + j, + (char) dcp->stree[i + j]); + printf("\n"); + } + + printk("\n Tree Leaves:\n"); + for (i = 0; i < LPERCTL; i += 8) { + n = min(8, LPERCTL - i); + + for (j = 0; j < n; j++) + printf(" [%03x]: %02x", + i + j, + (char) dcp->stree[i + j + CTLLEAFIND]); + printf("\n"); + } +} +#endif /* _JFS_DEBUG_DMAP */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_dmap.h linux.19pre5-ac1/fs/jfs/jfs_dmap.h --- linux.19p5/fs/jfs/jfs_dmap.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_dmap.h Thu Apr 4 16:04:13 2002 @@ -0,0 +1,301 @@ +/* + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + * + * jfs_dmap.h: block allocation map manager + */ + +#ifndef _H_JFS_DMAP +#define _H_JFS_DMAP + +#include "jfs_txnmgr.h" + +#define BMAPVERSION 1 /* version number */ +#define TREESIZE (256+64+16+4+1) /* size of a dmap tree */ +#define LEAFIND (64+16+4+1) /* index of 1st leaf of a dmap tree */ +#define LPERDMAP 256 /* num leaves per dmap tree */ +#define L2LPERDMAP 8 /* l2 number of leaves per dmap tree */ +#define DBWORD 32 /* # of blks covered by a map word */ +#define L2DBWORD 5 /* l2 # of blks covered by a mword */ +#define BUDMIN L2DBWORD /* max free string in a map word */ +#define BPERDMAP (LPERDMAP * DBWORD) /* num of blks per dmap */ +#define L2BPERDMAP 13 /* l2 num of blks per dmap */ +#define CTLTREESIZE (1024+256+64+16+4+1) /* size of a dmapctl tree */ +#define CTLLEAFIND (256+64+16+4+1) /* idx of 1st leaf of a dmapctl tree */ +#define LPERCTL 1024 /* num of leaves per dmapctl tree */ +#define L2LPERCTL 10 /* l2 num of leaves per dmapctl tree */ +#define ROOT 0 /* index of the root of a tree */ +#define NOFREE ((s8) -1) /* no blocks free */ +#define MAXAG 128 /* max number of allocation groups */ +#define L2MAXAG 7 /* l2 max num of AG */ +#define L2MINAGSZ 25 /* l2 of minimum AG size in bytes */ +#define BMAPBLKNO 0 /* lblkno of bmap within the map */ + +/* + * maximum l2 number of disk blocks at the various dmapctl levels. + */ +#define L2MAXL0SIZE (L2BPERDMAP + 1 * L2LPERCTL) +#define L2MAXL1SIZE (L2BPERDMAP + 2 * L2LPERCTL) +#define L2MAXL2SIZE (L2BPERDMAP + 3 * L2LPERCTL) + +/* + * maximum number of disk blocks at the various dmapctl levels. + */ +#define MAXL0SIZE ((s64)1 << L2MAXL0SIZE) +#define MAXL1SIZE ((s64)1 << L2MAXL1SIZE) +#define MAXL2SIZE ((s64)1 << L2MAXL2SIZE) + +#define MAXMAPSIZE MAXL2SIZE /* maximum aggregate map size */ + +/* + * determine the maximum free string for four (lower level) nodes + * of the tree. + */ +static __inline signed char TREEMAX(signed char *cp) +{ + signed char tmp1, tmp2; + + tmp1 = max(*(cp+2), *(cp+3)); + tmp2 = max(*(cp), *(cp+1)); + + return max(tmp1, tmp2); +} + +/* + * convert disk block number to the logical block number of the dmap + * describing the disk block. s is the log2(number of logical blocks per page) + * + * The calculation figures out how many logical pages are in front of the dmap. + * - the number of dmaps preceding it + * - the number of L0 pages preceding its L0 page + * - the number of L1 pages preceding its L1 page + * - 3 is added to account for the L2, L1, and L0 page for this dmap + * - 1 is added to account for the control page of the map. + */ +#define BLKTODMAP(b,s) \ + ((((b) >> 13) + ((b) >> 23) + ((b) >> 33) + 3 + 1) << (s)) + +/* + * convert disk block number to the logical block number of the LEVEL 0 + * dmapctl describing the disk block. s is the log2(number of logical blocks + * per page) + * + * The calculation figures out how many logical pages are in front of the L0. + * - the number of dmap pages preceding it + * - the number of L0 pages preceding it + * - the number of L1 pages preceding its L1 page + * - 2 is added to account for the L2, and L1 page for this L0 + * - 1 is added to account for the control page of the map. + */ +#define BLKTOL0(b,s) \ + (((((b) >> 23) << 10) + ((b) >> 23) + ((b) >> 33) + 2 + 1) << (s)) + +/* + * convert disk block number to the logical block number of the LEVEL 1 + * dmapctl describing the disk block. s is the log2(number of logical blocks + * per page) + * + * The calculation figures out how many logical pages are in front of the L1. + * - the number of dmap pages preceding it + * - the number of L0 pages preceding it + * - the number of L1 pages preceding it + * - 1 is added to account for the L2 page + * - 1 is added to account for the control page of the map. + */ +#define BLKTOL1(b,s) \ + (((((b) >> 33) << 20) + (((b) >> 33) << 10) + ((b) >> 33) + 1 + 1) << (s)) + +/* + * convert disk block number to the logical block number of the dmapctl + * at the specified level which describes the disk block. + */ +#define BLKTOCTL(b,s,l) \ + (((l) == 2) ? 1 : ((l) == 1) ? BLKTOL1((b),(s)) : BLKTOL0((b),(s))) + +/* + * convert aggregate map size to the zero origin dmapctl level of the + * top dmapctl. + */ +#define BMAPSZTOLEV(size) \ + (((size) <= MAXL0SIZE) ? 0 : ((size) <= MAXL1SIZE) ? 1 : 2) + +/* convert disk block number to allocation group number. + */ +#define BLKTOAG(b,sbi) ((b) >> ((sbi)->bmap->db_agl2size)) + +/* convert allocation group number to starting disk block + * number. + */ +#define AGTOBLK(a,ip) \ + ((s64)(a) << (JFS_SBI((ip)->i_sb)->bmap->db_agl2size)) + +/* + * dmap summary tree + * + * dmaptree_t must be consistent with dmapctl_t. + */ +typedef struct { + s32 nleafs; /* 4: number of tree leafs */ + s32 l2nleafs; /* 4: l2 number of tree leafs */ + s32 leafidx; /* 4: index of first tree leaf */ + s32 height; /* 4: height of the tree */ + s8 budmin; /* 1: min l2 tree leaf value to combine */ + s8 stree[TREESIZE]; /* TREESIZE: tree */ + u8 pad[2]; /* 2: pad to word boundary */ +} dmaptree_t; /* - 360 - */ + +/* + * dmap page per 8K blocks bitmap + */ +typedef struct { + s32 nblocks; /* 4: num blks covered by this dmap */ + s32 nfree; /* 4: num of free blks in this dmap */ + s64 start; /* 8: starting blkno for this dmap */ + dmaptree_t tree; /* 360: dmap tree */ + u8 pad[1672]; /* 1672: pad to 2048 bytes */ + u32 wmap[LPERDMAP]; /* 1024: bits of the working map */ + u32 pmap[LPERDMAP]; /* 1024: bits of the persistent map */ +} dmap_t; /* - 4096 - */ + +/* + * disk map control page per level. + * + * dmapctl_t must be consistent with dmaptree_t. + */ +typedef struct { + s32 nleafs; /* 4: number of tree leafs */ + s32 l2nleafs; /* 4: l2 number of tree leafs */ + s32 leafidx; /* 4: index of the first tree leaf */ + s32 height; /* 4: height of tree */ + s8 budmin; /* 1: minimum l2 tree leaf value */ + s8 stree[CTLTREESIZE]; /* CTLTREESIZE: dmapctl tree */ + u8 pad[2714]; /* 2714: pad to 4096 */ +} dmapctl_t; /* - 4096 - */ + +/* + * common definition for dmaptree_t within dmap and dmapctl + */ +typedef union { + dmaptree_t t1; + dmapctl_t t2; +} dmtree_t; + +/* macros for accessing fields within dmtree_t */ +#define dmt_nleafs t1.nleafs +#define dmt_l2nleafs t1.l2nleafs +#define dmt_leafidx t1.leafidx +#define dmt_height t1.height +#define dmt_budmin t1.budmin +#define dmt_stree t1.stree + +/* + * on-disk aggregate disk allocation map descriptor. + */ +typedef struct { + s64 dn_mapsize; /* 8: number of blocks in aggregate */ + s64 dn_nfree; /* 8: num free blks in aggregate map */ + s32 dn_l2nbperpage; /* 4: number of blks per page */ + s32 dn_numag; /* 4: total number of ags */ + s32 dn_maxlevel; /* 4: number of active ags */ + s32 dn_maxag; /* 4: max active alloc group number */ + s32 dn_agpref; /* 4: preferred alloc group (hint) */ + s32 dn_aglevel; /* 4: dmapctl level holding the AG */ + s32 dn_agheigth; /* 4: height in dmapctl of the AG */ + s32 dn_agwidth; /* 4: width in dmapctl of the AG */ + s32 dn_agstart; /* 4: start tree index at AG height */ + s32 dn_agl2size; /* 4: l2 num of blks per alloc group */ + s64 dn_agfree[MAXAG]; /* 8*MAXAG: per AG free count */ + s64 dn_agsize; /* 8: num of blks per alloc group */ + s8 dn_maxfreebud; /* 1: max free buddy system */ + u8 pad[3007]; /* 3007: pad to 4096 */ +} dbmap_t; /* - 4096 - */ + +/* + * in-memory aggregate disk allocation map descriptor. + */ +typedef struct bmap { + dbmap_t db_bmap; /* on-disk aggregate map descriptor */ + struct inode *db_ipbmap; /* ptr to aggregate map incore inode */ + struct semaphore db_bmaplock; /* aggregate map lock */ + u32 *db_DBmap; +} bmap_t; + +/* macros for accessing fields within in-memory aggregate map descriptor */ +#define db_mapsize db_bmap.dn_mapsize +#define db_nfree db_bmap.dn_nfree +#define db_agfree db_bmap.dn_agfree +#define db_agsize db_bmap.dn_agsize +#define db_agl2size db_bmap.dn_agl2size +#define db_agwidth db_bmap.dn_agwidth +#define db_agheigth db_bmap.dn_agheigth +#define db_agstart db_bmap.dn_agstart +#define db_numag db_bmap.dn_numag +#define db_maxlevel db_bmap.dn_maxlevel +#define db_aglevel db_bmap.dn_aglevel +#define db_agpref db_bmap.dn_agpref +#define db_maxag db_bmap.dn_maxag +#define db_maxfreebud db_bmap.dn_maxfreebud +#define db_l2nbperpage db_bmap.dn_l2nbperpage + +/* + * macros for various conversions needed by the allocators. + * blkstol2(), cntlz(), and cnttz() are operating system dependent functions. + */ +/* convert number of blocks to log2 number of blocks, rounding up to + * the next log2 value if blocks is not a l2 multiple. + */ +#define BLKSTOL2(d) (blkstol2(d)) + +/* convert number of leafs to log2 leaf value */ +#define NLSTOL2BSZ(n) (31 - cntlz((n)) + BUDMIN) + +/* convert leaf index to log2 leaf value */ +#define LITOL2BSZ(n,m,b) ((((n) == 0) ? (m) : cnttz((n))) + (b)) + +/* convert a block number to a dmap control leaf index */ +#define BLKTOCTLLEAF(b,m) \ + (((b) & (((s64)1 << ((m) + L2LPERCTL)) - 1)) >> (m)) + +/* convert log2 leaf value to buddy size */ +#define BUDSIZE(s,m) (1 << ((s) - (m))) + +/* + * external references. + */ +extern int dbMount(struct inode *ipbmap); + +extern int dbUnmount(struct inode *ipbmap, int mounterror); + +extern int dbFree(struct inode *ipbmap, s64 blkno, s64 nblocks); + +extern int dbUpdatePMap(struct inode *ipbmap, + int free, s64 blkno, s64 nblocks, tblock_t * tblk); + +extern int dbNextAG(struct inode *ipbmap); + +extern int dbAlloc(struct inode *ipbmap, s64 hint, s64 nblocks, s64 * results); + +extern int dbAllocExact(struct inode *ip, s64 blkno, int nblocks); + +extern int dbReAlloc(struct inode *ipbmap, + s64 blkno, s64 nblocks, s64 addnblocks, s64 * results); + +extern int dbSync(struct inode *ipbmap); +extern int dbAllocBottomUp(struct inode *ip, s64 blkno, s64 nblocks); +extern int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks); +extern void dbFinalizeBmap(struct inode *ipbmap); +extern s64 dbMapFileSizeToMapSize(struct inode *ipbmap); +#endif /* _H_JFS_DMAP */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_dtree.c linux.19pre5-ac1/fs/jfs/jfs_dtree.c --- linux.19p5/fs/jfs/jfs_dtree.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_dtree.c Wed Mar 20 15:46:08 2002 @@ -0,0 +1,4525 @@ +/* + * + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + * + * +*/ + +/* + * jfs_dtree.c: directory B+-tree manager + * + * B+-tree with variable length key directory: + * + * each directory page is structured as an array of 32-byte + * directory entry slots initialized as a freelist + * to avoid search/compaction of free space at insertion. + * when an entry is inserted, a number of slots are allocated + * from the freelist as required to store variable length data + * of the entry; when the entry is deleted, slots of the entry + * are returned to freelist. + * + * leaf entry stores full name as key and file serial number + * (aka inode number) as data. + * internal/router entry stores sufffix compressed name + * as key and simple extent descriptor as data. + * + * each directory page maintains a sorted entry index table + * which stores the start slot index of sorted entries + * to allow binary search on the table. + * + * directory starts as a root/leaf page in on-disk inode + * inline data area. + * when it becomes full, it starts a leaf of a external extent + * of length of 1 block. each time the first leaf becomes full, + * it is extended rather than split (its size is doubled), + * until its length becoms 4 KBytes, from then the extent is split + * with new 4 Kbyte extent when it becomes full + * to reduce external fragmentation of small directories. + * + * blah, blah, blah, for linear scan of directory in pieces by + * readdir(). + * + * + * case-insensitive directory file system + * + * names are stored in case-sensitive way in leaf entry. + * but stored, searched and compared in case-insensitive (uppercase) order + * (i.e., both search key and entry key are folded for search/compare): + * (note that case-sensitive order is BROKEN in storage, e.g., + * sensitive: Ad, aB, aC, aD -> insensitive: aB, aC, aD, Ad + * + * entries which folds to the same key makes up a equivalent class + * whose members are stored as contiguous cluster (may cross page boundary) + * but whose order is arbitrary and acts as duplicate, e.g., + * abc, Abc, aBc, abC) + * + * once match is found at leaf, requires scan forward/backward + * either for, in case-insensitive search, duplicate + * or for, in case-sensitive search, for exact match + * + * router entry must be created/stored in case-insensitive way + * in internal entry: + * (right most key of left page and left most key of right page + * are folded, and its suffix compression is propagated as router + * key in parent) + * (e.g., if split occurs and , trather than + * should be made the router key for the split) + * + * case-insensitive search: + * + * fold search key; + * + * case-insensitive search of B-tree: + * for internal entry, router key is already folded; + * for leaf entry, fold the entry key before comparison. + * + * if (leaf entry case-insensitive match found) + * if (next entry satisfies case-insensitive match) + * return EDUPLICATE; + * if (prev entry satisfies case-insensitive match) + * return EDUPLICATE; + * return match; + * else + * return no match; + * + * serialization: + * target directory inode lock is being held on entry/exit + * of all main directory service routines. + * + * log based recovery: + */ + +#include +#include +#include "jfs_incore.h" +#include "jfs_superblock.h" +#include "jfs_filsys.h" +#include "jfs_metapage.h" +#include "jfs_dmap.h" +#include "jfs_unicode.h" +#include "jfs_debug.h" + +/* dtree split parameter */ +typedef struct { + metapage_t *mp; + s16 index; + s16 nslot; + component_t *key; + ddata_t *data; + pxdlist_t *pxdlist; +} dtsplit_t; + +#define DT_PAGE(IP, MP) BT_PAGE(IP, MP, dtpage_t, i_dtroot) + +/* get page buffer for specified block address */ +#define DT_GETPAGE(IP, BN, MP, SIZE, P, RC)\ +{\ + BT_GETPAGE(IP, BN, MP, dtpage_t, SIZE, P, RC, i_dtroot)\ + if (!(RC))\ + {\ + if (((P)->header.nextindex > (((BN)==0)?DTROOTMAXSLOT:(P)->header.maxslot)) ||\ + ((BN) && ((P)->header.maxslot > DTPAGEMAXSLOT)))\ + {\ + jERROR(1,("DT_GETPAGE: dtree page corrupt\n"));\ + BT_PUTPAGE(MP);\ + updateSuper((IP)->i_sb, FM_DIRTY);\ + MP = NULL;\ + RC = EIO;\ + }\ + }\ +} + +/* for consistency */ +#define DT_PUTPAGE(MP) BT_PUTPAGE(MP) + +#define DT_GETSEARCH(IP, LEAF, BN, MP, P, INDEX) \ + BT_GETSEARCH(IP, LEAF, BN, MP, dtpage_t, P, INDEX, i_dtroot) + +/* + * forward references + */ +static int dtSplitUp(tid_t tid, struct inode *ip, + dtsplit_t * split, btstack_t * btstack); + +static int dtSplitPage(tid_t tid, struct inode *ip, dtsplit_t * split, + metapage_t ** rmpp, dtpage_t ** rpp, pxd_t * rxdp); + +static int dtExtendPage(tid_t tid, struct inode *ip, + dtsplit_t * split, btstack_t * btstack); + +static int dtSplitRoot(tid_t tid, struct inode *ip, + dtsplit_t * split, metapage_t ** rmpp); + +static int dtDeleteUp(tid_t tid, struct inode *ip, metapage_t * fmp, + dtpage_t * fp, btstack_t * btstack); + +static int dtSearchNode(struct inode *ip, + s64 lmxaddr, pxd_t * kpxd, btstack_t * btstack); + +static int dtRelink(tid_t tid, struct inode *ip, dtpage_t * p); + +static int dtReadFirst(struct inode *ip, btstack_t * btstack); + +static int dtReadNext(struct inode *ip, + loff_t * offset, btstack_t * btstack); + +static int dtCompare(component_t * key, dtpage_t * p, int si); + +static int ciCompare(component_t * key, dtpage_t * p, int si, int flag); + +static void dtGetKey(dtpage_t * p, int i, component_t * key, int flag); + +static void ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp, + int ri, component_t * key, int flag); + +static void dtInsertEntry(dtpage_t * p, int index, component_t * key, + ddata_t * data, dtlock_t ** dtlock); + +static void dtMoveEntry(dtpage_t * sp, int si, dtpage_t * dp, + dtlock_t ** sdtlock, dtlock_t ** ddtlock, + int do_index); + +static void dtDeleteEntry(dtpage_t * p, int fi, dtlock_t ** dtlock); + +static void dtTruncateEntry(dtpage_t * p, int ti, dtlock_t ** dtlock); + +static void dtLinelockFreelist(dtpage_t * p, int m, dtlock_t ** dtlock); + +#define ciToUpper(c) UniStrupr((c)->name) + +/* + * find_index() + * + * Returns dtree page containing directory table entry for specified + * index and pointer to its entry. + * + * mp must be released by caller. + */ +static dir_table_slot_t *find_index(struct inode *ip, u32 index, + metapage_t ** mp) +{ + struct jfs_inode_info *jfs_ip = JFS_IP(ip); + s64 blkno; + s64 offset; + int page_offset; + dir_table_slot_t *slot; + static int maxWarnings = 10; + + if (index < 2) { + if (maxWarnings) { + jERROR(1, ("find_entry called with index = %d\n", + index)); + maxWarnings--; + } + return 0; + } + + if (index >= jfs_ip->next_index) { + jFYI(1, ("find_entry called with index >= next_index\n")); + return 0; + } + + if (jfs_ip->next_index <= (MAX_INLINE_DIRTABLE_ENTRY + 1)) { + /* + * Inline directory table + */ + *mp = 0; + slot = &jfs_ip->i_dirtable[index - 2]; + } else { + offset = (index - 2) * sizeof(dir_table_slot_t); + page_offset = offset & (PSIZE - 1); + blkno = ((offset + 1) >> L2PSIZE) << + JFS_SBI(ip->i_sb)->l2nbperpage; + + if (*mp && ((*mp)->index != blkno)) { + release_metapage(*mp); + *mp = 0; + } + if (*mp == 0) + *mp = read_metapage(ip, blkno, PSIZE, 0); + if (*mp == 0) { + jERROR(1, + ("free_index: error reading directory table\n")); + return 0; + } + + slot = + (dir_table_slot_t *) ((char *) (*mp)->data + + page_offset); + } + return slot; +} + +static inline void lock_index(tid_t tid, struct inode *ip, metapage_t * mp, + u32 index) +{ + tlock_t *tlck; + linelock_t *llck; + lv_t *lv; + + tlck = txLock(tid, ip, mp, tlckDATA); + llck = (linelock_t *) tlck->lock; + + if (llck->index >= llck->maxcnt) + llck = txLinelock(llck); + lv = &llck->lv[llck->index]; + + /* + * Linelock slot size is twice the size of directory table + * slot size. 512 entries per page. + */ + lv->offset = ((index - 2) & 511) >> 1; + lv->length = 1; + llck->index++; +} + +/* + * add_index() + * + * Adds an entry to the directory index table. This is used to provide + * each directory entry with a persistent index in which to resume + * directory traversals + */ +static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot) +{ + struct super_block *sb = ip->i_sb; + struct jfs_sb_info *sbi = JFS_SBI(sb); + struct jfs_inode_info *jfs_ip = JFS_IP(ip); + u64 blkno; + dir_table_slot_t *dirtab_slot; + u32 index; + linelock_t *llck; + lv_t *lv; + metapage_t *mp; + s64 offset; + uint page_offset; + int rc; + tlock_t *tlck; + s64 xaddr; + + ASSERT(DO_INDEX(ip)); + + if (jfs_ip->next_index < 2) { + jERROR(1, ("next_index = %d. Please fix this!\n", + jfs_ip->next_index)); + jfs_ip->next_index = 2; + } + + index = jfs_ip->next_index++; + + if (index <= MAX_INLINE_DIRTABLE_ENTRY) { + /* + * i_size reflects size of index table, or 8 bytes per entry. + */ + ip->i_size = (loff_t) (index - 1) << 3; + + /* + * dir table fits inline within inode + */ + dirtab_slot = &jfs_ip->i_dirtable[index-2]; + dirtab_slot->flag = DIR_INDEX_VALID; + dirtab_slot->slot = slot; + DTSaddress(dirtab_slot, bn); + + set_cflag(COMMIT_Dirtable, ip); + + return index; + } + if (index == (MAX_INLINE_DIRTABLE_ENTRY + 1)) { + /* + * It's time to move the inline table to an external + * page and begin to build the xtree + */ + + /* + * Save the table, we're going to overwrite it with the + * xtree root + */ + dir_table_slot_t temp_table[12]; + memcpy(temp_table, &jfs_ip->i_dirtable, sizeof(temp_table)); + + /* + * Initialize empty x-tree + */ + xtInitRoot(tid, ip); + + /* + * Allocate the first block & add it to the xtree + */ + xaddr = 0; + if ((rc = + xtInsert(tid, ip, 0, 0, sbi->nbperpage, + &xaddr, 0))) { + jFYI(1, ("add_index: xtInsert failed!\n")); + return -1; + } + ip->i_size = PSIZE; + ip->i_blocks += LBLK2PBLK(sb, sbi->nbperpage); + + if ((mp = get_metapage(ip, 0, ip->i_blksize, 0)) == 0) { + jERROR(1, ("add_index: get_metapage failed!\n")); + xtTruncate(tid, ip, 0, COMMIT_PWMAP); + return -1; + } + tlck = txLock(tid, ip, mp, tlckDATA); + llck = (linelock_t *) & tlck->lock; + ASSERT(llck->index == 0); + lv = &llck->lv[0]; + + lv->offset = 0; + lv->length = 6; /* tlckDATA slot size is 16 bytes */ + llck->index++; + + memcpy(mp->data, temp_table, sizeof(temp_table)); + + mark_metapage_dirty(mp); + release_metapage(mp); + + /* + * Logging is now directed by xtree tlocks + */ + clear_cflag(COMMIT_Dirtable, ip); + } + + offset = (index - 2) * sizeof(dir_table_slot_t); + page_offset = offset & (PSIZE - 1); + blkno = ((offset + 1) >> L2PSIZE) << sbi->l2nbperpage; + if (page_offset == 0) { + /* + * This will be the beginning of a new page + */ + xaddr = 0; + if ((rc = + xtInsert(tid, ip, 0, blkno, sbi->nbperpage, + &xaddr, 0))) { + jFYI(1, ("add_index: xtInsert failed!\n")); + jfs_ip->next_index--; + return -1; + } + ip->i_size += PSIZE; + ip->i_blocks += LBLK2PBLK(sb, sbi->nbperpage); + + if ((mp = get_metapage(ip, blkno, PSIZE, 0))) + memset(mp->data, 0, PSIZE); /* Just looks better */ + else + xtTruncate(tid, ip, offset, COMMIT_PWMAP); + } else + mp = read_metapage(ip, blkno, PSIZE, 0); + + if (mp == 0) { + jERROR(1, ("add_index: get/read_metapage failed!\n")); + return -1; + } + + lock_index(tid, ip, mp, index); + + dirtab_slot = + (dir_table_slot_t *) ((char *) mp->data + page_offset); + dirtab_slot->flag = DIR_INDEX_VALID; + dirtab_slot->slot = slot; + DTSaddress(dirtab_slot, bn); + + mark_metapage_dirty(mp); + release_metapage(mp); + + return index; +} + +/* + * free_index() + * + * Marks an entry to the directory index table as free. + */ +static void free_index(tid_t tid, struct inode *ip, u32 index, u32 next) +{ + dir_table_slot_t *dirtab_slot; + metapage_t *mp = 0; + + dirtab_slot = find_index(ip, index, &mp); + + if (dirtab_slot == 0) + return; + + dirtab_slot->flag = DIR_INDEX_FREE; + dirtab_slot->slot = dirtab_slot->addr1 = 0; + dirtab_slot->addr2 = cpu_to_le32(next); + + if (mp) { + lock_index(tid, ip, mp, index); + mark_metapage_dirty(mp); + release_metapage(mp); + } else + set_cflag(COMMIT_Dirtable, ip); +} + +/* + * modify_index() + * + * Changes an entry in the directory index table + */ +static void modify_index(tid_t tid, struct inode *ip, u32 index, s64 bn, + int slot, metapage_t ** mp) +{ + dir_table_slot_t *dirtab_slot; + + dirtab_slot = find_index(ip, index, mp); + + if (dirtab_slot == 0) + return; + + DTSaddress(dirtab_slot, bn); + dirtab_slot->slot = slot; + + if (*mp) { + lock_index(tid, ip, *mp, index); + mark_metapage_dirty(*mp); + } else + set_cflag(COMMIT_Dirtable, ip); +} + +/* + * get_index() + * + * reads a directory table slot + */ +static int get_index(struct inode *ip, u32 index, + dir_table_slot_t * dirtab_slot) +{ + metapage_t *mp = 0; + dir_table_slot_t *slot; + + slot = find_index(ip, index, &mp); + if (slot == 0) { + return -EIO; + } + + memcpy(dirtab_slot, slot, sizeof(dir_table_slot_t)); + + if (mp) + release_metapage(mp); + + return 0; +} + +/* + * dtSearch() + * + * function: + * Search for the entry with specified key + * + * parameter: + * + * return: 0 - search result on stack, leaf page pinned; + * errno - I/O error + */ +int dtSearch(struct inode *ip, + component_t * key, ino_t * data, btstack_t * btstack, int flag) +{ + int rc = 0; + int cmp = 1; /* init for empty page */ + s64 bn; + metapage_t *mp; + dtpage_t *p; + s8 *stbl; + int base, index, lim; + btframe_t *btsp; + pxd_t *pxd; + int psize = 288; /* initial in-line directory */ + ino_t inumber; + component_t ciKey; + struct super_block *sb = ip->i_sb; + + ciKey.name = + (wchar_t *) kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t), + GFP_NOFS); + if (ciKey.name == 0) { + rc = ENOMEM; + goto dtSearch_Exit2; + } + + + /* uppercase search key for c-i directory */ + UniStrcpy(ciKey.name, key->name); + ciKey.namlen = key->namlen; + + /* only uppercase if case-insensitive support is on */ + if ((JFS_SBI(sb)->mntflag & JFS_OS2) == JFS_OS2) { + ciToUpper(&ciKey); + } + BT_CLR(btstack); /* reset stack */ + + /* init level count for max pages to split */ + btstack->nsplit = 1; + + /* + * search down tree from root: + * + * between two consecutive entries of and of + * internal page, child page Pi contains entry with k, Ki <= K < Kj. + * + * if entry with search key K is not found + * internal page search find the entry with largest key Ki + * less than K which point to the child page to search; + * leaf page search find the entry with smallest key Kj + * greater than K so that the returned index is the position of + * the entry to be shifted right for insertion of new entry. + * for empty tree, search key is greater than any key of the tree. + * + * by convention, root bn = 0. + */ + for (bn = 0;;) { + /* get/pin the page to search */ + DT_GETPAGE(ip, bn, mp, psize, p, rc); + if (rc) + goto dtSearch_Exit1; + + /* get sorted entry table of the page */ + stbl = DT_GETSTBL(p); + + /* + * binary search with search key K on the current page. + */ + for (base = 0, lim = p->header.nextindex; lim; lim >>= 1) { + index = base + (lim >> 1); + + if (p->header.flag & BT_LEAF) { + /* uppercase leaf name to compare */ + cmp = + ciCompare(&ciKey, p, stbl[index], + JFS_SBI(sb)->mntflag); + } else { + /* router key is in uppercase */ + + cmp = dtCompare(&ciKey, p, stbl[index]); + + + } + if (cmp == 0) { + /* + * search hit + */ + /* search hit - leaf page: + * return the entry found + */ + if (p->header.flag & BT_LEAF) { + inumber = le32_to_cpu( + ((ldtentry_t *) & p->slot[stbl[index]])->inumber); + + /* + * search for JFS_LOOKUP + */ + if (flag == JFS_LOOKUP) { + *data = inumber; + rc = 0; + goto out; + } + + /* + * search for JFS_CREATE + */ + if (flag == JFS_CREATE) { + *data = inumber; + rc = EEXIST; + goto out; + } + + /* + * search for JFS_REMOVE or JFS_RENAME + */ + if ((flag == JFS_REMOVE || + flag == JFS_RENAME) && + *data != inumber) { + rc = ESTALE; + goto out; + } + + /* + * JFS_REMOVE|JFS_FINDDIR|JFS_RENAME + */ + /* save search result */ + *data = inumber; + btsp = btstack->top; + btsp->bn = bn; + btsp->index = index; + btsp->mp = mp; + + rc = 0; + goto dtSearch_Exit1; + } + + /* search hit - internal page: + * descend/search its child page + */ + goto getChild; + } + + if (cmp > 0) { + base = index + 1; + --lim; + } + } + + /* + * search miss + * + * base is the smallest index with key (Kj) greater than + * search key (K) and may be zero or (maxindex + 1) index. + */ + /* + * search miss - leaf page + * + * return location of entry (base) where new entry with + * search key K is to be inserted. + */ + if (p->header.flag & BT_LEAF) { + /* + * search for JFS_LOOKUP, JFS_REMOVE, or JFS_RENAME + */ + if (flag == JFS_LOOKUP || flag == JFS_REMOVE || + flag == JFS_RENAME) { + rc = ENOENT; + goto out; + } + + /* + * search for JFS_CREATE|JFS_FINDDIR: + * + * save search result + */ + *data = 0; + btsp = btstack->top; + btsp->bn = bn; + btsp->index = base; + btsp->mp = mp; + + rc = 0; + goto dtSearch_Exit1; + } + + /* + * search miss - internal page + * + * if base is non-zero, decrement base by one to get the parent + * entry of the child page to search. + */ + index = base ? base - 1 : base; + + /* + * go down to child page + */ + getChild: + /* update max. number of pages to split */ + if (btstack->nsplit >= 8) { + /* Something's corrupted, mark filesytem dirty so + * chkdsk will fix it. + */ + jERROR(1, ("stack overrun in dtSearch!\n")); + updateSuper(sb, FM_DIRTY); + rc = EIO; + goto out; + } + btstack->nsplit++; + + /* push (bn, index) of the parent page/entry */ + BT_PUSH(btstack, bn, index); + + /* get the child page block number */ + pxd = (pxd_t *) & p->slot[stbl[index]]; + bn = addressPXD(pxd); + psize = lengthPXD(pxd) << JFS_SBI(ip->i_sb)->l2bsize; + + /* unpin the parent page */ + DT_PUTPAGE(mp); + } + + out: + DT_PUTPAGE(mp); + + dtSearch_Exit1: + + kfree(ciKey.name); + + dtSearch_Exit2: + + return rc; +} + + +/* + * dtInsert() + * + * function: insert an entry to directory tree + * + * parameter: + * + * return: 0 - success; + * errno - failure; + */ +int dtInsert(tid_t tid, struct inode *ip, + component_t * name, ino_t * fsn, btstack_t * btstack) +{ + int rc = 0; + metapage_t *mp; /* meta-page buffer */ + dtpage_t *p; /* base B+-tree index page */ + s64 bn; + int index; + dtsplit_t split; /* split information */ + ddata_t data; + dtlock_t *dtlck; + int n; + tlock_t *tlck; + lv_t *lv; + + /* + * retrieve search result + * + * dtSearch() returns (leaf page pinned, index at which to insert). + * n.b. dtSearch() may return index of (maxindex + 1) of + * the full page. + */ + DT_GETSEARCH(ip, btstack->top, bn, mp, p, index); + + /* + * insert entry for new key + */ + if (DO_INDEX(ip)) { + if (JFS_IP(ip)->next_index == DIREND) { + DT_PUTPAGE(mp); + return EMLINK; + } + n = NDTLEAF(name->namlen); + data.leaf.tid = tid; + data.leaf.ip = ip; + } else { + n = NDTLEAF_LEGACY(name->namlen); + data.leaf.ip = 0; /* signifies legacy directory format */ + } + data.leaf.ino = cpu_to_le32(*fsn); + + /* + * leaf page does not have enough room for new entry: + * + * extend/split the leaf page; + * + * dtSplitUp() will insert the entry and unpin the leaf page. + */ + if (n > p->header.freecnt) { + split.mp = mp; + split.index = index; + split.nslot = n; + split.key = name; + split.data = &data; + rc = dtSplitUp(tid, ip, &split, btstack); + return rc; + } + + /* + * leaf page does have enough room for new entry: + * + * insert the new data entry into the leaf page; + */ + BT_MARK_DIRTY(mp, ip); + /* + * acquire a transaction lock on the leaf page + */ + tlck = txLock(tid, ip, mp, tlckDTREE | tlckENTRY); + dtlck = (dtlock_t *) & tlck->lock; + ASSERT(dtlck->index == 0); + lv = (lv_t *) & dtlck->lv[0]; + + /* linelock header */ + lv->offset = 0; + lv->length = 1; + dtlck->index++; + + dtInsertEntry(p, index, name, &data, &dtlck); + + /* linelock stbl of non-root leaf page */ + if (!(p->header.flag & BT_ROOT)) { + if (dtlck->index >= dtlck->maxcnt) + dtlck = (dtlock_t *) txLinelock(dtlck); + lv = (lv_t *) & dtlck->lv[dtlck->index]; + n = index >> L2DTSLOTSIZE; + lv->offset = p->header.stblindex + n; + lv->length = + ((p->header.nextindex - 1) >> L2DTSLOTSIZE) - n + 1; + dtlck->index++; + } + + /* unpin the leaf page */ + DT_PUTPAGE(mp); + + return 0; +} + + +/* + * dtSplitUp() + * + * function: propagate insertion bottom up; + * + * parameter: + * + * return: 0 - success; + * errno - failure; + * leaf page unpinned; + */ +static int dtSplitUp(tid_t tid, + struct inode *ip, dtsplit_t * split, btstack_t * btstack) +{ + struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb); + int rc = 0; + metapage_t *smp; + dtpage_t *sp; /* split page */ + metapage_t *rmp; + dtpage_t *rp; /* new right page split from sp */ + pxd_t rpxd; /* new right page extent descriptor */ + metapage_t *lmp; + dtpage_t *lp; /* left child page */ + int skip; /* index of entry of insertion */ + btframe_t *parent; /* parent page entry on traverse stack */ + s64 xaddr, nxaddr; + int xlen, xsize; + pxdlist_t pxdlist; + pxd_t *pxd; + component_t key = { 0, 0 }; + ddata_t *data = split->data; + int n; + dtlock_t *dtlck; + tlock_t *tlck; + lv_t *lv; + + /* get split page */ + smp = split->mp; + sp = DT_PAGE(ip, smp); + + key.name = + (wchar_t *) kmalloc((JFS_NAME_MAX + 2) * sizeof(wchar_t), + GFP_NOFS); + if (key.name == 0) { + DT_PUTPAGE(smp); + rc = ENOMEM; + goto dtSplitUp_Exit; + } + + /* + * split leaf page + * + * The split routines insert the new entry, and + * acquire txLock as appropriate. + */ + /* + * split root leaf page: + */ + if (sp->header.flag & BT_ROOT) { + /* + * allocate a single extent child page + */ + xlen = 1; + n = sbi->bsize >> L2DTSLOTSIZE; + n -= (n + 31) >> L2DTSLOTSIZE; /* stbl size */ + n -= DTROOTMAXSLOT - sp->header.freecnt; /* header + entries */ + if (n <= split->nslot) + xlen++; + if ((rc = dbAlloc(ip, 0, (s64) xlen, &xaddr))) + goto freeKeyName; + + pxdlist.maxnpxd = 1; + pxdlist.npxd = 0; + pxd = &pxdlist.pxd[0]; + PXDaddress(pxd, xaddr); + PXDlength(pxd, xlen); + split->pxdlist = &pxdlist; + rc = dtSplitRoot(tid, ip, split, &rmp); + + DT_PUTPAGE(rmp); + DT_PUTPAGE(smp); + + goto freeKeyName; + } + + /* + * extend first leaf page + * + * extend the 1st extent if less than buffer page size + * (dtExtendPage() reurns leaf page unpinned) + */ + pxd = &sp->header.self; + xlen = lengthPXD(pxd); + xsize = xlen << sbi->l2bsize; + if (xsize < PSIZE) { + xaddr = addressPXD(pxd); + n = xsize >> L2DTSLOTSIZE; + n -= (n + 31) >> L2DTSLOTSIZE; /* stbl size */ + if ((n + sp->header.freecnt) <= split->nslot) + n = xlen + (xlen << 1); + else + n = xlen; + if ((rc = dbReAlloc(sbi->ipbmap, xaddr, (s64) xlen, + (s64) n, &nxaddr))) + goto extendOut; + + pxdlist.maxnpxd = 1; + pxdlist.npxd = 0; + pxd = &pxdlist.pxd[0]; + PXDaddress(pxd, nxaddr) + PXDlength(pxd, xlen + n); + split->pxdlist = &pxdlist; + if ((rc = dtExtendPage(tid, ip, split, btstack))) { + nxaddr = addressPXD(pxd); + if (xaddr != nxaddr) { + /* free relocated extent */ + xlen = lengthPXD(pxd); + dbFree(ip, nxaddr, (s64) xlen); + } else { + /* free extended delta */ + xlen = lengthPXD(pxd) - n; + xaddr = addressPXD(pxd) + xlen; + dbFree(ip, xaddr, (s64) n); + } + } + + extendOut: + DT_PUTPAGE(smp); + goto freeKeyName; + } + + /* + * split leaf page into and a new right page . + * + * return pinned and its extent descriptor + */ + /* + * allocate new directory page extent and + * new index page(s) to cover page split(s) + * + * allocation hint: ? + */ + n = btstack->nsplit; + pxdlist.maxnpxd = pxdlist.npxd = 0; + xlen = sbi->nbperpage; + for (pxd = pxdlist.pxd; n > 0; n--, pxd++) { + if ((rc = dbAlloc(ip, 0, (s64) xlen, &xaddr)) == 0) { + PXDaddress(pxd, xaddr); + PXDlength(pxd, xlen); + pxdlist.maxnpxd++; + continue; + } + + DT_PUTPAGE(smp); + + /* undo allocation */ + goto splitOut; + } + + split->pxdlist = &pxdlist; + if ((rc = dtSplitPage(tid, ip, split, &rmp, &rp, &rpxd))) { + DT_PUTPAGE(smp); + + /* undo allocation */ + goto splitOut; + } + + /* + * propagate up the router entry for the leaf page just split + * + * insert a router entry for the new page into the parent page, + * propagate the insert/split up the tree by walking back the stack + * of (bn of parent page, index of child page entry in parent page) + * that were traversed during the search for the page that split. + * + * the propagation of insert/split up the tree stops if the root + * splits or the page inserted into doesn't have to split to hold + * the new entry. + * + * the parent entry for the split page remains the same, and + * a new entry is inserted at its right with the first key and + * block number of the new right page. + * + * There are a maximum of 4 pages pinned at any time: + * two children, left parent and right parent (when the parent splits). + * keep the child pages pinned while working on the parent. + * make sure that all pins are released at exit. + */ + while ((parent = BT_POP(btstack)) != NULL) { + /* parent page specified by stack frame */ + + /* keep current child pages (, ) pinned */ + lmp = smp; + lp = sp; + + /* + * insert router entry in parent for new right child page + */ + /* get the parent page */ + DT_GETPAGE(ip, parent->bn, smp, PSIZE, sp, rc); + if (rc) { + DT_PUTPAGE(lmp); + DT_PUTPAGE(rmp); + goto splitOut; + } + + /* + * The new key entry goes ONE AFTER the index of parent entry, + * because the split was to the right. + */ + skip = parent->index + 1; + + /* + * compute the key for the router entry + * + * key suffix compression: + * for internal pages that have leaf pages as children, + * retain only what's needed to distinguish between + * the new entry and the entry on the page to its left. + * If the keys compare equal, retain the entire key. + * + * note that compression is performed only at computing + * router key at the lowest internal level. + * further compression of the key between pairs of higher + * level internal pages loses too much information and + * the search may fail. + * (e.g., two adjacent leaf pages of {a, ..., x} {xx, ...,} + * results in two adjacent parent entries (a)(xx). + * if split occurs between these two entries, and + * if compression is applied, the router key of parent entry + * of right page (x) will divert search for x into right + * subtree and miss x in the left subtree.) + * + * the entire key must be retained for the next-to-leftmost + * internal key at any level of the tree, or search may fail + * (e.g., ?) + */ + switch (rp->header.flag & BT_TYPE) { + case BT_LEAF: + /* + * compute the length of prefix for suffix compression + * between last entry of left page and first entry + * of right page + */ + if ((sp->header.flag & BT_ROOT && skip > 1) || + sp->header.prev != 0 || skip > 1) { + /* compute uppercase router prefix key */ + ciGetLeafPrefixKey(lp, + lp->header.nextindex - 1, + rp, 0, &key, sbi->mntflag); + } else { + /* next to leftmost entry of + lowest internal level */ + + /* compute uppercase router key */ + dtGetKey(rp, 0, &key, sbi->mntflag); + key.name[key.namlen] = 0; + + if ((sbi->mntflag & JFS_OS2) == JFS_OS2) + ciToUpper(&key); + } + + n = NDTINTERNAL(key.namlen); + break; + + case BT_INTERNAL: + dtGetKey(rp, 0, &key, sbi->mntflag); + n = NDTINTERNAL(key.namlen); + break; + + default: + jERROR(2, ("dtSplitUp(): UFO!\n")); + break; + } + + /* unpin left child page */ + DT_PUTPAGE(lmp); + + /* + * compute the data for the router entry + */ + data->xd = rpxd; /* child page xd */ + + /* + * parent page is full - split the parent page + */ + if (n > sp->header.freecnt) { + /* init for parent page split */ + split->mp = smp; + split->index = skip; /* index at insert */ + split->nslot = n; + split->key = &key; + /* split->data = data; */ + + /* unpin right child page */ + DT_PUTPAGE(rmp); + + /* The split routines insert the new entry, + * acquire txLock as appropriate. + * return pinned and its block number . + */ + rc = (sp->header.flag & BT_ROOT) ? + dtSplitRoot(tid, ip, split, &rmp) : + dtSplitPage(tid, ip, split, &rmp, &rp, &rpxd); + if (rc) { + DT_PUTPAGE(smp); + goto splitOut; + } + + /* smp and rmp are pinned */ + } + /* + * parent page is not full - insert router entry in parent page + */ + else { + BT_MARK_DIRTY(smp, ip); + /* + * acquire a transaction lock on the parent page + */ + tlck = txLock(tid, ip, smp, tlckDTREE | tlckENTRY); + dtlck = (dtlock_t *) & tlck->lock; + ASSERT(dtlck->index == 0); + lv = (lv_t *) & dtlck->lv[0]; + + /* linelock header */ + lv->offset = 0; + lv->length = 1; + dtlck->index++; + + /* linelock stbl of non-root parent page */ + if (!(sp->header.flag & BT_ROOT)) { + lv++; + n = skip >> L2DTSLOTSIZE; + lv->offset = sp->header.stblindex + n; + lv->length = + ((sp->header.nextindex - + 1) >> L2DTSLOTSIZE) - n + 1; + dtlck->index++; + } + + dtInsertEntry(sp, skip, &key, data, &dtlck); + + /* exit propagate up */ + break; + } + } + + /* unpin current split and its right page */ + DT_PUTPAGE(smp); + DT_PUTPAGE(rmp); + + /* + * free remaining extents allocated for split + */ + splitOut: + n = pxdlist.npxd; + pxd = &pxdlist.pxd[n]; + for (; n < pxdlist.maxnpxd; n++, pxd++) + dbFree(ip, addressPXD(pxd), (s64) lengthPXD(pxd)); + + freeKeyName: + kfree(key.name); + + dtSplitUp_Exit: + + return rc; +} + + +/* + * dtSplitPage() + * + * function: Split a non-root page of a btree. + * + * parameter: + * + * return: 0 - success; + * errno - failure; + * return split and new page pinned; + */ +static int dtSplitPage(tid_t tid, struct inode *ip, dtsplit_t * split, + metapage_t ** rmpp, dtpage_t ** rpp, pxd_t * rpxdp) +{ + struct super_block *sb = ip->i_sb; + int rc = 0; + metapage_t *smp; + dtpage_t *sp; + metapage_t *rmp; + dtpage_t *rp; /* new right page allocated */ + s64 rbn; /* new right page block number */ + metapage_t *mp; + dtpage_t *p; + s64 nextbn; + pxdlist_t *pxdlist; + pxd_t *pxd; + int skip, nextindex, half, left, nxt, off, si; + ldtentry_t *ldtentry; + idtentry_t *idtentry; + u8 *stbl; + dtslot_t *f; + int fsi, stblsize; + int n; + dtlock_t *sdtlck, *rdtlck; + tlock_t *tlck; + dtlock_t *dtlck; + lv_t *slv, *rlv, *lv; + + /* get split page */ + smp = split->mp; + sp = DT_PAGE(ip, smp); + + /* + * allocate the new right page for the split + */ + pxdlist = split->pxdlist; + pxd = &pxdlist->pxd[pxdlist->npxd]; + pxdlist->npxd++; + rbn = addressPXD(pxd); + rmp = get_metapage(ip, rbn, PSIZE, 1); + if (rmp == NULL) + return EIO; + + jEVENT(0, + ("dtSplitPage: ip:0x%p smp:0x%p rmp:0x%p\n", ip, smp, rmp)); + + BT_MARK_DIRTY(rmp, ip); + /* + * acquire a transaction lock on the new right page + */ + tlck = txLock(tid, ip, rmp, tlckDTREE | tlckNEW); + rdtlck = (dtlock_t *) & tlck->lock; + + rp = (dtpage_t *) rmp->data; + *rpp = rp; + rp->header.self = *pxd; + + BT_MARK_DIRTY(smp, ip); + /* + * acquire a transaction lock on the split page + * + * action: + */ + tlck = txLock(tid, ip, smp, tlckDTREE | tlckENTRY); + sdtlck = (dtlock_t *) & tlck->lock; + + /* linelock header of split page */ + ASSERT(sdtlck->index == 0); + slv = (lv_t *) & sdtlck->lv[0]; + slv->offset = 0; + slv->length = 1; + sdtlck->index++; + + /* + * initialize/update sibling pointers between sp and rp + */ + nextbn = le64_to_cpu(sp->header.next); + rp->header.next = cpu_to_le64(nextbn); + rp->header.prev = cpu_to_le64(addressPXD(&sp->header.self)); + sp->header.next = cpu_to_le64(rbn); + + /* + * initialize new right page + */ + rp->header.flag = sp->header.flag; + + /* compute sorted entry table at start of extent data area */ + rp->header.nextindex = 0; + rp->header.stblindex = 1; + + n = PSIZE >> L2DTSLOTSIZE; + rp->header.maxslot = n; + stblsize = (n + 31) >> L2DTSLOTSIZE; /* in unit of slot */ + + /* init freelist */ + fsi = rp->header.stblindex + stblsize; + rp->header.freelist = fsi; + rp->header.freecnt = rp->header.maxslot - fsi; + + /* + * sequential append at tail: append without split + * + * If splitting the last page on a level because of appending + * a entry to it (skip is maxentry), it's likely that the access is + * sequential. Adding an empty page on the side of the level is less + * work and can push the fill factor much higher than normal. + * If we're wrong it's no big deal, we'll just do the split the right + * way next time. + * (It may look like it's equally easy to do a similar hack for + * reverse sorted data, that is, split the tree left, + * but it's not. Be my guest.) + */ + if (nextbn == 0 && split->index == sp->header.nextindex) { + /* linelock header + stbl (first slot) of new page */ + rlv = (lv_t *) & rdtlck->lv[rdtlck->index]; + rlv->offset = 0; + rlv->length = 2; + rdtlck->index++; + + /* + * initialize freelist of new right page + */ + f = &rp->slot[fsi]; + for (fsi++; fsi < rp->header.maxslot; f++, fsi++) + f->next = fsi; + f->next = -1; + + /* insert entry at the first entry of the new right page */ + dtInsertEntry(rp, 0, split->key, split->data, &rdtlck); + + goto out; + } + + /* + * non-sequential insert (at possibly middle page) + */ + + /* + * update prev pointer of previous right sibling page; + */ + if (nextbn != 0) { + DT_GETPAGE(ip, nextbn, mp, PSIZE, p, rc); + if (rc) + return rc; + + BT_MARK_DIRTY(mp, ip); + /* + * acquire a transaction lock on the next page + */ + tlck = txLock(tid, ip, mp, tlckDTREE | tlckRELINK); + jEVENT(0, + ("dtSplitPage: tlck = 0x%p, ip = 0x%p, mp=0x%p\n", + tlck, ip, mp)); + dtlck = (dtlock_t *) & tlck->lock; + + /* linelock header of previous right sibling page */ + lv = (lv_t *) & dtlck->lv[dtlck->index]; + lv->offset = 0; + lv->length = 1; + dtlck->index++; + + p->header.prev = cpu_to_le64(rbn); + + DT_PUTPAGE(mp); + } + + /* + * split the data between the split and right pages. + */ + skip = split->index; + half = (PSIZE >> L2DTSLOTSIZE) >> 1; /* swag */ + left = 0; + + /* + * compute fill factor for split pages + * + * traces the next entry to move to rp + * traces the next entry to stay in sp + */ + stbl = (u8 *) & sp->slot[sp->header.stblindex]; + nextindex = sp->header.nextindex; + for (nxt = off = 0; nxt < nextindex; ++off) { + if (off == skip) + /* check for fill factor with new entry size */ + n = split->nslot; + else { + si = stbl[nxt]; + switch (sp->header.flag & BT_TYPE) { + case BT_LEAF: + ldtentry = (ldtentry_t *) & sp->slot[si]; + if (DO_INDEX(ip)) + n = NDTLEAF(ldtentry->namlen); + else + n = NDTLEAF_LEGACY(ldtentry-> + namlen); + break; + + case BT_INTERNAL: + idtentry = (idtentry_t *) & sp->slot[si]; + n = NDTINTERNAL(idtentry->namlen); + break; + + default: + break; + } + + ++nxt; /* advance to next entry to move in sp */ + } + + left += n; + if (left >= half) + break; + } + + /* poins to the 1st entry to move */ + + /* + * move entries to right page + * + * dtMoveEntry() initializes rp and reserves entry for insertion + * + * split page moved out entries are linelocked; + * new/right page moved in entries are linelocked; + */ + /* linelock header + stbl of new right page */ + rlv = (lv_t *) & rdtlck->lv[rdtlck->index]; + rlv->offset = 0; + rlv->length = 5; + rdtlck->index++; + + dtMoveEntry(sp, nxt, rp, &sdtlck, &rdtlck, DO_INDEX(ip)); + + sp->header.nextindex = nxt; + + /* + * finalize freelist of new right page + */ + fsi = rp->header.freelist; + f = &rp->slot[fsi]; + for (fsi++; fsi < rp->header.maxslot; f++, fsi++) + f->next = fsi; + f->next = -1; + + /* + * Update directory index table for entries now in right page + */ + if ((rp->header.flag & BT_LEAF) && DO_INDEX(ip)) { + mp = 0; + stbl = DT_GETSTBL(rp); + for (n = 0; n < rp->header.nextindex; n++) { + ldtentry = (ldtentry_t *) & rp->slot[stbl[n]]; + modify_index(tid, ip, le32_to_cpu(ldtentry->index), + rbn, n, &mp); + } + if (mp) + release_metapage(mp); + } + + /* + * the skipped index was on the left page, + */ + if (skip <= off) { + /* insert the new entry in the split page */ + dtInsertEntry(sp, skip, split->key, split->data, &sdtlck); + + /* linelock stbl of split page */ + if (sdtlck->index >= sdtlck->maxcnt) + sdtlck = (dtlock_t *) txLinelock(sdtlck); + slv = (lv_t *) & sdtlck->lv[sdtlck->index]; + n = skip >> L2DTSLOTSIZE; + slv->offset = sp->header.stblindex + n; + slv->length = + ((sp->header.nextindex - 1) >> L2DTSLOTSIZE) - n + 1; + sdtlck->index++; + } + /* + * the skipped index was on the right page, + */ + else { + /* adjust the skip index to reflect the new position */ + skip -= nxt; + + /* insert the new entry in the right page */ + dtInsertEntry(rp, skip, split->key, split->data, &rdtlck); + } + + out: + *rmpp = rmp; + *rpxdp = *pxd; + + ip->i_blocks += LBLK2PBLK(sb, lengthPXD(pxd)); + + jEVENT(0, ("dtSplitPage: ip:0x%p sp:0x%p rp:0x%p\n", ip, sp, rp)); + return 0; +} + + +/* + * dtExtendPage() + * + * function: extend 1st/only directory leaf page + * + * parameter: + * + * return: 0 - success; + * errno - failure; + * return extended page pinned; + */ +static int dtExtendPage(tid_t tid, + struct inode *ip, dtsplit_t * split, btstack_t * btstack) +{ + struct super_block *sb = ip->i_sb; + int rc; + metapage_t *smp, *pmp, *mp; + dtpage_t *sp, *pp; + pxdlist_t *pxdlist; + pxd_t *pxd, *tpxd; + int xlen, xsize; + int newstblindex, newstblsize; + int oldstblindex, oldstblsize; + int fsi, last; + dtslot_t *f; + btframe_t *parent; + int n; + dtlock_t *dtlck; + s64 xaddr, txaddr; + tlock_t *tlck; + pxdlock_t *pxdlock; + lv_t *lv; + uint type; + ldtentry_t *ldtentry; + u8 *stbl; + + /* get page to extend */ + smp = split->mp; + sp = DT_PAGE(ip, smp); + + /* get parent/root page */ + parent = BT_POP(btstack); + DT_GETPAGE(ip, parent->bn, pmp, PSIZE, pp, rc); + if (rc) + return (rc); + + /* + * extend the extent + */ + pxdlist = split->pxdlist; + pxd = &pxdlist->pxd[pxdlist->npxd]; + pxdlist->npxd++; + + xaddr = addressPXD(pxd); + tpxd = &sp->header.self; + txaddr = addressPXD(tpxd); + /* in-place extension */ + if (xaddr == txaddr) { + type = tlckEXTEND; + } + /* relocation */ + else { + type = tlckNEW; + + /* save moved extent descriptor for later free */ + tlck = txMaplock(tid, ip, tlckDTREE | tlckRELOCATE); + pxdlock = (pxdlock_t *) & tlck->lock; + pxdlock->flag = mlckFREEPXD; + pxdlock->pxd = sp->header.self; + pxdlock->index = 1; + + /* + * Update directory index table to reflect new page address + */ + if (DO_INDEX(ip)) { + mp = 0; + stbl = DT_GETSTBL(sp); + for (n = 0; n < sp->header.nextindex; n++) { + ldtentry = + (ldtentry_t *) & sp->slot[stbl[n]]; + modify_index(tid, ip, + le32_to_cpu(ldtentry->index), + xaddr, n, &mp); + } + if (mp) + release_metapage(mp); + } + } + + /* + * extend the page + */ + sp->header.self = *pxd; + + jEVENT(0, + ("dtExtendPage: ip:0x%p smp:0x%p sp:0x%p\n", ip, smp, sp)); + + BT_MARK_DIRTY(smp, ip); + /* + * acquire a transaction lock on the extended/leaf page + */ + tlck = txLock(tid, ip, smp, tlckDTREE | type); + dtlck = (dtlock_t *) & tlck->lock; + lv = (lv_t *) & dtlck->lv[0]; + + /* update buffer extent descriptor of extended page */ + xlen = lengthPXD(pxd); + xsize = xlen << JFS_SBI(sb)->l2bsize; +#ifdef _STILL_TO_PORT + bmSetXD(smp, xaddr, xsize); +#endif /* _STILL_TO_PORT */ + + /* + * copy old stbl to new stbl at start of extended area + */ + oldstblindex = sp->header.stblindex; + oldstblsize = (sp->header.maxslot + 31) >> L2DTSLOTSIZE; + newstblindex = sp->header.maxslot; + n = xsize >> L2DTSLOTSIZE; + newstblsize = (n + 31) >> L2DTSLOTSIZE; + memcpy(&sp->slot[newstblindex], &sp->slot[oldstblindex], + sp->header.nextindex); + + /* + * in-line extension: linelock old area of extended page + */ + if (type == tlckEXTEND) { + /* linelock header */ + lv->offset = 0; + lv->length = 1; + dtlck->index++; + lv++; + + /* linelock new stbl of extended page */ + lv->offset = newstblindex; + lv->length = newstblsize; + } + /* + * relocation: linelock whole relocated area + */ + else { + lv->offset = 0; + lv->length = sp->header.maxslot + newstblsize; + } + + dtlck->index++; + + sp->header.maxslot = n; + sp->header.stblindex = newstblindex; + /* sp->header.nextindex remains the same */ + + /* + * add old stbl region at head of freelist + */ + fsi = oldstblindex; + f = &sp->slot[fsi]; + last = sp->header.freelist; + for (n = 0; n < oldstblsize; n++, fsi++, f++) { + f->next = last; + last = fsi; + } + sp->header.freelist = last; + sp->header.freecnt += oldstblsize; + + /* + * append free region of newly extended area at tail of freelist + */ + /* init free region of newly extended area */ + fsi = n = newstblindex + newstblsize; + f = &sp->slot[fsi]; + for (fsi++; fsi < sp->header.maxslot; f++, fsi++) + f->next = fsi; + f->next = -1; + + /* append new free region at tail of old freelist */ + fsi = sp->header.freelist; + if (fsi == -1) + sp->header.freelist = n; + else { + do { + f = &sp->slot[fsi]; + fsi = f->next; + } while (fsi != -1); + + f->next = n; + } + + sp->header.freecnt += sp->header.maxslot - n; + + /* + * insert the new entry + */ + dtInsertEntry(sp, split->index, split->key, split->data, &dtlck); + + BT_MARK_DIRTY(pmp, ip); + /* + * linelock any freeslots residing in old extent + */ + if (type == tlckEXTEND) { + n = sp->header.maxslot >> 2; + if (sp->header.freelist < n) + dtLinelockFreelist(sp, n, &dtlck); + } + + /* + * update parent entry on the parent/root page + */ + /* + * acquire a transaction lock on the parent/root page + */ + tlck = txLock(tid, ip, pmp, tlckDTREE | tlckENTRY); + dtlck = (dtlock_t *) & tlck->lock; + lv = (lv_t *) & dtlck->lv[dtlck->index]; + + /* linelock parent entry - 1st slot */ + lv->offset = 1; + lv->length = 1; + dtlck->index++; + + /* update the parent pxd for page extension */ + tpxd = (pxd_t *) & pp->slot[1]; + *tpxd = *pxd; + + /* Since the directory might have an EA and/or ACL associated with it + * we need to make sure we take that into account when setting the + * i_nblocks + */ + ip->i_blocks = LBLK2PBLK(ip->i_sb, xlen + + ((JFS_IP(ip)->ea.flag & DXD_EXTENT) ? + lengthDXD(&JFS_IP(ip)->ea) : 0) + + ((JFS_IP(ip)->acl.flag & DXD_EXTENT) ? + lengthDXD(&JFS_IP(ip)->acl) : 0)); + + jEVENT(0, + ("dtExtendPage: ip:0x%p smp:0x%p sp:0x%p\n", ip, smp, sp)); + + + DT_PUTPAGE(pmp); + return 0; +} + + +/* + * dtSplitRoot() + * + * function: + * split the full root page into + * original/root/split page and new right page + * i.e., root remains fixed in tree anchor (inode) and + * the root is copied to a single new right child page + * since root page << non-root page, and + * the split root page contains a single entry for the + * new right child page. + * + * parameter: + * + * return: 0 - success; + * errno - failure; + * return new page pinned; + */ +static int dtSplitRoot(tid_t tid, + struct inode *ip, dtsplit_t * split, metapage_t ** rmpp) +{ + struct super_block *sb = ip->i_sb; + metapage_t *smp; + dtroot_t *sp; + metapage_t *rmp; + dtpage_t *rp; + s64 rbn; + int xlen; + int xsize; + dtslot_t *f; + s8 *stbl; + int fsi, stblsize, n; + idtentry_t *s; + pxd_t *ppxd; + pxdlist_t *pxdlist; + pxd_t *pxd; + dtlock_t *dtlck; + tlock_t *tlck; + lv_t *lv; + + /* get split root page */ + smp = split->mp; + sp = &JFS_IP(ip)->i_dtroot; + + /* + * allocate/initialize a single (right) child page + * + * N.B. at first split, a one (or two) block to fit new entry + * is allocated; at subsequent split, a full page is allocated; + */ + pxdlist = split->pxdlist; + pxd = &pxdlist->pxd[pxdlist->npxd]; + pxdlist->npxd++; + rbn = addressPXD(pxd); + xlen = lengthPXD(pxd); + xsize = xlen << JFS_SBI(sb)->l2bsize; + rmp = get_metapage(ip, rbn, xsize, 1); + rp = rmp->data; + + BT_MARK_DIRTY(rmp, ip); + /* + * acquire a transaction lock on the new right page + */ + tlck = txLock(tid, ip, rmp, tlckDTREE | tlckNEW); + dtlck = (dtlock_t *) & tlck->lock; + + rp->header.flag = + (sp->header.flag & BT_LEAF) ? BT_LEAF : BT_INTERNAL; + rp->header.self = *pxd; + + /* initialize sibling pointers */ + rp->header.next = 0; + rp->header.prev = 0; + + /* + * move in-line root page into new right page extent + */ + /* linelock header + copied entries + new stbl (1st slot) in new page */ + ASSERT(dtlck->index == 0); + lv = (lv_t *) & dtlck->lv[0]; + lv->offset = 0; + lv->length = 10; /* 1 + 8 + 1 */ + dtlck->index++; + + n = xsize >> L2DTSLOTSIZE; + rp->header.maxslot = n; + stblsize = (n + 31) >> L2DTSLOTSIZE; + + /* copy old stbl to new stbl at start of extended area */ + rp->header.stblindex = DTROOTMAXSLOT; + stbl = (s8 *) & rp->slot[DTROOTMAXSLOT]; + memcpy(stbl, sp->header.stbl, sp->header.nextindex); + rp->header.nextindex = sp->header.nextindex; + + /* copy old data area to start of new data area */ + memcpy(&rp->slot[1], &sp->slot[1], IDATASIZE); + + /* + * append free region of newly extended area at tail of freelist + */ + /* init free region of newly extended area */ + fsi = n = DTROOTMAXSLOT + stblsize; + f = &rp->slot[fsi]; + for (fsi++; fsi < rp->header.maxslot; f++, fsi++) + f->next = fsi; + f->next = -1; + + /* append new free region at tail of old freelist */ + fsi = sp->header.freelist; + if (fsi == -1) + rp->header.freelist = n; + else { + rp->header.freelist = fsi; + + do { + f = &rp->slot[fsi]; + fsi = f->next; + } while (fsi != -1); + + f->next = n; + } + + rp->header.freecnt = sp->header.freecnt + rp->header.maxslot - n; + + /* + * Update directory index table for entries now in right page + */ + if ((rp->header.flag & BT_LEAF) && DO_INDEX(ip)) { + metapage_t *mp = 0; + ldtentry_t *ldtentry; + + stbl = DT_GETSTBL(rp); + for (n = 0; n < rp->header.nextindex; n++) { + ldtentry = (ldtentry_t *) & rp->slot[stbl[n]]; + modify_index(tid, ip, le32_to_cpu(ldtentry->index), + rbn, n, &mp); + } + if (mp) + release_metapage(mp); + } + /* + * insert the new entry into the new right/child page + * (skip index in the new right page will not change) + */ + dtInsertEntry(rp, split->index, split->key, split->data, &dtlck); + + /* + * reset parent/root page + * + * set the 1st entry offset to 0, which force the left-most key + * at any level of the tree to be less than any search key. + * + * The btree comparison code guarantees that the left-most key on any + * level of the tree is never used, so it doesn't need to be filled in. + */ + BT_MARK_DIRTY(smp, ip); + /* + * acquire a transaction lock on the root page (in-memory inode) + */ + tlck = txLock(tid, ip, smp, tlckDTREE | tlckNEW | tlckBTROOT); + dtlck = (dtlock_t *) & tlck->lock; + + /* linelock root */ + ASSERT(dtlck->index == 0); + lv = (lv_t *) & dtlck->lv[0]; + lv->offset = 0; + lv->length = DTROOTMAXSLOT; + dtlck->index++; + + /* update page header of root */ + if (sp->header.flag & BT_LEAF) { + sp->header.flag &= ~BT_LEAF; + sp->header.flag |= BT_INTERNAL; + } + + /* init the first entry */ + s = (idtentry_t *) & sp->slot[DTENTRYSTART]; + ppxd = (pxd_t *) s; + *ppxd = *pxd; + s->next = -1; + s->namlen = 0; + + stbl = sp->header.stbl; + stbl[0] = DTENTRYSTART; + sp->header.nextindex = 1; + + /* init freelist */ + fsi = DTENTRYSTART + 1; + f = &sp->slot[fsi]; + + /* init free region of remaining area */ + for (fsi++; fsi < DTROOTMAXSLOT; f++, fsi++) + f->next = fsi; + f->next = -1; + + sp->header.freelist = DTENTRYSTART + 1; + sp->header.freecnt = DTROOTMAXSLOT - (DTENTRYSTART + 1); + + *rmpp = rmp; + + ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd)); + return 0; +} + + +/* + * dtDelete() + * + * function: delete the entry(s) referenced by a key. + * + * parameter: + * + * return: + */ +int dtDelete(tid_t tid, + struct inode *ip, component_t * key, ino_t * ino, int flag) +{ + int rc = 0; + s64 bn; + metapage_t *mp, *imp; + dtpage_t *p; + int index; + btstack_t btstack; + dtlock_t *dtlck; + tlock_t *tlck; + lv_t *lv; + int i; + ldtentry_t *ldtentry; + u8 *stbl; + u32 table_index, next_index; + metapage_t *nmp; + dtpage_t *np; + + /* + * search for the entry to delete: + * + * dtSearch() returns (leaf page pinned, index at which to delete). + */ + if ((rc = dtSearch(ip, key, ino, &btstack, flag))) + return rc; + + /* retrieve search result */ + DT_GETSEARCH(ip, btstack.top, bn, mp, p, index); + + /* + * We need to find put the index of the next entry into the + * directory index table in order to resume a readdir from this + * entry. + */ + if (DO_INDEX(ip)) { + stbl = DT_GETSTBL(p); + ldtentry = (ldtentry_t *) & p->slot[stbl[index]]; + table_index = le32_to_cpu(ldtentry->index); + if (index == (p->header.nextindex - 1)) { + /* + * Last entry in this leaf page + */ + if ((p->header.flag & BT_ROOT) + || (p->header.next == 0)) + next_index = -1; + else { + /* Read next leaf page */ + DT_GETPAGE(ip, le64_to_cpu(p->header.next), + nmp, PSIZE, np, rc); + if (rc) + next_index = -1; + else { + stbl = DT_GETSTBL(np); + ldtentry = + (ldtentry_t *) & np-> + slot[stbl[0]]; + next_index = + le32_to_cpu(ldtentry->index); + DT_PUTPAGE(nmp); + } + } + } else { + ldtentry = + (ldtentry_t *) & p->slot[stbl[index + 1]]; + next_index = le32_to_cpu(ldtentry->index); + } + free_index(tid, ip, table_index, next_index); + } + /* + * the leaf page becomes empty, delete the page + */ + if (p->header.nextindex == 1) { + /* delete empty page */ + rc = dtDeleteUp(tid, ip, mp, p, &btstack); + } + /* + * the leaf page has other entries remaining: + * + * delete the entry from the leaf page. + */ + else { + BT_MARK_DIRTY(mp, ip); + /* + * acquire a transaction lock on the leaf page + */ + tlck = txLock(tid, ip, mp, tlckDTREE | tlckENTRY); + dtlck = (dtlock_t *) & tlck->lock; + + /* + * Do not assume that dtlck->index will be zero. During a + * rename within a directory, this transaction may have + * modified this page already when adding the new entry. + */ + + /* linelock header */ + if (dtlck->index >= dtlck->maxcnt) + dtlck = (dtlock_t *) txLinelock(dtlck); + lv = (lv_t *) & dtlck->lv[dtlck->index]; + lv->offset = 0; + lv->length = 1; + dtlck->index++; + + /* linelock stbl of non-root leaf page */ + if (!(p->header.flag & BT_ROOT)) { + if (dtlck->index >= dtlck->maxcnt) + dtlck = (dtlock_t *) txLinelock(dtlck); + lv = (lv_t *) & dtlck->lv[dtlck->index]; + i = index >> L2DTSLOTSIZE; + lv->offset = p->header.stblindex + i; + lv->length = + ((p->header.nextindex - 1) >> L2DTSLOTSIZE) - + i + 1; + dtlck->index++; + } + + /* free the leaf entry */ + dtDeleteEntry(p, index, &dtlck); + + /* + * Update directory index table for entries moved in stbl + */ + if (DO_INDEX(ip) && index < p->header.nextindex) { + imp = 0; + stbl = DT_GETSTBL(p); + for (i = index; i < p->header.nextindex; i++) { + ldtentry = + (ldtentry_t *) & p->slot[stbl[i]]; + modify_index(tid, ip, + le32_to_cpu(ldtentry->index), + bn, i, &imp); + } + if (imp) + release_metapage(imp); + } + + DT_PUTPAGE(mp); + } + + return rc; +} + + +/* + * dtDeleteUp() + * + * function: + * free empty pages as propagating deletion up the tree + * + * parameter: + * + * return: + */ +static int dtDeleteUp(tid_t tid, struct inode *ip, + metapage_t * fmp, dtpage_t * fp, btstack_t * btstack) +{ + int rc = 0; + metapage_t *mp; + dtpage_t *p; + int index, nextindex; + int xlen; + btframe_t *parent; + dtlock_t *dtlck; + tlock_t *tlck; + lv_t *lv; + pxdlock_t *pxdlock; + int i; + + /* + * keep the root leaf page which has become empty + */ + if (BT_IS_ROOT(fmp)) { + /* + * reset the root + * + * dtInitRoot() acquires txlock on the root + */ + dtInitRoot(tid, ip, PARENT(ip)); + + DT_PUTPAGE(fmp); + + return 0; + } + + /* + * free the non-root leaf page + */ + /* + * acquire a transaction lock on the page + * + * write FREEXTENT|NOREDOPAGE log record + * N.B. linelock is overlaid as freed extent descriptor, and + * the buffer page is freed; + */ + tlck = txMaplock(tid, ip, tlckDTREE | tlckFREE); + pxdlock = (pxdlock_t *) & tlck->lock; + pxdlock->flag = mlckFREEPXD; + pxdlock->pxd = fp->header.self; + pxdlock->index = 1; + + /* update sibling pointers */ + if ((rc = dtRelink(tid, ip, fp))) + return rc; + + xlen = lengthPXD(&fp->header.self); + ip->i_blocks -= LBLK2PBLK(ip->i_sb, xlen); + + /* free/invalidate its buffer page */ + discard_metapage(fmp); + + /* + * propagate page deletion up the directory tree + * + * If the delete from the parent page makes it empty, + * continue all the way up the tree. + * stop if the root page is reached (which is never deleted) or + * if the entry deletion does not empty the page. + */ + while ((parent = BT_POP(btstack)) != NULL) { + /* pin the parent page */ + DT_GETPAGE(ip, parent->bn, mp, PSIZE, p, rc); + if (rc) + return rc; + + /* + * free the extent of the child page deleted + */ + index = parent->index; + + /* + * delete the entry for the child page from parent + */ + nextindex = p->header.nextindex; + + /* + * the parent has the single entry being deleted: + * + * free the parent page which has become empty. + */ + if (nextindex == 1) { + /* + * keep the root internal page which has become empty + */ + if (p->header.flag & BT_ROOT) { + /* + * reset the root + * + * dtInitRoot() acquires txlock on the root + */ + dtInitRoot(tid, ip, PARENT(ip)); + + DT_PUTPAGE(mp); + + return 0; + } + /* + * free the parent page + */ + else { + /* + * acquire a transaction lock on the page + * + * write FREEXTENT|NOREDOPAGE log record + */ + tlck = + txMaplock(tid, ip, + tlckDTREE | tlckFREE); + pxdlock = (pxdlock_t *) & tlck->lock; + pxdlock->flag = mlckFREEPXD; + pxdlock->pxd = p->header.self; + pxdlock->index = 1; + + /* update sibling pointers */ + if ((rc = dtRelink(tid, ip, p))) + return rc; + + xlen = lengthPXD(&p->header.self); + ip->i_blocks -= LBLK2PBLK(ip->i_sb, xlen); + + /* free/invalidate its buffer page */ + discard_metapage(mp); + + /* propagate up */ + continue; + } + } + + /* + * the parent has other entries remaining: + * + * delete the router entry from the parent page. + */ + BT_MARK_DIRTY(mp, ip); + /* + * acquire a transaction lock on the page + * + * action: router entry deletion + */ + tlck = txLock(tid, ip, mp, tlckDTREE | tlckENTRY); + dtlck = (dtlock_t *) & tlck->lock; + + /* linelock header */ + if (dtlck->index >= dtlck->maxcnt) + dtlck = (dtlock_t *) txLinelock(dtlck); + lv = (lv_t *) & dtlck->lv[dtlck->index]; + lv->offset = 0; + lv->length = 1; + dtlck->index++; + + /* linelock stbl of non-root leaf page */ + if (!(p->header.flag & BT_ROOT)) { + if (dtlck->index < dtlck->maxcnt) + lv++; + else { + dtlck = (dtlock_t *) txLinelock(dtlck); + lv = (lv_t *) & dtlck->lv[0]; + } + i = index >> L2DTSLOTSIZE; + lv->offset = p->header.stblindex + i; + lv->length = + ((p->header.nextindex - 1) >> L2DTSLOTSIZE) - + i + 1; + dtlck->index++; + } + + /* free the router entry */ + dtDeleteEntry(p, index, &dtlck); + + /* reset key of new leftmost entry of level (for consistency) */ + if (index == 0 && + ((p->header.flag & BT_ROOT) || p->header.prev == 0)) + dtTruncateEntry(p, 0, &dtlck); + + /* unpin the parent page */ + DT_PUTPAGE(mp); + + /* exit propagation up */ + break; + } + + return 0; +} + + +/* + * NAME: dtRelocate() + * + * FUNCTION: relocate dtpage (internal or leaf) of directory; + * This function is mainly used by defragfs utility. + */ +int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd, + s64 nxaddr) +{ + int rc = 0; + metapage_t *mp, *pmp, *lmp, *rmp; + dtpage_t *p, *pp, *rp = 0, *lp= 0; + s64 bn; + int index; + btstack_t btstack; + pxd_t *pxd; + s64 oxaddr, nextbn, prevbn; + int xlen, xsize; + tlock_t *tlck; + dtlock_t *dtlck; + pxdlock_t *pxdlock; + s8 *stbl; + lv_t *lv; + + oxaddr = addressPXD(opxd); + xlen = lengthPXD(opxd); + + jEVENT(0, ("dtRelocate: lmxaddr:%Ld xaddr:%Ld:%Ld xlen:%d\n", + lmxaddr, oxaddr, nxaddr, xlen)); + + /* + * 1. get the internal parent dtpage covering + * router entry for the tartget page to be relocated; + */ + rc = dtSearchNode(ip, lmxaddr, opxd, &btstack); + if (rc) + return rc; + + /* retrieve search result */ + DT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index); + jEVENT(0, ("dtRelocate: parent router entry validated.\n")); + + /* + * 2. relocate the target dtpage + */ + /* read in the target page from src extent */ + DT_GETPAGE(ip, oxaddr, mp, PSIZE, p, rc); + if (rc) { + /* release the pinned parent page */ + DT_PUTPAGE(pmp); + return rc; + } + + /* + * read in sibling pages if any to update sibling pointers; + */ + rmp = NULL; + if (p->header.next) { + nextbn = le64_to_cpu(p->header.next); + DT_GETPAGE(ip, nextbn, rmp, PSIZE, rp, rc); + if (rc) { + DT_PUTPAGE(mp); + DT_PUTPAGE(pmp); + return (rc); + } + } + + lmp = NULL; + if (p->header.prev) { + prevbn = le64_to_cpu(p->header.prev); + DT_GETPAGE(ip, prevbn, lmp, PSIZE, lp, rc); + if (rc) { + DT_PUTPAGE(mp); + DT_PUTPAGE(pmp); + if (rmp) + DT_PUTPAGE(rmp); + return (rc); + } + } + + /* at this point, all xtpages to be updated are in memory */ + + /* + * update sibling pointers of sibling dtpages if any; + */ + if (lmp) { + tlck = txLock(tid, ip, lmp, tlckDTREE | tlckRELINK); + dtlck = (dtlock_t *) & tlck->lock; + /* linelock header */ + ASSERT(dtlck->index == 0); + lv = (lv_t *) & dtlck->lv[0]; + lv->offset = 0; + lv->length = 1; + dtlck->index++; + + lp->header.next = cpu_to_le64(nxaddr); + DT_PUTPAGE(lmp); + } + + if (rmp) { + tlck = txLock(tid, ip, rmp, tlckDTREE | tlckRELINK); + dtlck = (dtlock_t *) & tlck->lock; + /* linelock header */ + ASSERT(dtlck->index == 0); + lv = (lv_t *) & dtlck->lv[0]; + lv->offset = 0; + lv->length = 1; + dtlck->index++; + + rp->header.prev = cpu_to_le64(nxaddr); + DT_PUTPAGE(rmp); + } + + /* + * update the target dtpage to be relocated + * + * write LOG_REDOPAGE of LOG_NEW type for dst page + * for the whole target page (logredo() will apply + * after image and update bmap for allocation of the + * dst extent), and update bmap for allocation of + * the dst extent; + */ + tlck = txLock(tid, ip, mp, tlckDTREE | tlckNEW); + dtlck = (dtlock_t *) & tlck->lock; + /* linelock header */ + ASSERT(dtlck->index == 0); + lv = (lv_t *) & dtlck->lv[0]; + + /* update the self address in the dtpage header */ + pxd = &p->header.self; + PXDaddress(pxd, nxaddr); + + /* the dst page is the same as the src page, i.e., + * linelock for afterimage of the whole page; + */ + lv->offset = 0; + lv->length = p->header.maxslot; + dtlck->index++; + + /* update the buffer extent descriptor of the dtpage */ + xsize = xlen << JFS_SBI(ip->i_sb)->l2bsize; +#ifdef _STILL_TO_PORT + bmSetXD(mp, nxaddr, xsize); +#endif /* _STILL_TO_PORT */ + /* unpin the relocated page */ + DT_PUTPAGE(mp); + jEVENT(0, ("dtRelocate: target dtpage relocated.\n")); + + /* the moved extent is dtpage, then a LOG_NOREDOPAGE log rec + * needs to be written (in logredo(), the LOG_NOREDOPAGE log rec + * will also force a bmap update ). + */ + + /* + * 3. acquire maplock for the source extent to be freed; + */ + /* for dtpage relocation, write a LOG_NOREDOPAGE record + * for the source dtpage (logredo() will init NoRedoPage + * filter and will also update bmap for free of the source + * dtpage), and upadte bmap for free of the source dtpage; + */ + tlck = txMaplock(tid, ip, tlckDTREE | tlckFREE); + pxdlock = (pxdlock_t *) & tlck->lock; + pxdlock->flag = mlckFREEPXD; + PXDaddress(&pxdlock->pxd, oxaddr); + PXDlength(&pxdlock->pxd, xlen); + pxdlock->index = 1; + + /* + * 4. update the parent router entry for relocation; + * + * acquire tlck for the parent entry covering the target dtpage; + * write LOG_REDOPAGE to apply after image only; + */ + jEVENT(0, ("dtRelocate: update parent router entry.\n")); + tlck = txLock(tid, ip, pmp, tlckDTREE | tlckENTRY); + dtlck = (dtlock_t *) & tlck->lock; + lv = (lv_t *) & dtlck->lv[dtlck->index]; + + /* update the PXD with the new address */ + stbl = DT_GETSTBL(pp); + pxd = (pxd_t *) & pp->slot[stbl[index]]; + PXDaddress(pxd, nxaddr); + lv->offset = stbl[index]; + lv->length = 1; + dtlck->index++; + + /* unpin the parent dtpage */ + DT_PUTPAGE(pmp); + + return rc; +} + + +/* + * NAME: dtSearchNode() + * + * FUNCTION: Search for an dtpage containing a specified address + * This function is mainly used by defragfs utility. + * + * NOTE: Search result on stack, the found page is pinned at exit. + * The result page must be an internal dtpage. + * lmxaddr give the address of the left most page of the + * dtree level, in which the required dtpage resides. + */ +static int dtSearchNode(struct inode *ip, s64 lmxaddr, pxd_t * kpxd, + btstack_t * btstack) +{ + int rc = 0; + s64 bn; + metapage_t *mp; + dtpage_t *p; + int psize = 288; /* initial in-line directory */ + s8 *stbl; + int i; + pxd_t *pxd; + btframe_t *btsp; + + BT_CLR(btstack); /* reset stack */ + + /* + * descend tree to the level with specified leftmost page + * + * by convention, root bn = 0. + */ + for (bn = 0;;) { + /* get/pin the page to search */ + DT_GETPAGE(ip, bn, mp, psize, p, rc); + if (rc) + return rc; + + /* does the xaddr of leftmost page of the levevl + * matches levevl search key ? + */ + if (p->header.flag & BT_ROOT) { + if (lmxaddr == 0) + break; + } else if (addressPXD(&p->header.self) == lmxaddr) + break; + + /* + * descend down to leftmost child page + */ + if (p->header.flag & BT_LEAF) + return ESTALE; + + /* get the leftmost entry */ + stbl = DT_GETSTBL(p); + pxd = (pxd_t *) & p->slot[stbl[0]]; + + /* get the child page block address */ + bn = addressPXD(pxd); + psize = lengthPXD(pxd) << JFS_SBI(ip->i_sb)->l2bsize; + /* unpin the parent page */ + DT_PUTPAGE(mp); + } + + /* + * search each page at the current levevl + */ + loop: + stbl = DT_GETSTBL(p); + for (i = 0; i < p->header.nextindex; i++) { + pxd = (pxd_t *) & p->slot[stbl[i]]; + + /* found the specified router entry */ + if (addressPXD(pxd) == addressPXD(kpxd) && + lengthPXD(pxd) == lengthPXD(kpxd)) { + btsp = btstack->top; + btsp->bn = bn; + btsp->index = i; + btsp->mp = mp; + + return 0; + } + } + + /* get the right sibling page if any */ + if (p->header.next) + bn = le64_to_cpu(p->header.next); + else { + DT_PUTPAGE(mp); + return ESTALE; + } + + /* unpin current page */ + DT_PUTPAGE(mp); + + /* get the right sibling page */ + DT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) + return rc; + + goto loop; +} + + +/* + * dtRelink() + * + * function: + * link around a freed page. + * + * parameter: + * fp: page to be freed + * + * return: + */ +static int dtRelink(tid_t tid, struct inode *ip, dtpage_t * p) +{ + int rc; + metapage_t *mp; + s64 nextbn, prevbn; + tlock_t *tlck; + dtlock_t *dtlck; + lv_t *lv; + + nextbn = le64_to_cpu(p->header.next); + prevbn = le64_to_cpu(p->header.prev); + + /* update prev pointer of the next page */ + if (nextbn != 0) { + DT_GETPAGE(ip, nextbn, mp, PSIZE, p, rc); + if (rc) + return rc; + + BT_MARK_DIRTY(mp, ip); + /* + * acquire a transaction lock on the next page + * + * action: update prev pointer; + */ + tlck = txLock(tid, ip, mp, tlckDTREE | tlckRELINK); + jEVENT(0, + ("dtRelink nextbn: tlck = 0x%p, ip = 0x%p, mp=0x%p\n", + tlck, ip, mp)); + dtlck = (dtlock_t *) & tlck->lock; + + /* linelock header */ + if (dtlck->index >= dtlck->maxcnt) + dtlck = (dtlock_t *) txLinelock(dtlck); + lv = (lv_t *) & dtlck->lv[dtlck->index]; + lv->offset = 0; + lv->length = 1; + dtlck->index++; + + p->header.prev = cpu_to_le64(prevbn); + DT_PUTPAGE(mp); + } + + /* update next pointer of the previous page */ + if (prevbn != 0) { + DT_GETPAGE(ip, prevbn, mp, PSIZE, p, rc); + if (rc) + return rc; + + BT_MARK_DIRTY(mp, ip); + /* + * acquire a transaction lock on the prev page + * + * action: update next pointer; + */ + tlck = txLock(tid, ip, mp, tlckDTREE | tlckRELINK); + jEVENT(0, + ("dtRelink prevbn: tlck = 0x%p, ip = 0x%p, mp=0x%p\n", + tlck, ip, mp)); + dtlck = (dtlock_t *) & tlck->lock; + + /* linelock header */ + if (dtlck->index >= dtlck->maxcnt) + dtlck = (dtlock_t *) txLinelock(dtlck); + lv = (lv_t *) & dtlck->lv[dtlck->index]; + lv->offset = 0; + lv->length = 1; + dtlck->index++; + + p->header.next = cpu_to_le64(nextbn); + DT_PUTPAGE(mp); + } + + return 0; +} + + +/* + * dtInitRoot() + * + * initialize directory root (inline in inode) + */ +void dtInitRoot(tid_t tid, struct inode *ip, u32 idotdot) +{ + struct jfs_inode_info *jfs_ip = JFS_IP(ip); + dtroot_t *p; + int fsi; + dtslot_t *f; + tlock_t *tlck; + dtlock_t *dtlck; + lv_t *lv; + u16 xflag_save; + + /* + * If this was previously an non-empty directory, we need to remove + * the old directory table. + */ + if (DO_INDEX(ip)) { + if (jfs_ip->next_index > (MAX_INLINE_DIRTABLE_ENTRY + 1)) { + tblock_t *tblk = tid_to_tblock(tid); + /* + * We're playing games with the tid's xflag. If + * we're removing a regular file, the file's xtree + * is committed with COMMIT_PMAP, but we always + * commit the directories xtree with COMMIT_PWMAP. + */ + xflag_save = tblk->xflag; + tblk->xflag = 0; + /* + * xtTruncate isn't guaranteed to fully truncate + * the xtree. The caller needs to check i_size + * after committing the transaction to see if + * additional truncation is needed. The + * COMMIT_Stale flag tells caller that we + * initiated the truncation. + */ + xtTruncate(tid, ip, 0, COMMIT_PWMAP); + set_cflag(COMMIT_Stale, ip); + + tblk->xflag = xflag_save; + /* + * Tells jfs_metapage code that the metadata pages + * for the index table are no longer useful, and + * remove them from page cache. + */ + invalidate_inode_metapages(ip); + } else + ip->i_size = 1; + + jfs_ip->next_index = 2; + } else + ip->i_size = IDATASIZE; + + /* + * acquire a transaction lock on the root + * + * action: directory initialization; + */ + tlck = txLock(tid, ip, (metapage_t *) & jfs_ip->bxflag, + tlckDTREE | tlckENTRY | tlckBTROOT); + dtlck = (dtlock_t *) & tlck->lock; + + /* linelock root */ + ASSERT(dtlck->index == 0); + lv = (lv_t *) & dtlck->lv[0]; + lv->offset = 0; + lv->length = DTROOTMAXSLOT; + dtlck->index++; + + p = &jfs_ip->i_dtroot; + + p->header.flag = DXD_INDEX | BT_ROOT | BT_LEAF; + + p->header.nextindex = 0; + + /* init freelist */ + fsi = 1; + f = &p->slot[fsi]; + + /* init data area of root */ + for (fsi++; fsi < DTROOTMAXSLOT; f++, fsi++) + f->next = fsi; + f->next = -1; + + p->header.freelist = 1; + p->header.freecnt = 8; + + /* init '..' entry */ + p->header.idotdot = cpu_to_le32(idotdot); + +#if 0 + ip->i_blocks = LBLK2PBLK(ip->i_sb, + ((jfs_ip->ea.flag & DXD_EXTENT) ? + lengthDXD(&jfs_ip->ea) : 0) + + ((jfs_ip->acl.flag & DXD_EXTENT) ? + lengthDXD(&jfs_ip->acl) : 0)); +#endif + + return; +} + +/* + * jfs_readdir() + * + * function: read directory entries sequentially + * from the specified entry offset + * + * parameter: + * + * return: offset = (pn, index) of start entry + * of next jfs_readdir()/dtRead() + */ +int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) +{ + struct inode *ip = filp->f_dentry->d_inode; + struct nls_table *codepage = JFS_SBI(ip->i_sb)->nls_tab; + int rc = 0; + struct dtoffset { + s16 pn; + s16 index; + s32 unused; + } *dtoffset = (struct dtoffset *) &filp->f_pos; + s64 bn; + metapage_t *mp; + dtpage_t *p; + int index; + s8 *stbl; + btstack_t btstack; + int i, next; + ldtentry_t *d; + dtslot_t *t; + int d_namleft, d_namlen, len, outlen; + char *d_name, *name_ptr; + int dtlhdrdatalen; + u32 dir_index; + int do_index = 0; + uint loop_count = 0; + + if (filp->f_pos == DIREND) + return 0; + + if (DO_INDEX(ip)) { + /* + * persistent index is stored in directory entries. + * Special cases: 0 = . + * 1 = .. + * -1 = End of directory + */ + do_index = 1; + dtlhdrdatalen = DTLHDRDATALEN; + + dir_index = (u32) filp->f_pos; + + if (dir_index > 1) { + dir_table_slot_t dirtab_slot; + + if (dtEmpty(ip)) { + filp->f_pos = DIREND; + return 0; + } + repeat: + rc = get_index(ip, dir_index, &dirtab_slot); + if (rc) { + filp->f_pos = DIREND; + return rc; + } + if (dirtab_slot.flag == DIR_INDEX_FREE) { + if (loop_count++ > JFS_IP(ip)->next_index) { + jERROR(1, ("jfs_readdir detected " + "infinite loop!\n")); + filp->f_pos = DIREND; + return 0; + } + dir_index = le32_to_cpu(dirtab_slot.addr2); + if (dir_index == -1) { + filp->f_pos = DIREND; + return 0; + } + goto repeat; + } + bn = addressDTS(&dirtab_slot); + index = dirtab_slot.slot; + DT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) { + filp->f_pos = DIREND; + return 0; + } + if (p->header.flag & BT_INTERNAL) { + jERROR(1,("jfs_readdir: bad index table\n")); + DT_PUTPAGE(mp); + filp->f_pos = -1; + return 0; + } + } else { + if (dir_index == 0) { + /* + * self "." + */ + filp->f_pos = 0; + if (filldir(dirent, ".", 1, 0, ip->i_ino, + DT_DIR)) + return 0; + } + /* + * parent ".." + */ + filp->f_pos = 1; + if (filldir + (dirent, "..", 2, 1, PARENT(ip), DT_DIR)) + return 0; + + /* + * Find first entry of left-most leaf + */ + if (dtEmpty(ip)) { + filp->f_pos = DIREND; + return 0; + } + + if ((rc = dtReadFirst(ip, &btstack))) + return -rc; + + DT_GETSEARCH(ip, btstack.top, bn, mp, p, index); + } + } else { + /* + * Legacy filesystem - OS/2 & Linux JFS < 0.3.6 + * + * pn = index = 0: First entry "." + * pn = 0; index = 1: Second entry ".." + * pn > 0: Real entries, pn=1 -> leftmost page + * pn = index = -1: No more entries + */ + dtlhdrdatalen = DTLHDRDATALEN_LEGACY; + + if (filp->f_pos == 0) { + /* build "." entry */ + + if (filldir(dirent, ".", 1, filp->f_pos, ip->i_ino, + DT_DIR)) + return 0; + dtoffset->index = 1; + } + + if (dtoffset->pn == 0) { + if (dtoffset->index == 1) { + /* build ".." entry */ + + if (filldir(dirent, "..", 2, filp->f_pos, + PARENT(ip), DT_DIR)) + return 0; + } else { + jERROR(1, + ("jfs_readdir called with invalid offset!\n")); + } + dtoffset->pn = 1; + dtoffset->index = 0; + } + + if (dtEmpty(ip)) { + filp->f_pos = DIREND; + return 0; + } + + if ((rc = dtReadNext(ip, &filp->f_pos, &btstack))) { + jERROR(1, + ("jfs_readdir: unexpected rc = %d from dtReadNext\n", + rc)); + filp->f_pos = DIREND; + return 0; + } + /* get start leaf page and index */ + DT_GETSEARCH(ip, btstack.top, bn, mp, p, index); + + /* offset beyond directory eof ? */ + if (bn < 0) { + filp->f_pos = DIREND; + return 0; + } + } + + d_name = kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t), GFP_NOFS); + if (d_name == NULL) { + DT_PUTPAGE(mp); + jERROR(1, ("jfs_readdir: kmalloc failed!\n")); + filp->f_pos = DIREND; + return 0; + } + while (1) { + stbl = DT_GETSTBL(p); + + for (i = index; i < p->header.nextindex; i++) { + d = (ldtentry_t *) & p->slot[stbl[i]]; + + d_namleft = d->namlen; + name_ptr = d_name; + + if (do_index) { + filp->f_pos = le32_to_cpu(d->index); + len = min(d_namleft, DTLHDRDATALEN); + } else + len = min(d_namleft, DTLHDRDATALEN_LEGACY); + + /* copy the name of head/only segment */ + outlen = jfs_strfromUCS_le(name_ptr, d->name, len, + codepage); + d_namlen = outlen; + + /* copy name in the additional segment(s) */ + next = d->next; + while (next >= 0) { + t = (dtslot_t *) & p->slot[next]; + name_ptr += outlen; + d_namleft -= len; + /* Sanity Check */ + if (d_namleft == 0) { + jERROR(1,("JFS:Dtree error: " + "ino = %ld, bn=%Ld, index = %d\n", + ip->i_ino, bn, i)); + updateSuper(ip->i_sb, FM_DIRTY); + goto skip_one; + } + len = min(d_namleft, DTSLOTDATALEN); + outlen = jfs_strfromUCS_le(name_ptr, t->name, + len, codepage); + d_namlen+= outlen; + + next = t->next; + } + + if (filldir(dirent, d_name, d_namlen, filp->f_pos, + le32_to_cpu(d->inumber), DT_UNKNOWN)) + goto out; +skip_one: + if (!do_index) + dtoffset->index++; + } + + /* + * get next leaf page + */ + + if (p->header.flag & BT_ROOT) { + filp->f_pos = DIREND; + break; + } + + bn = le64_to_cpu(p->header.next); + if (bn == 0) { + filp->f_pos = DIREND; + break; + } + + /* unpin previous leaf page */ + DT_PUTPAGE(mp); + + /* get next leaf page */ + DT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) { + kfree(d_name); + return -rc; + } + + /* update offset (pn:index) for new page */ + index = 0; + if (!do_index) { + dtoffset->pn++; + dtoffset->index = 0; + } + + } + + out: + kfree(d_name); + DT_PUTPAGE(mp); + + return rc; +} + + +/* + * dtReadFirst() + * + * function: get the leftmost page of the directory + */ +static int dtReadFirst(struct inode *ip, btstack_t * btstack) +{ + int rc = 0; + s64 bn; + int psize = 288; /* initial in-line directory */ + metapage_t *mp; + dtpage_t *p; + s8 *stbl; + btframe_t *btsp; + pxd_t *xd; + + BT_CLR(btstack); /* reset stack */ + + /* + * descend leftmost path of the tree + * + * by convention, root bn = 0. + */ + for (bn = 0;;) { + DT_GETPAGE(ip, bn, mp, psize, p, rc); + if (rc) + return rc; + + /* + * leftmost leaf page + */ + if (p->header.flag & BT_LEAF) { + /* return leftmost entry */ + btsp = btstack->top; + btsp->bn = bn; + btsp->index = 0; + btsp->mp = mp; + + return 0; + } + + /* + * descend down to leftmost child page + */ + /* push (bn, index) of the parent page/entry */ + BT_PUSH(btstack, bn, 0); + + /* get the leftmost entry */ + stbl = DT_GETSTBL(p); + xd = (pxd_t *) & p->slot[stbl[0]]; + + /* get the child page block address */ + bn = addressPXD(xd); + psize = lengthPXD(xd) << JFS_SBI(ip->i_sb)->l2bsize; + + /* unpin the parent page */ + DT_PUTPAGE(mp); + } +} + + +/* + * dtReadNext() + * + * function: get the page of the specified offset (pn:index) + * + * return: if (offset > eof), bn = -1; + * + * note: if index > nextindex of the target leaf page, + * start with 1st entry of next leaf page; + */ +static int dtReadNext(struct inode *ip, loff_t * offset, btstack_t * btstack) +{ + int rc = 0; + struct dtoffset { + s16 pn; + s16 index; + s32 unused; + } *dtoffset = (struct dtoffset *) offset; + s64 bn; + metapage_t *mp; + dtpage_t *p; + int index; + int pn; + s8 *stbl; + btframe_t *btsp, *parent; + pxd_t *xd; + + /* + * get leftmost leaf page pinned + */ + if ((rc = dtReadFirst(ip, btstack))) + return rc; + + /* get leaf page */ + DT_GETSEARCH(ip, btstack->top, bn, mp, p, index); + + /* get the start offset (pn:index) */ + pn = dtoffset->pn - 1; /* Now pn = 0 represents leftmost leaf */ + index = dtoffset->index; + + /* start at leftmost page ? */ + if (pn == 0) { + /* offset beyond eof ? */ + if (index < p->header.nextindex) + goto out; + + if (p->header.flag & BT_ROOT) { + bn = -1; + goto out; + } + + /* start with 1st entry of next leaf page */ + dtoffset->pn++; + dtoffset->index = index = 0; + goto a; + } + + /* start at non-leftmost page: scan parent pages for large pn */ + if (p->header.flag & BT_ROOT) { + bn = -1; + goto out; + } + + /* start after next leaf page ? */ + if (pn > 1) + goto b; + + /* get leaf page pn = 1 */ + a: + bn = le64_to_cpu(p->header.next); + + /* unpin leaf page */ + DT_PUTPAGE(mp); + + /* offset beyond eof ? */ + if (bn == 0) { + bn = -1; + goto out; + } + + goto c; + + /* + * scan last internal page level to get target leaf page + */ + b: + /* unpin leftmost leaf page */ + DT_PUTPAGE(mp); + + /* get left most parent page */ + btsp = btstack->top; + parent = btsp - 1; + bn = parent->bn; + DT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) + return rc; + + /* scan parent pages at last internal page level */ + while (pn >= p->header.nextindex) { + pn -= p->header.nextindex; + + /* get next parent page address */ + bn = le64_to_cpu(p->header.next); + + /* unpin current parent page */ + DT_PUTPAGE(mp); + + /* offset beyond eof ? */ + if (bn == 0) { + bn = -1; + goto out; + } + + /* get next parent page */ + DT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) + return rc; + + /* update parent page stack frame */ + parent->bn = bn; + } + + /* get leaf page address */ + stbl = DT_GETSTBL(p); + xd = (pxd_t *) & p->slot[stbl[pn]]; + bn = addressPXD(xd); + + /* unpin parent page */ + DT_PUTPAGE(mp); + + /* + * get target leaf page + */ + c: + DT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) + return rc; + + /* + * leaf page has been completed: + * start with 1st entry of next leaf page + */ + if (index >= p->header.nextindex) { + bn = le64_to_cpu(p->header.next); + + /* unpin leaf page */ + DT_PUTPAGE(mp); + + /* offset beyond eof ? */ + if (bn == 0) { + bn = -1; + goto out; + } + + /* get next leaf page */ + DT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) + return rc; + + /* start with 1st entry of next leaf page */ + dtoffset->pn++; + dtoffset->index = 0; + } + + out: + /* return target leaf page pinned */ + btsp = btstack->top; + btsp->bn = bn; + btsp->index = dtoffset->index; + btsp->mp = mp; + + return 0; +} + + +/* + * dtCompare() + * + * function: compare search key with an internal entry + * + * return: + * < 0 if k is < record + * = 0 if k is = record + * > 0 if k is > record + */ +static int dtCompare(component_t * key, /* search key */ + dtpage_t * p, /* directory page */ + int si) +{ /* entry slot index */ + register int rc; + register wchar_t *kname, *name; + register int klen, namlen, len; + idtentry_t *ih; + dtslot_t *t; + + /* + * force the left-most key on internal pages, at any level of + * the tree, to be less than any search key. + * this obviates having to update the leftmost key on an internal + * page when the user inserts a new key in the tree smaller than + * anything that has been stored. + * + * (? if/when dtSearch() narrows down to 1st entry (index = 0), + * at any internal page at any level of the tree, + * it descends to child of the entry anyway - + * ? make the entry as min size dummy entry) + * + * if (e->index == 0 && h->prevpg == P_INVALID && !(h->flags & BT_LEAF)) + * return (1); + */ + + kname = key->name; + klen = key->namlen; + + ih = (idtentry_t *) & p->slot[si]; + si = ih->next; + name = ih->name; + namlen = ih->namlen; + len = min(namlen, DTIHDRDATALEN); + + /* compare with head/only segment */ + len = min(klen, len); + if ((rc = UniStrncmp_le(kname, name, len))) + return rc; + + klen -= len; + namlen -= len; + + /* compare with additional segment(s) */ + kname += len; + while (klen > 0 && namlen > 0) { + /* compare with next name segment */ + t = (dtslot_t *) & p->slot[si]; + len = min(namlen, DTSLOTDATALEN); + len = min(klen, len); + name = t->name; + if ((rc = UniStrncmp_le(kname, name, len))) + return rc; + + klen -= len; + namlen -= len; + kname += len; + si = t->next; + } + + return (klen - namlen); +} + + + + +/* + * ciCompare() + * + * function: compare search key with an (leaf/internal) entry + * + * return: + * < 0 if k is < record + * = 0 if k is = record + * > 0 if k is > record + */ +static int ciCompare(component_t * key, /* search key */ + dtpage_t * p, /* directory page */ + int si, /* entry slot index */ + int flag) +{ + register int rc; + register wchar_t *kname, *name, x; + register int klen, namlen, len; + ldtentry_t *lh; + idtentry_t *ih; + dtslot_t *t; + int i; + + /* + * force the left-most key on internal pages, at any level of + * the tree, to be less than any search key. + * this obviates having to update the leftmost key on an internal + * page when the user inserts a new key in the tree smaller than + * anything that has been stored. + * + * (? if/when dtSearch() narrows down to 1st entry (index = 0), + * at any internal page at any level of the tree, + * it descends to child of the entry anyway - + * ? make the entry as min size dummy entry) + * + * if (e->index == 0 && h->prevpg == P_INVALID && !(h->flags & BT_LEAF)) + * return (1); + */ + + kname = key->name; + klen = key->namlen; + + /* + * leaf page entry + */ + if (p->header.flag & BT_LEAF) { + lh = (ldtentry_t *) & p->slot[si]; + si = lh->next; + name = lh->name; + namlen = lh->namlen; + if (flag & JFS_DIR_INDEX) + len = min(namlen, DTLHDRDATALEN); + else + len = min(namlen, DTLHDRDATALEN_LEGACY); + } + /* + * internal page entry + */ + else { + ih = (idtentry_t *) & p->slot[si]; + si = ih->next; + name = ih->name; + namlen = ih->namlen; + len = min(namlen, DTIHDRDATALEN); + } + + /* compare with head/only segment */ + len = min(klen, len); + for (i = 0; i < len; i++, kname++, name++) { + /* only uppercase if case-insensitive support is on */ + if ((flag & JFS_OS2) == JFS_OS2) + x = UniToupper(le16_to_cpu(*name)); + else + x = le16_to_cpu(*name); + if ((rc = *kname - x)) + return rc; + } + + klen -= len; + namlen -= len; + + /* compare with additional segment(s) */ + while (klen > 0 && namlen > 0) { + /* compare with next name segment */ + t = (dtslot_t *) & p->slot[si]; + len = min(namlen, DTSLOTDATALEN); + len = min(klen, len); + name = t->name; + for (i = 0; i < len; i++, kname++, name++) { + /* only uppercase if case-insensitive support is on */ + if ((flag & JFS_OS2) == JFS_OS2) + x = UniToupper(le16_to_cpu(*name)); + else + x = le16_to_cpu(*name); + + if ((rc = *kname - x)) + return rc; + } + + klen -= len; + namlen -= len; + si = t->next; + } + + return (klen - namlen); +} + + +/* + * ciGetLeafPrefixKey() + * + * function: compute prefix of suffix compression + * from two adjacent leaf entries + * across page boundary + * + * return: + * Number of prefix bytes needed to distinguish b from a. + */ +static void ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp, + int ri, component_t * key, int flag) +{ + register int klen, namlen; + register wchar_t *pl, *pr, *kname; + wchar_t lname[JFS_NAME_MAX + 1]; + component_t lkey = { 0, lname }; + wchar_t rname[JFS_NAME_MAX + 1]; + component_t rkey = { 0, rname }; + + /* get left and right key */ + dtGetKey(lp, li, &lkey, flag); + lkey.name[lkey.namlen] = 0; + + if ((flag & JFS_OS2) == JFS_OS2) + ciToUpper(&lkey); + + dtGetKey(rp, ri, &rkey, flag); + rkey.name[rkey.namlen] = 0; + + + if ((flag & JFS_OS2) == JFS_OS2) + ciToUpper(&rkey); + + /* compute prefix */ + klen = 0; + kname = key->name; + namlen = min(lkey.namlen, rkey.namlen); + for (pl = lkey.name, pr = rkey.name; + namlen; pl++, pr++, namlen--, klen++, kname++) { + *kname = *pr; + if (*pl != *pr) { + key->namlen = klen + 1; + return; + } + } + + /* l->namlen <= r->namlen since l <= r */ + if (lkey.namlen < rkey.namlen) { + *kname = *pr; + key->namlen = klen + 1; + } else /* l->namelen == r->namelen */ + key->namlen = klen; + + return; +} + + + +/* + * dtGetKey() + * + * function: get key of the entry + */ +static void dtGetKey(dtpage_t * p, int i, /* entry index */ + component_t * key, int flag) +{ + int si; + s8 *stbl; + ldtentry_t *lh; + idtentry_t *ih; + dtslot_t *t; + int namlen, len; + wchar_t *name, *kname; + + /* get entry */ + stbl = DT_GETSTBL(p); + si = stbl[i]; + if (p->header.flag & BT_LEAF) { + lh = (ldtentry_t *) & p->slot[si]; + si = lh->next; + namlen = lh->namlen; + name = lh->name; + if (flag & JFS_DIR_INDEX) + len = min(namlen, DTLHDRDATALEN); + else + len = min(namlen, DTLHDRDATALEN_LEGACY); + } else { + ih = (idtentry_t *) & p->slot[si]; + si = ih->next; + namlen = ih->namlen; + name = ih->name; + len = min(namlen, DTIHDRDATALEN); + } + + key->namlen = namlen; + kname = key->name; + + /* + * move head/only segment + */ + UniStrncpy_le(kname, name, len); + + /* + * move additional segment(s) + */ + while (si >= 0) { + /* get next segment */ + t = &p->slot[si]; + kname += len; + namlen -= len; + len = min(namlen, DTSLOTDATALEN); + UniStrncpy_le(kname, t->name, len); + + si = t->next; + } +} + + +/* + * dtInsertEntry() + * + * function: allocate free slot(s) and + * write a leaf/internal entry + * + * return: entry slot index + */ +static void dtInsertEntry(dtpage_t * p, int index, component_t * key, + ddata_t * data, dtlock_t ** dtlock) +{ + dtslot_t *h, *t; + ldtentry_t *lh = 0; + idtentry_t *ih = 0; + int hsi, fsi, klen, len, nextindex; + wchar_t *kname, *name; + s8 *stbl; + pxd_t *xd; + dtlock_t *dtlck = *dtlock; + lv_t *lv; + int xsi, n; + s64 bn = 0; + metapage_t *mp = 0; + + klen = key->namlen; + kname = key->name; + + /* allocate a free slot */ + hsi = fsi = p->header.freelist; + h = &p->slot[fsi]; + p->header.freelist = h->next; + --p->header.freecnt; + + /* open new linelock */ + if (dtlck->index >= dtlck->maxcnt) + dtlck = (dtlock_t *) txLinelock(dtlck); + + lv = (lv_t *) & dtlck->lv[dtlck->index]; + lv->offset = hsi; + + /* write head/only segment */ + if (p->header.flag & BT_LEAF) { + lh = (ldtentry_t *) h; + lh->next = h->next; + lh->inumber = data->leaf.ino; /* little-endian */ + lh->namlen = klen; + name = lh->name; + if (data->leaf.ip) { + len = min(klen, DTLHDRDATALEN); + if (!(p->header.flag & BT_ROOT)) + bn = addressPXD(&p->header.self); + lh->index = cpu_to_le32(add_index(data->leaf.tid, + data->leaf.ip, + bn, index)); + } else + len = min(klen, DTLHDRDATALEN_LEGACY); + } else { + ih = (idtentry_t *) h; + ih->next = h->next; + xd = (pxd_t *) ih; + *xd = data->xd; + ih->namlen = klen; + name = ih->name; + len = min(klen, DTIHDRDATALEN); + } + + UniStrncpy_le(name, kname, len); + + n = 1; + xsi = hsi; + + /* write additional segment(s) */ + t = h; + klen -= len; + while (klen) { + /* get free slot */ + fsi = p->header.freelist; + t = &p->slot[fsi]; + p->header.freelist = t->next; + --p->header.freecnt; + + /* is next slot contiguous ? */ + if (fsi != xsi + 1) { + /* close current linelock */ + lv->length = n; + dtlck->index++; + + /* open new linelock */ + if (dtlck->index < dtlck->maxcnt) + lv++; + else { + dtlck = (dtlock_t *) txLinelock(dtlck); + lv = (lv_t *) & dtlck->lv[0]; + } + + lv->offset = fsi; + n = 0; + } + + kname += len; + len = min(klen, DTSLOTDATALEN); + UniStrncpy_le(t->name, kname, len); + + n++; + xsi = fsi; + klen -= len; + } + + /* close current linelock */ + lv->length = n; + dtlck->index++; + + *dtlock = dtlck; + + /* terminate last/only segment */ + if (h == t) { + /* single segment entry */ + if (p->header.flag & BT_LEAF) + lh->next = -1; + else + ih->next = -1; + } else + /* multi-segment entry */ + t->next = -1; + + /* if insert into middle, shift right succeeding entries in stbl */ + stbl = DT_GETSTBL(p); + nextindex = p->header.nextindex; + if (index < nextindex) { + memmove(stbl + index + 1, stbl + index, nextindex - index); + + if ((p->header.flag & BT_LEAF) && data->leaf.ip) { + /* + * Need to update slot number for entries that moved + * in the stbl + */ + mp = 0; + for (n = index + 1; n <= nextindex; n++) { + lh = (ldtentry_t *) & (p->slot[stbl[n]]); + modify_index(data->leaf.tid, data->leaf.ip, + le32_to_cpu(lh->index), bn, n, + &mp); + } + if (mp) + release_metapage(mp); + } + } + + stbl[index] = hsi; + + /* advance next available entry index of stbl */ + ++p->header.nextindex; +} + + +/* + * dtMoveEntry() + * + * function: move entries from split/left page to new/right page + * + * nextindex of dst page and freelist/freecnt of both pages + * are updated. + */ +static void dtMoveEntry(dtpage_t * sp, int si, dtpage_t * dp, + dtlock_t ** sdtlock, dtlock_t ** ddtlock, + int do_index) +{ + int ssi, next; /* src slot index */ + int di; /* dst entry index */ + int dsi; /* dst slot index */ + s8 *sstbl, *dstbl; /* sorted entry table */ + int snamlen, len; + ldtentry_t *slh, *dlh = 0; + idtentry_t *sih, *dih = 0; + dtslot_t *h, *s, *d; + dtlock_t *sdtlck = *sdtlock, *ddtlck = *ddtlock; + lv_t *slv, *dlv; + int xssi, ns, nd; + int sfsi; + + sstbl = (s8 *) & sp->slot[sp->header.stblindex]; + dstbl = (s8 *) & dp->slot[dp->header.stblindex]; + + dsi = dp->header.freelist; /* first (whole page) free slot */ + sfsi = sp->header.freelist; + + /* linelock destination entry slot */ + dlv = (lv_t *) & ddtlck->lv[ddtlck->index]; + dlv->offset = dsi; + + /* linelock source entry slot */ + slv = (lv_t *) & sdtlck->lv[sdtlck->index]; + slv->offset = sstbl[si]; + xssi = slv->offset - 1; + + /* + * move entries + */ + ns = nd = 0; + for (di = 0; si < sp->header.nextindex; si++, di++) { + ssi = sstbl[si]; + dstbl[di] = dsi; + + /* is next slot contiguous ? */ + if (ssi != xssi + 1) { + /* close current linelock */ + slv->length = ns; + sdtlck->index++; + + /* open new linelock */ + if (sdtlck->index < sdtlck->maxcnt) + slv++; + else { + sdtlck = (dtlock_t *) txLinelock(sdtlck); + slv = (lv_t *) & sdtlck->lv[0]; + } + + slv->offset = ssi; + ns = 0; + } + + /* + * move head/only segment of an entry + */ + /* get dst slot */ + h = d = &dp->slot[dsi]; + + /* get src slot and move */ + s = &sp->slot[ssi]; + if (sp->header.flag & BT_LEAF) { + /* get source entry */ + slh = (ldtentry_t *) s; + dlh = (ldtentry_t *) h; + snamlen = slh->namlen; + + if (do_index) { + len = min(snamlen, DTLHDRDATALEN); + dlh->index = slh->index; /* little-endian */ + } else + len = min(snamlen, DTLHDRDATALEN_LEGACY); + + memcpy(dlh, slh, 6 + len * 2); + + next = slh->next; + + /* update dst head/only segment next field */ + dsi++; + dlh->next = dsi; + } else { + sih = (idtentry_t *) s; + snamlen = sih->namlen; + + len = min(snamlen, DTIHDRDATALEN); + dih = (idtentry_t *) h; + memcpy(dih, sih, 10 + len * 2); + next = sih->next; + + dsi++; + dih->next = dsi; + } + + /* free src head/only segment */ + s->next = sfsi; + s->cnt = 1; + sfsi = ssi; + + ns++; + nd++; + xssi = ssi; + + /* + * move additional segment(s) of the entry + */ + snamlen -= len; + while ((ssi = next) >= 0) { + /* is next slot contiguous ? */ + if (ssi != xssi + 1) { + /* close current linelock */ + slv->length = ns; + sdtlck->index++; + + /* open new linelock */ + if (sdtlck->index < sdtlck->maxcnt) + slv++; + else { + sdtlck = + (dtlock_t *) + txLinelock(sdtlck); + slv = (lv_t *) & sdtlck->lv[0]; + } + + slv->offset = ssi; + ns = 0; + } + + /* get next source segment */ + s = &sp->slot[ssi]; + + /* get next destination free slot */ + d++; + + len = min(snamlen, DTSLOTDATALEN); + UniStrncpy(d->name, s->name, len); + + ns++; + nd++; + xssi = ssi; + + dsi++; + d->next = dsi; + + /* free source segment */ + next = s->next; + s->next = sfsi; + s->cnt = 1; + sfsi = ssi; + + snamlen -= len; + } /* end while */ + + /* terminate dst last/only segment */ + if (h == d) { + /* single segment entry */ + if (dp->header.flag & BT_LEAF) + dlh->next = -1; + else + dih->next = -1; + } else + /* multi-segment entry */ + d->next = -1; + } /* end for */ + + /* close current linelock */ + slv->length = ns; + sdtlck->index++; + *sdtlock = sdtlck; + + dlv->length = nd; + ddtlck->index++; + *ddtlock = ddtlck; + + /* update source header */ + sp->header.freelist = sfsi; + sp->header.freecnt += nd; + + /* update destination header */ + dp->header.nextindex = di; + + dp->header.freelist = dsi; + dp->header.freecnt -= nd; +} + + +/* + * dtDeleteEntry() + * + * function: free a (leaf/internal) entry + * + * log freelist header, stbl, and each segment slot of entry + * (even though last/only segment next field is modified, + * physical image logging requires all segment slots of + * the entry logged to avoid applying previous updates + * to the same slots) + */ +static void dtDeleteEntry(dtpage_t * p, int fi, dtlock_t ** dtlock) +{ + int fsi; /* free entry slot index */ + s8 *stbl; + dtslot_t *t; + int si, freecnt; + dtlock_t *dtlck = *dtlock; + lv_t *lv; + int xsi, n; + + /* get free entry slot index */ + stbl = DT_GETSTBL(p); + fsi = stbl[fi]; + + /* open new linelock */ + if (dtlck->index >= dtlck->maxcnt) + dtlck = (dtlock_t *) txLinelock(dtlck); + lv = (lv_t *) & dtlck->lv[dtlck->index]; + + lv->offset = fsi; + + /* get the head/only segment */ + t = &p->slot[fsi]; + if (p->header.flag & BT_LEAF) + si = ((ldtentry_t *) t)->next; + else + si = ((idtentry_t *) t)->next; + t->next = si; + t->cnt = 1; + + n = freecnt = 1; + xsi = fsi; + + /* find the last/only segment */ + while (si >= 0) { + /* is next slot contiguous ? */ + if (si != xsi + 1) { + /* close current linelock */ + lv->length = n; + dtlck->index++; + + /* open new linelock */ + if (dtlck->index < dtlck->maxcnt) + lv++; + else { + dtlck = (dtlock_t *) txLinelock(dtlck); + lv = (lv_t *) & dtlck->lv[0]; + } + + lv->offset = si; + n = 0; + } + + n++; + xsi = si; + freecnt++; + + t = &p->slot[si]; + t->cnt = 1; + si = t->next; + } + + /* close current linelock */ + lv->length = n; + dtlck->index++; + + *dtlock = dtlck; + + /* update freelist */ + t->next = p->header.freelist; + p->header.freelist = fsi; + p->header.freecnt += freecnt; + + /* if delete from middle, + * shift left the succedding entries in the stbl + */ + si = p->header.nextindex; + if (fi < si - 1) + memmove(&stbl[fi], &stbl[fi + 1], si - fi - 1); + + p->header.nextindex--; +} + + +/* + * dtTruncateEntry() + * + * function: truncate a (leaf/internal) entry + * + * log freelist header, stbl, and each segment slot of entry + * (even though last/only segment next field is modified, + * physical image logging requires all segment slots of + * the entry logged to avoid applying previous updates + * to the same slots) + */ +static void dtTruncateEntry(dtpage_t * p, int ti, dtlock_t ** dtlock) +{ + int tsi; /* truncate entry slot index */ + s8 *stbl; + dtslot_t *t; + int si, freecnt; + dtlock_t *dtlck = *dtlock; + lv_t *lv; + int fsi, xsi, n; + + /* get free entry slot index */ + stbl = DT_GETSTBL(p); + tsi = stbl[ti]; + + /* open new linelock */ + if (dtlck->index >= dtlck->maxcnt) + dtlck = (dtlock_t *) txLinelock(dtlck); + lv = (lv_t *) & dtlck->lv[dtlck->index]; + + lv->offset = tsi; + + /* get the head/only segment */ + t = &p->slot[tsi]; + ASSERT(p->header.flag & BT_INTERNAL); + ((idtentry_t *) t)->namlen = 0; + si = ((idtentry_t *) t)->next; + ((idtentry_t *) t)->next = -1; + + n = 1; + freecnt = 0; + fsi = si; + xsi = tsi; + + /* find the last/only segment */ + while (si >= 0) { + /* is next slot contiguous ? */ + if (si != xsi + 1) { + /* close current linelock */ + lv->length = n; + dtlck->index++; + + /* open new linelock */ + if (dtlck->index < dtlck->maxcnt) + lv++; + else { + dtlck = (dtlock_t *) txLinelock(dtlck); + lv = (lv_t *) & dtlck->lv[0]; + } + + lv->offset = si; + n = 0; + } + + n++; + xsi = si; + freecnt++; + + t = &p->slot[si]; + t->cnt = 1; + si = t->next; + } + + /* close current linelock */ + lv->length = n; + dtlck->index++; + + *dtlock = dtlck; + + /* update freelist */ + if (freecnt == 0) + return; + t->next = p->header.freelist; + p->header.freelist = fsi; + p->header.freecnt += freecnt; +} + + +/* + * dtLinelockFreelist() + */ +static void dtLinelockFreelist(dtpage_t * p, /* directory page */ + int m, /* max slot index */ + dtlock_t ** dtlock) +{ + int fsi; /* free entry slot index */ + dtslot_t *t; + int si; + dtlock_t *dtlck = *dtlock; + lv_t *lv; + int xsi, n; + + /* get free entry slot index */ + fsi = p->header.freelist; + + /* open new linelock */ + if (dtlck->index >= dtlck->maxcnt) + dtlck = (dtlock_t *) txLinelock(dtlck); + lv = (lv_t *) & dtlck->lv[dtlck->index]; + + lv->offset = fsi; + + n = 1; + xsi = fsi; + + t = &p->slot[fsi]; + si = t->next; + + /* find the last/only segment */ + while (si < m && si >= 0) { + /* is next slot contiguous ? */ + if (si != xsi + 1) { + /* close current linelock */ + lv->length = n; + dtlck->index++; + + /* open new linelock */ + if (dtlck->index < dtlck->maxcnt) + lv++; + else { + dtlck = (dtlock_t *) txLinelock(dtlck); + lv = (lv_t *) & dtlck->lv[0]; + } + + lv->offset = si; + n = 0; + } + + n++; + xsi = si; + + t = &p->slot[si]; + si = t->next; + } + + /* close current linelock */ + lv->length = n; + dtlck->index++; + + *dtlock = dtlck; +} + + +/* + * NAME: dtModify + * + * FUNCTION: Modify the inode number part of a directory entry + * + * PARAMETERS: + * tid - Transaction id + * ip - Inode of parent directory + * key - Name of entry to be modified + * orig_ino - Original inode number expected in entry + * new_ino - New inode number to put into entry + * flag - JFS_RENAME + * + * RETURNS: + * ESTALE - If entry found does not match orig_ino passed in + * ENOENT - If no entry can be found to match key + * 0 - If successfully modified entry + */ +int dtModify(tid_t tid, struct inode *ip, + component_t * key, ino_t * orig_ino, ino_t new_ino, int flag) +{ + int rc; + s64 bn; + metapage_t *mp; + dtpage_t *p; + int index; + btstack_t btstack; + tlock_t *tlck; + dtlock_t *dtlck; + lv_t *lv; + s8 *stbl; + int entry_si; /* entry slot index */ + ldtentry_t *entry; + + /* + * search for the entry to modify: + * + * dtSearch() returns (leaf page pinned, index at which to modify). + */ + if ((rc = dtSearch(ip, key, orig_ino, &btstack, flag))) + return rc; + + /* retrieve search result */ + DT_GETSEARCH(ip, btstack.top, bn, mp, p, index); + + BT_MARK_DIRTY(mp, ip); + /* + * acquire a transaction lock on the leaf page of named entry + */ + tlck = txLock(tid, ip, mp, tlckDTREE | tlckENTRY); + dtlck = (dtlock_t *) & tlck->lock; + + /* get slot index of the entry */ + stbl = DT_GETSTBL(p); + entry_si = stbl[index]; + + /* linelock entry */ + ASSERT(dtlck->index == 0); + lv = (lv_t *) & dtlck->lv[0]; + lv->offset = entry_si; + lv->length = 1; + dtlck->index++; + + /* get the head/only segment */ + entry = (ldtentry_t *) & p->slot[entry_si]; + + /* substitute the inode number of the entry */ + entry->inumber = cpu_to_le32(new_ino); + + /* unpin the leaf page */ + DT_PUTPAGE(mp); + + return 0; +} + +#ifdef _JFS_DEBUG_DTREE +/* + * dtDisplayTree() + * + * function: traverse forward + */ +int dtDisplayTree(struct inode *ip) +{ + int rc; + metapage_t *mp; + dtpage_t *p; + s64 bn, pbn; + int index, lastindex, v, h; + pxd_t *xd; + btstack_t btstack; + btframe_t *btsp; + btframe_t *parent; + u8 *stbl; + int psize = 256; + + printk("display B+-tree.\n"); + + /* clear stack */ + btsp = btstack.stack; + + /* + * start with root + * + * root resides in the inode + */ + bn = 0; + v = h = 0; + + /* + * first access of each page: + */ + newPage: + DT_GETPAGE(ip, bn, mp, psize, p, rc); + if (rc) + return rc; + + /* process entries forward from first index */ + index = 0; + lastindex = p->header.nextindex - 1; + + if (p->header.flag & BT_INTERNAL) { + /* + * first access of each internal page + */ + printf("internal page "); + dtDisplayPage(ip, bn, p); + + goto getChild; + } else { /* (p->header.flag & BT_LEAF) */ + + /* + * first access of each leaf page + */ + printf("leaf page "); + dtDisplayPage(ip, bn, p); + + /* + * process leaf page entries + * + for ( ; index <= lastindex; index++) + { + } + */ + + /* unpin the leaf page */ + DT_PUTPAGE(mp); + } + + /* + * go back up to the parent page + */ + getParent: + /* pop/restore parent entry for the current child page */ + if ((parent = (btsp == btstack.stack ? NULL : --btsp)) == NULL) + /* current page must have been root */ + return; + + /* + * parent page scan completed + */ + if ((index = parent->index) == (lastindex = parent->lastindex)) { + /* go back up to the parent page */ + goto getParent; + } + + /* + * parent page has entries remaining + */ + /* get back the parent page */ + bn = parent->bn; + /* v = parent->level; */ + DT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) + return rc; + + /* get next parent entry */ + index++; + + /* + * internal page: go down to child page of current entry + */ + getChild: + /* push/save current parent entry for the child page */ + btsp->bn = pbn = bn; + btsp->index = index; + btsp->lastindex = lastindex; + /* btsp->level = v; */ + /* btsp->node = h; */ + ++btsp; + + /* get current entry for the child page */ + stbl = DT_GETSTBL(p); + xd = (pxd_t *) & p->slot[stbl[index]]; + + /* + * first access of each internal entry: + */ + + /* get child page */ + bn = addressPXD(xd); + psize = lengthPXD(xd) << ip->i_ipmnt->i_l2bsize; + + printk("traverse down 0x%Lx[%d]->0x%Lx\n", pbn, index, bn); + v++; + h = index; + + /* release parent page */ + DT_PUTPAGE(mp); + + /* process the child page */ + goto newPage; +} + + +/* + * dtDisplayPage() + * + * function: display page + */ +int dtDisplayPage(struct inode *ip, s64 bn, dtpage_t * p) +{ + int rc; + metapage_t *mp; + ldtentry_t *lh; + idtentry_t *ih; + pxd_t *xd; + int i, j; + u8 *stbl; + wchar_t name[JFS_NAME_MAX + 1]; + component_t key = { 0, name }; + int freepage = 0; + + if (p == NULL) { + freepage = 1; + DT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) + return rc; + } + + /* display page control */ + printk("bn:0x%Lx flag:0x%08x nextindex:%d\n", + bn, p->header.flag, p->header.nextindex); + + /* display entries */ + stbl = DT_GETSTBL(p); + for (i = 0, j = 1; i < p->header.nextindex; i++, j++) { + dtGetKey(p, i, &key, JFS_SBI(ip->i_sb)->mntflag); + key.name[key.namlen] = '\0'; + if (p->header.flag & BT_LEAF) { + lh = (ldtentry_t *) & p->slot[stbl[i]]; + printf("\t[%d] %s:%d", i, key.name, + le32_to_cpu(lh->inumber)); + } else { + ih = (idtentry_t *) & p->slot[stbl[i]]; + xd = (pxd_t *) ih; + bn = addressPXD(xd); + printf("\t[%d] %s:0x%Lx", i, key.name, bn); + } + + if (j == 4) { + printf("\n"); + j = 0; + } + } + + printf("\n"); + + if (freepage) + DT_PUTPAGE(mp); + + return 0; +} +#endif /* _JFS_DEBUG_DTREE */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_dtree.h linux.19pre5-ac1/fs/jfs/jfs_dtree.h --- linux.19p5/fs/jfs/jfs_dtree.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_dtree.h Sat Mar 9 20:15:17 2002 @@ -0,0 +1,288 @@ +/* + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + */ + +/* + * Change History : + * + */ + +#ifndef _H_JFS_DTREE +#define _H_JFS_DTREE + +/* + * jfs_dtree.h: directory B+-tree manager + */ + +#include "jfs_btree.h" + +typedef union { + struct { + tid_t tid; + struct inode *ip; + u32 ino; + } leaf; + pxd_t xd; +} ddata_t; + + +/* + * entry segment/slot + * + * an entry consists of type dependent head/only segment/slot and + * additional segments/slots linked vi next field; + * N.B. last/only segment of entry is terminated by next = -1; + */ +/* + * directory page slot + */ +typedef struct { + s8 next; /* 1: */ + s8 cnt; /* 1: */ + wchar_t name[15]; /* 30: */ +} dtslot_t; /* (32) */ + + +#define DATASLOTSIZE 16 +#define L2DATASLOTSIZE 4 +#define DTSLOTSIZE 32 +#define L2DTSLOTSIZE 5 +#define DTSLOTHDRSIZE 2 +#define DTSLOTDATASIZE 30 +#define DTSLOTDATALEN 15 + +/* + * internal node entry head/only segment + */ +typedef struct { + pxd_t xd; /* 8: child extent descriptor */ + + s8 next; /* 1: */ + u8 namlen; /* 1: */ + wchar_t name[11]; /* 22: 2-byte aligned */ +} idtentry_t; /* (32) */ + +#define DTIHDRSIZE 10 +#define DTIHDRDATALEN 11 + +/* compute number of slots for entry */ +#define NDTINTERNAL(klen) ( ((4 + (klen)) + (15 - 1)) / 15 ) + + +/* + * leaf node entry head/only segment + * + * For legacy filesystems, name contains 13 wchars -- no index field + */ +typedef struct { + u32 inumber; /* 4: 4-byte aligned */ + s8 next; /* 1: */ + u8 namlen; /* 1: */ + wchar_t name[11]; /* 22: 2-byte aligned */ + u32 index; /* 4: index into dir_table */ +} ldtentry_t; /* (32) */ + +#define DTLHDRSIZE 6 +#define DTLHDRDATALEN_LEGACY 13 /* Old (OS/2) format */ +#define DTLHDRDATALEN 11 + +/* + * dir_table used for directory traversal during readdir + */ + +/* + * Keep persistent index for directory entries + */ +#define DO_INDEX(INODE) (JFS_SBI((INODE)->i_sb)->mntflag & JFS_DIR_INDEX) + +/* + * Maximum entry in inline directory table + */ +#define MAX_INLINE_DIRTABLE_ENTRY 13 + +typedef struct dir_table_slot { + u8 rsrvd; /* 1: */ + u8 flag; /* 1: 0 if free */ + u8 slot; /* 1: slot within leaf page of entry */ + u8 addr1; /* 1: upper 8 bits of leaf page address */ + u32 addr2; /* 4: lower 32 bits of leaf page address -OR- + index of next entry when this entry was deleted */ +} dir_table_slot_t; /* (8) */ + +/* + * flag values + */ +#define DIR_INDEX_VALID 1 +#define DIR_INDEX_FREE 0 + +#define DTSaddress(dir_table_slot, address64)\ +{\ + (dir_table_slot)->addr1 = ((u64)address64) >> 32;\ + (dir_table_slot)->addr2 = __cpu_to_le32((address64) & 0xffffffff);\ +} + +#define addressDTS(dts)\ + ( ((s64)((dts)->addr1)) << 32 | __le32_to_cpu((dts)->addr2) ) + +/* compute number of slots for entry */ +#define NDTLEAF_LEGACY(klen) ( ((2 + (klen)) + (15 - 1)) / 15 ) +#define NDTLEAF NDTINTERNAL + + +/* + * directory root page (in-line in on-disk inode): + * + * cf. dtpage_t below. + */ +typedef union { + struct { + dasd_t DASD; /* 16: DASD limit/usage info F226941 */ + + u8 flag; /* 1: */ + u8 nextindex; /* 1: next free entry in stbl */ + s8 freecnt; /* 1: free count */ + s8 freelist; /* 1: freelist header */ + + u32 idotdot; /* 4: parent inode number */ + + s8 stbl[8]; /* 8: sorted entry index table */ + } header; /* (32) */ + + dtslot_t slot[9]; +} dtroot_t; + +#define PARENT(IP) \ + (le32_to_cpu(JFS_IP(IP)->i_dtroot.header.idotdot)) + +#define DTROOTMAXSLOT 9 + +#define dtEmpty(IP) (JFS_IP(IP)->i_dtroot.header.nextindex == 0) + + +/* + * directory regular page: + * + * entry slot array of 32 byte slot + * + * sorted entry slot index table (stbl): + * contiguous slots at slot specified by stblindex, + * 1-byte per entry + * 512 byte block: 16 entry tbl (1 slot) + * 1024 byte block: 32 entry tbl (1 slot) + * 2048 byte block: 64 entry tbl (2 slot) + * 4096 byte block: 128 entry tbl (4 slot) + * + * data area: + * 512 byte block: 16 - 2 = 14 slot + * 1024 byte block: 32 - 2 = 30 slot + * 2048 byte block: 64 - 3 = 61 slot + * 4096 byte block: 128 - 5 = 123 slot + * + * N.B. index is 0-based; index fields refer to slot index + * except nextindex which refers to entry index in stbl; + * end of entry stot list or freelist is marked with -1. + */ +typedef union { + struct { + s64 next; /* 8: next sibling */ + s64 prev; /* 8: previous sibling */ + + u8 flag; /* 1: */ + u8 nextindex; /* 1: next entry index in stbl */ + s8 freecnt; /* 1: */ + s8 freelist; /* 1: slot index of head of freelist */ + + u8 maxslot; /* 1: number of slots in page slot[] */ + u8 stblindex; /* 1: slot index of start of stbl */ + u8 rsrvd[2]; /* 2: */ + + pxd_t self; /* 8: self pxd */ + } header; /* (32) */ + + dtslot_t slot[128]; +} dtpage_t; + +#define DTPAGEMAXSLOT 128 + +#define DT8THPGNODEBYTES 512 +#define DT8THPGNODETSLOTS 1 +#define DT8THPGNODESLOTS 16 + +#define DTQTRPGNODEBYTES 1024 +#define DTQTRPGNODETSLOTS 1 +#define DTQTRPGNODESLOTS 32 + +#define DTHALFPGNODEBYTES 2048 +#define DTHALFPGNODETSLOTS 2 +#define DTHALFPGNODESLOTS 64 + +#define DTFULLPGNODEBYTES 4096 +#define DTFULLPGNODETSLOTS 4 +#define DTFULLPGNODESLOTS 128 + +#define DTENTRYSTART 1 + +/* get sorted entry table of the page */ +#define DT_GETSTBL(p) ( ((p)->header.flag & BT_ROOT) ?\ + ((dtroot_t *)(p))->header.stbl : \ + (s8 *)&(p)->slot[(p)->header.stblindex] ) + +/* + * Flags for dtSearch + */ +#define JFS_CREATE 1 +#define JFS_LOOKUP 2 +#define JFS_REMOVE 3 +#define JFS_RENAME 4 + +#define DIRENTSIZ(namlen) \ + ( (sizeof(struct dirent) - 2*(JFS_NAME_MAX+1) + 2*((namlen)+1) + 3) &~ 3 ) + +/* + * Maximum file offset for directories. + */ +#define DIREND INT_MAX + +/* + * external declarations + */ +extern void dtInitRoot(tid_t tid, struct inode *ip, u32 idotdot); + +extern int dtSearch(struct inode *ip, component_t * key, + ino_t * data, btstack_t * btstack, int flag); + +extern int dtInsert(tid_t tid, struct inode *ip, + component_t * key, ino_t * ino, btstack_t * btstack); + +extern int dtDelete(tid_t tid, + struct inode *ip, component_t * key, ino_t * data, int flag); + +extern int dtRelocate(tid_t tid, + struct inode *ip, s64 lmxaddr, pxd_t * opxd, s64 nxaddr); + +extern int dtModify(tid_t tid, struct inode *ip, + component_t * key, ino_t * orig_ino, ino_t new_ino, int flag); + +extern int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir); + +#ifdef _JFS_DEBUG_DTREE +extern int dtDisplayTree(struct inode *ip); + +extern int dtDisplayPage(struct inode *ip, s64 bn, dtpage_t * p); +#endif /* _JFS_DEBUG_DTREE */ + +#endif /* !_H_JFS_DTREE */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_extendfs.h linux.19pre5-ac1/fs/jfs/jfs_extendfs.h --- linux.19p5/fs/jfs/jfs_extendfs.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_extendfs.h Thu Feb 14 20:46:53 2002 @@ -0,0 +1,39 @@ +/* + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _H_JFS_EXTENDFS +#define _H_JFS_EXTENDFS + +/* + * jfs_extendfs.h + */ +/* + * extendfs parameter list + */ +typedef struct { + u32 flag; /* 4: */ + u8 dev; /* 1: */ + u8 pad[3]; /* 3: */ + s64 LVSize; /* 8: LV size in LV block */ + s64 FSSize; /* 8: FS size in LV block */ + s32 LogSize; /* 4: inlinelog size in LV block */ +} extendfs_t; /* (28) */ + +/* plist flag */ +#define EXTENDFS_QUERY 0x00000001 + +#endif /* _H_JFS_EXTENDFS */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_extent.c linux.19pre5-ac1/fs/jfs/jfs_extent.c --- linux.19p5/fs/jfs/jfs_extent.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_extent.c Thu Feb 14 20:46:53 2002 @@ -0,0 +1,637 @@ +/* + * + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + * + * + * + * Module: jfs_extent.c: + */ + +#include +#include "jfs_incore.h" +#include "jfs_dmap.h" +#include "jfs_extent.h" +#include "jfs_debug.h" + +/* + * forward references + */ +static int extBalloc(struct inode *, s64, s64 *, s64 *); +static int extBrealloc(struct inode *, s64, s64, s64 *, s64 *); +int extRecord(struct inode *, xad_t *); +static s64 extRoundDown(s64 nb); + +/* + * external references + */ +extern int dbExtend(struct inode *, s64, s64, s64); +extern int jfs_commit_inode(struct inode *, int); + + +#define DPD(a) (printk("(a): %d\n",(a))) +#define DPC(a) (printk("(a): %c\n",(a))) +#define DPL1(a) \ +{ \ + if ((a) >> 32) \ + printk("(a): %x%08x ",(a)); \ + else \ + printk("(a): %x ",(a) << 32); \ +} +#define DPL(a) \ +{ \ + if ((a) >> 32) \ + printk("(a): %x%08x\n",(a)); \ + else \ + printk("(a): %x\n",(a) << 32); \ +} + +#define DPD1(a) (printk("(a): %d ",(a))) +#define DPX(a) (printk("(a): %08x\n",(a))) +#define DPX1(a) (printk("(a): %08x ",(a))) +#define DPS(a) (printk("%s\n",(a))) +#define DPE(a) (printk("\nENTERING: %s\n",(a))) +#define DPE1(a) (printk("\nENTERING: %s",(a))) +#define DPS1(a) (printk(" %s ",(a))) + + +/* + * NAME: extAlloc() + * + * FUNCTION: allocate an extent for a specified page range within a + * file. + * + * PARAMETERS: + * ip - the inode of the file. + * xlen - requested extent length. + * pno - the starting page number with the file. + * xp - pointer to an xad. on entry, xad describes an + * extent that is used as an allocation hint if the + * xaddr of the xad is non-zero. on successful exit, + * the xad describes the newly allocated extent. + * abnr - boolean_t indicating whether the newly allocated extent + * should be marked as allocated but not recorded. + * + * RETURN VALUES: + * 0 - success + * EIO - i/o error. + * ENOSPC - insufficient disk resources. + */ +int +extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr) +{ + struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb); + s64 nxlen, nxaddr, xoff, hint, xaddr = 0; + int rc, nbperpage; + int xflag; + + /* This blocks if we are low on resources */ + txBeginAnon(ip->i_sb); + + /* validate extent length */ + if (xlen > MAXXLEN) + xlen = MAXXLEN; + + /* get the number of blocks per page */ + nbperpage = sbi->nbperpage; + + /* get the page's starting extent offset */ + xoff = pno << sbi->l2nbperpage; + + /* check if an allocation hint was provided */ + if ((hint = addressXAD(xp))) { + /* get the size of the extent described by the hint */ + nxlen = lengthXAD(xp); + + /* check if the hint is for the portion of the file + * immediately previous to the current allocation + * request and if hint extent has the same abnr + * value as the current request. if so, we can + * extend the hint extent to include the current + * extent if we can allocate the blocks immediately + * following the hint extent. + */ + if (offsetXAD(xp) + nxlen == xoff && + abnr == ((xp->flag & XAD_NOTRECORDED) ? TRUE : FALSE)) + xaddr = hint + nxlen; + + /* adjust the hint to the last block of the extent */ + hint += (nxlen - 1); + } + + /* allocate the disk blocks for the extent. initially, extBalloc() + * will try to allocate disk blocks for the requested size (xlen). + * if this fails (xlen contigious free blocks not avaliable), it'll + * try to allocate a smaller number of blocks (producing a smaller + * extent), with this smaller number of blocks consisting of the + * requested number of blocks rounded down to the next smaller + * power of 2 number (i.e. 16 -> 8). it'll continue to round down + * and retry the allocation until the number of blocks to allocate + * is smaller than the number of blocks per page. + */ + nxlen = xlen; + if ((rc = + extBalloc(ip, hint ? hint : INOHINT(ip), &nxlen, &nxaddr))) { + return (rc); + } + + /* determine the value of the extent flag */ + xflag = (abnr == TRUE) ? XAD_NOTRECORDED : 0; + + /* if we can extend the hint extent to cover the current request, + * extend it. otherwise, insert a new extent to + * cover the current request. + */ + if (xaddr && xaddr == nxaddr) + rc = xtExtend(0, ip, xoff, (int) nxlen, 0); + else + rc = xtInsert(0, ip, xflag, xoff, (int) nxlen, &nxaddr, 0); + + /* if the extend or insert failed, + * free the newly allocated blocks and return the error. + */ + if (rc) { + dbFree(ip, nxaddr, nxlen); + return (rc); + } + + /* update the number of blocks allocated to the file */ + ip->i_blocks += LBLK2PBLK(ip->i_sb, nxlen); + + /* set the results of the extent allocation */ + XADaddress(xp, nxaddr); + XADlength(xp, nxlen); + XADoffset(xp, xoff); + xp->flag = xflag; + + mark_inode_dirty(ip); + + /* + * COMMIT_SyncList flags an anonymous tlock on page that is on + * sync list. + * We need to commit the inode to get the page written disk. + */ + if (test_and_clear_cflag(COMMIT_Synclist,ip)) + jfs_commit_inode(ip, 0); + + return (0); +} + + +/* + * NAME: extRealloc() + * + * FUNCTION: extend the allocation of a file extent containing a + * partial back last page. + * + * PARAMETERS: + * ip - the inode of the file. + * cp - cbuf for the partial backed last page. + * xlen - request size of the resulting extent. + * xp - pointer to an xad. on successful exit, the xad + * describes the newly allocated extent. + * abnr - boolean_t indicating whether the newly allocated extent + * should be marked as allocated but not recorded. + * + * RETURN VALUES: + * 0 - success + * EIO - i/o error. + * ENOSPC - insufficient disk resources. + */ +int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr) +{ + struct super_block *sb = ip->i_sb; + s64 xaddr, xlen, nxaddr, delta, xoff; + s64 ntail, nextend, ninsert; + int rc, nbperpage = JFS_SBI(sb)->nbperpage; + int xflag; + + /* This blocks if we are low on resources */ + txBeginAnon(ip->i_sb); + + /* validate extent length */ + if (nxlen > MAXXLEN) + nxlen = MAXXLEN; + + /* get the extend (partial) page's disk block address and + * number of blocks. + */ + xaddr = addressXAD(xp); + xlen = lengthXAD(xp); + xoff = offsetXAD(xp); + + /* if the extend page is abnr and if the request is for + * the extent to be allocated and recorded, + * make the page allocated and recorded. + */ + if ((xp->flag & XAD_NOTRECORDED) && !abnr) { + xp->flag = 0; + if ((rc = xtUpdate(0, ip, xp))) + return (rc); + } + + /* try to allocated the request number of blocks for the + * extent. dbRealloc() first tries to satisfy the request + * by extending the allocation in place. otherwise, it will + * try to allocate a new set of blocks large enough for the + * request. in satisfying a request, dbReAlloc() may allocate + * less than what was request but will always allocate enough + * space as to satisfy the extend page. + */ + if ((rc = extBrealloc(ip, xaddr, xlen, &nxlen, &nxaddr))) + return (rc); + + delta = nxlen - xlen; + + /* check if the extend page is not abnr but the request is abnr + * and the allocated disk space is for more than one page. if this + * is the case, there is a miss match of abnr between the extend page + * and the one or more pages following the extend page. as a result, + * two extents will have to be manipulated. the first will be that + * of the extent of the extend page and will be manipulated thru + * an xtExtend() or an xtTailgate(), depending upon whether the + * disk allocation occurred as an inplace extension. the second + * extent will be manipulated (created) through an xtInsert() and + * will be for the pages following the extend page. + */ + if (abnr && (!(xp->flag & XAD_NOTRECORDED)) && (nxlen > nbperpage)) { + ntail = nbperpage; + nextend = ntail - xlen; + ninsert = nxlen - nbperpage; + + xflag = XAD_NOTRECORDED; + } else { + ntail = nxlen; + nextend = delta; + ninsert = 0; + + xflag = xp->flag; + } + + /* if we were able to extend the disk allocation in place, + * extend the extent. otherwise, move the extent to a + * new disk location. + */ + if (xaddr == nxaddr) { + /* extend the extent */ + if ((rc = xtExtend(0, ip, xoff + xlen, (int) nextend, 0))) { + dbFree(ip, xaddr + xlen, delta); + return (rc); + } + } else { + /* + * move the extent to a new location: + * + * xtTailgate() accounts for relocated tail extent; + */ + if ((rc = xtTailgate(0, ip, xoff, (int) ntail, nxaddr, 0))) { + dbFree(ip, nxaddr, nxlen); + return (rc); + } + } + + + /* check if we need to also insert a new extent */ + if (ninsert) { + /* perform the insert. if it fails, free the blocks + * to be inserted and make it appear that we only did + * the xtExtend() or xtTailgate() above. + */ + xaddr = nxaddr + ntail; + if (xtInsert (0, ip, xflag, xoff + ntail, (int) ninsert, + &xaddr, 0)) { + dbFree(ip, xaddr, (s64) ninsert); + delta = nextend; + nxlen = ntail; + xflag = 0; + } + } + + /* update the inode with the number of blocks allocated */ + ip->i_blocks += LBLK2PBLK(sb, delta); + + /* set the return results */ + XADaddress(xp, nxaddr); + XADlength(xp, nxlen); + XADoffset(xp, xoff); + xp->flag = xflag; + + mark_inode_dirty(ip); + + return (0); +} + + +/* + * NAME: extHint() + * + * FUNCTION: produce an extent allocation hint for a file offset. + * + * PARAMETERS: + * ip - the inode of the file. + * offset - file offset for which the hint is needed. + * xp - pointer to the xad that is to be filled in with + * the hint. + * + * RETURN VALUES: + * 0 - success + * EIO - i/o error. + */ +int extHint(struct inode *ip, s64 offset, xad_t * xp) +{ + struct super_block *sb = ip->i_sb; + xadlist_t xadl; + lxdlist_t lxdl; + lxd_t lxd; + s64 prev; + int rc, nbperpage = JFS_SBI(sb)->nbperpage; + + /* init the hint as "no hint provided" */ + XADaddress(xp, 0); + + /* determine the starting extent offset of the page previous + * to the page containing the offset. + */ + prev = ((offset & ~POFFSET) >> JFS_SBI(sb)->l2bsize) - nbperpage; + + /* if the offsets in the first page of the file, + * no hint provided. + */ + if (prev < 0) + return (0); + + /* prepare to lookup the previous page's extent info */ + lxdl.maxnlxd = 1; + lxdl.nlxd = 1; + lxdl.lxd = &lxd; + LXDoffset(&lxd, prev) + LXDlength(&lxd, nbperpage); + + xadl.maxnxad = 1; + xadl.nxad = 0; + xadl.xad = xp; + + /* perform the lookup */ + if ((rc = xtLookupList(ip, &lxdl, &xadl, 0))) + return (rc); + + /* check if not extent exists for the previous page. + * this is possible for sparse files. + */ + if (xadl.nxad == 0) { +// assert(ISSPARSE(ip)); + return (0); + } + + /* only preserve the abnr flag within the xad flags + * of the returned hint. + */ + xp->flag &= XAD_NOTRECORDED; + + assert(xadl.nxad == 1); + assert(lengthXAD(xp) == nbperpage); + + return (0); +} + + +/* + * NAME: extRecord() + * + * FUNCTION: change a page with a file from not recorded to recorded. + * + * PARAMETERS: + * ip - inode of the file. + * cp - cbuf of the file page. + * + * RETURN VALUES: + * 0 - success + * EIO - i/o error. + * ENOSPC - insufficient disk resources. + */ +int extRecord(struct inode *ip, xad_t * xp) +{ + int rc; + + txBeginAnon(ip->i_sb); + + /* update the extent */ + if ((rc = xtUpdate(0, ip, xp))) + return (rc); + +#ifdef _STILL_TO_PORT + /* no longer abnr */ + cp->cm_abnr = FALSE; + + /* mark the cbuf as modified */ + cp->cm_modified = TRUE; +#endif /* _STILL_TO_PORT */ + + return (0); +} + + +/* + * NAME: extFill() + * + * FUNCTION: allocate disk space for a file page that represents + * a file hole. + * + * PARAMETERS: + * ip - the inode of the file. + * cp - cbuf of the file page represent the hole. + * + * RETURN VALUES: + * 0 - success + * EIO - i/o error. + * ENOSPC - insufficient disk resources. + */ +int extFill(struct inode *ip, xad_t * xp) +{ + int rc, nbperpage = JFS_SBI(ip->i_sb)->nbperpage; + s64 blkno = offsetXAD(xp) >> ip->i_blksize; + +// assert(ISSPARSE(ip)); + + /* initialize the extent allocation hint */ + XADaddress(xp, 0); + + /* allocate an extent to fill the hole */ + if ((rc = extAlloc(ip, nbperpage, blkno, xp, FALSE))) + return (rc); + + assert(lengthPXD(xp) == nbperpage); + + return (0); +} + + +/* + * NAME: extBalloc() + * + * FUNCTION: allocate disk blocks to form an extent. + * + * initially, we will try to allocate disk blocks for the + * requested size (nblocks). if this fails (nblocks + * contigious free blocks not avaliable), we'll try to allocate + * a smaller number of blocks (producing a smaller extent), with + * this smaller number of blocks consisting of the requested + * number of blocks rounded down to the next smaller power of 2 + * number (i.e. 16 -> 8). we'll continue to round down and + * retry the allocation until the number of blocks to allocate + * is smaller than the number of blocks per page. + * + * PARAMETERS: + * ip - the inode of the file. + * hint - disk block number to be used as an allocation hint. + * *nblocks - pointer to an s64 value. on entry, this value specifies + * the desired number of block to be allocated. on successful + * exit, this value is set to the number of blocks actually + * allocated. + * blkno - pointer to a block address that is filled in on successful + * return with the starting block number of the newly + * allocated block range. + * + * RETURN VALUES: + * 0 - success + * EIO - i/o error. + * ENOSPC - insufficient disk resources. + */ +static int +extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno) +{ + s64 nb, nblks, daddr, max; + int rc, nbperpage = JFS_SBI(ip->i_sb)->nbperpage; + bmap_t *mp = JFS_SBI(ip->i_sb)->bmap; + + /* get the number of blocks to initially attempt to allocate. + * we'll first try the number of blocks requested unless this + * number is greater than the maximum number of contigious free + * blocks in the map. in that case, we'll start off with the + * maximum free. + */ + max = (s64) 1 << mp->db_maxfreebud; + if (*nblocks >= max && *nblocks > nbperpage) + nb = nblks = (max > nbperpage) ? max : nbperpage; + else + nb = nblks = *nblocks; + + /* try to allocate blocks */ + while ((rc = dbAlloc(ip, hint, nb, &daddr))) { + /* if something other than an out of space error, + * stop and return this error. + */ + if (rc != ENOSPC) + return (rc); + + /* decrease the allocation request size */ + nb = min(nblks, extRoundDown(nb)); + + /* give up if we cannot cover a page */ + if (nb < nbperpage) + return (rc); + } + + *nblocks = nb; + *blkno = daddr; + + return (0); +} + + +/* + * NAME: extBrealloc() + * + * FUNCTION: attempt to extend an extent's allocation. + * + * initially, we will try to extend the extent's allocation + * in place. if this fails, we'll try to move the extent + * to a new set of blocks. if moving the extent, we initially + * will try to allocate disk blocks for the requested size + * (nnew). if this fails (nnew contigious free blocks not + * avaliable), we'll try to allocate a smaller number of + * blocks (producing a smaller extent), with this smaller + * number of blocks consisting of the requested number of + * blocks rounded down to the next smaller power of 2 + * number (i.e. 16 -> 8). we'll continue to round down and + * retry the allocation until the number of blocks to allocate + * is smaller than the number of blocks per page. + * + * PARAMETERS: + * ip - the inode of the file. + * blkno - starting block number of the extents current allocation. + * nblks - number of blocks within the extents current allocation. + * newnblks - pointer to a s64 value. on entry, this value is the + * the new desired extent size (number of blocks). on + * successful exit, this value is set to the extent's actual + * new size (new number of blocks). + * newblkno - the starting block number of the extents new allocation. + * + * RETURN VALUES: + * 0 - success + * EIO - i/o error. + * ENOSPC - insufficient disk resources. + */ +static int +extBrealloc(struct inode *ip, + s64 blkno, s64 nblks, s64 * newnblks, s64 * newblkno) +{ + int rc; + + /* try to extend in place */ + if ((rc = dbExtend(ip, blkno, nblks, *newnblks - nblks)) == 0) { + *newblkno = blkno; + return (0); + } else { + if (rc != ENOSPC) + return (rc); + } + + /* in place extension not possible. + * try to move the extent to a new set of blocks. + */ + return (extBalloc(ip, blkno, newnblks, newblkno)); +} + + +/* + * NAME: extRoundDown() + * + * FUNCTION: round down a specified number of blocks to the next + * smallest power of 2 number. + * + * PARAMETERS: + * nb - the inode of the file. + * + * RETURN VALUES: + * next smallest power of 2 number. + */ +static s64 extRoundDown(s64 nb) +{ + int i; + u64 m, k; + + for (i = 0, m = (u64) 1 << 63; i < 64; i++, m >>= 1) { + if (m & nb) + break; + } + + i = 63 - i; + k = (u64) 1 << i; + k = ((k - 1) & nb) ? k : k >> 1; + + return (k); +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_extent.h linux.19pre5-ac1/fs/jfs/jfs_extent.h --- linux.19p5/fs/jfs/jfs_extent.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_extent.h Thu Feb 14 20:46:53 2002 @@ -0,0 +1,31 @@ +/* + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _H_JFS_EXTENT +#define _H_JFS_EXTENT + +/* get block allocation allocation hint as location of disk inode */ +#define INOHINT(ip) \ + (addressPXD(&(JFS_IP(ip)->ixpxd)) + lengthPXD(&(JFS_IP(ip)->ixpxd)) - 1) + +extern int extAlloc(struct inode *, s64, s64, xad_t *, boolean_t); +extern int extFill(struct inode *, xad_t *); +extern int extHint(struct inode *, s64, xad_t *); +extern int extRealloc(struct inode *, s64, xad_t *, boolean_t); +extern int extRecord(struct inode *, xad_t *); + +#endif /* _H_JFS_EXTENT */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_filsys.h linux.19pre5-ac1/fs/jfs/jfs_filsys.h --- linux.19p5/fs/jfs/jfs_filsys.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_filsys.h Thu Feb 14 20:46:53 2002 @@ -0,0 +1,274 @@ +/* + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#ifndef _H_JFS_FILSYS +#define _H_JFS_FILSYS + +/* + * jfs_filsys.h + * + * file system (implementation-dependent) constants + * + * refer to for system wide implementation-dependent constants + */ + +/* + * file system option (superblock flag) + */ +/* platform option (conditional compilation) */ +#define JFS_AIX 0x80000000 /* AIX support */ +/* POSIX name/directory support */ + +#define JFS_OS2 0x40000000 /* OS/2 support */ +/* case-insensitive name/directory support */ + +#define JFS_DFS 0x20000000 /* DCE DFS LFS support */ + +#define JFS_LINUX 0x10000000 /* Linux support */ +/* case-sensitive name/directory support */ + +/* directory option */ +#define JFS_UNICODE 0x00000001 /* unicode name */ + +/* commit option */ +#define JFS_COMMIT 0x00000f00 /* commit option mask */ +#define JFS_GROUPCOMMIT 0x00000100 /* group (of 1) commit */ +#define JFS_LAZYCOMMIT 0x00000200 /* lazy commit */ +#define JFS_TMPFS 0x00000400 /* temporary file system - + * do not log/commit: + */ + +/* log logical volume option */ +#define JFS_INLINELOG 0x00000800 /* inline log within file system */ +#define JFS_INLINEMOVE 0x00001000 /* inline log being moved */ + +/* Secondary aggregate inode table */ +#define JFS_BAD_SAIT 0x00010000 /* current secondary ait is bad */ + +/* sparse regular file support */ +#define JFS_SPARSE 0x00020000 /* sparse regular file */ + +/* DASD Limits F226941 */ +#define JFS_DASD_ENABLED 0x00040000 /* DASD limits enabled */ +#define JFS_DASD_PRIME 0x00080000 /* Prime DASD usage on boot */ + +/* big endian flag */ +#define JFS_SWAP_BYTES 0x00100000 /* running on big endian computer */ + +/* Directory index */ +#define JFS_DIR_INDEX 0x00200000 /* Persistant index for */ + /* directory entries */ + + +/* + * buffer cache configuration + */ +/* page size */ +#ifdef PSIZE +#undef PSIZE +#endif +#define PSIZE 4096 /* page size (in byte) */ +#define L2PSIZE 12 /* log2(PSIZE) */ +#define POFFSET 4095 /* offset within page */ + +/* buffer page size */ +#define BPSIZE PSIZE + +/* + * fs fundamental size + * + * PSIZE >= file system block size >= PBSIZE >= DISIZE + */ +#define PBSIZE 512 /* physical block size (in byte) */ +#define L2PBSIZE 9 /* log2(PBSIZE) */ + +#define DISIZE 512 /* on-disk inode size (in byte) */ +#define L2DISIZE 9 /* log2(DISIZE) */ + +#define IDATASIZE 256 /* inode inline data size */ +#define IXATTRSIZE 128 /* inode inline extended attribute size */ + +#define XTPAGE_SIZE 4096 +#define log2_PAGESIZE 12 + +#define IAG_SIZE 4096 +#define IAG_EXTENT_SIZE 4096 +#define INOSPERIAG 4096 /* number of disk inodes per iag */ +#define L2INOSPERIAG 12 /* l2 number of disk inodes per iag */ +#define INOSPEREXT 32 /* number of disk inode per extent */ +#define L2INOSPEREXT 5 /* l2 number of disk inode per extent */ +#define IXSIZE (DISIZE * INOSPEREXT) /* inode extent size */ +#define INOSPERPAGE 8 /* number of disk inodes per 4K page */ +#define L2INOSPERPAGE 3 /* log2(INOSPERPAGE) */ + +#define IAGFREELIST_LWM 64 + +#define INODE_EXTENT_SIZE IXSIZE /* inode extent size */ +#define NUM_INODE_PER_EXTENT INOSPEREXT +#define NUM_INODE_PER_IAG INOSPERIAG + +#define MINBLOCKSIZE 512 +#define MAXBLOCKSIZE 4096 +#define MAXFILESIZE ((s64)1 << 52) + +#define JFS_LINK_MAX 65535 /* nlink_t is unsigned short */ + +/* Minimum number of bytes supported for a JFS partition */ +#define MINJFS (0x1000000) +#define MINJFSTEXT "16" + +/* + * file system block size -> physical block size + */ +#define LBOFFSET(x) ((x) & (PBSIZE - 1)) +#define LBNUMBER(x) ((x) >> L2PBSIZE) +#define LBLK2PBLK(sb,b) ((b) << (sb->s_blocksize_bits - L2PBSIZE)) +#define PBLK2LBLK(sb,b) ((b) >> (sb->s_blocksize_bits - L2PBSIZE)) +/* size in byte -> last page number */ +#define SIZE2PN(size) ( ((s64)((size) - 1)) >> (L2PSIZE) ) +/* size in byte -> last file system block number */ +#define SIZE2BN(size, l2bsize) ( ((s64)((size) - 1)) >> (l2bsize) ) + +/* + * fixed physical block address (physical block size = 512 byte) + * + * NOTE: since we can't guarantee a physical block size of 512 bytes the use of + * these macros should be removed and the byte offset macros used instead. + */ +#define SUPER1_B 64 /* primary superblock */ +#define AIMAP_B (SUPER1_B + 8) /* 1st extent of aggregate inode map */ +#define AITBL_B (AIMAP_B + 16) /* + * 1st extent of aggregate inode table + */ +#define SUPER2_B (AITBL_B + 32) /* 2ndary superblock pbn */ +#define BMAP_B (SUPER2_B + 8) /* block allocation map */ + +/* + * SIZE_OF_SUPER defines the total amount of space reserved on disk for the + * superblock. This is not the same as the superblock structure, since all of + * this space is not currently being used. + */ +#define SIZE_OF_SUPER PSIZE + +/* + * SIZE_OF_AG_TABLE defines the amount of space reserved to hold the AG table + */ +#define SIZE_OF_AG_TABLE PSIZE + +/* + * SIZE_OF_MAP_PAGE defines the amount of disk space reserved for each page of + * the inode allocation map (to hold iag) + */ +#define SIZE_OF_MAP_PAGE PSIZE + +/* + * fixed byte offset address + */ +#define SUPER1_OFF 0x8000 /* primary superblock */ +#define AIMAP_OFF (SUPER1_OFF + SIZE_OF_SUPER) + /* + * Control page of aggregate inode map + * followed by 1st extent of map + */ +#define AITBL_OFF (AIMAP_OFF + (SIZE_OF_MAP_PAGE << 1)) + /* + * 1st extent of aggregate inode table + */ +#define SUPER2_OFF (AITBL_OFF + INODE_EXTENT_SIZE) + /* + * secondary superblock + */ +#define BMAP_OFF (SUPER2_OFF + SIZE_OF_SUPER) + /* + * block allocation map + */ + +/* + * The following macro is used to indicate the number of reserved disk blocks at + * the front of an aggregate, in terms of physical blocks. This value is + * currently defined to be 32K. This turns out to be the same as the primary + * superblock's address, since it directly follows the reserved blocks. + */ +#define AGGR_RSVD_BLOCKS SUPER1_B + +/* + * The following macro is used to indicate the number of reserved bytes at the + * front of an aggregate. This value is currently defined to be 32K. This + * turns out to be the same as the primary superblock's byte offset, since it + * directly follows the reserved blocks. + */ +#define AGGR_RSVD_BYTES SUPER1_OFF + +/* + * The following macro defines the byte offset for the first inode extent in + * the aggregate inode table. This allows us to find the self inode to find the + * rest of the table. Currently this value is 44K. + */ +#define AGGR_INODE_TABLE_START AITBL_OFF + +/* + * fixed reserved inode number + */ +/* aggregate inode */ +#define AGGR_RESERVED_I 0 /* aggregate inode (reserved) */ +#define AGGREGATE_I 1 /* aggregate inode map inode */ +#define BMAP_I 2 /* aggregate block allocation map inode */ +#define LOG_I 3 /* aggregate inline log inode */ +#define BADBLOCK_I 4 /* aggregate bad block inode */ +#define FILESYSTEM_I 16 /* 1st/only fileset inode in ait: + * fileset inode map inode + */ + +/* per fileset inode */ +#define FILESET_RSVD_I 0 /* fileset inode (reserved) */ +#define FILESET_EXT_I 1 /* fileset inode extension */ +#define ROOT_I 2 /* fileset root inode */ +#define ACL_I 3 /* fileset ACL inode */ + +#define FILESET_OBJECT_I 4 /* the first fileset inode available for a file + * or directory or link... + */ +#define FIRST_FILESET_INO 16 /* the first aggregate inode which describes + * an inode. (To fsck this is also the first + * inode in part 2 of the agg inode table.) + */ + +/* + * directory configuration + */ +#define JFS_NAME_MAX 255 +#define JFS_PATH_MAX BPSIZE + + +/* + * file system state (superblock state) + */ +#define FM_CLEAN 0x00000000 /* file system is unmounted and clean */ +#define FM_MOUNT 0x00000001 /* file system is mounted cleanly */ +#define FM_DIRTY 0x00000002 /* file system was not unmounted and clean + * when mounted or + * commit failure occurred while being mounted: + * fsck() must be run to repair + */ +#define FM_LOGREDO 0x00000004 /* log based recovery (logredo()) failed: + * fsck() must be run to repair + */ +#define FM_EXTENDFS 0x00000008 /* file system extendfs() in progress */ + +#endif /* _H_JFS_FILSYS */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_imap.c linux.19pre5-ac1/fs/jfs/jfs_imap.c --- linux.19p5/fs/jfs/jfs_imap.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_imap.c Thu Mar 14 22:44:22 2002 @@ -0,0 +1,3236 @@ +/* + + * + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + * + */ + +/* + * Change History : + * + */ + +/* + * jfs_imap.c: inode allocation map manager + * + * Serialization: + * Each AG has a simple lock which is used to control the serialization of + * the AG level lists. This lock should be taken first whenever an AG + * level list will be modified or accessed. + * + * Each IAG is locked by obtaining the buffer for the IAG page. + * + * There is also a inode lock for the inode map inode. A read lock needs to + * be taken whenever an IAG is read from the map or the global level + * information is read. A write lock needs to be taken whenever the global + * level information is modified or an atomic operation needs to be used. + * + * If more than one IAG is read at one time, the read lock may not + * be given up until all of the IAG's are read. Otherwise, a deadlock + * may occur when trying to obtain the read lock while another thread + * holding the read lock is waiting on the IAG already being held. + * + * The control page of the inode map is read into memory by diMount(). + * Thereafter it should only be modified in memory and then it will be + * written out when the filesystem is unmounted by diUnmount(). + */ + +#include +#include +#include "jfs_incore.h" +#include "jfs_filsys.h" +#include "jfs_dinode.h" +#include "jfs_dmap.h" +#include "jfs_imap.h" +#include "jfs_metapage.h" +#include "jfs_superblock.h" +#include "jfs_debug.h" + +/* + * imap locks + */ +/* iag free list lock */ +#define IAGFREE_LOCK_INIT(imap) init_MUTEX(&imap->im_freelock) +#define IAGFREE_LOCK(imap) down(&imap->im_freelock) +#define IAGFREE_UNLOCK(imap) up(&imap->im_freelock) + +/* per ag iag list locks */ +#define AG_LOCK_INIT(imap,index) init_MUTEX(&(imap->im_aglock[index])) +#define AG_LOCK(imap,agno) down(&imap->im_aglock[agno]) +#define AG_UNLOCK(imap,agno) up(&imap->im_aglock[agno]) + +/* + * external references + */ +extern struct address_space_operations jfs_aops; + +/* + * forward references + */ +static int diAllocAG(imap_t *, int, boolean_t, struct inode *); +static int diAllocAny(imap_t *, int, boolean_t, struct inode *); +static int diAllocBit(imap_t *, iag_t *, int); +static int diAllocExt(imap_t *, int, struct inode *); +static int diAllocIno(imap_t *, int, struct inode *); +static int diFindFree(u32, int); +static int diNewExt(imap_t *, iag_t *, int); +static int diNewIAG(imap_t *, int *, int, metapage_t **); +static void duplicateIXtree(struct super_block *, s64, int, s64 *); + +static int diIAGRead(imap_t * imap, int, metapage_t **); +static int copy_from_dinode(dinode_t *, struct inode *); +static void copy_to_dinode(dinode_t *, struct inode *); + +/* + * debug code for double-checking inode map + */ +/* #define _JFS_DEBUG_IMAP 1 */ + +#ifdef _JFS_DEBUG_IMAP +#define DBG_DIINIT(imap) DBGdiInit(imap) +#define DBG_DIALLOC(imap, ino) DBGdiAlloc(imap, ino) +#define DBG_DIFREE(imap, ino) DBGdiFree(imap, ino) + +static void *DBGdiInit(imap_t * imap); +static void DBGdiAlloc(imap_t * imap, ino_t ino); +static void DBGdiFree(imap_t * imap, ino_t ino); +#else +#define DBG_DIINIT(imap) +#define DBG_DIALLOC(imap, ino) +#define DBG_DIFREE(imap, ino) +#endif /* _JFS_DEBUG_IMAP */ + +/* + * NAME: diMount() + * + * FUNCTION: initialize the incore inode map control structures for + * a fileset or aggregate init time. + * + * the inode map's control structure (dinomap_t) is + * brought in from disk and placed in virtual memory. + * + * PARAMETERS: + * ipimap - pointer to inode map inode for the aggregate or fileset. + * + * RETURN VALUES: + * 0 - success + * ENOMEM - insufficient free virtual memory. + * EIO - i/o error. + */ +int diMount(struct inode *ipimap) +{ + imap_t *imap; + metapage_t *mp; + int index; + dinomap_t *dinom_le; + + /* + * allocate/initialize the in-memory inode map control structure + */ + /* allocate the in-memory inode map control structure. */ + imap = (imap_t *) kmalloc(sizeof(imap_t), GFP_KERNEL); + if (imap == NULL) { + jERROR(1, ("diMount: kmalloc returned NULL!\n")); + return (ENOMEM); + } + + /* read the on-disk inode map control structure. */ + + mp = read_metapage(ipimap, + IMAPBLKNO << JFS_SBI(ipimap->i_sb)->l2nbperpage, + PSIZE, 0); + if (mp == NULL) { + kfree(imap); + return (EIO); + } + + /* copy the on-disk version to the in-memory version. */ + dinom_le = (dinomap_t *) mp->data; + imap->im_freeiag = le32_to_cpu(dinom_le->in_freeiag); + imap->im_nextiag = le32_to_cpu(dinom_le->in_nextiag); + atomic_set(&imap->im_numinos, le32_to_cpu(dinom_le->in_numinos)); + atomic_set(&imap->im_numfree, le32_to_cpu(dinom_le->in_numfree)); + imap->im_nbperiext = le32_to_cpu(dinom_le->in_nbperiext); + imap->im_l2nbperiext = le32_to_cpu(dinom_le->in_l2nbperiext); + for (index = 0; index < MAXAG; index++) { + imap->im_agctl[index].inofree = + le32_to_cpu(dinom_le->in_agctl[index].inofree); + imap->im_agctl[index].extfree = + le32_to_cpu(dinom_le->in_agctl[index].extfree); + imap->im_agctl[index].numinos = + le32_to_cpu(dinom_le->in_agctl[index].numinos); + imap->im_agctl[index].numfree = + le32_to_cpu(dinom_le->in_agctl[index].numfree); + } + + /* release the buffer. */ + release_metapage(mp); + + /* + * allocate/initialize inode allocation map locks + */ + /* allocate and init iag free list lock */ + IAGFREE_LOCK_INIT(imap); + + /* allocate and init ag list locks */ + for (index = 0; index < MAXAG; index++) { + AG_LOCK_INIT(imap, index); + } + + /* bind the inode map inode and inode map control structure + * to each other. + */ + imap->im_ipimap = ipimap; + JFS_IP(ipimap)->i_imap = imap; + +// DBG_DIINIT(imap); + + return (0); +} + + +/* + * NAME: diUnmount() + * + * FUNCTION: write to disk the incore inode map control structures for + * a fileset or aggregate at unmount time. + * + * PARAMETERS: + * ipimap - pointer to inode map inode for the aggregate or fileset. + * + * RETURN VALUES: + * 0 - success + * ENOMEM - insufficient free virtual memory. + * EIO - i/o error. + */ +int diUnmount(struct inode *ipimap, int mounterror) +{ + imap_t *imap = JFS_IP(ipimap)->i_imap; + + /* + * update the on-disk inode map control structure + */ + + if (!(mounterror || isReadOnly(ipimap))) + diSync(ipimap); + + /* + * Invalidate the page cache buffers + */ + truncate_inode_pages(ipimap->i_mapping, 0); + + /* + * free in-memory control structure + */ + kfree(imap); + + return (0); +} + + +/* + * diSync() + */ +int diSync(struct inode *ipimap) +{ + dinomap_t *dinom_le; + imap_t *imp = JFS_IP(ipimap)->i_imap; + metapage_t *mp; + int index; + + /* + * write imap global conrol page + */ + /* read the on-disk inode map control structure */ + mp = get_metapage(ipimap, + IMAPBLKNO << JFS_SBI(ipimap->i_sb)->l2nbperpage, + PSIZE, 0); + if (mp == NULL) { + jERROR(1,("diSync: get_metapage failed!\n")); + return EIO; + } + + /* copy the in-memory version to the on-disk version */ + //memcpy(mp->data, &imp->im_imap,sizeof(dinomap_t)); + dinom_le = (dinomap_t *) mp->data; + dinom_le->in_freeiag = cpu_to_le32(imp->im_freeiag); + dinom_le->in_nextiag = cpu_to_le32(imp->im_nextiag); + dinom_le->in_numinos = cpu_to_le32(atomic_read(&imp->im_numinos)); + dinom_le->in_numfree = cpu_to_le32(atomic_read(&imp->im_numfree)); + dinom_le->in_nbperiext = cpu_to_le32(imp->im_nbperiext); + dinom_le->in_l2nbperiext = cpu_to_le32(imp->im_l2nbperiext); + for (index = 0; index < MAXAG; index++) { + dinom_le->in_agctl[index].inofree = + cpu_to_le32(imp->im_agctl[index].inofree); + dinom_le->in_agctl[index].extfree = + cpu_to_le32(imp->im_agctl[index].extfree); + dinom_le->in_agctl[index].numinos = + cpu_to_le32(imp->im_agctl[index].numinos); + dinom_le->in_agctl[index].numfree = + cpu_to_le32(imp->im_agctl[index].numfree); + } + + /* write out the control structure */ + write_metapage(mp); + + /* + * write out dirty pages of imap + */ + fsync_inode_data_buffers(ipimap); + + diWriteSpecial(ipimap); + + return (0); +} + + +/* + * NAME: diRead() + * + * FUNCTION: initialize an incore inode from disk. + * + * on entry, the specifed incore inode should itself + * specify the disk inode number corresponding to the + * incore inode (i.e. i_number should be initialized). + * + * this routine handles incore inode initialization for + * both "special" and "regular" inodes. special inodes + * are those required early in the mount process and + * require special handling since much of the file system + * is not yet initialized. these "special" inodes are + * identified by a NULL inode map inode pointer and are + * actually initialized by a call to diReadSpecial(). + * + * for regular inodes, the iag describing the disk inode + * is read from disk to determine the inode extent address + * for the disk inode. with the inode extent address in + * hand, the page of the extent that contains the disk + * inode is read and the disk inode is copied to the + * incore inode. + * + * PARAMETERS: + * ip - pointer to incore inode to be initialized from disk. + * + * RETURN VALUES: + * 0 - success + * EIO - i/o error. + * ENOMEM - insufficient memory + * + */ +int diRead(struct inode *ip) +{ + struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb); + int iagno, ino, extno, rc; + struct inode *ipimap; + dinode_t *dp; + iag_t *iagp; + metapage_t *mp; + s64 blkno, agstart; + imap_t *imap; + int block_offset; + int inodes_left; + uint pageno; + int rel_inode; + + jFYI(1, ("diRead: ino = %ld\n", ip->i_ino)); + + ipimap = sbi->ipimap; + JFS_IP(ip)->ipimap = ipimap; + + /* determine the iag number for this inode (number) */ + iagno = INOTOIAG(ip->i_ino); + + /* read the iag */ + imap = JFS_IP(ipimap)->i_imap; + IREAD_LOCK(ipimap); + rc = diIAGRead(imap, iagno, &mp); + IREAD_UNLOCK(ipimap); + if (rc) { + jERROR(1, ("diRead: diIAGRead returned %d\n", rc)); + return (rc); + } + + iagp = (iag_t *) mp->data; + + /* determine inode extent that holds the disk inode */ + ino = ip->i_ino & (INOSPERIAG - 1); + extno = ino >> L2INOSPEREXT; + + if ((lengthPXD(&iagp->inoext[extno]) != imap->im_nbperiext) || + (addressPXD(&iagp->inoext[extno]) == 0)) { + jERROR(1, ("diRead: Bad inoext: 0x%lx, 0x%lx\n", + (ulong) addressPXD(&iagp->inoext[extno]), + (ulong) lengthPXD(&iagp->inoext[extno]))); + release_metapage(mp); + updateSuper(ip->i_sb, FM_DIRTY); + return ESTALE; + } + + /* get disk block number of the page within the inode extent + * that holds the disk inode. + */ + blkno = INOPBLK(&iagp->inoext[extno], ino, sbi->l2nbperpage); + + /* get the ag for the iag */ + agstart = le64_to_cpu(iagp->agstart); + + release_metapage(mp); + + rel_inode = (ino & (INOSPERPAGE - 1)); + pageno = blkno >> sbi->l2nbperpage; + + if ((block_offset = ((u32) blkno & (sbi->nbperpage - 1)))) { + /* + * OS/2 didn't always align inode extents on page boundaries + */ + inodes_left = + (sbi->nbperpage - block_offset) << sbi->l2niperblk; + + if (rel_inode < inodes_left) + rel_inode += block_offset << sbi->l2niperblk; + else { + pageno += 1; + rel_inode -= inodes_left; + } + } + + /* read the page of disk inode */ + mp = read_metapage(ipimap, pageno << sbi->l2nbperpage, PSIZE, 1); + if (mp == 0) { + jERROR(1, ("diRead: read_metapage failed\n")); + return EIO; + } + + /* locate the the disk inode requested */ + dp = (dinode_t *) mp->data; + dp += rel_inode; + + if (ip->i_ino != le32_to_cpu(dp->di_number)) { + jERROR(1, ("diRead: i_ino != di_number\n")); + updateSuper(ip->i_sb, FM_DIRTY); + rc = EIO; + } else if (le32_to_cpu(dp->di_nlink) == 0) { + jERROR(1, + ("diRead: di_nlink is zero. ino=%ld\n", ip->i_ino)); + updateSuper(ip->i_sb, FM_DIRTY); + rc = ESTALE; + } else + /* copy the disk inode to the in-memory inode */ + rc = copy_from_dinode(dp, ip); + + release_metapage(mp); + + /* set the ag for the inode */ + JFS_IP(ip)->agno = BLKTOAG(agstart, sbi); + + return (rc); +} + + +/* + * NAME: diReadSpecial() + * + * FUNCTION: initialize a 'special' inode from disk. + * + * this routines handles aggregate level inodes. The + * inode cache cannot differentiate between the + * aggregate inodes and the filesystem inodes, so we + * handle these here. We don't actually use the aggregate + * inode map, since these inodes are at a fixed location + * and in some cases the aggregate inode map isn't initialized + * yet. + * + * PARAMETERS: + * sb - filesystem superblock + * inum - aggregate inode number + * + * RETURN VALUES: + * new inode - success + * NULL - i/o error. + */ +struct inode *diReadSpecial(struct super_block *sb, ino_t inum) +{ + struct jfs_sb_info *sbi = JFS_SBI(sb); + uint address; + dinode_t *dp; + struct inode *ip; + metapage_t *mp; + int rc; + + ip = new_inode(sb); + if (ip == NULL) { + jERROR(1, + ("diReadSpecial: new_inode returned NULL!\n")); + return ip; + } + + rc = alloc_jfs_inode(ip); + if (rc) { + make_bad_inode(ip); + iput(ip); + return NULL; + } + + /* + * If ip->i_number >= 32 (INOSPEREXT), then read from secondary + * aggregate inode table. + */ + + if (inum >= INOSPEREXT) { + address = + addressPXD(&sbi->ait2) >> sbi->l2nbperpage; + inum -= INOSPEREXT; + ASSERT(inum < INOSPEREXT); + JFS_IP(ip)->ipimap = sbi->ipaimap2; + } else { + address = AITBL_OFF >> L2PSIZE; + JFS_IP(ip)->ipimap = sbi->ipaimap; + } + ip->i_ino = inum; + + address += inum >> 3; /* 8 inodes per 4K page */ + + /* read the page of fixed disk inode (AIT) in raw mode */ + jEVENT(0, + ("Reading aggregate inode %d from block %d\n", (uint) inum, + address)); + mp = read_metapage(ip, address << sbi->l2nbperpage, PSIZE, 1); + if (mp == NULL) { + ip->i_sb = NULL; + ip->i_nlink = 1; /* Don't want iput() deleting it */ + iput(ip); + return (NULL); + } + + /* get the pointer to the disk inode of interest */ + dp = (dinode_t *) (mp->data); + dp += inum % 8; /* 8 inodes per 4K page */ + + /* copy on-disk inode to in-memory inode */ + if ((copy_from_dinode(dp, ip)) != 0) { + /* handle bad return by returning NULL for ip */ + ip->i_sb = NULL; + ip->i_nlink = 1; /* Don't want iput() deleting it */ + iput(ip); + /* release the page */ + release_metapage(mp); + return (NULL); + + } + + ip->i_mapping->a_ops = &jfs_aops; + ip->i_mapping->gfp_mask = GFP_NOFS; + + if ((inum == FILESYSTEM_I) && (JFS_IP(ip)->ipimap == sbi->ipaimap)) { + sbi->gengen = le32_to_cpu(dp->di_gengen); + sbi->inostamp = le32_to_cpu(dp->di_inostamp); + } + + /* release the page */ + release_metapage(mp); + + return (ip); +} + +/* + * NAME: diWriteSpecial() + * + * FUNCTION: Write the special inode to disk + * + * PARAMETERS: + * ip - special inode + * + * RETURN VALUES: none + */ + +void diWriteSpecial(struct inode *ip) +{ + struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb); + uint address; + dinode_t *dp; + ino_t inum = ip->i_ino; + metapage_t *mp; + + /* + * If ip->i_number >= 32 (INOSPEREXT), then write to secondary + * aggregate inode table. + */ + + if (!(ip->i_state & I_DIRTY)) + return; + + ip->i_state &= ~I_DIRTY; + + if (inum >= INOSPEREXT) { + address = + addressPXD(&sbi->ait2) >> sbi->l2nbperpage; + inum -= INOSPEREXT; + ASSERT(inum < INOSPEREXT); + } else { + address = AITBL_OFF >> L2PSIZE; + } + + address += inum >> 3; /* 8 inodes per 4K page */ + + /* read the page of fixed disk inode (AIT) in raw mode */ + jEVENT(0, + ("Reading aggregate inode %d from block %d\n", (uint) inum, + address)); + mp = read_metapage(ip, address << sbi->l2nbperpage, PSIZE, 1); + if (mp == NULL) { + jERROR(1, + ("diWriteSpecial: failed to read aggregate inode extent!\n")); + return; + } + + /* get the pointer to the disk inode of interest */ + dp = (dinode_t *) (mp->data); + dp += inum % 8; /* 8 inodes per 4K page */ + + /* copy on-disk inode to in-memory inode */ + copy_to_dinode(dp, ip); + memcpy(&dp->di_xtroot, &JFS_IP(ip)->i_xtroot, 288); + + if (inum == FILESYSTEM_I) + dp->di_gengen = cpu_to_le32(sbi->gengen); + + /* write the page */ + write_metapage(mp); +} + +/* + * NAME: diFreeSpecial() + * + * FUNCTION: Free allocated space for special inode + */ +void diFreeSpecial(struct inode *ip) +{ + if (ip == NULL) { + jERROR(1, ("diFreeSpecial called with NULL ip!\n")); + return; + } + fsync_inode_data_buffers(ip); + truncate_inode_pages(ip->i_mapping, 0); + iput(ip); +} + + + +/* + * NAME: diWrite() + * + * FUNCTION: write the on-disk inode portion of the in-memory inode + * to its corresponding on-disk inode. + * + * on entry, the specifed incore inode should itself + * specify the disk inode number corresponding to the + * incore inode (i.e. i_number should be initialized). + * + * the inode contains the inode extent address for the disk + * inode. with the inode extent address in hand, the + * page of the extent that contains the disk inode is + * read and the disk inode portion of the incore inode + * is copied to the disk inode. + * + * PARAMETERS: + * tid - transacation id + * ip - pointer to incore inode to be written to the inode extent. + * + * RETURN VALUES: + * 0 - success + * EIO - i/o error. + */ +int diWrite(tid_t tid, struct inode *ip) +{ + struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb); + struct jfs_inode_info *jfs_ip = JFS_IP(ip); + int rc = 0; + s32 ino; + dinode_t *dp; + s64 blkno; + int block_offset; + int inodes_left; + metapage_t *mp; + uint pageno; + int rel_inode; + int dioffset; + struct inode *ipimap; + uint type; + lid_t lid; + tlock_t *ditlck, *tlck; + linelock_t *dilinelock, *ilinelock; + lv_t *lv; + int n; + + ipimap = jfs_ip->ipimap; + + ino = ip->i_ino & (INOSPERIAG - 1); + + assert(lengthPXD(&(jfs_ip->ixpxd)) == + JFS_IP(ipimap)->i_imap->im_nbperiext); + assert(addressPXD(&(jfs_ip->ixpxd))); + + /* + * read the page of disk inode containing the specified inode: + */ + /* compute the block address of the page */ + blkno = INOPBLK(&(jfs_ip->ixpxd), ino, sbi->l2nbperpage); + + rel_inode = (ino & (INOSPERPAGE - 1)); + pageno = blkno >> sbi->l2nbperpage; + + if ((block_offset = ((u32) blkno & (sbi->nbperpage - 1)))) { + /* + * OS/2 didn't always align inode extents on page boundaries + */ + inodes_left = + (sbi->nbperpage - block_offset) << sbi->l2niperblk; + + if (rel_inode < inodes_left) + rel_inode += block_offset << sbi->l2niperblk; + else { + pageno += 1; + rel_inode -= inodes_left; + } + } + /* read the page of disk inode */ + retry: + mp = read_metapage(ipimap, pageno << sbi->l2nbperpage, PSIZE, 1); + if (mp == 0) + return (EIO); + + /* get the pointer to the disk inode */ + dp = (dinode_t *) mp->data; + dp += rel_inode; + + dioffset = (ino & (INOSPERPAGE - 1)) << L2DISIZE; + + /* + * acquire transaction lock on the on-disk inode; + * N.B. tlock is acquired on ipimap not ip; + */ + if ((ditlck = + txLock(tid, ipimap, mp, tlckINODE | tlckENTRY)) == NULL) + goto retry; + dilinelock = (linelock_t *) & ditlck->lock; + + /* + * copy btree root from in-memory inode to on-disk inode + * + * (tlock is taken from inline B+-tree root in in-memory + * inode when the B+-tree root is updated, which is pointed + * by jfs_ip->blid as well as being on tx tlock list) + * + * further processing of btree root is based on the copy + * in in-memory inode, where txLog() will log from, and, + * for xtree root, txUpdateMap() will update map and reset + * XAD_NEW bit; + */ + + if (S_ISDIR(ip->i_mode) && (lid = jfs_ip->xtlid)) { + /* + * This is the special xtree inside the directory for storing + * the directory table + */ + xtpage_t *p, *xp; + xad_t *xad; + + jfs_ip->xtlid = 0; + tlck = lid_to_tlock(lid); + assert(tlck->type & tlckXTREE); + tlck->type |= tlckBTROOT; + tlck->mp = mp; + ilinelock = (linelock_t *) & tlck->lock; + + /* + * copy xtree root from inode to dinode: + */ + p = &jfs_ip->i_xtroot; + xp = (xtpage_t *) &dp->di_dirtable; + lv = (lv_t *) & ilinelock->lv; + for (n = 0; n < ilinelock->index; n++, lv++) { + memcpy(&xp->xad[lv->offset], &p->xad[lv->offset], + lv->length << L2XTSLOTSIZE); + } + + /* reset on-disk (metadata page) xtree XAD_NEW bit */ + xad = &xp->xad[XTENTRYSTART]; + for (n = XTENTRYSTART; + n < le16_to_cpu(xp->header.nextindex); n++, xad++) + if (xad->flag & (XAD_NEW | XAD_EXTENDED)) + xad->flag &= ~(XAD_NEW | XAD_EXTENDED); + } + + if ((lid = jfs_ip->blid) == 0) + goto inlineData; + jfs_ip->blid = 0; + + tlck = lid_to_tlock(lid); + type = tlck->type; + tlck->type |= tlckBTROOT; + tlck->mp = mp; + ilinelock = (linelock_t *) & tlck->lock; + + /* + * regular file: 16 byte (XAD slot) granularity + */ + if (type & tlckXTREE) { + xtpage_t *p, *xp; + xad_t *xad; + + /* + * copy xtree root from inode to dinode: + */ + p = &jfs_ip->i_xtroot; + xp = &dp->di_xtroot; + lv = (lv_t *) & ilinelock->lv; + for (n = 0; n < ilinelock->index; n++, lv++) { + memcpy(&xp->xad[lv->offset], &p->xad[lv->offset], + lv->length << L2XTSLOTSIZE); + } + + /* reset on-disk (metadata page) xtree XAD_NEW bit */ + xad = &xp->xad[XTENTRYSTART]; + for (n = XTENTRYSTART; + n < le16_to_cpu(xp->header.nextindex); n++, xad++) + if (xad->flag & (XAD_NEW | XAD_EXTENDED)) + xad->flag &= ~(XAD_NEW | XAD_EXTENDED); + } + /* + * directory: 32 byte (directory entry slot) granularity + */ + else if (type & tlckDTREE) { + dtpage_t *p, *xp; + + /* + * copy dtree root from inode to dinode: + */ + p = (dtpage_t *) &jfs_ip->i_dtroot; + xp = (dtpage_t *) & dp->di_dtroot; + lv = (lv_t *) & ilinelock->lv; + for (n = 0; n < ilinelock->index; n++, lv++) { + memcpy(&xp->slot[lv->offset], &p->slot[lv->offset], + lv->length << L2DTSLOTSIZE); + } + } else { + jERROR(1, ("diWrite: UFO tlock\n")); + } + + inlineData: + /* + * copy inline symlink from in-memory inode to on-disk inode + */ + if (S_ISLNK(ip->i_mode) && ip->i_size < IDATASIZE) { + lv = (lv_t *) & dilinelock->lv[dilinelock->index]; + lv->offset = (dioffset + 2 * 128) >> L2INODESLOTSIZE; + lv->length = 2; + memcpy(&dp->di_fastsymlink, jfs_ip->i_inline, IDATASIZE); + dilinelock->index++; + } +#ifdef _STILL_TO_PORT + /* + * copy inline data from in-memory inode to on-disk inode: + * 128 byte slot granularity + */ + if (test_cflag(COMMIT_Inlineea, ip)) + lv = (lv_t *) & dilinelock->lv[dilinelock->index]; + lv->offset = (dioffset + 3 * 128) >> L2INODESLOTSIZE; + lv->length = 1; + memcpy(&dp->di_inlineea, &ip->i_inlineea, INODESLOTSIZE); + dilinelock->index++; + + clear_cflag(COMMIT_Inlineea, ip); + } +#endif /* _STILL_TO_PORT */ + + /* + * lock/copy inode base: 128 byte slot granularity + */ +// baseDinode: + lv = (lv_t *) & dilinelock->lv[dilinelock->index]; + lv->offset = dioffset >> L2INODESLOTSIZE; + copy_to_dinode(dp, ip); + if (test_and_clear_cflag(COMMIT_Dirtable, ip)) { + lv->length = 2; + memcpy(&dp->di_dirtable, &jfs_ip->i_dirtable, 96); + } else + lv->length = 1; + dilinelock->index++; + +#ifdef _JFS_FASTDASD + /* + * We aren't logging changes to the DASD used in directory inodes, + * but we need to write them to disk. If we don't unmount cleanly, + * mount will recalculate the DASD used. + */ + if (S_ISDIR(ip->i_mode) + && (ip->i_ipmnt->i_mntflag & JFS_DASD_ENABLED)) + bcopy(&ip->i_DASD, &dp->di_DASD, sizeof(dasd_t)); +#endif /* _JFS_FASTDASD */ + + /* release the buffer holding the updated on-disk inode. + * the buffer will be later written by commit processing. + */ + write_metapage(mp); + + return (rc); +} + + +/* + * NAME: diFree(ip) + * + * FUNCTION: free a specified inode from the inode working map + * for a fileset or aggregate. + * + * if the inode to be freed represents the first (only) + * free inode within the iag, the iag will be placed on + * the ag free inode list. + * + * freeing the inode will cause the inode extent to be + * freed if the inode is the only allocated inode within + * the extent. in this case all the disk resource backing + * up the inode extent will be freed. in addition, the iag + * will be placed on the ag extent free list if the extent + * is the first free extent in the iag. if freeing the + * extent also means that no free inodes will exist for + * the iag, the iag will also be removed from the ag free + * inode list. + * + * the iag describing the inode will be freed if the extent + * is to be freed and it is the only backed extent within + * the iag. in this case, the iag will be removed from the + * ag free extent list and ag free inode list and placed on + * the inode map's free iag list. + * + * a careful update approach is used to provide consistency + * in the face of updates to multiple buffers. under this + * approach, all required buffers are obtained before making + * any updates and are held until all updates are complete. + * + * PARAMETERS: + * ip - inode to be freed. + * + * RETURN VALUES: + * 0 - success + * EIO - i/o error. + */ +int diFree(struct inode *ip) +{ + int rc; + ino_t inum = ip->i_ino; + iag_t *iagp, *aiagp, *biagp, *ciagp, *diagp; + metapage_t *mp, *amp, *bmp, *cmp, *dmp; + int iagno, ino, extno, bitno, sword, agno; + int back, fwd; + u32 bitmap, mask; + struct inode *ipimap = JFS_SBI(ip->i_sb)->ipimap; + imap_t *imap = JFS_IP(ipimap)->i_imap; + s64 xaddr; + s64 xlen; + pxd_t freepxd; + tid_t tid; + struct inode *iplist[3]; + tlock_t *tlck; + pxdlock_t *pxdlock; + + /* + * This is just to suppress compiler warnings. The same logic that + * references these variables is used to initialize them. + */ + aiagp = biagp = ciagp = diagp = NULL; + + /* get the iag number containing the inode. + */ + iagno = INOTOIAG(inum); + + /* make sure that the iag is contained within + * the map. + */ + //assert(iagno < imap->im_nextiag); + if (iagno >= imap->im_nextiag) { + jERROR(1, ("diFree: inum = %d, iagno = %d, nextiag = %d\n", + (uint) inum, iagno, imap->im_nextiag)); + dump_mem("imap", imap, 32); + updateSuper(ip->i_sb, FM_DIRTY); + return EIO; + } + + /* get the allocation group for this ino. + */ + agno = JFS_IP(ip)->agno; + + /* Lock the AG specific inode map information + */ + AG_LOCK(imap, agno); + + /* Obtain read lock in imap inode. Don't release it until we have + * read all of the IAG's that we are going to. + */ + IREAD_LOCK(ipimap); + + /* read the iag. + */ + if ((rc = diIAGRead(imap, iagno, &mp))) { + IREAD_UNLOCK(ipimap); + AG_UNLOCK(imap, agno); + return (rc); + } + iagp = (iag_t *) mp->data; + + /* get the inode number and extent number of the inode within + * the iag and the inode number within the extent. + */ + ino = inum & (INOSPERIAG - 1); + extno = ino >> L2INOSPEREXT; + bitno = ino & (INOSPEREXT - 1); + mask = HIGHORDER >> bitno; + + assert(le32_to_cpu(iagp->wmap[extno]) & mask); +#ifdef _STILL_TO_PORT + assert((le32_to_cpu(iagp->pmap[extno]) & mask) == 0); +#endif /* _STILL_TO_PORT */ + assert(addressPXD(&iagp->inoext[extno])); + + /* compute the bitmap for the extent reflecting the freed inode. + */ + bitmap = le32_to_cpu(iagp->wmap[extno]) & ~mask; + + if (imap->im_agctl[agno].numfree > imap->im_agctl[agno].numinos) { + jERROR(1,("diFree: numfree > numinos\n")); + release_metapage(mp); + IREAD_UNLOCK(ipimap); + AG_UNLOCK(imap, agno); + updateSuper(ip->i_sb, FM_DIRTY); + return EIO; + } + /* + * inode extent still has some inodes or below low water mark: + * keep the inode extent; + */ + if (bitmap || + imap->im_agctl[agno].numfree < 96 || + (imap->im_agctl[agno].numfree < 288 && + (((imap->im_agctl[agno].numfree * 100) / + imap->im_agctl[agno].numinos) <= 25))) { + /* if the iag currently has no free inodes (i.e., + * the inode being freed is the first free inode of iag), + * insert the iag at head of the inode free list for the ag. + */ + if (iagp->nfreeinos == 0) { + /* check if there are any iags on the ag inode + * free list. if so, read the first one so that + * we can link the current iag onto the list at + * the head. + */ + if ((fwd = imap->im_agctl[agno].inofree) >= 0) { + /* read the iag that currently is the head + * of the list. + */ + if ((rc = diIAGRead(imap, fwd, &))) { + IREAD_UNLOCK(ipimap); + AG_UNLOCK(imap, agno); + release_metapage(mp); + return (rc); + } + aiagp = (iag_t *) amp->data; + + /* make current head point back to the iag. + */ + aiagp->inofreeback = cpu_to_le32(iagno); + + write_metapage(amp); + } + + /* iag points forward to current head and iag + * becomes the new head of the list. + */ + iagp->inofreefwd = + cpu_to_le32(imap->im_agctl[agno].inofree); + iagp->inofreeback = -1; + imap->im_agctl[agno].inofree = iagno; + } + IREAD_UNLOCK(ipimap); + + /* update the free inode summary map for the extent if + * freeing the inode means the extent will now have free + * inodes (i.e., the inode being freed is the first free + * inode of extent), + */ + if (iagp->wmap[extno] == ONES) { + sword = extno >> L2EXTSPERSUM; + bitno = extno & (EXTSPERSUM - 1); + iagp->inosmap[sword] &= + cpu_to_le32(~(HIGHORDER >> bitno)); + } + + /* update the bitmap. + */ + iagp->wmap[extno] = cpu_to_le32(bitmap); + DBG_DIFREE(imap, inum); + + /* update the free inode counts at the iag, ag and + * map level. + */ + iagp->nfreeinos = + cpu_to_le32(le32_to_cpu(iagp->nfreeinos) + 1); + imap->im_agctl[agno].numfree += 1; + atomic_inc(&imap->im_numfree); + + /* release the AG inode map lock + */ + AG_UNLOCK(imap, agno); + + /* write the iag */ + write_metapage(mp); + + return (0); + } + + + /* + * inode extent has become free and above low water mark: + * free the inode extent; + */ + + /* + * prepare to update iag list(s) (careful update step 1) + */ + amp = bmp = cmp = dmp = NULL; + fwd = back = -1; + + /* check if the iag currently has no free extents. if so, + * it will be placed on the head of the ag extent free list. + */ + if (iagp->nfreeexts == 0) { + /* check if the ag extent free list has any iags. + * if so, read the iag at the head of the list now. + * this (head) iag will be updated later to reflect + * the addition of the current iag at the head of + * the list. + */ + if ((fwd = imap->im_agctl[agno].extfree) >= 0) { + if ((rc = diIAGRead(imap, fwd, &))) + goto error_out; + aiagp = (iag_t *) amp->data; + } + } else { + /* iag has free extents. check if the addition of a free + * extent will cause all extents to be free within this + * iag. if so, the iag will be removed from the ag extent + * free list and placed on the inode map's free iag list. + */ + if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG - 1)) { + /* in preparation for removing the iag from the + * ag extent free list, read the iags preceeding + * and following the iag on the ag extent free + * list. + */ + if ((fwd = le32_to_cpu(iagp->extfreefwd)) >= 0) { + if ((rc = diIAGRead(imap, fwd, &))) + goto error_out; + aiagp = (iag_t *) amp->data; + } + + if ((back = le32_to_cpu(iagp->extfreeback)) >= 0) { + if ((rc = diIAGRead(imap, back, &bmp))) + goto error_out; + biagp = (iag_t *) bmp->data; + } + } + } + + /* remove the iag from the ag inode free list if freeing + * this extent cause the iag to have no free inodes. + */ + if (iagp->nfreeinos == cpu_to_le32(INOSPEREXT - 1)) { + int inofreeback = le32_to_cpu(iagp->inofreeback); + int inofreefwd = le32_to_cpu(iagp->inofreefwd); + + /* in preparation for removing the iag from the + * ag inode free list, read the iags preceeding + * and following the iag on the ag inode free + * list. before reading these iags, we must make + * sure that we already don't have them in hand + * from up above, since re-reading an iag (buffer) + * we are currently holding would cause a deadlock. + */ + if (inofreefwd >= 0) { + + if (inofreefwd == fwd) + ciagp = (iag_t *) amp->data; + else if (inofreefwd == back) + ciagp = (iag_t *) bmp->data; + else { + if ((rc = + diIAGRead(imap, inofreefwd, &cmp))) + goto error_out; + assert(cmp != NULL); + ciagp = (iag_t *) cmp->data; + } + assert(ciagp != NULL); + } + + if (inofreeback >= 0) { + if (inofreeback == fwd) + diagp = (iag_t *) amp->data; + else if (inofreeback == back) + diagp = (iag_t *) bmp->data; + else { + if ((rc = + diIAGRead(imap, inofreeback, &dmp))) + goto error_out; + assert(dmp != NULL); + diagp = (iag_t *) dmp->data; + } + assert(diagp != NULL); + } + } + + IREAD_UNLOCK(ipimap); + + /* + * invalidate any page of the inode extent freed from buffer cache; + */ + freepxd = iagp->inoext[extno]; + xaddr = addressPXD(&iagp->inoext[extno]); + xlen = lengthPXD(&iagp->inoext[extno]); + invalidate_metapages(JFS_SBI(ip->i_sb)->direct_inode, xaddr, xlen); + + /* + * update iag list(s) (careful update step 2) + */ + /* add the iag to the ag extent free list if this is the + * first free extent for the iag. + */ + if (iagp->nfreeexts == 0) { + if (fwd >= 0) + aiagp->extfreeback = cpu_to_le32(iagno); + + iagp->extfreefwd = + cpu_to_le32(imap->im_agctl[agno].extfree); + iagp->extfreeback = -1; + imap->im_agctl[agno].extfree = iagno; + } else { + /* remove the iag from the ag extent list if all extents + * are now free and place it on the inode map iag free list. + */ + if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG - 1)) { + if (fwd >= 0) + aiagp->extfreeback = iagp->extfreeback; + + if (back >= 0) + biagp->extfreefwd = iagp->extfreefwd; + else + imap->im_agctl[agno].extfree = + le32_to_cpu(iagp->extfreefwd); + + iagp->extfreefwd = iagp->extfreeback = -1; + + IAGFREE_LOCK(imap); + iagp->iagfree = cpu_to_le32(imap->im_freeiag); + imap->im_freeiag = iagno; + IAGFREE_UNLOCK(imap); + } + } + + /* remove the iag from the ag inode free list if freeing + * this extent causes the iag to have no free inodes. + */ + if (iagp->nfreeinos == cpu_to_le32(INOSPEREXT - 1)) { + if ((int) le32_to_cpu(iagp->inofreefwd) >= 0) + ciagp->inofreeback = iagp->inofreeback; + + if ((int) le32_to_cpu(iagp->inofreeback) >= 0) + diagp->inofreefwd = iagp->inofreefwd; + else + imap->im_agctl[agno].inofree = + le32_to_cpu(iagp->inofreefwd); + + iagp->inofreefwd = iagp->inofreeback = -1; + } + + /* update the inode extent address and working map + * to reflect the free extent. + * the permanent map should have been updated already + * for the inode being freed. + */ + assert(iagp->pmap[extno] == 0); + iagp->wmap[extno] = 0; + DBG_DIFREE(imap, inum); + PXDlength(&iagp->inoext[extno], 0); + PXDaddress(&iagp->inoext[extno], 0); + + /* update the free extent and free inode summary maps + * to reflect the freed extent. + * the inode summary map is marked to indicate no inodes + * available for the freed extent. + */ + sword = extno >> L2EXTSPERSUM; + bitno = extno & (EXTSPERSUM - 1); + mask = HIGHORDER >> bitno; + iagp->inosmap[sword] |= cpu_to_le32(mask); + iagp->extsmap[sword] &= cpu_to_le32(~mask); + + /* update the number of free inodes and number of free extents + * for the iag. + */ + iagp->nfreeinos = cpu_to_le32(le32_to_cpu(iagp->nfreeinos) - + (INOSPEREXT - 1)); + iagp->nfreeexts = cpu_to_le32(le32_to_cpu(iagp->nfreeexts) + 1); + + /* update the number of free inodes and backed inodes + * at the ag and inode map level. + */ + imap->im_agctl[agno].numfree -= (INOSPEREXT - 1); + imap->im_agctl[agno].numinos -= INOSPEREXT; + atomic_sub(INOSPEREXT - 1, &imap->im_numfree); + atomic_sub(INOSPEREXT, &imap->im_numinos); + + if (amp) + write_metapage(amp); + if (bmp) + write_metapage(bmp); + if (cmp) + write_metapage(cmp); + if (dmp) + write_metapage(dmp); + + /* + * start transaction to update block allocation map + * for the inode extent freed; + * + * N.B. AG_LOCK is released and iag will be released below, and + * other thread may allocate inode from/reusing the ixad freed + * BUT with new/different backing inode extent from the extent + * to be freed by the transaction; + */ + tid = txBegin(ipimap->i_sb, COMMIT_FORCE); + + /* acquire tlock of the iag page of the freed ixad + * to force the page NOHOMEOK (even though no data is + * logged from the iag page) until NOREDOPAGE|FREEXTENT log + * for the free of the extent is committed; + * write FREEXTENT|NOREDOPAGE log record + * N.B. linelock is overlaid as freed extent descriptor; + */ + tlck = txLock(tid, ipimap, mp, tlckINODE | tlckFREE); + pxdlock = (pxdlock_t *) & tlck->lock; + pxdlock->flag = mlckFREEPXD; + pxdlock->pxd = freepxd; + pxdlock->index = 1; + + write_metapage(mp); + + iplist[0] = ipimap; + + /* + * logredo needs the IAG number and IAG extent index in order + * to ensure that the IMap is consistent. The least disruptive + * way to pass these values through to the transaction manager + * is in the iplist array. + * + * It's not pretty, but it works. + */ + iplist[1] = (struct inode *) (size_t)iagno; + iplist[2] = (struct inode *) (size_t)extno; + + rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE); // D233382 + + txEnd(tid); + + /* unlock the AG inode map information */ + AG_UNLOCK(imap, agno); + + return (0); + + error_out: + IREAD_UNLOCK(ipimap); + + if (amp) + release_metapage(amp); + if (bmp) + release_metapage(bmp); + if (cmp) + release_metapage(cmp); + if (dmp) + release_metapage(dmp); + + AG_UNLOCK(imap, agno); + + release_metapage(mp); + + return (rc); +} + +/* + * There are several places in the diAlloc* routines where we initialize + * the inode. + */ +static inline void +diInitInode(struct inode *ip, int iagno, int ino, int extno, iag_t * iagp) +{ + struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb); + struct jfs_inode_info *jfs_ip = JFS_IP(ip); + + ip->i_ino = (iagno << L2INOSPERIAG) + ino; + DBG_DIALLOC(JFS_IP(ipimap)->i_imap, ip->i_ino); + jfs_ip->ixpxd = iagp->inoext[extno]; + jfs_ip->agno = BLKTOAG(le64_to_cpu(iagp->agstart), sbi); +} + + +/* + * NAME: diAlloc(pip,dir,ip) + * + * FUNCTION: allocate a disk inode from the inode working map + * for a fileset or aggregate. + * + * PARAMETERS: + * pip - pointer to incore inode for the parent inode. + * dir - TRUE if the new disk inode is for a directory. + * ip - pointer to a new inode + * + * RETURN VALUES: + * 0 - success. + * ENOSPC - insufficient disk resources. + * EIO - i/o error. + */ +int diAlloc(struct inode *pip, boolean_t dir, struct inode *ip) +{ + int rc, ino, iagno, addext, extno, bitno, sword; + int nwords, rem, i, agno; + u32 mask, inosmap, extsmap; + struct inode *ipimap; + metapage_t *mp; + ino_t inum; + iag_t *iagp; + imap_t *imap; + + /* get the pointers to the inode map inode and the + * corresponding imap control structure. + */ + ipimap = JFS_SBI(pip->i_sb)->ipimap; + imap = JFS_IP(ipimap)->i_imap; + JFS_IP(ip)->ipimap = ipimap; + JFS_IP(ip)->fileset = FILESYSTEM_I; + + /* for a directory, the allocation policy is to start + * at the ag level using the preferred ag. + */ + if (dir == TRUE) { + agno = dbNextAG(JFS_SBI(pip->i_sb)->ipbmap); + AG_LOCK(imap, agno); + goto tryag; + } + + /* for files, the policy starts off by trying to allocate from + * the same iag containing the parent disk inode: + * try to allocate the new disk inode close to the parent disk + * inode, using parent disk inode number + 1 as the allocation + * hint. (we use a left-to-right policy to attempt to avoid + * moving backward on the disk.) compute the hint within the + * file system and the iag. + */ + inum = pip->i_ino + 1; + ino = inum & (INOSPERIAG - 1); + + /* back off the the hint if it is outside of the iag */ + if (ino == 0) + inum = pip->i_ino; + + /* get the ag number of this iag */ + agno = JFS_IP(pip)->agno; + + /* lock the AG inode map information */ + AG_LOCK(imap, agno); + + /* Get read lock on imap inode */ + IREAD_LOCK(ipimap); + + /* get the iag number and read the iag */ + iagno = INOTOIAG(inum); + if ((rc = diIAGRead(imap, iagno, &mp))) { + IREAD_UNLOCK(ipimap); + return (rc); + } + iagp = (iag_t *) mp->data; + + /* determine if new inode extent is allowed to be added to the iag. + * new inode extent can be added to the iag if the ag + * has less than 32 free disk inodes and the iag has free extents. + */ + addext = (imap->im_agctl[agno].numfree < 32 && iagp->nfreeexts); + + /* + * try to allocate from the IAG + */ + /* check if the inode may be allocated from the iag + * (i.e. the inode has free inodes or new extent can be added). + */ + if (iagp->nfreeinos || addext) { + /* determine the extent number of the hint. + */ + extno = ino >> L2INOSPEREXT; + + /* check if the extent containing the hint has backed + * inodes. if so, try to allocate within this extent. + */ + if (addressPXD(&iagp->inoext[extno])) { + bitno = ino & (INOSPEREXT - 1); + if ((bitno = + diFindFree(le32_to_cpu(iagp->wmap[extno]), + bitno)) + < INOSPEREXT) { + ino = (extno << L2INOSPEREXT) + bitno; + + /* a free inode (bit) was found within this + * extent, so allocate it. + */ + rc = diAllocBit(imap, iagp, ino); + IREAD_UNLOCK(ipimap); + if (rc) { + assert(rc == EIO); + } else { + /* set the results of the allocation + * and write the iag. + */ + diInitInode(ip, iagno, ino, extno, + iagp); + mark_metapage_dirty(mp); + } + release_metapage(mp); + + /* free the AG lock and return. + */ + AG_UNLOCK(imap, agno); + return (rc); + } + + if (!addext) + extno = + (extno == + EXTSPERIAG - 1) ? 0 : extno + 1; + } + + /* + * no free inodes within the extent containing the hint. + * + * try to allocate from the backed extents following + * hint or, if appropriate (i.e. addext is true), allocate + * an extent of free inodes at or following the extent + * containing the hint. + * + * the free inode and free extent summary maps are used + * here, so determine the starting summary map position + * and the number of words we'll have to examine. again, + * the approach is to allocate following the hint, so we + * might have to initially ignore prior bits of the summary + * map that represent extents prior to the extent containing + * the hint and later revisit these bits. + */ + bitno = extno & (EXTSPERSUM - 1); + nwords = (bitno == 0) ? SMAPSZ : SMAPSZ + 1; + sword = extno >> L2EXTSPERSUM; + + /* mask any prior bits for the starting words of the + * summary map. + */ + mask = ONES << (EXTSPERSUM - bitno); + inosmap = le32_to_cpu(iagp->inosmap[sword]) | mask; + extsmap = le32_to_cpu(iagp->extsmap[sword]) | mask; + + /* scan the free inode and free extent summary maps for + * free resources. + */ + for (i = 0; i < nwords; i++) { + /* check if this word of the free inode summary + * map describes an extent with free inodes. + */ + if (~inosmap) { + /* an extent with free inodes has been + * found. determine the extent number + * and the inode number within the extent. + */ + rem = diFindFree(inosmap, 0); + extno = (sword << L2EXTSPERSUM) + rem; + rem = + diFindFree(le32_to_cpu + (iagp->wmap[extno]), 0); + assert(rem < INOSPEREXT); + + /* determine the inode number within the + * iag and allocate the inode from the + * map. + */ + ino = (extno << L2INOSPEREXT) + rem; + rc = diAllocBit(imap, iagp, ino); + IREAD_UNLOCK(ipimap); + if (rc) { + assert(rc == EIO); + } else { + /* set the results of the allocation + * and write the iag. + */ + diInitInode(ip, iagno, ino, extno, + iagp); + mark_metapage_dirty(mp); + } + release_metapage(mp); + + /* free the AG lock and return. + */ + AG_UNLOCK(imap, agno); + return (rc); + + } + + /* check if we may allocate an extent of free + * inodes and whether this word of the free + * extents summary map describes a free extent. + */ + if (addext && ~extsmap) { + /* a free extent has been found. determine + * the extent number. + */ + rem = diFindFree(extsmap, 0); + extno = (sword << L2EXTSPERSUM) + rem; + + /* allocate an extent of free inodes. + */ + if ((rc = diNewExt(imap, iagp, extno))) { + /* if there is no disk space for a + * new extent, try to allocate the + * disk inode from somewhere else. + */ + if (rc == ENOSPC) + break; + + assert(rc == EIO); + } else { + /* set the results of the allocation + * and write the iag. + */ + diInitInode(ip, iagno, + extno << L2INOSPEREXT, + extno, iagp); + mark_metapage_dirty(mp); + } + release_metapage(mp); + /* free the imap inode & the AG lock & return. + */ + IREAD_UNLOCK(ipimap); + AG_UNLOCK(imap, agno); + return (rc); + } + + /* move on to the next set of summary map words. + */ + sword = (sword == SMAPSZ - 1) ? 0 : sword + 1; + inosmap = le32_to_cpu(iagp->inosmap[sword]); + extsmap = le32_to_cpu(iagp->extsmap[sword]); + } + } + /* unlock imap inode */ + IREAD_UNLOCK(ipimap); + + /* nothing doing in this iag, so release it. */ + release_metapage(mp); + + tryag: + /* + * try to allocate anywhere within the same AG as the parent inode. + */ + rc = diAllocAG(imap, agno, dir, ip); + + AG_UNLOCK(imap, agno); + + if (rc != ENOSPC) + return (rc); + + /* + * try to allocate in any AG. + */ + return (diAllocAny(imap, agno, dir, ip)); +} + + +/* + * NAME: diAllocAG(imap,agno,dir,ip) + * + * FUNCTION: allocate a disk inode from the allocation group. + * + * this routine first determines if a new extent of free + * inodes should be added for the allocation group, with + * the current request satisfied from this extent. if this + * is the case, an attempt will be made to do just that. if + * this attempt fails or it has been determined that a new + * extent should not be added, an attempt is made to satisfy + * the request by allocating an existing (backed) free inode + * from the allocation group. + * + * PRE CONDITION: Already have the AG lock for this AG. + * + * PARAMETERS: + * imap - pointer to inode map control structure. + * agno - allocation group to allocate from. + * dir - TRUE if the new disk inode is for a directory. + * ip - pointer to the new inode to be filled in on successful return + * with the disk inode number allocated, its extent address + * and the start of the ag. + * + * RETURN VALUES: + * 0 - success. + * ENOSPC - insufficient disk resources. + * EIO - i/o error. + */ +static int +diAllocAG(imap_t * imap, int agno, boolean_t dir, struct inode *ip) +{ + int rc, addext, numfree, numinos; + + /* get the number of free and the number of backed disk + * inodes currently within the ag. + */ + numfree = imap->im_agctl[agno].numfree; + numinos = imap->im_agctl[agno].numinos; + + if (numfree > numinos) { + jERROR(1,("diAllocAG: numfree > numinos\n")); + updateSuper(ip->i_sb, FM_DIRTY); + return EIO; + } + + /* determine if we should allocate a new extent of free inodes + * within the ag: for directory inodes, add a new extent + * if there are a small number of free inodes or number of free + * inodes is a small percentage of the number of backed inodes. + */ + if (dir == TRUE) + addext = (numfree < 64 || + (numfree < 256 + && ((numfree * 100) / numinos) <= 20)); + else + addext = (numfree == 0); + + /* + * try to allocate a new extent of free inodes. + */ + if (addext) { + /* if free space is not avaliable for this new extent, try + * below to allocate a free and existing (already backed) + * inode from the ag. + */ + if ((rc = diAllocExt(imap, agno, ip)) != ENOSPC) + return (rc); + } + + /* + * try to allocate an existing free inode from the ag. + */ + return (diAllocIno(imap, agno, ip)); +} + + +/* + * NAME: diAllocAny(imap,agno,dir,iap) + * + * FUNCTION: allocate a disk inode from any other allocation group. + * + * this routine is called when an allocation attempt within + * the primary allocation group has failed. if attempts to + * allocate an inode from any allocation group other than the + * specified primary group. + * + * PARAMETERS: + * imap - pointer to inode map control structure. + * agno - primary allocation group (to avoid). + * dir - TRUE if the new disk inode is for a directory. + * ip - pointer to a new inode to be filled in on successful return + * with the disk inode number allocated, its extent address + * and the start of the ag. + * + * RETURN VALUES: + * 0 - success. + * ENOSPC - insufficient disk resources. + * EIO - i/o error. + */ +static int +diAllocAny(imap_t * imap, int agno, boolean_t dir, struct inode *ip) +{ + int ag, rc; + int maxag = JFS_SBI(imap->im_ipimap->i_sb)->bmap->db_maxag; + + + /* try to allocate from the ags following agno up to + * the maximum ag number. + */ + for (ag = agno + 1; ag <= maxag; ag++) { + AG_LOCK(imap, ag); + + rc = diAllocAG(imap, ag, dir, ip); + + AG_UNLOCK(imap, ag); + + if (rc != ENOSPC) + return (rc); + } + + /* try to allocate from the ags in front of agno. + */ + for (ag = 0; ag < agno; ag++) { + AG_LOCK(imap, ag); + + rc = diAllocAG(imap, ag, dir, ip); + + AG_UNLOCK(imap, ag); + + if (rc != ENOSPC) + return (rc); + } + + /* no free disk inodes. + */ + return (ENOSPC); +} + + +/* + * NAME: diAllocIno(imap,agno,ip) + * + * FUNCTION: allocate a disk inode from the allocation group's free + * inode list, returning an error if this free list is + * empty (i.e. no iags on the list). + * + * allocation occurs from the first iag on the list using + * the iag's free inode summary map to find the leftmost + * free inode in the iag. + * + * PRE CONDITION: Already have AG lock for this AG. + * + * PARAMETERS: + * imap - pointer to inode map control structure. + * agno - allocation group. + * ip - pointer to new inode to be filled in on successful return + * with the disk inode number allocated, its extent address + * and the start of the ag. + * + * RETURN VALUES: + * 0 - success. + * ENOSPC - insufficient disk resources. + * EIO - i/o error. + */ +static int diAllocIno(imap_t * imap, int agno, struct inode *ip) +{ + int iagno, ino, rc, rem, extno, sword; + metapage_t *mp; + iag_t *iagp; + + /* check if there are iags on the ag's free inode list. + */ + if ((iagno = imap->im_agctl[agno].inofree) < 0) + return (ENOSPC); + + /* obtain read lock on imap inode */ + IREAD_LOCK(imap->im_ipimap); + + /* read the iag at the head of the list. + */ + if ((rc = diIAGRead(imap, iagno, &mp))) { + IREAD_UNLOCK(imap->im_ipimap); + return (rc); + } + iagp = (iag_t *) mp->data; + + /* better be free inodes in this iag if it is on the + * list. + */ + //assert(iagp->nfreeinos); + if (!iagp->nfreeinos) { + jERROR(1, + ("diAllocIno: nfreeinos = 0, but iag on freelist\n")); + jERROR(1, (" agno = %d, iagno = %d\n", agno, iagno)); + dump_mem("iag", iagp, 64); + updateSuper(ip->i_sb, FM_DIRTY); + return EIO; + } + + /* scan the free inode summary map to find an extent + * with free inodes. + */ + for (sword = 0;; sword++) { + assert(sword < SMAPSZ); + + if (~iagp->inosmap[sword]) + break; + } + + /* found a extent with free inodes. determine + * the extent number. + */ + rem = diFindFree(le32_to_cpu(iagp->inosmap[sword]), 0); + assert(rem < EXTSPERSUM); + extno = (sword << L2EXTSPERSUM) + rem; + + /* find the first free inode in the extent. + */ + rem = diFindFree(le32_to_cpu(iagp->wmap[extno]), 0); + assert(rem < INOSPEREXT); + + /* compute the inode number within the iag. + */ + ino = (extno << L2INOSPEREXT) + rem; + + /* allocate the inode. + */ + rc = diAllocBit(imap, iagp, ino); + IREAD_UNLOCK(imap->im_ipimap); + if (rc) { + release_metapage(mp); + return (rc); + } + + /* set the results of the allocation and write the iag. + */ + diInitInode(ip, iagno, ino, extno, iagp); + write_metapage(mp); + + return (0); +} + + +/* + * NAME: diAllocExt(imap,agno,ip) + * + * FUNCTION: add a new extent of free inodes to an iag, allocating + * an inode from this extent to satisfy the current allocation + * request. + * + * this routine first tries to find an existing iag with free + * extents through the ag free extent list. if list is not + * empty, the head of the list will be selected as the home + * of the new extent of free inodes. otherwise (the list is + * empty), a new iag will be allocated for the ag to contain + * the extent. + * + * once an iag has been selected, the free extent summary map + * is used to locate a free extent within the iag and diNewExt() + * is called to initialize the extent, with initialization + * including the allocation of the first inode of the extent + * for the purpose of satisfying this request. + * + * PARAMETERS: + * imap - pointer to inode map control structure. + * agno - allocation group number. + * ip - pointer to new inode to be filled in on successful return + * with the disk inode number allocated, its extent address + * and the start of the ag. + * + * RETURN VALUES: + * 0 - success. + * ENOSPC - insufficient disk resources. + * EIO - i/o error. + */ +static int diAllocExt(imap_t * imap, int agno, struct inode *ip) +{ + int rem, iagno, sword, extno, rc; + metapage_t *mp; + iag_t *iagp; + + /* check if the ag has any iags with free extents. if not, + * allocate a new iag for the ag. + */ + if ((iagno = imap->im_agctl[agno].extfree) < 0) { + /* If successful, diNewIAG will obtain the read lock on the + * imap inode. + */ + if ((rc = diNewIAG(imap, &iagno, agno, &mp))) { + return (rc); + } + iagp = (iag_t *) mp->data; + + /* set the ag number if this a brand new iag + */ + iagp->agstart = + cpu_to_le64(AGTOBLK(agno, imap->im_ipimap)); + } else { + /* read the iag. + */ + IREAD_LOCK(imap->im_ipimap); + if ((rc = diIAGRead(imap, iagno, &mp))) { + assert(0); + } + iagp = (iag_t *) mp->data; + } + + /* using the free extent summary map, find a free extent. + */ + for (sword = 0;; sword++) { + assert(sword < SMAPSZ); + if (~iagp->extsmap[sword]) + break; + } + + /* determine the extent number of the free extent. + */ + rem = diFindFree(le32_to_cpu(iagp->extsmap[sword]), 0); + assert(rem < EXTSPERSUM); + extno = (sword << L2EXTSPERSUM) + rem; + + /* initialize the new extent. + */ + rc = diNewExt(imap, iagp, extno); + IREAD_UNLOCK(imap->im_ipimap); + if (rc) { + /* something bad happened. if a new iag was allocated, + * place it back on the inode map's iag free list, and + * clear the ag number information. + */ + if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) { + IAGFREE_LOCK(imap); + iagp->iagfree = cpu_to_le32(imap->im_freeiag); + imap->im_freeiag = iagno; + IAGFREE_UNLOCK(imap); + } + write_metapage(mp); + return (rc); + } + + /* set the results of the allocation and write the iag. + */ + diInitInode(ip, iagno, extno << L2INOSPEREXT, extno, iagp); + + write_metapage(mp); + + return (0); +} + + +/* + * NAME: diAllocBit(imap,iagp,ino) + * + * FUNCTION: allocate a backed inode from an iag. + * + * this routine performs the mechanics of allocating a + * specified inode from a backed extent. + * + * if the inode to be allocated represents the last free + * inode within the iag, the iag will be removed from the + * ag free inode list. + * + * a careful update approach is used to provide consistency + * in the face of updates to multiple buffers. under this + * approach, all required buffers are obtained before making + * any updates and are held all are updates are complete. + * + * PRE CONDITION: Already have buffer lock on iagp. Already have AG lock on + * this AG. Must have read lock on imap inode. + * + * PARAMETERS: + * imap - pointer to inode map control structure. + * iagp - pointer to iag. + * ino - inode number to be allocated within the iag. + * + * RETURN VALUES: + * 0 - success. + * ENOSPC - insufficient disk resources. + * EIO - i/o error. + */ +static int diAllocBit(imap_t * imap, iag_t * iagp, int ino) +{ + int extno, bitno, agno, sword, rc; + metapage_t *amp, *bmp; + iag_t *aiagp = 0, *biagp = 0; + u32 mask; + + /* check if this is the last free inode within the iag. + * if so, it will have to be removed from the ag free + * inode list, so get the iags preceeding and following + * it on the list. + */ + if (iagp->nfreeinos == cpu_to_le32(1)) { + amp = bmp = NULL; + + if ((int) le32_to_cpu(iagp->inofreefwd) >= 0) { + if ((rc = + diIAGRead(imap, le32_to_cpu(iagp->inofreefwd), + &))) + return (rc); + aiagp = (iag_t *) amp->data; + } + + if ((int) le32_to_cpu(iagp->inofreeback) >= 0) { + if ((rc = + diIAGRead(imap, + le32_to_cpu(iagp->inofreeback), + &bmp))) { + if (amp) + release_metapage(amp); + return (rc); + } + biagp = (iag_t *) bmp->data; + } + } + + /* get the ag number, extent number, inode number within + * the extent. + */ + agno = BLKTOAG(le64_to_cpu(iagp->agstart), JFS_SBI(imap->im_ipimap->i_sb)); + extno = ino >> L2INOSPEREXT; + bitno = ino & (INOSPEREXT - 1); + + /* compute the mask for setting the map. + */ + mask = HIGHORDER >> bitno; + + /* the inode should be free and backed. + */ + assert((le32_to_cpu(iagp->pmap[extno]) & mask) == 0); + assert((le32_to_cpu(iagp->wmap[extno]) & mask) == 0); + assert(addressPXD(&iagp->inoext[extno]) != 0); + + /* mark the inode as allocated in the working map. + */ + iagp->wmap[extno] |= cpu_to_le32(mask); + + /* check if all inodes within the extent are now + * allocated. if so, update the free inode summary + * map to reflect this. + */ + if (iagp->wmap[extno] == ONES) { + sword = extno >> L2EXTSPERSUM; + bitno = extno & (EXTSPERSUM - 1); + iagp->inosmap[sword] |= cpu_to_le32(HIGHORDER >> bitno); + } + + /* if this was the last free inode in the iag, remove the + * iag from the ag free inode list. + */ + if (iagp->nfreeinos == cpu_to_le32(1)) { + if (amp) { + aiagp->inofreeback = iagp->inofreeback; + write_metapage(amp); + } + + if (bmp) { + biagp->inofreefwd = iagp->inofreefwd; + write_metapage(bmp); + } else { + imap->im_agctl[agno].inofree = + le32_to_cpu(iagp->inofreefwd); + } + iagp->inofreefwd = iagp->inofreeback = -1; + } + + /* update the free inode count at the iag, ag, inode + * map levels. + */ + iagp->nfreeinos = cpu_to_le32(le32_to_cpu(iagp->nfreeinos) - 1); + imap->im_agctl[agno].numfree -= 1; + atomic_dec(&imap->im_numfree); + + return (0); +} + + +/* + * NAME: diNewExt(imap,iagp,extno) + * + * FUNCTION: initialize a new extent of inodes for an iag, allocating + * the first inode of the extent for use for the current + * allocation request. + * + * disk resources are allocated for the new extent of inodes + * and the inodes themselves are initialized to reflect their + * existence within the extent (i.e. their inode numbers and + * inode extent addresses are set) and their initial state + * (mode and link count are set to zero). + * + * if the iag is new, it is not yet on an ag extent free list + * but will now be placed on this list. + * + * if the allocation of the new extent causes the iag to + * have no free extent, the iag will be removed from the + * ag extent free list. + * + * if the iag has no free backed inodes, it will be placed + * on the ag free inode list, since the addition of the new + * extent will now cause it to have free inodes. + * + * a careful update approach is used to provide consistency + * (i.e. list consistency) in the face of updates to multiple + * buffers. under this approach, all required buffers are + * obtained before making any updates and are held until all + * updates are complete. + * + * PRE CONDITION: Already have buffer lock on iagp. Already have AG lock on + * this AG. Must have read lock on imap inode. + * + * PARAMETERS: + * imap - pointer to inode map control structure. + * iagp - pointer to iag. + * extno - extent number. + * + * RETURN VALUES: + * 0 - success. + * ENOSPC - insufficient disk resources. + * EIO - i/o error. + */ +static int diNewExt(imap_t * imap, iag_t * iagp, int extno) +{ + int agno, iagno, fwd, back, freei = 0, sword, rc; + iag_t *aiagp = 0, *biagp = 0, *ciagp = 0; + metapage_t *amp, *bmp, *cmp, *dmp; + struct inode *ipimap; + s64 blkno, hint; + int i, j; + u32 mask; + ino_t ino; + dinode_t *dp; + struct jfs_sb_info *sbi; + + /* better have free extents. + */ + assert(iagp->nfreeexts); + + /* get the inode map inode. + */ + ipimap = imap->im_ipimap; + sbi = JFS_SBI(ipimap->i_sb); + + amp = bmp = cmp = NULL; + + /* get the ag and iag numbers for this iag. + */ + agno = BLKTOAG(le64_to_cpu(iagp->agstart), sbi); + iagno = le32_to_cpu(iagp->iagnum); + + /* check if this is the last free extent within the + * iag. if so, the iag must be removed from the ag + * free extent list, so get the iags preceeding and + * following the iag on this list. + */ + if (iagp->nfreeexts == cpu_to_le32(1)) { + if ((fwd = le32_to_cpu(iagp->extfreefwd)) >= 0) { + if ((rc = diIAGRead(imap, fwd, &))) + return (rc); + aiagp = (iag_t *) amp->data; + } + + if ((back = le32_to_cpu(iagp->extfreeback)) >= 0) { + if ((rc = diIAGRead(imap, back, &bmp))) + goto error_out; + biagp = (iag_t *) bmp->data; + } + } else { + /* the iag has free extents. if all extents are free + * (as is the case for a newly allocated iag), the iag + * must be added to the ag free extent list, so get + * the iag at the head of the list in preparation for + * adding this iag to this list. + */ + fwd = back = -1; + if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) { + if ((fwd = imap->im_agctl[agno].extfree) >= 0) { + if ((rc = diIAGRead(imap, fwd, &))) + goto error_out; + aiagp = (iag_t *) amp->data; + } + } + } + + /* check if the iag has no free inodes. if so, the iag + * will have to be added to the ag free inode list, so get + * the iag at the head of the list in preparation for + * adding this iag to this list. in doing this, we must + * check if we already have the iag at the head of + * the list in hand. + */ + if (iagp->nfreeinos == 0) { + freei = imap->im_agctl[agno].inofree; + + if (freei >= 0) { + if (freei == fwd) { + ciagp = aiagp; + } else if (freei == back) { + ciagp = biagp; + } else { + if ((rc = diIAGRead(imap, freei, &cmp))) + goto error_out; + ciagp = (iag_t *) cmp->data; + } + assert(ciagp != NULL); + } + } + + /* allocate disk space for the inode extent. + */ + if ((extno == 0) || (addressPXD(&iagp->inoext[extno - 1]) == 0)) + hint = ((s64) agno << sbi->bmap->db_agl2size) - 1; + else + hint = addressPXD(&iagp->inoext[extno - 1]) + + lengthPXD(&iagp->inoext[extno - 1]) - 1; + + if ((rc = dbAlloc(ipimap, hint, (s64) imap->im_nbperiext, &blkno))) + goto error_out; + + /* compute the inode number of the first inode within the + * extent. + */ + ino = (iagno << L2INOSPERIAG) + (extno << L2INOSPEREXT); + + /* initialize the inodes within the newly allocated extent a + * page at a time. + */ + for (i = 0; i < imap->im_nbperiext; i += sbi->nbperpage) { + /* get a buffer for this page of disk inodes. + */ + dmp = get_metapage(ipimap, blkno + i, PSIZE, 1); + if (dmp == NULL) { + rc = EIO; + goto error_out; + } + dp = (dinode_t *) dmp->data; + + /* initialize the inode number, mode, link count and + * inode extent address. + */ + for (j = 0; j < INOSPERPAGE; j++, dp++, ino++) { + dp->di_inostamp = cpu_to_le32(sbi->inostamp); + dp->di_number = cpu_to_le32(ino); + dp->di_fileset = cpu_to_le32(FILESYSTEM_I); + dp->di_mode = 0; + dp->di_nlink = 0; + PXDaddress(&(dp->di_ixpxd), blkno); + PXDlength(&(dp->di_ixpxd), imap->im_nbperiext); + } + write_metapage(dmp); + } + + /* if this is the last free extent within the iag, remove the + * iag from the ag free extent list. + */ + if (iagp->nfreeexts == cpu_to_le32(1)) { + if (fwd >= 0) + aiagp->extfreeback = iagp->extfreeback; + + if (back >= 0) + biagp->extfreefwd = iagp->extfreefwd; + else + imap->im_agctl[agno].extfree = + le32_to_cpu(iagp->extfreefwd); + + iagp->extfreefwd = iagp->extfreeback = -1; + } else { + /* if the iag has all free extents (newly allocated iag), + * add the iag to the ag free extent list. + */ + if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) { + if (fwd >= 0) + aiagp->extfreeback = cpu_to_le32(iagno); + + iagp->extfreefwd = cpu_to_le32(fwd); + iagp->extfreeback = -1; + imap->im_agctl[agno].extfree = iagno; + } + } + + /* if the iag has no free inodes, add the iag to the + * ag free inode list. + */ + if (iagp->nfreeinos == 0) { + if (freei >= 0) + ciagp->inofreeback = cpu_to_le32(iagno); + + iagp->inofreefwd = + cpu_to_le32(imap->im_agctl[agno].inofree); + iagp->inofreeback = -1; + imap->im_agctl[agno].inofree = iagno; + } + + /* initialize the extent descriptor of the extent. */ + PXDlength(&iagp->inoext[extno], imap->im_nbperiext); + PXDaddress(&iagp->inoext[extno], blkno); + + /* initialize the working and persistent map of the extent. + * the working map will be initialized such that + * it indicates the first inode of the extent is allocated. + */ + iagp->wmap[extno] = cpu_to_le32(HIGHORDER); + iagp->pmap[extno] = 0; + + /* update the free inode and free extent summary maps + * for the extent to indicate the extent has free inodes + * and no longer represents a free extent. + */ + sword = extno >> L2EXTSPERSUM; + mask = HIGHORDER >> (extno & (EXTSPERSUM - 1)); + iagp->extsmap[sword] |= cpu_to_le32(mask); + iagp->inosmap[sword] &= cpu_to_le32(~mask); + + /* update the free inode and free extent counts for the + * iag. + */ + iagp->nfreeinos = cpu_to_le32(le32_to_cpu(iagp->nfreeinos) + + (INOSPEREXT - 1)); + iagp->nfreeexts = cpu_to_le32(le32_to_cpu(iagp->nfreeexts) - 1); + + /* update the free and backed inode counts for the ag. + */ + imap->im_agctl[agno].numfree += (INOSPEREXT - 1); + imap->im_agctl[agno].numinos += INOSPEREXT; + + /* update the free and backed inode counts for the inode map. + */ + atomic_add(INOSPEREXT - 1, &imap->im_numfree); + atomic_add(INOSPEREXT, &imap->im_numinos); + + /* write the iags. + */ + if (amp) + write_metapage(amp); + if (bmp) + write_metapage(bmp); + if (cmp) + write_metapage(cmp); + + return (0); + + error_out: + + /* release the iags. + */ + if (amp) + release_metapage(amp); + if (bmp) + release_metapage(bmp); + if (cmp) + release_metapage(cmp); + + return (rc); +} + + +/* + * NAME: diNewIAG(imap,iagnop,agno) + * + * FUNCTION: allocate a new iag for an allocation group. + * + * first tries to allocate the iag from the inode map + * iagfree list: + * if the list has free iags, the head of the list is removed + * and returned to satisfy the request. + * if the inode map's iag free list is empty, the inode map + * is extended to hold a new iag. this new iag is initialized + * and returned to satisfy the request. + * + * PARAMETERS: + * imap - pointer to inode map control structure. + * iagnop - pointer to an iag number set with the number of the + * newly allocated iag upon successful return. + * agno - allocation group number. + * bpp - Buffer pointer to be filled in with new IAG's buffer + * + * RETURN VALUES: + * 0 - success. + * ENOSPC - insufficient disk resources. + * EIO - i/o error. + * + * serialization: + * AG lock held on entry/exit; + * write lock on the map is held inside; + * read lock on the map is held on successful completion; + * + * note: new iag transaction: + * . synchronously write iag; + * . write log of xtree and inode of imap; + * . commit; + * . synchronous write of xtree (right to left, bottom to top); + * . at start of logredo(): init in-memory imap with one additional iag page; + * . at end of logredo(): re-read imap inode to determine + * new imap size; + */ +static int +diNewIAG(imap_t * imap, int *iagnop, int agno, metapage_t ** mpp) +{ + int rc; + int iagno, i, xlen; + struct inode *ipimap; + struct super_block *sb; + struct jfs_sb_info *sbi; + metapage_t *mp; + iag_t *iagp; + s64 xaddr = 0; + s64 blkno; + tid_t tid; +#ifdef _STILL_TO_PORT + xad_t xad; +#endif /* _STILL_TO_PORT */ + struct inode *iplist[1]; + + /* pick up pointers to the inode map and mount inodes */ + ipimap = imap->im_ipimap; + sb = ipimap->i_sb; + sbi = JFS_SBI(sb); + + /* acquire the free iag lock */ + IAGFREE_LOCK(imap); + + /* if there are any iags on the inode map free iag list, + * allocate the iag from the head of the list. + */ + if (imap->im_freeiag >= 0) { + /* pick up the iag number at the head of the list */ + iagno = imap->im_freeiag; + + /* determine the logical block number of the iag */ + blkno = IAGTOLBLK(iagno, sbi->l2nbperpage); + } else { + /* no free iags. the inode map will have to be extented + * to include a new iag. + */ + + /* acquire inode map lock */ + IWRITE_LOCK(ipimap); + + assert(ipimap->i_size >> L2PSIZE == imap->im_nextiag + 1); + + /* get the next avaliable iag number */ + iagno = imap->im_nextiag; + + /* make sure that we have not exceeded the maximum inode + * number limit. + */ + if (iagno > (MAXIAGS - 1)) { + /* release the inode map lock */ + IWRITE_UNLOCK(ipimap); + + rc = ENOSPC; + goto out; + } + + /* + * synchronously append new iag page. + */ + /* determine the logical address of iag page to append */ + blkno = IAGTOLBLK(iagno, sbi->l2nbperpage); + + /* Allocate extent for new iag page */ + xlen = sbi->nbperpage; + if ((rc = dbAlloc(ipimap, 0, (s64) xlen, &xaddr))) { + /* release the inode map lock */ + IWRITE_UNLOCK(ipimap); + + goto out; + } + + /* assign a buffer for the page */ + mp = get_metapage(ipimap, xaddr, PSIZE, 1); + //bp = bmAssign(ipimap, blkno, xaddr, PSIZE, bmREAD_PAGE); + if (!mp) { + /* Free the blocks allocated for the iag since it was + * not successfully added to the inode map + */ + dbFree(ipimap, xaddr, (s64) xlen); + + /* release the inode map lock */ + IWRITE_UNLOCK(ipimap); + + rc = EIO; + goto out; + } + iagp = (iag_t *) mp->data; + + /* init the iag */ + memset(iagp, 0, sizeof(iag_t)); + iagp->iagnum = cpu_to_le32(iagno); + iagp->inofreefwd = iagp->inofreeback = -1; + iagp->extfreefwd = iagp->extfreeback = -1; + iagp->iagfree = -1; + iagp->nfreeinos = 0; + iagp->nfreeexts = cpu_to_le32(EXTSPERIAG); + + /* initialize the free inode summary map (free extent + * summary map initialization handled by bzero). + */ + for (i = 0; i < SMAPSZ; i++) + iagp->inosmap[i] = ONES; + + flush_metapage(mp); +#ifdef _STILL_TO_PORT + /* synchronously write the iag page */ + if (bmWrite(bp)) { + /* Free the blocks allocated for the iag since it was + * not successfully added to the inode map + */ + dbFree(ipimap, xaddr, (s64) xlen); + + /* release the inode map lock */ + IWRITE_UNLOCK(ipimap); + + rc = EIO; + goto out; + } + + /* Now the iag is on disk */ + + /* + * start tyransaction of update of the inode map + * addressing structure pointing to the new iag page; + */ +#endif /* _STILL_TO_PORT */ + tid = txBegin(sb, COMMIT_FORCE); + + /* update the inode map addressing structure to point to it */ + if ((rc = + xtInsert(tid, ipimap, 0, blkno, xlen, &xaddr, 0))) { + /* Free the blocks allocated for the iag since it was + * not successfully added to the inode map + */ + dbFree(ipimap, xaddr, (s64) xlen); + + /* release the inode map lock */ + IWRITE_UNLOCK(ipimap); + + goto out; + } + + /* update the inode map's inode to reflect the extension */ + ipimap->i_size += PSIZE; + ipimap->i_blocks += LBLK2PBLK(sb, xlen); + + /* + * txCommit(COMMIT_FORCE) will synchronously write address + * index pages and inode after commit in careful update order + * of address index pages (right to left, bottom up); + */ + iplist[0] = ipimap; + rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE); + + txEnd(tid); + + duplicateIXtree(sb, blkno, xlen, &xaddr); + + /* update the next avaliable iag number */ + imap->im_nextiag += 1; + + /* Add the iag to the iag free list so we don't lose the iag + * if a failure happens now. + */ + imap->im_freeiag = iagno; + + /* Until we have logredo working, we want the imap inode & + * control page to be up to date. + */ + diSync(ipimap); + + /* release the inode map lock */ + IWRITE_UNLOCK(ipimap); + } + + /* obtain read lock on map */ + IREAD_LOCK(ipimap); + + /* read the iag */ + if ((rc = diIAGRead(imap, iagno, &mp))) { + IREAD_UNLOCK(ipimap); + rc = EIO; + goto out; + } + iagp = (iag_t *) mp->data; + + /* remove the iag from the iag free list */ + imap->im_freeiag = le32_to_cpu(iagp->iagfree); + iagp->iagfree = -1; + + /* set the return iag number and buffer pointer */ + *iagnop = iagno; + *mpp = mp; + + out: + /* release the iag free lock */ + IAGFREE_UNLOCK(imap); + + return (rc); +} + +/* + * NAME: diIAGRead() + * + * FUNCTION: get the buffer for the specified iag within a fileset + * or aggregate inode map. + * + * PARAMETERS: + * imap - pointer to inode map control structure. + * iagno - iag number. + * bpp - point to buffer pointer to be filled in on successful + * exit. + * + * SERIALIZATION: + * must have read lock on imap inode + * (When called by diExtendFS, the filesystem is quiesced, therefore + * the read lock is unnecessary.) + * + * RETURN VALUES: + * 0 - success. + * EIO - i/o error. + */ +static int diIAGRead(imap_t * imap, int iagno, metapage_t ** mpp) +{ + struct inode *ipimap = imap->im_ipimap; + s64 blkno; + + /* compute the logical block number of the iag. */ + blkno = IAGTOLBLK(iagno, JFS_SBI(ipimap->i_sb)->l2nbperpage); + + /* read the iag. */ + *mpp = read_metapage(ipimap, blkno, PSIZE, 0); + if (*mpp == NULL) { + return (EIO); + } + + return (0); +} + +/* + * NAME: diFindFree() + * + * FUNCTION: find the first free bit in a word starting at + * the specified bit position. + * + * PARAMETERS: + * word - word to be examined. + * start - starting bit position. + * + * RETURN VALUES: + * bit position of first free bit in the word or 32 if + * no free bits were found. + */ +static int diFindFree(u32 word, int start) +{ + int bitno; + assert(start < 32); + /* scan the word for the first free bit. */ + for (word <<= start, bitno = start; bitno < 32; + bitno++, word <<= 1) { + if ((word & HIGHORDER) == 0) + break; + } + return (bitno); +} + +/* + * NAME: diUpdatePMap() + * + * FUNCTION: Update the persistent map in an IAG for the allocation or + * freeing of the specified inode. + * + * PRE CONDITIONS: Working map has already been updated for allocate. + * + * PARAMETERS: + * ipimap - Incore inode map inode + * inum - Number of inode to mark in permanent map + * is_free - If TRUE indicates inode should be marked freed, otherwise + * indicates inode should be marked allocated. + * + * RETURNS: 0 for success + */ +int +diUpdatePMap(struct inode *ipimap, + unsigned long inum, boolean_t is_free, tblock_t * tblk) +{ + int rc; + iag_t *iagp; + metapage_t *mp; + int iagno, ino, extno, bitno; + imap_t *imap; + u32 mask; + log_t *log; + int lsn, difft, diffp; + + imap = JFS_IP(ipimap)->i_imap; + /* get the iag number containing the inode */ + iagno = INOTOIAG(inum); + /* make sure that the iag is contained within the map */ + assert(iagno < imap->im_nextiag); + /* read the iag */ + IREAD_LOCK(ipimap); + rc = diIAGRead(imap, iagno, &mp); + IREAD_UNLOCK(ipimap); + if (rc) + return (rc); + iagp = (iag_t *) mp->data; + /* get the inode number and extent number of the inode within + * the iag and the inode number within the extent. + */ + ino = inum & (INOSPERIAG - 1); + extno = ino >> L2INOSPEREXT; + bitno = ino & (INOSPEREXT - 1); + mask = HIGHORDER >> bitno; + /* + * mark the inode free in persistent map: + */ + if (is_free == TRUE) { + /* The inode should have been allocated both in working + * map and in persistent map; + * the inode will be freed from working map at the release + * of last reference release; + */ +// assert(le32_to_cpu(iagp->wmap[extno]) & mask); + if (!(le32_to_cpu(iagp->wmap[extno]) & mask)) { + jERROR(1, + ("diUpdatePMap: inode %ld not marked as allocated in wmap!\n", + inum)); + updateSuper(ipimap->i_sb, FM_DIRTY); + } +// assert(le32_to_cpu(iagp->pmap[extno]) & mask); + if (!(le32_to_cpu(iagp->pmap[extno]) & mask)) { + jERROR(1, + ("diUpdatePMap: inode %ld not marked as allocated in pmap!\n", + inum)); + updateSuper(ipimap->i_sb, FM_DIRTY); + } + /* update the bitmap for the extent of the freed inode */ + iagp->pmap[extno] &= cpu_to_le32(~mask); + } + /* + * mark the inode allocated in persistent map: + */ + else { + /* The inode should be already allocated in the working map + * and should be free in persistent map; + */ + assert(le32_to_cpu(iagp->wmap[extno]) & mask); + assert((le32_to_cpu(iagp->pmap[extno]) & mask) == 0); + /* update the bitmap for the extent of the allocated inode */ + iagp->pmap[extno] |= cpu_to_le32(mask); + } + /* + * update iag lsn + */ + lsn = tblk->lsn; + log = JFS_SBI(tblk->sb)->log; + if (mp->lsn != 0) { + /* inherit older/smaller lsn */ + logdiff(difft, lsn, log); + logdiff(diffp, mp->lsn, log); + if (difft < diffp) { + mp->lsn = lsn; + /* move mp after tblock in logsync list */ + LOGSYNC_LOCK(log); + list_del(&mp->synclist); + list_add(&mp->synclist, &tblk->synclist); + LOGSYNC_UNLOCK(log); + } + /* inherit younger/larger clsn */ + LOGSYNC_LOCK(log); + assert(mp->clsn); + logdiff(difft, tblk->clsn, log); + logdiff(diffp, mp->clsn, log); + if (difft > diffp) + mp->clsn = tblk->clsn; + LOGSYNC_UNLOCK(log); + } else { + mp->log = log; + mp->lsn = lsn; + /* insert mp after tblock in logsync list */ + LOGSYNC_LOCK(log); + log->count++; + list_add(&mp->synclist, &tblk->synclist); + mp->clsn = tblk->clsn; + LOGSYNC_UNLOCK(log); + } +// bmLazyWrite(mp, log->flag & JFS_COMMIT); + write_metapage(mp); + return (0); +} + +/* + * diExtendFS() + * + * function: update imap for extendfs(); + * + * note: AG size has been increased s.t. each k old contiguous AGs are + * coalesced into a new AG; + */ +int diExtendFS(struct inode *ipimap, struct inode *ipbmap) +{ + int rc, rcx = 0; + imap_t *imap = JFS_IP(ipimap)->i_imap; + iag_t *iagp = 0, *hiagp = 0; + bmap_t *mp = JFS_SBI(ipbmap->i_sb)->bmap; + metapage_t *bp, *hbp; + int i, n, head; + int numinos, xnuminos = 0, xnumfree = 0; + s64 agstart; + + jEVENT(0, ("diExtendFS: nextiag:%d numinos:%d numfree:%d\n", + imap->im_nextiag, atomic_read(&imap->im_numinos), + atomic_read(&imap->im_numfree))); + + /* + * reconstruct imap + * + * coalesce contiguous k (newAGSize/oldAGSize) AGs; + * i.e., (AGi, ..., AGj) where i = k*n and j = k*(n+1) - 1 to AGn; + * note: new AG size = old AG size * (2**x). + */ + + /* init per AG control information im_agctl[] */ + for (i = 0; i < MAXAG; i++) { + imap->im_agctl[i].inofree = -1; /* free inode list */ + imap->im_agctl[i].extfree = -1; /* free extent list */ + imap->im_agctl[i].numinos = 0; /* number of backed inodes */ + imap->im_agctl[i].numfree = 0; /* number of free backed inodes */ + } + + /* + * process each iag_t page of the map. + * + * rebuild AG Free Inode List, AG Free Inode Extent List; + */ + for (i = 0; i < imap->im_nextiag; i++) { + if ((rc = diIAGRead(imap, i, &bp))) { + rcx = rc; + continue; + } + iagp = (iag_t *) bp->data; + assert(le32_to_cpu(iagp->iagnum) == i); + + /* leave free iag in the free iag list */ + if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) { + release_metapage(bp); + continue; + } + + /* agstart that computes to the same ag is treated as same; */ + agstart = le64_to_cpu(iagp->agstart); + /* iagp->agstart = agstart & ~(mp->db_agsize - 1); */ + n = agstart >> mp->db_agl2size; +/* +printf("diExtendFS: iag:%d agstart:%Ld agno:%d\n", i, agstart, n); +*/ + + /* compute backed inodes */ + numinos = (EXTSPERIAG - le32_to_cpu(iagp->nfreeexts)) + << L2INOSPEREXT; + if (numinos > 0) { + /* merge AG backed inodes */ + imap->im_agctl[n].numinos += numinos; + xnuminos += numinos; + } + + /* if any backed free inodes, insert at AG free inode list */ + if ((int) le32_to_cpu(iagp->nfreeinos) > 0) { + if ((head = imap->im_agctl[n].inofree) == -1) + iagp->inofreefwd = iagp->inofreeback = -1; + else { + if ((rc = diIAGRead(imap, head, &hbp))) { + rcx = rc; + goto nextiag; + } + hiagp = (iag_t *) hbp->data; + hiagp->inofreeback = + le32_to_cpu(iagp->iagnum); + iagp->inofreefwd = cpu_to_le32(head); + iagp->inofreeback = -1; + write_metapage(hbp); + } + + imap->im_agctl[n].inofree = + le32_to_cpu(iagp->iagnum); + + /* merge AG backed free inodes */ + imap->im_agctl[n].numfree += + le32_to_cpu(iagp->nfreeinos); + xnumfree += le32_to_cpu(iagp->nfreeinos); + } + + /* if any free extents, insert at AG free extent list */ + if (le32_to_cpu(iagp->nfreeexts) > 0) { + if ((head = imap->im_agctl[n].extfree) == -1) + iagp->extfreefwd = iagp->extfreeback = -1; + else { + if ((rc = diIAGRead(imap, head, &hbp))) { + rcx = rc; + goto nextiag; + } + hiagp = (iag_t *) hbp->data; + hiagp->extfreeback = iagp->iagnum; + iagp->extfreefwd = cpu_to_le32(head); + iagp->extfreeback = -1; + write_metapage(hbp); + } + + imap->im_agctl[n].extfree = + le32_to_cpu(iagp->iagnum); + } + + nextiag: + write_metapage(bp); + } + + ASSERT(xnuminos == atomic_read(&imap->im_numinos) && + xnumfree == atomic_read(&imap->im_numfree)); + + return rcx; +} + + +/* + * duplicateIXtree() + * + * serialization: IWRITE_LOCK held on entry/exit + * + * note: shadow page with regular inode (rel.2); + */ +static void +duplicateIXtree(struct super_block *sb, s64 blkno, int xlen, s64 * xaddr) +{ + int rc; + tid_t tid; + struct inode *ip; + metapage_t *mpsuper; + struct jfs_superblock *j_sb; + + /* if AIT2 ipmap2 is bad, do not try to update it */ + if (JFS_SBI(sb)->mntflag & JFS_BAD_SAIT) /* s_flag */ + return; + ip = diReadSpecial(sb, FILESYSTEM_I + INOSPEREXT); + if (ip == 0) { + JFS_SBI(sb)->mntflag |= JFS_BAD_SAIT; + if ((rc = readSuper(sb, &mpsuper))) + return; + j_sb = (struct jfs_superblock *) (mpsuper->data); + j_sb->s_flag |= JFS_BAD_SAIT; + write_metapage(mpsuper); + return; + } + + /* start transaction */ + tid = txBegin(sb, COMMIT_FORCE); + /* update the inode map addressing structure to point to it */ + if ((rc = xtInsert(tid, ip, 0, blkno, xlen, xaddr, 0))) { + JFS_SBI(sb)->mntflag |= JFS_BAD_SAIT; + txAbort(tid, 1); + goto cleanup; + + } + /* update the inode map's inode to reflect the extension */ + ip->i_size += PSIZE; + ip->i_blocks += LBLK2PBLK(sb, xlen); + rc = txCommit(tid, 1, &ip, COMMIT_FORCE); + cleanup: + txEnd(tid); + diFreeSpecial(ip); +} + +/* + * NAME: copy_from_dinode() + * + * FUNCTION: Copies inode info from disk inode to in-memory inode + * + * RETURN VALUES: + * 0 - success + * ENOMEM - insufficient memory + */ +static int copy_from_dinode(dinode_t * dip, struct inode *ip) +{ + struct jfs_inode_info *jfs_ip = JFS_IP(ip); + + jfs_ip->fileset = le32_to_cpu(dip->di_fileset); + jfs_ip->mode2 = le32_to_cpu(dip->di_mode); + + ip->i_mode = le32_to_cpu(dip->di_mode) & 0xffff; + ip->i_nlink = le32_to_cpu(dip->di_nlink); + ip->i_uid = le32_to_cpu(dip->di_uid); + ip->i_gid = le32_to_cpu(dip->di_gid); + ip->i_size = le64_to_cpu(dip->di_size); + ip->i_atime = le32_to_cpu(dip->di_atime.tv_sec); + ip->i_mtime = le32_to_cpu(dip->di_mtime.tv_sec); + ip->i_ctime = le32_to_cpu(dip->di_ctime.tv_sec); + ip->i_blksize = ip->i_sb->s_blocksize; + ip->i_blocks = LBLK2PBLK(ip->i_sb, le64_to_cpu(dip->di_nblocks)); + ip->i_version = ++event; + ip->i_generation = le32_to_cpu(dip->di_gen); + + jfs_ip->ixpxd = dip->di_ixpxd; /* in-memory pxd's are little-endian */ + jfs_ip->acl = dip->di_acl; /* as are dxd's */ + jfs_ip->ea = dip->di_ea; + jfs_ip->next_index = le32_to_cpu(dip->di_next_index); + jfs_ip->otime = le32_to_cpu(dip->di_otime.tv_sec); + jfs_ip->acltype = le32_to_cpu(dip->di_acltype); + /* + * We may only need to do this for "special" inodes (dmap, imap) + */ + if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode)) + ip->i_rdev = to_kdev_t(le32_to_cpu(dip->di_rdev)); + else if (S_ISDIR(ip->i_mode)) { + memcpy(&jfs_ip->i_dirtable, &dip->di_dirtable, 384); + } else if (!S_ISFIFO(ip->i_mode)) { + memcpy(&jfs_ip->i_xtroot, &dip->di_xtroot, 288); + } + /* Zero the in-memory-only stuff */ + jfs_ip->cflag = 0; + jfs_ip->btindex = 0; + jfs_ip->btorder = 0; + jfs_ip->bxflag = 0; + jfs_ip->blid = 0; + jfs_ip->atlhead = 0; + jfs_ip->atltail = 0; + jfs_ip->xtlid = 0; + return (0); +} + +/* + * NAME: copy_to_dinode() + * + * FUNCTION: Copies inode info from in-memory inode to disk inode + */ +static void copy_to_dinode(dinode_t * dip, struct inode *ip) +{ + struct jfs_inode_info *jfs_ip = JFS_IP(ip); + + dip->di_fileset = cpu_to_le32(jfs_ip->fileset); + dip->di_inostamp = cpu_to_le32(JFS_SBI(ip->i_sb)->inostamp); + dip->di_number = cpu_to_le32(ip->i_ino); + dip->di_gen = cpu_to_le32(ip->i_generation); + dip->di_size = cpu_to_le64(ip->i_size); + dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks)); + dip->di_nlink = cpu_to_le32(ip->i_nlink); + dip->di_uid = cpu_to_le32(ip->i_uid); + dip->di_gid = cpu_to_le32(ip->i_gid); + /* + * mode2 is only needed for storing the higher order bits. + * Trust i_mode for the lower order ones + */ + dip->di_mode = cpu_to_le32((jfs_ip->mode2 & 0xffff0000) | ip->i_mode); + dip->di_atime.tv_sec = cpu_to_le32(ip->i_atime); + dip->di_atime.tv_nsec = 0; + dip->di_ctime.tv_sec = cpu_to_le32(ip->i_ctime); + dip->di_ctime.tv_nsec = 0; + dip->di_mtime.tv_sec = cpu_to_le32(ip->i_mtime); + dip->di_mtime.tv_nsec = 0; + dip->di_ixpxd = jfs_ip->ixpxd; /* in-memory pxd's are little-endian */ + dip->di_acl = jfs_ip->acl; /* as are dxd's */ + dip->di_ea = jfs_ip->ea; + dip->di_next_index = cpu_to_le32(jfs_ip->next_index); + dip->di_otime.tv_sec = cpu_to_le32(jfs_ip->otime); + dip->di_otime.tv_nsec = 0; + dip->di_acltype = cpu_to_le32(jfs_ip->acltype); + + if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode)) + dip->di_rdev = cpu_to_le32(kdev_t_to_nr(ip->i_rdev)); +} + +void diClearExtension(struct inode *ip) +{ + jFYI(1, ("diClearExtension called ip = 0x%p\n", ip)); + + assert(list_empty(&JFS_IP(ip)->mp_list)); + assert(list_empty(&JFS_IP(ip)->anon_inode_list)); + + if (JFS_IP(ip)->atlhead) { + jERROR(1, + ("diClearExtension: inode 0x%p has anonymous tlocks\n", + ip)); + } + + free_jfs_inode(ip); + ip->u.generic_ip = 0; +} + +#ifdef _JFS_DEBUG_IMAP +/* + * DBGdiInit() + */ +static void *DBGdiInit(imap_t * imap) +{ + u32 *dimap; + int size; + size = 64 * 1024; + if ((dimap = (u32 *) xmalloc(size, L2PSIZE, kernel_heap)) == NULL) + assert(0); + bzero((void *) dimap, size); + imap->im_DBGdimap = dimap; +} + +/* + * DBGdiAlloc() + */ +static void DBGdiAlloc(imap_t * imap, ino_t ino) +{ + u32 *dimap = imap->im_DBGdimap; + int w, b; + u32 m; + w = ino >> 5; + b = ino & 31; + m = 0x80000000 >> b; + assert(w < 64 * 256); + if (dimap[w] & m) { + printk("DEBUG diAlloc: duplicate alloc ino:0x%x\n", ino); + } + dimap[w] |= m; +} + +/* + * DBGdiFree() + */ +static void DBGdiFree(imap_t * imap, ino_t ino) +{ + u32 *dimap = imap->im_DBGdimap; + int w, b; + u32 m; + w = ino >> 5; + b = ino & 31; + m = 0x80000000 >> b; + assert(w < 64 * 256); + if ((dimap[w] & m) == 0) { + printk("DEBUG diFree: duplicate free ino:0x%x\n", ino); + } + dimap[w] &= ~m; +} + +static void dump_cp(imap_t * ipimap, char *function, int line) +{ + printk("\n* ********* *\nControl Page %s %d\n", function, line); + printk("FreeIAG %d\tNextIAG %d\n", ipimap->im_freeiag, + ipimap->im_nextiag); + printk("NumInos %d\tNumFree %d\n", + atomic_read(&ipimap->im_numinos), + atomic_read(&ipimap->im_numfree)); + printk("AG InoFree %d\tAG ExtFree %d\n", + ipimap->im_agctl[0].inofree, ipimap->im_agctl[0].extfree); + printk("AG NumInos %d\tAG NumFree %d\n", + ipimap->im_agctl[0].numinos, ipimap->im_agctl[0].numfree); +} + +static void dump_iag(iag_t * iag, char *function, int line) +{ + printk("\n* ********* *\nIAG %s %d\n", function, line); + printk("IagNum %d\tIAG Free %d\n", le32_to_cpu(iag->iagnum), + le32_to_cpu(iag->iagfree)); + printk("InoFreeFwd %d\tInoFreeBack %d\n", + le32_to_cpu(iag->inofreefwd), + le32_to_cpu(iag->inofreeback)); + printk("ExtFreeFwd %d\tExtFreeBack %d\n", + le32_to_cpu(iag->extfreefwd), + le32_to_cpu(iag->extfreeback)); + printk("NFreeInos %d\tNFreeExts %d\n", le32_to_cpu(iag->nfreeinos), + le32_to_cpu(iag->nfreeexts)); +} +#endif /* _JFS_DEBUG_IMAP */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_imap.h linux.19pre5-ac1/fs/jfs/jfs_imap.h --- linux.19p5/fs/jfs/jfs_imap.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_imap.h Thu Apr 4 16:04:13 2002 @@ -0,0 +1,161 @@ +/* + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _H_JFS_IMAP +#define _H_JFS_IMAP + +#include "jfs_txnmgr.h" + +/* + * jfs_imap.h: disk inode manager + */ + +#define EXTSPERIAG 128 /* number of disk inode extent per iag */ +#define IMAPBLKNO 0 /* lblkno of dinomap within inode map */ +#define SMAPSZ 4 /* number of words per summary map */ +#define EXTSPERSUM 32 /* number of extents per summary map entry */ +#define L2EXTSPERSUM 5 /* l2 number of extents per summary map */ +#define PGSPERIEXT 4 /* number of 4K pages per dinode extent */ +#define MAXIAGS ((1<<20)-1) /* maximum number of iags */ +#define MAXAG 128 /* maximum number of allocation groups */ + +#define AMAPSIZE 512 /* bytes in the IAG allocation maps */ +#define SMAPSIZE 16 /* bytes in the IAG summary maps */ + +/* convert inode number to iag number */ +#define INOTOIAG(ino) ((ino) >> L2INOSPERIAG) + +/* convert iag number to logical block number of the iag page */ +#define IAGTOLBLK(iagno,l2nbperpg) (((iagno) + 1) << (l2nbperpg)) + +/* get the starting block number of the 4K page of an inode extent + * that contains ino. + */ +#define INOPBLK(pxd,ino,l2nbperpg) (addressPXD((pxd)) + \ + ((((ino) & (INOSPEREXT-1)) >> L2INOSPERPAGE) << (l2nbperpg))) + +/* + * inode allocation map: + * + * inode allocation map consists of + * . the inode map control page and + * . inode allocation group pages (per 4096 inodes) + * which are addressed by standard JFS xtree. + */ +/* + * inode allocation group page (per 4096 inodes of an AG) + */ +typedef struct { + s64 agstart; /* 8: starting block of ag */ + s32 iagnum; /* 4: inode allocation group number */ + s32 inofreefwd; /* 4: ag inode free list forward */ + s32 inofreeback; /* 4: ag inode free list back */ + s32 extfreefwd; /* 4: ag inode extent free list forward */ + s32 extfreeback; /* 4: ag inode extent free list back */ + s32 iagfree; /* 4: iag free list */ + + /* summary map: 1 bit per inode extent */ + s32 inosmap[SMAPSZ]; /* 16: sum map of mapwords w/ free inodes; + * note: this indicates free and backed + * inodes, if the extent is not backed the + * value will be 1. if the extent is + * backed but all inodes are being used the + * value will be 1. if the extent is + * backed but at least one of the inodes is + * free the value will be 0. + */ + s32 extsmap[SMAPSZ]; /* 16: sum map of mapwords w/ free extents */ + s32 nfreeinos; /* 4: number of free inodes */ + s32 nfreeexts; /* 4: number of free extents */ + /* (72) */ + u8 pad[1976]; /* 1976: pad to 2048 bytes */ + /* allocation bit map: 1 bit per inode (0 - free, 1 - allocated) */ + u32 wmap[EXTSPERIAG]; /* 512: working allocation map */ + u32 pmap[EXTSPERIAG]; /* 512: persistent allocation map */ + pxd_t inoext[EXTSPERIAG]; /* 1024: inode extent addresses */ +} iag_t; /* (4096) */ + +/* + * per AG control information (in inode map control page) + */ +typedef struct { + s32 inofree; /* 4: free inode list anchor */ + s32 extfree; /* 4: free extent list anchor */ + s32 numinos; /* 4: number of backed inodes */ + s32 numfree; /* 4: number of free inodes */ +} iagctl_t; /* (16) */ + +/* + * per fileset/aggregate inode map control page + */ +typedef struct { + s32 in_freeiag; /* 4: free iag list anchor */ + s32 in_nextiag; /* 4: next free iag number */ + s32 in_numinos; /* 4: num of backed inodes */ + s32 in_numfree; /* 4: num of free backed inodes */ + s32 in_nbperiext; /* 4: num of blocks per inode extent */ + s32 in_l2nbperiext; /* 4: l2 of in_nbperiext */ + s32 in_diskblock; /* 4: for standalone test driver */ + s32 in_maxag; /* 4: for standalone test driver */ + u8 pad[2016]; /* 2016: pad to 2048 */ + iagctl_t in_agctl[MAXAG]; /* 2048: AG control information */ +} dinomap_t; /* (4096) */ + + +/* + * In-core inode map control page + */ +typedef struct inomap { + dinomap_t im_imap; /* 4096: inode allocation control */ + struct inode *im_ipimap; /* 4: ptr to inode for imap */ + struct semaphore im_freelock; /* 4: iag free list lock */ + struct semaphore im_aglock[MAXAG]; /* 512: per AG locks */ + u32 *im_DBGdimap; + atomic_t im_numinos; /* num of backed inodes */ + atomic_t im_numfree; /* num of free backed inodes */ +} imap_t; + +#define im_freeiag im_imap.in_freeiag +#define im_nextiag im_imap.in_nextiag +#define im_agctl im_imap.in_agctl +#define im_nbperiext im_imap.in_nbperiext +#define im_l2nbperiext im_imap.in_l2nbperiext + +/* for standalone testdriver + */ +#define im_diskblock im_imap.in_diskblock +#define im_maxag im_imap.in_maxag + +extern int diFree(struct inode *); +extern int diAlloc(struct inode *, boolean_t, struct inode *); +extern int diSync(struct inode *); +/* external references */ +extern int diUpdatePMap(struct inode *ipimap, unsigned long inum, + boolean_t is_free, tblock_t * tblk); +#ifdef _STILL_TO_PORT +extern int diExtendFS(inode_t * ipimap, inode_t * ipbmap); +#endif /* _STILL_TO_PORT */ + +extern int diMount(struct inode *); +extern int diUnmount(struct inode *, int); +extern int diRead(struct inode *); +extern void diClearExtension(struct inode *); +extern struct inode *diReadSpecial(struct super_block *, ino_t); +extern void diWriteSpecial(struct inode *); +extern void diFreeSpecial(struct inode *); +extern int diWrite(tid_t tid, struct inode *); +#endif /* _H_JFS_IMAP */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_incore.h linux.19pre5-ac1/fs/jfs/jfs_incore.h --- linux.19p5/fs/jfs/jfs_incore.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_incore.h Thu Apr 4 16:04:13 2002 @@ -0,0 +1,155 @@ +/* + * + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ +#ifndef _H_JFS_INCORE +#define _H_JFS_INCORE + +#include +#include +#include "jfs_types.h" +#include "jfs_xtree.h" +#include "jfs_dtree.h" + +/* + * JFS magic number + */ +#define JFS_SUPER_MAGIC 0x3153464a /* "JFS1" */ + +/* + * Due to header ordering problems this can't be in jfs_lock.h + */ +typedef struct jfs_rwlock { + struct rw_semaphore rw_sem; + atomic_t in_use; /* for hacked implementation of trylock */ +} jfs_rwlock_t; + +/* + * JFS-private inode information + */ +struct jfs_inode_info { + struct inode *inode; /* pointer back to fs-independent inode */ + int fileset; /* fileset number (always 16)*/ + uint mode2; /* jfs-specific mode */ + pxd_t ixpxd; /* inode extent descriptor */ + dxd_t acl; /* dxd describing acl */ + dxd_t ea; /* dxd describing ea */ + time_t otime; /* time created */ + uint next_index; /* next available directory entry index */ + int acltype; /* Type of ACL */ + short btorder; /* access order */ + short btindex; /* btpage entry index*/ + struct inode *ipimap; /* inode map */ + long cflag; /* commit flags */ + u16 bxflag; /* xflag of pseudo buffer? */ + unchar agno; /* ag number */ + unchar pad; /* pad */ + lid_t blid; /* lid of pseudo buffer? */ + lid_t atlhead; /* anonymous tlock list head */ + lid_t atltail; /* anonymous tlock list tail */ + struct list_head anon_inode_list; /* inodes having anonymous txns */ + struct list_head mp_list; /* metapages in inode's address space */ + jfs_rwlock_t rdwrlock; /* read/write lock */ + lid_t xtlid; /* lid of xtree lock on directory */ + union { + struct { + xtpage_t _xtroot; /* 288: xtree root */ + struct inomap *_imap; /* 4: inode map header */ + } file; + struct { + dir_table_slot_t _table[12]; /* 96: directory index */ + dtroot_t _dtroot; /* 288: dtree root */ + } dir; + struct { + unchar _unused[16]; /* 16: */ + dxd_t _dxd; /* 16: */ + unchar _inline[128]; /* 128: inline symlink */ + } link; + } u; +}; +#define i_xtroot u.file._xtroot +#define i_imap u.file._imap +#define i_dirtable u.dir._table +#define i_dtroot u.dir._dtroot +#define i_inline u.link._inline + +/* + * cflag + */ +enum cflags { + COMMIT_New, /* never committed inode */ + COMMIT_Nolink, /* inode committed with zero link count */ + COMMIT_Inlineea, /* commit inode inline EA */ + COMMIT_Freewmap, /* free WMAP at iClose() */ + COMMIT_Dirty, /* Inode is really dirty */ + COMMIT_Holdlock, /* Hold the IWRITE_LOCK until commit is done */ + COMMIT_Dirtable, /* commit changes to di_dirtable */ + COMMIT_Stale, /* data extent is no longer valid */ + COMMIT_Synclist, /* metadata pages on group commit synclist */ +}; + +#define set_cflag(flag, ip) set_bit(flag, &(JFS_IP(ip)->cflag)) +#define clear_cflag(flag, ip) clear_bit(flag, &(JFS_IP(ip)->cflag)) +#define test_cflag(flag, ip) test_bit(flag, &(JFS_IP(ip)->cflag)) +#define test_and_clear_cflag(flag, ip) \ + test_and_clear_bit(flag, &(JFS_IP(ip)->cflag)) +/* + * JFS-private superblock information. + */ +struct jfs_sb_info { + unsigned long mntflag; /* 4: aggregate attributes */ + struct inode *ipbmap; /* 4: block map inode */ + struct inode *ipaimap; /* 4: aggregate inode map inode */ + struct inode *ipaimap2; /* 4: secondary aimap inode */ + struct inode *ipimap; /* 4: aggregate inode map inode */ + struct jfs_log *log; /* 4: log */ + short bsize; /* 2: logical block size */ + short l2bsize; /* 2: log2 logical block size */ + short nbperpage; /* 2: blocks per page */ + short l2nbperpage; /* 2: log2 blocks per page */ + short l2niperblk; /* 2: log2 inodes per page */ + short reserved; /* 2: log2 inodes per page */ + pxd_t logpxd; /* 8: pxd describing log */ + pxd_t ait2; /* 8: pxd describing AIT copy */ + /* Formerly in ipimap */ + uint gengen; /* 4: inode generation generator*/ + uint inostamp; /* 4: shows inode belongs to fileset*/ + + /* Formerly in ipbmap */ + struct bmap *bmap; /* 4: incore bmap descriptor */ + struct nls_table *nls_tab; /* 4: current codepage */ + struct inode *direct_inode; /* 4: inode for physical I/O */ + struct address_space *direct_mapping; /* 4: mapping for physical I/O */ + uint state; /* 4: mount/recovery state */ +}; + +#define JFS_IP(ip) ((struct jfs_inode_info *)(ip)->u.generic_ip) +#define JFS_SBI(sb) ((struct jfs_sb_info *)(sb)->u.generic_sbp) + +#define isReadOnly(ip) ((JFS_SBI((ip)->i_sb)->log) ? 0 : 1) + +/* + * Allocating and freeing the structure + */ +extern kmem_cache_t *jfs_inode_cachep; +extern int alloc_jfs_inode(struct inode *); + +#define free_jfs_inode(inode) \ + kmem_cache_free(jfs_inode_cachep, (inode)->u.generic_ip) + +#endif /* _H_JFS_INCORE */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_inode.c linux.19pre5-ac1/fs/jfs/jfs_inode.c --- linux.19p5/fs/jfs/jfs_inode.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_inode.c Thu Mar 14 22:44:22 2002 @@ -0,0 +1,160 @@ +/* + * + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include "jfs_incore.h" +#include "jfs_filsys.h" +#include "jfs_imap.h" +#include "jfs_dinode.h" +#include "jfs_debug.h" + +kmem_cache_t *jfs_inode_cachep; + +/* + * NAME: ialloc() + * + * FUNCTION: Allocate a new inode + * + */ +struct inode *ialloc(struct inode *parent, umode_t mode) +{ + struct super_block *sb = parent->i_sb; + struct inode *inode; + struct jfs_inode_info *jfs_inode; + int rc; + + inode = new_inode(sb); + if (!inode) { + jERROR(1, ("ialloc: new_inode returned NULL!\n")); + return inode; + } + + rc = alloc_jfs_inode(inode); + if (rc) { + make_bad_inode(inode); + iput(inode); + return NULL; + } + jfs_inode = JFS_IP(inode); + + rc = diAlloc(parent, S_ISDIR(mode), inode); + if (rc) { + jERROR(1, ("ialloc: diAlloc returned %d!\n", rc)); + free_jfs_inode(inode); + make_bad_inode(inode); + iput(inode); + return NULL; + } + + inode->i_uid = current->fsuid; + if (parent->i_mode & S_ISGID) { + inode->i_gid = parent->i_gid; + if (S_ISDIR(mode)) + mode |= S_ISGID; + } else + inode->i_gid = current->fsgid; + + inode->i_mode = mode; + if (S_ISDIR(mode)) + jfs_inode->mode2 = IDIRECTORY | mode; + else + jfs_inode->mode2 = INLINEEA | ISPARSE | mode; + inode->i_blksize = sb->s_blocksize; + inode->i_blocks = 0; + inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; + jfs_inode->otime = inode->i_ctime; + inode->i_version = ++event; + inode->i_generation = JFS_SBI(sb)->gengen++; + + jfs_inode->cflag = 0; + set_cflag(COMMIT_New, inode); + + /* Zero remaining fields */ + memset(&jfs_inode->acl, 0, sizeof(dxd_t)); + memset(&jfs_inode->ea, 0, sizeof(dxd_t)); + jfs_inode->next_index = 0; + jfs_inode->acltype = 0; + jfs_inode->btorder = 0; + jfs_inode->btindex = 0; + jfs_inode->bxflag = 0; + jfs_inode->blid = 0; + jfs_inode->atlhead = 0; + jfs_inode->atltail = 0; + jfs_inode->xtlid = 0; + + jFYI(1, ("ialloc returns inode = 0x%p\n", inode)); + + return inode; +} + +/* + * NAME: iwritelocklist() + * + * FUNCTION: Lock multiple inodes in sorted order to avoid deadlock + * + */ +void iwritelocklist(int n, ...) +{ + va_list ilist; + struct inode *sort[4]; + struct inode *ip; + int k, m; + + va_start(ilist, n); + for (k = 0; k < n; k++) + sort[k] = va_arg(ilist, struct inode *); + va_end(ilist); + + /* Bubble sort in descending order */ + do { + m = 0; + for (k = 0; k < n; k++) + if ((k + 1) < n + && sort[k + 1]->i_ino > sort[k]->i_ino) { + ip = sort[k]; + sort[k] = sort[k + 1]; + sort[k + 1] = ip; + m++; + } + } while (m); + + /* Lock them */ + for (k = 0; k < n; k++) { + IWRITE_LOCK(sort[k]); + } +} + +/* + * NAME: alloc_jfs_inode() + * + * FUNCTION: Allocate jfs portion of in-memory inode + * + */ +int alloc_jfs_inode(struct inode *inode) +{ + struct jfs_inode_info *jfs_inode; + + jfs_inode = kmem_cache_alloc(jfs_inode_cachep, GFP_NOFS); + JFS_IP(inode) = jfs_inode; + if (!jfs_inode) + return -ENOSPC; + jfs_inode->inode = inode; + + return 0; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_inode.h linux.19pre5-ac1/fs/jfs/jfs_inode.h --- linux.19p5/fs/jfs/jfs_inode.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_inode.h Thu Feb 14 20:46:53 2002 @@ -0,0 +1,23 @@ +/* + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _H_JFS_INODE +#define _H_JFS_INODE + +extern struct inode *ialloc(struct inode *, umode_t); + +#endif /* _H_JFS_INODE */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_lock.h linux.19pre5-ac1/fs/jfs/jfs_lock.h --- linux.19p5/fs/jfs/jfs_lock.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_lock.h Thu Apr 4 16:04:13 2002 @@ -0,0 +1,106 @@ +/* + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _H_JFS_LOCK +#define _H_JFS_LOCK + +#include +#include + +/* + * jfs_lock.h + * + * JFS lock definition for globally referenced locks + */ + +/* readers/writer lock: thread-thread */ + +/* + * RW semaphores do not currently have a trylock function. Since the + * implementation varies by platform, I have implemented a platform-independent + * wrapper around the rw_semaphore routines. If this turns out to be the best + * way of avoiding our locking problems, I will push to get a trylock + * implemented in the kernel, but I'd rather find a way to avoid having to + * use it. + */ +#define RDWRLOCK_T jfs_rwlock_t +static inline void RDWRLOCK_INIT(jfs_rwlock_t * Lock) +{ + init_rwsem(&Lock->rw_sem); + atomic_set(&Lock->in_use, 0); +} +static inline void READ_LOCK(jfs_rwlock_t * Lock) +{ + atomic_inc(&Lock->in_use); + down_read(&Lock->rw_sem); +} +static inline void READ_UNLOCK(jfs_rwlock_t * Lock) +{ + up_read(&Lock->rw_sem); + atomic_dec(&Lock->in_use); +} +static inline void WRITE_LOCK(jfs_rwlock_t * Lock) +{ + atomic_inc(&Lock->in_use); + down_write(&Lock->rw_sem); +} + +static inline int WRITE_TRYLOCK(jfs_rwlock_t * Lock) +{ + if (atomic_read(&Lock->in_use)) + return 0; + WRITE_LOCK(Lock); + return 1; +} +static inline void WRITE_UNLOCK(jfs_rwlock_t * Lock) +{ + up_write(&Lock->rw_sem); + atomic_dec(&Lock->in_use); +} + +#define IREAD_LOCK(ip) READ_LOCK(&JFS_IP(ip)->rdwrlock) +#define IREAD_UNLOCK(ip) READ_UNLOCK(&JFS_IP(ip)->rdwrlock) +#define IWRITE_LOCK(ip) WRITE_LOCK(&JFS_IP(ip)->rdwrlock) +#define IWRITE_TRYLOCK(ip) WRITE_TRYLOCK(&JFS_IP(ip)->rdwrlock) +#define IWRITE_UNLOCK(ip) WRITE_UNLOCK(&JFS_IP(ip)->rdwrlock) +#define IWRITE_LOCK_LIST iwritelocklist + +extern void iwritelocklist(int, ...); + +/* + * Conditional sleep where condition is protected by spinlock + * + * lock_cmd and unlock_cmd take and release the spinlock + */ +#define __SLEEP_COND(wq, cond, lock_cmd, unlock_cmd) \ +do { \ + DECLARE_WAITQUEUE(__wait, current); \ + \ + add_wait_queue(&wq, &__wait); \ + for (;;) { \ + set_current_state(TASK_UNINTERRUPTIBLE);\ + if (cond) \ + break; \ + unlock_cmd; \ + schedule(); \ + lock_cmd; \ + } \ + current->state = TASK_RUNNING; \ + remove_wait_queue(&wq, &__wait); \ +} while (0) + +#endif /* _H_JFS_LOCK */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_logmgr.c linux.19pre5-ac1/fs/jfs/jfs_logmgr.c --- linux.19p5/fs/jfs/jfs_logmgr.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_logmgr.c Fri Mar 22 16:35:53 2002 @@ -0,0 +1,2388 @@ +/* + * + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + * +*/ + +/* + * jfs_logmgr.c: log manager + * + * for related information, see transaction manager (jfs_txnmgr.c), and + * recovery manager (jfs_logredo.c). + * + * note: for detail, RTFS. + * + * log buffer manager: + * special purpose buffer manager supporting log i/o requirements. + * per log serial pageout of logpage + * queuing i/o requests and redrive i/o at iodone + * maintain current logpage buffer + * no caching since append only + * appropriate jfs buffer cache buffers as needed + * + * group commit: + * transactions which wrote COMMIT records in the same in-memory + * log page during the pageout of previous/current log page(s) are + * committed together by the pageout of the page. + * + * TBD lazy commit: + * transactions are committed asynchronously when the log page + * containing it COMMIT is paged out when it becomes full; + * + * serialization: + * . a per log lock serialize log write. + * . a per log lock serialize group commit. + * . a per log lock serialize log open/close; + * + * TBD log integrity: + * careful-write (ping-pong) of last logpage to recover from crash + * in overwrite. + * detection of split (out-of-order) write of physical sectors + * of last logpage via timestamp at end of each sector + * with its mirror data array at trailer). + * + * alternatives: + * lsn - 64-bit monotonically increasing integer vs + * 32-bit lspn and page eor. + */ + +#include +#include +#include +#include +#include +#include +#include "jfs_incore.h" +#include "jfs_filsys.h" +#include "jfs_metapage.h" +#include "jfs_txnmgr.h" +#include "jfs_debug.h" + + +/* + * lbuf's ready to be redriven. Protected by log_redrive_lock (jfsIOtask) + */ +static lbuf_t *log_redrive_list; +static spinlock_t log_redrive_lock = SPIN_LOCK_UNLOCKED; + + +/* + * log read/write serialization (per log) + */ +#define LOG_LOCK_INIT(log) init_MUTEX(&(log)->loglock) +#define LOG_LOCK(log) down(&((log)->loglock)) +#define LOG_UNLOCK(log) up(&((log)->loglock)) + + +/* + * log group commit serialization (per log) + */ + +#define LOGGC_LOCK_INIT(log) spin_lock_init(&(log)->gclock) +#define LOGGC_LOCK(log) spin_lock_irq(&(log)->gclock) +#define LOGGC_UNLOCK(log) spin_unlock_irq(&(log)->gclock) +#define LOGGC_WAKEUP(tblk) wake_up(&(tblk)->gcwait) + +/* + * log sync serialization (per log) + */ +#define LOGSYNC_DELTA(logsize) min((logsize)/8, 128*LOGPSIZE) +#define LOGSYNC_BARRIER(logsize) ((logsize)/4) +/* +#define LOGSYNC_DELTA(logsize) min((logsize)/4, 256*LOGPSIZE) +#define LOGSYNC_BARRIER(logsize) ((logsize)/2) +*/ + + +/* + * log buffer cache synchronization + */ +static spinlock_t jfsLCacheLock = SPIN_LOCK_UNLOCKED; + +#define LCACHE_LOCK(flags) spin_lock_irqsave(&jfsLCacheLock, flags) +#define LCACHE_UNLOCK(flags) spin_unlock_irqrestore(&jfsLCacheLock, flags) + +/* + * See __SLEEP_COND in jfs_locks.h + */ +#define LCACHE_SLEEP_COND(wq, cond, flags) \ +do { \ + if (cond) \ + break; \ + __SLEEP_COND(wq, cond, LCACHE_LOCK(flags), LCACHE_UNLOCK(flags)); \ +} while (0) + +#define LCACHE_WAKEUP(event) wake_up(event) + + +/* + * lbuf buffer cache (lCache) control + */ +/* log buffer manager pageout control (cumulative, inclusive) */ +#define lbmREAD 0x0001 +#define lbmWRITE 0x0002 /* enqueue at tail of write queue; + * init pageout if at head of queue; + */ +#define lbmRELEASE 0x0004 /* remove from write queue + * at completion of pageout; + * do not free/recycle it yet: + * caller will free it; + */ +#define lbmSYNC 0x0008 /* do not return to freelist + * when removed from write queue; + */ +#define lbmFREE 0x0010 /* return to freelist + * at completion of pageout; + * the buffer may be recycled; + */ +#define lbmDONE 0x0020 +#define lbmERROR 0x0040 +#define lbmGC 0x0080 /* lbmIODone to perform post-GC processing + * of log page + */ +#define lbmDIRECT 0x0100 + +/* + * external references + */ +extern void vPut(struct inode *ip); +extern void txLazyUnlock(tblock_t * tblk); +extern int jfs_thread_stopped(void); +extern struct task_struct *jfsIOtask; +extern struct completion jfsIOwait; + +/* + * forward references + */ +static int lmWriteRecord(log_t * log, tblock_t * tblk, lrd_t * lrd, + tlock_t * tlck); + +static int lmNextPage(log_t * log); +static int lmLogInit(log_t * log); +static int lmLogShutdown(log_t * log); + +static int lbmLogInit(log_t * log); +static void lbmLogShutdown(log_t * log); +static lbuf_t *lbmAllocate(log_t * log, int); +static void lbmFree(lbuf_t * bp); +static void lbmfree(lbuf_t * bp); +static int lbmRead(log_t * log, int pn, lbuf_t ** bpp); +static void lbmWrite(log_t * log, lbuf_t * bp, int flag, int cant_block); +static void lbmDirectWrite(log_t * log, lbuf_t * bp, int flag); +static int lbmIOWait(lbuf_t * bp, int flag); +static void lbmIODone(struct buffer_head *bh, int); + +void lbmStartIO(lbuf_t * bp); +void lmGCwrite(log_t * log, int cant_block); + + +/* + * statistics + */ +#ifdef CONFIG_JFS_STATISTICS +struct lmStat { + uint commit; /* # of commit */ + uint pagedone; /* # of page written */ + uint submitted; /* # of pages submitted */ +} lmStat; +#endif + + +/* + * NAME: lmLog() + * + * FUNCTION: write a log record; + * + * PARAMETER: + * + * RETURN: lsn - offset to the next log record to write (end-of-log); + * -1 - error; + * + * note: todo: log error handler + */ +int lmLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck) +{ + int lsn; + int diffp, difft; + metapage_t *mp = NULL; + + jFYI(1, ("lmLog: log:0x%p tblk:0x%p, lrd:0x%p tlck:0x%p\n", + log, tblk, lrd, tlck)); + + LOG_LOCK(log); + + /* log by (out-of-transaction) JFS ? */ + if (tblk == NULL) + goto writeRecord; + + /* log from page ? */ + if (tlck == NULL || + tlck->type & tlckBTROOT || (mp = tlck->mp) == NULL) + goto writeRecord; + + /* + * initialize/update page/transaction recovery lsn + */ + lsn = log->lsn; + + LOGSYNC_LOCK(log); + + /* + * initialize page lsn if first log write of the page + */ + if (mp->lsn == 0) { + mp->log = log; + mp->lsn = lsn; + log->count++; + + /* insert page at tail of logsynclist */ + list_add_tail(&mp->synclist, &log->synclist); + } + + /* + * initialize/update lsn of tblock of the page + * + * transaction inherits oldest lsn of pages associated + * with allocation/deallocation of resources (their + * log records are used to reconstruct allocation map + * at recovery time: inode for inode allocation map, + * B+-tree index of extent descriptors for block + * allocation map); + * allocation map pages inherit transaction lsn at + * commit time to allow forwarding log syncpt past log + * records associated with allocation/deallocation of + * resources only after persistent map of these map pages + * have been updated and propagated to home. + */ + /* + * initialize transaction lsn: + */ + if (tblk->lsn == 0) { + /* inherit lsn of its first page logged */ + tblk->lsn = mp->lsn; + log->count++; + + /* insert tblock after the page on logsynclist */ + list_add(&tblk->synclist, &mp->synclist); + } + /* + * update transaction lsn: + */ + else { + /* inherit oldest/smallest lsn of page */ + logdiff(diffp, mp->lsn, log); + logdiff(difft, tblk->lsn, log); + if (diffp < difft) { + /* update tblock lsn with page lsn */ + tblk->lsn = mp->lsn; + + /* move tblock after page on logsynclist */ + list_del(&tblk->synclist); + list_add(&tblk->synclist, &mp->synclist); + } + } + + LOGSYNC_UNLOCK(log); + + /* + * write the log record + */ + writeRecord: + lsn = lmWriteRecord(log, tblk, lrd, tlck); + + /* + * forward log syncpt if log reached next syncpt trigger + */ + logdiff(diffp, lsn, log); + if (diffp >= log->nextsync) + lsn = lmLogSync(log, 0); + + /* update end-of-log lsn */ + log->lsn = lsn; + + LOG_UNLOCK(log); + + /* return end-of-log address */ + return lsn; +} + + +/* + * NAME: lmWriteRecord() + * + * FUNCTION: move the log record to current log page + * + * PARAMETER: cd - commit descriptor + * + * RETURN: end-of-log address + * + * serialization: LOG_LOCK() held on entry/exit + */ +static int +lmWriteRecord(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck) +{ + int lsn = 0; /* end-of-log address */ + lbuf_t *bp; /* dst log page buffer */ + logpage_t *lp; /* dst log page */ + caddr_t dst; /* destination address in log page */ + int dstoffset; /* end-of-log offset in log page */ + int freespace; /* free space in log page */ + caddr_t p; /* src meta-data page */ + caddr_t src; + int srclen; + int nbytes; /* number of bytes to move */ + int i; + int len; + linelock_t *linelock; + lv_t *lv; + lvd_t *lvd; + int l2linesize; + + len = 0; + + /* retrieve destination log page to write */ + bp = (lbuf_t *) log->bp; + lp = (logpage_t *) bp->l_ldata; + dstoffset = log->eor; + + /* any log data to write ? */ + if (tlck == NULL) + goto moveLrd; + + /* + * move log record data + */ + /* retrieve source meta-data page to log */ + if (tlck->flag & tlckPAGELOCK) { + p = (caddr_t) (tlck->mp->data); + linelock = (linelock_t *) & tlck->lock; + } + /* retrieve source in-memory inode to log */ + else if (tlck->flag & tlckINODELOCK) { + if (tlck->type & tlckDTREE) + p = (caddr_t) &JFS_IP(tlck->ip)->i_dtroot; + else + p = (caddr_t) &JFS_IP(tlck->ip)->i_xtroot; + linelock = (linelock_t *) & tlck->lock; + } +#ifdef _JFS_WIP + else if (tlck->flag & tlckINLINELOCK) { + + inlinelock = (inlinelock_t *) & tlck; + p = (caddr_t) & inlinelock->pxd; + linelock = (linelock_t *) & tlck; + } +#endif /* _JFS_WIP */ + else { + jERROR(2, ("lmWriteRecord: UFO tlck:0x%p\n", tlck)); + return 0; /* Probably should trap */ + } + l2linesize = linelock->l2linesize; + + moveData: + ASSERT(linelock->index <= linelock->maxcnt); + + lv = (lv_t *) & linelock->lv; + for (i = 0; i < linelock->index; i++, lv++) { + if (lv->length == 0) + continue; + + /* is page full ? */ + if (dstoffset >= LOGPSIZE - LOGPTLRSIZE) { + /* page become full: move on to next page */ + lmNextPage(log); + + bp = log->bp; + lp = (logpage_t *) bp->l_ldata; + dstoffset = LOGPHDRSIZE; + } + + /* + * move log vector data + */ + src = (u8 *) p + (lv->offset << l2linesize); + srclen = lv->length << l2linesize; + len += srclen; + while (srclen > 0) { + freespace = (LOGPSIZE - LOGPTLRSIZE) - dstoffset; + nbytes = min(freespace, srclen); + dst = (caddr_t) lp + dstoffset; + memcpy(dst, src, nbytes); + dstoffset += nbytes; + + /* is page not full ? */ + if (dstoffset < LOGPSIZE - LOGPTLRSIZE) + break; + + /* page become full: move on to next page */ + lmNextPage(log); + + bp = (lbuf_t *) log->bp; + lp = (logpage_t *) bp->l_ldata; + dstoffset = LOGPHDRSIZE; + + srclen -= nbytes; + src += nbytes; + } + + /* + * move log vector descriptor + */ + len += 4; + lvd = (lvd_t *) ((caddr_t) lp + dstoffset); + lvd->offset = cpu_to_le16(lv->offset); + lvd->length = cpu_to_le16(lv->length); + dstoffset += 4; + jFYI(1, + ("lmWriteRecord: lv offset:%d length:%d\n", + lv->offset, lv->length)); + } + + if ((i = linelock->next)) { + linelock = (linelock_t *) lid_to_tlock(i); + goto moveData; + } + + /* + * move log record descriptor + */ + moveLrd: + lrd->length = cpu_to_le16(len); + + src = (caddr_t) lrd; + srclen = LOGRDSIZE; + + while (srclen > 0) { + freespace = (LOGPSIZE - LOGPTLRSIZE) - dstoffset; + nbytes = min(freespace, srclen); + dst = (caddr_t) lp + dstoffset; + memcpy(dst, src, nbytes); + + dstoffset += nbytes; + srclen -= nbytes; + + /* are there more to move than freespace of page ? */ + if (srclen) + goto pageFull; + + /* + * end of log record descriptor + */ + + /* update last log record eor */ + log->eor = dstoffset; + bp->l_eor = dstoffset; + lsn = (log->page << L2LOGPSIZE) + dstoffset; + + if (lrd->type & cpu_to_le16(LOG_COMMIT)) { + tblk->clsn = lsn; + jFYI(1, + ("wr: tclsn:0x%x, beor:0x%x\n", tblk->clsn, + bp->l_eor)); + + INCREMENT(lmStat.commit); /* # of commit */ + + /* + * enqueue tblock for group commit: + * + * enqueue tblock of non-trivial/synchronous COMMIT + * at tail of group commit queue + * (trivial/asynchronous COMMITs are ignored by + * group commit.) + */ + LOGGC_LOCK(log); + + /* init tblock gc state */ + tblk->flag = tblkGC_QUEUE; + tblk->bp = log->bp; + tblk->pn = log->page; + tblk->eor = log->eor; + init_waitqueue_head(&tblk->gcwait); + + /* enqueue transaction to commit queue */ + tblk->cqnext = NULL; + if (log->cqueue.head) { + log->cqueue.tail->cqnext = tblk; + log->cqueue.tail = tblk; + } else + log->cqueue.head = log->cqueue.tail = tblk; + + LOGGC_UNLOCK(log); + } + + jFYI(1, + ("lmWriteRecord: lrd:0x%04x bp:0x%p pn:%d eor:0x%x\n", + le16_to_cpu(lrd->type), log->bp, log->page, + dstoffset)); + + /* page not full ? */ + if (dstoffset < LOGPSIZE - LOGPTLRSIZE) + return lsn; + + pageFull: + /* page become full: move on to next page */ + lmNextPage(log); + + bp = (lbuf_t *) log->bp; + lp = (logpage_t *) bp->l_ldata; + dstoffset = LOGPHDRSIZE; + src += nbytes; + } + + return lsn; +} + + +/* + * NAME: lmNextPage() + * + * FUNCTION: write current page and allocate next page. + * + * PARAMETER: log + * + * RETURN: 0 + * + * serialization: LOG_LOCK() held on entry/exit + */ +static int lmNextPage(log_t * log) +{ + logpage_t *lp; + int lspn; /* log sequence page number */ + int pn; /* current page number */ + lbuf_t *bp; + lbuf_t *nextbp; + tblock_t *tblk; + + jFYI(1, ("lmNextPage\n")); + + /* get current log page number and log sequence page number */ + pn = log->page; + bp = log->bp; + lp = (logpage_t *) bp->l_ldata; + lspn = le32_to_cpu(lp->h.page); + + LOGGC_LOCK(log); + + /* + * write or queue the full page at the tail of write queue + */ + /* get the tail tblk on commit queue */ + tblk = log->cqueue.tail; + + /* every tblk who has COMMIT record on the current page, + * and has not been committed, must be on commit queue + * since tblk is queued at commit queueu at the time + * of writing its COMMIT record on the page before + * page becomes full (even though the tblk thread + * who wrote COMMIT record may have been suspended + * currently); + */ + + /* is page bound with outstanding tail tblk ? */ + if (tblk && tblk->pn == pn) { + /* mark tblk for end-of-page */ + tblk->flag |= tblkGC_EOP; + + /* if page is not already on write queue, + * just enqueue (no lbmWRITE to prevent redrive) + * buffer to wqueue to ensure correct serial order + * of the pages since log pages will be added + * continuously (tblk bound with the page hasn't + * got around to init write of the page, either + * preempted or the page got filled by its COMMIT + * record); + * pages with COMMIT are paged out explicitly by + * tblk in lmGroupCommit(); + */ + if (bp->l_wqnext == NULL) { + /* bp->l_ceor = bp->l_eor; */ + /* lp->h.eor = lp->t.eor = bp->l_ceor; */ + lbmWrite(log, bp, 0, 0); + } + } + /* page is not bound with outstanding tblk: + * init write or mark it to be redriven (lbmWRITE) + */ + else { + /* finalize the page */ + bp->l_ceor = bp->l_eor; + lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_ceor); + lbmWrite(log, bp, lbmWRITE | lbmRELEASE | lbmFREE, 0); + } + LOGGC_UNLOCK(log); + + /* + * allocate/initialize next page + */ + /* if log wraps, the first data page of log is 2 + * (0 never used, 1 is superblock). + */ + log->page = (pn == log->size - 1) ? 2 : pn + 1; + log->eor = LOGPHDRSIZE; /* ? valid page empty/full at logRedo() */ + + /* allocate/initialize next log page buffer */ + nextbp = lbmAllocate(log, log->page); + nextbp->l_eor = log->eor; + log->bp = nextbp; + + /* initialize next log page */ + lp = (logpage_t *) nextbp->l_ldata; + lp->h.page = lp->t.page = cpu_to_le32(lspn + 1); + lp->h.eor = lp->t.eor = cpu_to_le16(LOGPHDRSIZE); + + jFYI(1, ("lmNextPage done\n")); + return 0; +} + + +/* + * NAME: lmGroupCommit() + * + * FUNCTION: group commit + * initiate pageout of the pages with COMMIT in the order of + * page number - redrive pageout of the page at the head of + * pageout queue until full page has been written. + * + * RETURN: + * + * NOTE: + * LOGGC_LOCK serializes log group commit queue, and + * transaction blocks on the commit queue. + * N.B. LOG_LOCK is NOT held during lmGroupCommit(). + */ +int lmGroupCommit(log_t * log, tblock_t * tblk) +{ + int rc = 0; + + LOGGC_LOCK(log); + + /* group committed already ? */ + if (tblk->flag & tblkGC_COMMITTED) { + if (tblk->flag & tblkGC_ERROR) + rc = EIO; + + LOGGC_UNLOCK(log); + return rc; + } + jFYI(1, + ("lmGroup Commit: tblk = 0x%p, gcrtc = %d\n", tblk, + log->gcrtc)); + + /* + * group commit pageout in progress + */ + if ((!(log->cflag & logGC_PAGEOUT)) && log->cqueue.head) { + /* + * only transaction in the commit queue: + * + * start one-transaction group commit as + * its group leader. + */ + log->cflag |= logGC_PAGEOUT; + + lmGCwrite(log, 0); + } + /* lmGCwrite gives up LOGGC_LOCK, check again */ + + if (tblk->flag & tblkGC_COMMITTED) { + if (tblk->flag & tblkGC_ERROR) + rc = EIO; + + LOGGC_UNLOCK(log); + return rc; + } + + /* upcount transaction waiting for completion + */ + log->gcrtc++; + + if (tblk->xflag & COMMIT_LAZY) { + tblk->flag |= tblkGC_LAZY; + LOGGC_UNLOCK(log); + return 0; + } + tblk->flag |= tblkGC_READY; + + __SLEEP_COND(tblk->gcwait, (tblk->flag & tblkGC_COMMITTED), + LOGGC_LOCK(log), LOGGC_UNLOCK(log)); + + /* removed from commit queue */ + if (tblk->flag & tblkGC_ERROR) + rc = EIO; + + LOGGC_UNLOCK(log); + return rc; +} + +/* + * NAME: lmGCwrite() + * + * FUNCTION: group commit write + * initiate write of log page, building a group of all transactions + * with commit records on that page. + * + * RETURN: None + * + * NOTE: + * LOGGC_LOCK must be held by caller. + * N.B. LOG_LOCK is NOT held during lmGroupCommit(). + */ +void lmGCwrite(log_t * log, int cant_write) +{ + lbuf_t *bp; + logpage_t *lp; + int gcpn; /* group commit page number */ + tblock_t *tblk; + tblock_t *xtblk; + + /* + * build the commit group of a log page + * + * scan commit queue and make a commit group of all + * transactions with COMMIT records on the same log page. + */ + /* get the head tblk on the commit queue */ + tblk = xtblk = log->cqueue.head; + gcpn = tblk->pn; + + while (tblk && tblk->pn == gcpn) { + xtblk = tblk; + + /* state transition: (QUEUE, READY) -> COMMIT */ + tblk->flag |= tblkGC_COMMIT; + tblk = tblk->cqnext; + } + tblk = xtblk; /* last tblk of the page */ + + /* + * pageout to commit transactions on the log page. + */ + bp = (lbuf_t *) tblk->bp; + lp = (logpage_t *) bp->l_ldata; + /* is page already full ? */ + if (tblk->flag & tblkGC_EOP) { + /* mark page to free at end of group commit of the page */ + tblk->flag &= ~tblkGC_EOP; + tblk->flag |= tblkGC_FREE; + bp->l_ceor = bp->l_eor; + lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_ceor); + jEVENT(0, + ("gc: tclsn:0x%x, bceor:0x%x\n", tblk->clsn, + bp->l_ceor)); + lbmWrite(log, bp, lbmWRITE | lbmRELEASE | lbmGC, + cant_write); + } + /* page is not yet full */ + else { + bp->l_ceor = tblk->eor; /* ? bp->l_ceor = bp->l_eor; */ + lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_ceor); + jEVENT(0, + ("gc: tclsn:0x%x, bceor:0x%x\n", tblk->clsn, + bp->l_ceor)); + lbmWrite(log, bp, lbmWRITE | lbmGC, cant_write); + } +} + +/* + * NAME: lmPostGC() + * + * FUNCTION: group commit post-processing + * Processes transactions after their commit records have been written + * to disk, redriving log I/O if necessary. + * + * RETURN: None + * + * NOTE: + * This routine is called a interrupt time by lbmIODone + */ +void lmPostGC(lbuf_t * bp) +{ + unsigned long flags; + log_t *log = bp->l_log; + logpage_t *lp; + tblock_t *tblk; + + //LOGGC_LOCK(log); + spin_lock_irqsave(&log->gclock, flags); + /* + * current pageout of group commit completed. + * + * remove/wakeup transactions from commit queue who were + * group committed with the current log page + */ + while ((tblk = log->cqueue.head) && (tblk->flag & tblkGC_COMMIT)) { + /* if transaction was marked GC_COMMIT then + * it has been shipped in the current pageout + * and made it to disk - it is committed. + */ + + if (bp->l_flag & lbmERROR) + tblk->flag |= tblkGC_ERROR; + + /* remove it from the commit queue */ + log->cqueue.head = tblk->cqnext; + if (log->cqueue.head == NULL) + log->cqueue.tail = NULL; + tblk->flag &= ~tblkGC_QUEUE; + tblk->cqnext = 0; + + jEVENT(0, + ("lmPostGC: tblk = 0x%p, flag = 0x%x\n", tblk, + tblk->flag)); + + if (!(tblk->xflag & COMMIT_FORCE)) + /* + * Hand tblk over to lazy commit thread + */ + txLazyUnlock(tblk); + else { + /* state transition: COMMIT -> COMMITTED */ + tblk->flag |= tblkGC_COMMITTED; + + if (tblk->flag & tblkGC_READY) { + log->gcrtc--; + LOGGC_WAKEUP(tblk); + } + } + + /* was page full before pageout ? + * (and this is the last tblk bound with the page) + */ + if (tblk->flag & tblkGC_FREE) + lbmFree(bp); + /* did page become full after pageout ? + * (and this is the last tblk bound with the page) + */ + else if (tblk->flag & tblkGC_EOP) { + /* finalize the page */ + lp = (logpage_t *) bp->l_ldata; + bp->l_ceor = bp->l_eor; + lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_eor); + jEVENT(0, ("lmPostGC: calling lbmWrite\n")); + lbmWrite(log, bp, lbmWRITE | lbmRELEASE | lbmFREE, + 1); + } + + } + + /* are there any transactions who have entered lnGroupCommit() + * (whose COMMITs are after that of the last log page written. + * They are waiting for new group commit (above at (SLEEP 1)): + * select the latest ready transaction as new group leader and + * wake her up to lead her group. + */ + if ((log->gcrtc > 0) && log->cqueue.head) + /* + * Call lmGCwrite with new group leader + */ + lmGCwrite(log, 1); + + /* no transaction are ready yet (transactions are only just + * queued (GC_QUEUE) and not entered for group commit yet). + * let the first transaction entering group commit + * will elect hetself as new group leader. + */ + else + log->cflag &= ~logGC_PAGEOUT; + + //LOGGC_UNLOCK(log); + spin_unlock_irqrestore(&log->gclock, flags); + return; +} + +/* + * NAME: lmLogSync() + * + * FUNCTION: write log SYNCPT record for specified log + * if new sync address is available + * (normally the case if sync() is executed by back-ground + * process). + * if not, explicitly run jfs_blogsync() to initiate + * getting of new sync address. + * calculate new value of i_nextsync which determines when + * this code is called again. + * + * this is called only from lmLog(). + * + * PARAMETER: ip - pointer to logs inode. + * + * RETURN: 0 + * + * serialization: LOG_LOCK() held on entry/exit + */ +int lmLogSync(log_t * log, int nosyncwait) +{ + int logsize; + int written; /* written since last syncpt */ + int free; /* free space left available */ + int delta; /* additional delta to write normally */ + int more; /* additional write granted */ + lrd_t lrd; + int lsn; + struct logsyncblk *lp; + + /* + * forward syncpt + */ + /* if last sync is same as last syncpt, + * invoke sync point forward processing to update sync. + */ + + if (log->sync == log->syncpt) { + LOGSYNC_LOCK(log); + /* ToDo: push dirty metapages out to disk */ +// bmLogSync(log); + + if (list_empty(&log->synclist)) + log->sync = log->lsn; + else { + lp = list_entry(log->synclist.next, + struct logsyncblk, synclist); + log->sync = lp->lsn; + } + LOGSYNC_UNLOCK(log); + + } + + /* if sync is different from last syncpt, + * write a SYNCPT record with syncpt = sync. + * reset syncpt = sync + */ + if (log->sync != log->syncpt) { + struct jfs_sb_info *sbi = JFS_SBI(log->sb); + /* + * We need to make sure all of the "written" metapages + * actually make it to disk + */ + fsync_inode_data_buffers(sbi->ipbmap); + fsync_inode_data_buffers(sbi->ipimap); + fsync_inode_data_buffers(sbi->direct_inode); + + lrd.logtid = 0; + lrd.backchain = 0; + lrd.type = cpu_to_le16(LOG_SYNCPT); + lrd.length = 0; + lrd.log.syncpt.sync = cpu_to_le32(log->sync); + lsn = lmWriteRecord(log, NULL, &lrd, NULL); + + log->syncpt = log->sync; + } else + lsn = log->lsn; + + /* + * setup next syncpt trigger (SWAG) + */ + logsize = log->logsize; + + logdiff(written, lsn, log); + free = logsize - written; + delta = LOGSYNC_DELTA(logsize); + more = min(free / 2, delta); + if (more < 2 * LOGPSIZE) { + jEVENT(1, + ("\n ... Log Wrap ... Log Wrap ... Log Wrap ...\n\n")); + /* + * log wrapping + * + * option 1 - panic ? No.! + * option 2 - shutdown file systems + * associated with log ? + * option 3 - extend log ? + */ + /* + * option 4 - second chance + * + * mark log wrapped, and continue. + * when all active transactions are completed, + * mark log vaild for recovery. + * if crashed during invalid state, log state + * implies invald log, forcing fsck(). + */ + /* mark log state log wrap in log superblock */ + /* log->state = LOGWRAP; */ + + /* reset sync point computation */ + log->syncpt = log->sync = lsn; + log->nextsync = delta; + } else + /* next syncpt trigger = written + more */ + log->nextsync = written + more; + + /* return if lmLogSync() from outside of transaction, e.g., sync() */ + if (nosyncwait) + return lsn; + + /* if number of bytes written from last sync point is more + * than 1/4 of the log size, stop new transactions from + * starting until all current transactions are completed + * by setting syncbarrier flag. + */ + if (written > LOGSYNC_BARRIER(logsize) && logsize > 32 * LOGPSIZE) { + log->syncbarrier = 1; + jFYI(1, ("log barrier on: lsn=0x%x syncpt=0x%x\n", lsn, + log->syncpt)); + } + + return lsn; +} + + +/* + * NAME: lmLogOpen() + * + * FUNCTION: open the log on first open; + * insert filesystem in the active list of the log. + * + * PARAMETER: ipmnt - file system mount inode + * iplog - log inode (out) + * + * RETURN: + * + * serialization: + */ +int lmLogOpen(struct super_block *sb, log_t ** logptr) +{ + int rc; + kdev_t logdev; /* dev_t of log device */ + log_t *log; + + logdev = sb->s_dev; + +#ifdef _STILL_TO_PORT + /* + * open the inode representing the log device (aka log inode) + */ + if (logdev != fsdev) + goto externalLog; +#endif /* _STILL_TO_PORT */ + + /* + * in-line log in host file system + * + * file system to log have 1-to-1 relationship; + */ +// inlineLog: + + *logptr = log = kmalloc(sizeof(log_t), GFP_KERNEL); + if (log == 0) + return ENOMEM; + + memset(log, 0, sizeof(log_t)); + log->sb = sb; /* This should be a list */ + log->flag = JFS_INLINELOG; + log->dev = logdev; + log->base = addressPXD(&JFS_SBI(sb)->logpxd); + log->size = lengthPXD(&JFS_SBI(sb)->logpxd) >> + (L2LOGPSIZE - sb->s_blocksize_bits); + log->l2bsize = sb->s_blocksize_bits; + ASSERT(L2LOGPSIZE >= sb->s_blocksize_bits); + /* + * initialize log. + */ + if ((rc = lmLogInit(log))) + goto errout10; + +#ifdef _STILL_TO_PORT + goto out; + + /* + * external log as separate logical volume + * + * file systems to log may have n-to-1 relationship; + */ + externalLog: + /* + * open log inode + * + * log inode is reserved inode of (dev_t = log device, + * fileset number = 0, i_number = 0), which acquire + * one i_count for each open by file system. + * + * hand craft dummy vfs to force iget() the special case of + * an in-memory inode allocation without on-disk inode + */ + memset(&dummyvfs, 0, sizeof(struct vfs)); + dummyvfs.filesetvfs.vfs_data = NULL; + dummyvfs.dummyvfs.dev = logdev; + dummyvfs.dummyvfs.ipmnt = NULL; + ICACHE_LOCK(); + rc = iget((struct vfs *) &dummyvfs, 0, (inode_t **) & log, 0); + ICACHE_UNLOCK(); + if (rc) + return rc; + + log->flag = 0; + log->dev = logdev; + log->base = 0; + log->size = 0; + + /* + * serialize open/close between multiple file systems + * bound with the log; + */ + ip = (inode_t *) log; + IWRITE_LOCK(ip); + + /* + * subsequent open: add file system to log active file system list + */ +#ifdef _JFS_OS2 + if (log->strat2p) +#endif /* _JFS_OS2 */ + { + if (rc = lmLogFileSystem(log, fsdev, 1)) + goto errout10; + + IWRITE_UNLOCK(ip); + + *iplog = ip; + jFYI(1, ("lmLogOpen: exit(0)\n")); + return 0; + } + + /* decouple log inode from dummy vfs */ + vPut(ip); + + /* + * first open: + */ +#ifdef _JFS_OS2 + /* + * establish access to the single/shared (already open) log device + */ + logdevfp = (void *) logStrat2; + log->strat2p = logStrat2; + log->strat3p = logStrat3; + + log->l2pbsize = 9; /* todo: when OS/2 have multiple external log */ +#endif /* _JFS_OS2 */ + + /* + * initialize log: + */ + if (rc = lmLogInit(log)) + goto errout20; + + /* + * add file system to log active file system list + */ + if (rc = lmLogFileSystem(log, fsdev, 1)) + goto errout30; + + /* + * insert log device into log device list + */ + out: +#endif /* _STILL_TO_PORT */ + jFYI(1, ("lmLogOpen: exit(0)\n")); + return 0; + + /* + * unwind on error + */ +#ifdef _STILL_TO_PORT + errout30: /* unwind lbmLogInit() */ + lbmLogShutdown(log); + + errout20: /* close external log device */ + +#endif /* _STILL_TO_PORT */ + errout10: /* free log inode */ + kfree(log); + + jFYI(1, ("lmLogOpen: exit(%d)\n", rc)); + return rc; +} + + +/* + * NAME: lmLogInit() + * + * FUNCTION: log initialization at first log open. + * + * logredo() (or logformat()) should have been run previously. + * initialize the log inode from log superblock. + * set the log state in the superblock to LOGMOUNT and + * write SYNCPT log record. + * + * PARAMETER: log - log structure + * + * RETURN: 0 - if ok + * EINVAL - bad log magic number or superblock dirty + * error returned from logwait() + * + * serialization: single first open thread + */ +static int lmLogInit(log_t * log) +{ + int rc = 0; + lrd_t lrd; + logsuper_t *logsuper; + lbuf_t *bpsuper; + lbuf_t *bp; + logpage_t *lp; + int lsn; + + jFYI(1, ("lmLogInit: log:0x%p\n", log)); + + /* + * log inode is overlaid on generic inode where + * dinode have been zeroed out by iRead(); + */ + + /* + * initialize log i/o + */ + if ((rc = lbmLogInit(log))) + return rc; + + /* + * validate log superblock + */ + if ((rc = lbmRead(log, 1, &bpsuper))) + goto errout10; + + logsuper = (logsuper_t *) bpsuper->l_ldata; + + if (logsuper->magic != cpu_to_le32(LOGMAGIC)) { + jERROR(1, ("*** Log Format Error ! ***\n")); + rc = EINVAL; + goto errout20; + } + + /* logredo() should have been run successfully. */ + if (logsuper->state != cpu_to_le32(LOGREDONE)) { + jERROR(1, ("*** Log Is Dirty ! ***\n")); + rc = EINVAL; + goto errout20; + } + + /* initialize log inode from log superblock */ + if (log->flag & JFS_INLINELOG) { + if (log->size != le32_to_cpu(logsuper->size)) { + rc = EINVAL; + goto errout20; + } + jFYI(0, + ("lmLogInit: inline log:0x%p base:0x%Lx size:0x%x\n", + log, (unsigned long long) log->base, log->size)); + } else { + log->size = le32_to_cpu(logsuper->size); + jFYI(0, + ("lmLogInit: external log:0x%p base:0x%Lx size:0x%x\n", + log, (unsigned long long) log->base, log->size)); + } + + log->flag |= JFS_GROUPCOMMIT; +/* + log->flag |= JFS_LAZYCOMMIT; +*/ + log->page = le32_to_cpu(logsuper->end) / LOGPSIZE; + log->eor = le32_to_cpu(logsuper->end) - (LOGPSIZE * log->page); + + /* + * initialize for log append write mode + */ + /* establish current/end-of-log page/buffer */ + if ((rc = lbmRead(log, log->page, &bp))) + goto errout20; + + lp = (logpage_t *) bp->l_ldata; + + jFYI(1, ("lmLogInit: lsn:0x%x page:%d eor:%d:%d\n", + le32_to_cpu(logsuper->end), log->page, log->eor, + le16_to_cpu(lp->h.eor))); + +// ASSERT(log->eor == lp->h.eor); + + log->bp = bp; + bp->l_pn = log->page; + bp->l_eor = log->eor; + + /* initialize the group commit serialization lock */ + LOGGC_LOCK_INIT(log); + + /* if current page is full, move on to next page */ + if (log->eor >= LOGPSIZE - LOGPTLRSIZE) + lmNextPage(log); + + /* allocate/initialize the log write serialization lock */ + LOG_LOCK_INIT(log); + + /* + * initialize log syncpoint + */ + /* + * write the first SYNCPT record with syncpoint = 0 + * (i.e., log redo up to HERE !); + * remove current page from lbm write queue at end of pageout + * (to write log superblock update), but do not release to freelist; + */ + lrd.logtid = 0; + lrd.backchain = 0; + lrd.type = cpu_to_le16(LOG_SYNCPT); + lrd.length = 0; + lrd.log.syncpt.sync = 0; + lsn = lmWriteRecord(log, NULL, &lrd, NULL); + bp = log->bp; + bp->l_ceor = bp->l_eor; + lp = (logpage_t *) bp->l_ldata; + lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_eor); + lbmWrite(log, bp, lbmWRITE | lbmSYNC, 0); + if ((rc = lbmIOWait(bp, 0))) + goto errout30; + + /* initialize logsync parameters */ + log->logsize = (log->size - 2) << L2LOGPSIZE; + log->lsn = lsn; + log->syncpt = lsn; + log->sync = log->syncpt; + log->nextsync = LOGSYNC_DELTA(log->logsize); + init_waitqueue_head(&log->syncwait); + + jFYI(1, ("lmLogInit: lsn:0x%x syncpt:0x%x sync:0x%x\n", + log->lsn, log->syncpt, log->sync)); + + LOGSYNC_LOCK_INIT(log); + + INIT_LIST_HEAD(&log->synclist); + + log->cqueue.head = log->cqueue.tail = 0; + + log->count = 0; + + /* + * initialize for lazy/group commit + */ + log->clsn = lsn; + + /* + * update/write superblock + */ + logsuper->state = cpu_to_le32(LOGMOUNT); + log->serial = le32_to_cpu(logsuper->serial) + 1; + logsuper->serial = cpu_to_le32(log->serial); + lbmDirectWrite(log, bpsuper, lbmWRITE | lbmRELEASE | lbmSYNC); + if ((rc = lbmIOWait(bpsuper, lbmFREE))) + goto errout30; + + jFYI(1, ("lmLogInit: exit(%d)\n", rc)); + return 0; + + /* + * unwind on error + */ + errout30: /* release log page */ + lbmFree(bp); + + errout20: /* release log superblock */ + lbmFree(bpsuper); + + errout10: /* unwind lbmLogInit() */ + lbmLogShutdown(log); + + jFYI(1, ("lmLogInit: exit(%d)\n", rc)); + return rc; +} + + +/* + * NAME: lmLogClose() + * + * FUNCTION: remove file system from active list of log + * and close it on last close. + * + * PARAMETER: sb - superblock + * log - log inode + * + * RETURN: errors from subroutines + * + * serialization: + */ +int lmLogClose(struct super_block *sb, log_t * log) +{ + int rc; + + jFYI(1, ("lmLogClose: log:0x%p\n", log)); + + /* + * in-line log in host file system + */ +// inlineLog: +#ifdef _STILL_TO_PORT + if (log->flag & JFS_INLINELOG) { + rc = lmLogShutdown(log); + + goto out1; + } + + /* + * external log as separate logical volume + */ + externalLog: + + /* serialize open/close between multiple file systems + * associated with the log + */ + IWRITE_LOCK(iplog); + + /* + * remove file system from log active file system list + */ + rc = lmLogFileSystem(log, fsdev, 0); + + if (iplog->i_count > 1) + goto out2; + + /* + * last close: shut down log + */ + rc = ((rc1 = lmLogShutdown(log)) && rc == 0) ? rc1 : rc; + + out1: +#else /* _STILL_TO_PORT */ + rc = lmLogShutdown(log); +#endif /* _STILL_TO_PORT */ + +// out2: + + jFYI(0, ("lmLogClose: exit(%d)\n", rc)); + return rc; +} + + +/* + * NAME: lmLogShutdown() + * + * FUNCTION: log shutdown at last LogClose(). + * + * write log syncpt record. + * update super block to set redone flag to 0. + * + * PARAMETER: log - log inode + * + * RETURN: 0 - success + * + * serialization: single last close thread + */ +static int lmLogShutdown(log_t * log) +{ + int rc; + lrd_t lrd; + int lsn; + logsuper_t *logsuper; + lbuf_t *bpsuper; + lbuf_t *bp; + logpage_t *lp; + + jFYI(1, ("lmLogShutdown: log:0x%p\n", log)); + + if (log->cqueue.head || !list_empty(&log->synclist)) { + /* + * If there was very recent activity, we may need to wait + * for the lazycommit thread to catch up + */ + int i; + + for (i = 0; i < 800; i++) { /* Too much? */ + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(HZ / 4); + if ((log->cqueue.head == NULL) && + list_empty(&log->synclist)) + break; + } + } + assert(log->cqueue.head == NULL); + assert(list_empty(&log->synclist)); + + /* + * We need to make sure all of the "written" metapages + * actually make it to disk + */ + fsync_no_super(log->sb->s_dev); + + /* + * write the last SYNCPT record with syncpoint = 0 + * (i.e., log redo up to HERE !) + */ + lrd.logtid = 0; + lrd.backchain = 0; + lrd.type = cpu_to_le16(LOG_SYNCPT); + lrd.length = 0; + lrd.log.syncpt.sync = 0; + lsn = lmWriteRecord(log, NULL, &lrd, NULL); + bp = log->bp; + lp = (logpage_t *) bp->l_ldata; + lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_eor); + lbmWrite(log, log->bp, lbmWRITE | lbmRELEASE | lbmSYNC, 0); + lbmIOWait(log->bp, lbmFREE); + + /* + * synchronous update log superblock + * mark log state as shutdown cleanly + * (i.e., Log does not need to be replayed). + */ + if ((rc = lbmRead(log, 1, &bpsuper))) + goto out; + + logsuper = (logsuper_t *) bpsuper->l_ldata; + logsuper->state = cpu_to_le32(LOGREDONE); + logsuper->end = cpu_to_le32(lsn); + lbmDirectWrite(log, bpsuper, lbmWRITE | lbmRELEASE | lbmSYNC); + rc = lbmIOWait(bpsuper, lbmFREE); + + jFYI(1, ("lmLogShutdown: lsn:0x%x page:%d eor:%d\n", + lsn, log->page, log->eor)); + + out: + /* + * shutdown per log i/o + */ + lbmLogShutdown(log); + + if (rc) { + jFYI(1, ("lmLogShutdown: exit(%d)\n", rc)); + } + return rc; +} + + +#ifdef _STILL_TO_PORT +/* + * NAME: lmLogFileSystem() + * + * FUNCTION: insert ( = true)/remove ( = false) + * file system into/from log active file system list. + * + * PARAMETE: log - pointer to logs inode. + * fsdev - dev_t of filesystem. + * serial - pointer to returned log serial number + * activate - insert/remove device from active list. + * + * RETURN: 0 - success + * errors returned by vms_iowait(). + * + * serialization: IWRITE_LOCK(log inode) held on entry/exit + */ +static int lmLogFileSystem(log_t * log, dev_t fsdev, int activate) +{ + int rc = 0; + int bit, word; + logsuper_t *logsuper; + lbuf_t *bpsuper; + + /* + * insert/remove file system device to log active file system list. + */ + if ((rc = lbmRead(log, 1, &bpsuper))) + return rc; + + logsuper = (logsuper_t *) bpsuper->l_ldata; + bit = MINOR(fsdev); + word = bit / 32; + bit -= 32 * word; + if (activate) + logsuper->active[word] |= + cpu_to_le32((LEFTMOSTONE >> bit)); + else + logsuper->active[word] &= + cpu_to_le32((~(LEFTMOSTONE >> bit))); + + /* + * synchronous write log superblock: + * + * write sidestream bypassing write queue: + * at file system mount, log super block is updated for + * activation of the file system before any log record + * (MOUNT record) of the file system, and at file system + * unmount, all meta data for the file system has been + * flushed before log super block is updated for deactivation + * of the file system. + */ + lbmDirectWrite(log, bpsuper, lbmWRITE | lbmRELEASE | lbmSYNC); + rc = lbmIOWait(bpsuper, lbmFREE); + + return rc; +} +#endif /* _STILL_TO_PORT */ + + +/* + * lmLogQuiesce() + */ +int lmLogQuiesce(log_t * log) +{ + int rc; + + rc = lmLogShutdown(log); + + return rc; +} + + +/* + * lmLogResume() + */ +int lmLogResume(log_t * log, struct super_block *sb) +{ + struct jfs_sb_info *sbi = JFS_SBI(sb); + int rc; + + log->base = addressPXD(&sbi->logpxd); + log->size = + (lengthPXD(&sbi->logpxd) << sb->s_blocksize_bits) >> L2LOGPSIZE; + rc = lmLogInit(log); + + return rc; +} + + +/* + * log buffer manager (lbm) + * ------------------------ + * + * special purpose buffer manager supporting log i/o requirements. + * + * per log write queue: + * log pageout occurs in serial order by fifo write queue and + * restricting to a single i/o in pregress at any one time. + * a circular singly-linked list + * (log->wrqueue points to the tail, and buffers are linked via + * bp->wrqueue field), and + * maintains log page in pageout ot waiting for pageout in serial pageout. + */ + +/* + * lbmLogInit() + * + * initialize per log I/O setup at lmLogInit() + */ +static int lbmLogInit(log_t * log) +{ /* log inode */ + int i; + lbuf_t *lbuf; + + jFYI(1, ("lbmLogInit: log:0x%p\n", log)); + + /* initialize current buffer cursor */ + log->bp = NULL; + + /* initialize log device write queue */ + log->wqueue = NULL; + + /* + * Each log has its own buffer pages allocated to it. These are + * not managed by the page cache. This ensures that a transaction + * writing to the log does not block trying to allocate a page from + * the page cache (for the log). This would be bad, since page + * allocation waits on the kswapd thread that may be committing inodes + * which would cause log activity. Was that clear? I'm trying to + * avoid deadlock here. + */ + init_waitqueue_head(&log->free_wait); + + log->lbuf_free = NULL; + + for (i = 0; i < LOGPAGES; i++) { + lbuf = kmalloc(sizeof(lbuf_t), GFP_KERNEL); + if (lbuf == 0) + goto error; + lbuf->l_bh.b_data = lbuf->l_ldata = + (char *) __get_free_page(GFP_KERNEL); + if (lbuf->l_ldata == 0) { + kfree(lbuf); + goto error; + } + lbuf->l_log = log; + init_waitqueue_head(&lbuf->l_ioevent); + + lbuf->l_bh.b_size = LOGPSIZE; + lbuf->l_bh.b_dev = log->dev; + lbuf->l_bh.b_end_io = lbmIODone; + lbuf->l_bh.b_private = lbuf; + lbuf->l_bh.b_page = virt_to_page(lbuf->l_ldata); + lbuf->l_bh.b_state = 0; + init_waitqueue_head(&lbuf->l_bh.b_wait); + + lbuf->l_freelist = log->lbuf_free; + log->lbuf_free = lbuf; + } + + return (0); + + error: + lbmLogShutdown(log); + return (ENOMEM); +} + + +/* + * lbmLogShutdown() + * + * finalize per log I/O setup at lmLogShutdown() + */ +static void lbmLogShutdown(log_t * log) +{ + lbuf_t *lbuf; + + jFYI(1, ("lbmLogShutdown: log:0x%p\n", log)); + + lbuf = log->lbuf_free; + while (lbuf) { + lbuf_t *next = lbuf->l_freelist; + free_page((unsigned long) lbuf->l_ldata); + kfree(lbuf); + lbuf = next; + } + + log->bp = NULL; +} + + +/* + * lbmAllocate() + * + * allocate an empty log buffer + */ +static lbuf_t *lbmAllocate(log_t * log, int pn) +{ + lbuf_t *bp; + unsigned long flags; + + /* + * recycle from log buffer freelist if any + */ + LCACHE_LOCK(flags); + LCACHE_SLEEP_COND(log->free_wait, (bp = log->lbuf_free), flags); + log->lbuf_free = bp->l_freelist; + LCACHE_UNLOCK(flags); + + bp->l_flag = 0; + + bp->l_wqnext = NULL; + bp->l_freelist = NULL; + + bp->l_pn = pn; + bp->l_blkno = log->base + (pn << (L2LOGPSIZE - log->l2bsize)); + bp->l_bh.b_blocknr = bp->l_blkno; + bp->l_ceor = 0; + + return bp; +} + + +/* + * lbmFree() + * + * release a log buffer to freelist + */ +static void lbmFree(lbuf_t * bp) +{ + unsigned long flags; + + LCACHE_LOCK(flags); + + lbmfree(bp); + + LCACHE_UNLOCK(flags); +} + +static void lbmfree(lbuf_t * bp) +{ + log_t *log = bp->l_log; + + assert(bp->l_wqnext == NULL); + + /* + * return the buffer to head of freelist + */ + bp->l_freelist = log->lbuf_free; + log->lbuf_free = bp; + + wake_up(&log->free_wait); + return; +} + + +/* + * NAME: lbmRedrive + * + * FUNCTION: add a log buffer to the the log redrive list + * + * PARAMETER: + * bp - log buffer + * + * NOTES: + * Takes log_redrive_lock. + */ +static inline void lbmRedrive(lbuf_t *bp) +{ + unsigned long flags; + + spin_lock_irqsave(&log_redrive_lock, flags); + bp->l_redrive_next = log_redrive_list; + log_redrive_list = bp; + spin_unlock_irqrestore(&log_redrive_lock, flags); + + wake_up_process(jfsIOtask); +} + + +/* + * lbmRead() + */ +static int lbmRead(log_t * log, int pn, lbuf_t ** bpp) +{ + lbuf_t *bp; + + /* + * allocate a log buffer + */ + *bpp = bp = lbmAllocate(log, pn); + jFYI(1, ("lbmRead: bp:0x%p pn:0x%x\n", bp, pn)); + + bp->l_flag |= lbmREAD; + bp->l_bh.b_reqnext = NULL; + clear_bit(BH_Uptodate, &bp->l_bh.b_state); + lock_buffer(&bp->l_bh); + set_bit(BH_Mapped, &bp->l_bh.b_state); + set_bit(BH_Req, &bp->l_bh.b_state); + bp->l_bh.b_rdev = bp->l_bh.b_dev; + bp->l_bh.b_rsector = bp->l_blkno << (log->l2bsize - 9); + generic_make_request(READ, &bp->l_bh); + run_task_queue(&tq_disk); + + wait_event(bp->l_ioevent, (bp->l_flag != lbmREAD)); + + return 0; +} + + +/* + * lbmWrite() + * + * buffer at head of pageout queue stays after completion of + * partial-page pageout and redriven by explicit initiation of + * pageout by caller until full-page pageout is completed and + * released. + * + * device driver i/o done redrives pageout of new buffer at + * head of pageout queue when current buffer at head of pageout + * queue is released at the completion of its full-page pageout. + * + * LOGGC_LOCK() serializes lbmWrite() by lmNextPage() and lmGroupCommit(). + * LCACHE_LOCK() serializes xflag between lbmWrite() and lbmIODone() + */ +static void lbmWrite(log_t * log, lbuf_t * bp, int flag, int cant_block) +{ + lbuf_t *tail; + unsigned long flags; + + jFYI(1, ("lbmWrite: bp:0x%p flag:0x%x pn:0x%x\n", + bp, flag, bp->l_pn)); + + /* map the logical block address to physical block address */ + bp->l_blkno = + log->base + (bp->l_pn << (L2LOGPSIZE - log->l2bsize)); + + LCACHE_LOCK(flags); /* disable+lock */ + + /* + * initialize buffer for device driver + */ + bp->l_flag = flag; + + /* + * insert bp at tail of write queue associated with log + * + * (request is either for bp already/currently at head of queue + * or new bp to be inserted at tail) + */ + tail = log->wqueue; + + /* is buffer not already on write queue ? */ + if (bp->l_wqnext == NULL) { + /* insert at tail of wqueue */ + if (tail == NULL) { + log->wqueue = bp; + bp->l_wqnext = bp; + } else { + log->wqueue = bp; + bp->l_wqnext = tail->l_wqnext; + tail->l_wqnext = bp; + } + + tail = bp; + } + + /* is buffer at head of wqueue and for write ? */ + if ((bp != tail->l_wqnext) || !(flag & lbmWRITE)) { + LCACHE_UNLOCK(flags); /* unlock+enable */ + return; + } + + LCACHE_UNLOCK(flags); /* unlock+enable */ + + if (cant_block) + lbmRedrive(bp); + else if (flag & lbmSYNC) + lbmStartIO(bp); + else { + LOGGC_UNLOCK(log); + lbmStartIO(bp); + LOGGC_LOCK(log); + } +} + + +/* + * lbmDirectWrite() + * + * initiate pageout bypassing write queue for sidestream + * (e.g., log superblock) write; + */ +static void lbmDirectWrite(log_t * log, lbuf_t * bp, int flag) +{ + jEVENT(0, ("lbmDirectWrite: bp:0x%p flag:0x%x pn:0x%x\n", + bp, flag, bp->l_pn)); + + /* + * initialize buffer for device driver + */ + bp->l_flag = flag | lbmDIRECT; + + /* map the logical block address to physical block address */ + bp->l_blkno = + log->base + (bp->l_pn << (L2LOGPSIZE - log->l2bsize)); + + /* + * initiate pageout of the page + */ + lbmStartIO(bp); +} + + +/* + * NAME: lbmStartIO() + * + * FUNCTION: Interface to DD strategy routine + * + * RETURN: none + * + * serialization: LCACHE_LOCK() is NOT held during log i/o; + */ +void lbmStartIO(lbuf_t * bp) +{ + jFYI(1, ("lbmStartIO\n")); + + bp->l_bh.b_reqnext = NULL; + set_bit(BH_Dirty, &bp->l_bh.b_state); +// lock_buffer(&bp->l_bh); + assert(!test_bit(BH_Lock, &bp->l_bh.b_state)); + set_bit(BH_Lock, &bp->l_bh.b_state); + + set_bit(BH_Mapped, &bp->l_bh.b_state); + set_bit(BH_Req, &bp->l_bh.b_state); + bp->l_bh.b_rdev = bp->l_bh.b_dev; + bp->l_bh.b_rsector = bp->l_blkno << (bp->l_log->l2bsize - 9); + generic_make_request(WRITE, &bp->l_bh); + + INCREMENT(lmStat.submitted); + run_task_queue(&tq_disk); + + jFYI(1, ("lbmStartIO done\n")); +} + + +/* + * lbmIOWait() + */ +static int lbmIOWait(lbuf_t * bp, int flag) +{ + unsigned long flags; + int rc = 0; + + jFYI(1, + ("lbmIOWait1: bp:0x%p flag:0x%x:0x%x\n", bp, bp->l_flag, + flag)); + + LCACHE_LOCK(flags); /* disable+lock */ + + LCACHE_SLEEP_COND(bp->l_ioevent, (bp->l_flag & lbmDONE), flags); + + rc = (bp->l_flag & lbmERROR) ? EIO : 0; + + if (flag & lbmFREE) + lbmfree(bp); + + LCACHE_UNLOCK(flags); /* unlock+enable */ + + jFYI(1, + ("lbmIOWait2: bp:0x%p flag:0x%x:0x%x\n", bp, bp->l_flag, + flag)); + return rc; +} + +/* + * lbmIODone() + * + * executed at INTIODONE level + */ +static void lbmIODone(struct buffer_head *bh, int uptodate) +{ + lbuf_t *bp = bh->b_private; + lbuf_t *nextbp, *tail; + log_t *log; + unsigned long flags; + + /* + * get back jfs buffer bound to the i/o buffer + */ + jEVENT(0, ("lbmIODone: bp:0x%p flag:0x%x\n", bp, bp->l_flag)); + + LCACHE_LOCK(flags); /* disable+lock */ + + unlock_buffer(&bp->l_bh); + bp->l_flag |= lbmDONE; + + if (!uptodate) { + bp->l_flag |= lbmERROR; + + jERROR(1, ("lbmIODone: I/O error in JFS log\n")); + } + + /* + * pagein completion + */ + if (bp->l_flag & lbmREAD) { + bp->l_flag &= ~lbmREAD; + + LCACHE_UNLOCK(flags); /* unlock+enable */ + + /* wakeup I/O initiator */ + LCACHE_WAKEUP(&bp->l_ioevent); + + return; + } + + /* + * pageout completion + * + * the bp at the head of write queue has completed pageout. + * + * if single-commit/full-page pageout, remove the current buffer + * from head of pageout queue, and redrive pageout with + * the new buffer at head of pageout queue; + * otherwise, the partial-page pageout buffer stays at + * the head of pageout queue to be redriven for pageout + * by lmGroupCommit() until full-page pageout is completed. + */ + bp->l_flag &= ~lbmWRITE; + INCREMENT(lmStat.pagedone); + + /* update committed lsn */ + log = bp->l_log; + log->clsn = (bp->l_pn << L2LOGPSIZE) + bp->l_ceor; + + if (bp->l_flag & lbmDIRECT) { + LCACHE_WAKEUP(&bp->l_ioevent); + LCACHE_UNLOCK(flags); + return; + } + + tail = log->wqueue; + + /* single element queue */ + if (bp == tail) { + /* remove head buffer of full-page pageout + * from log device write queue + */ + if (bp->l_flag & lbmRELEASE) { + log->wqueue = NULL; + bp->l_wqnext = NULL; + } + } + /* multi element queue */ + else { + /* remove head buffer of full-page pageout + * from log device write queue + */ + if (bp->l_flag & lbmRELEASE) { + nextbp = tail->l_wqnext = bp->l_wqnext; + bp->l_wqnext = NULL; + + /* + * redrive pageout of next page at head of write queue: + * redrive next page without any bound tblk + * (i.e., page w/o any COMMIT records), or + * first page of new group commit which has been + * queued after current page (subsequent pageout + * is performed synchronously, except page without + * any COMMITs) by lmGroupCommit() as indicated + * by lbmWRITE flag; + */ + if (nextbp->l_flag & lbmWRITE) { + /* + * We can't do the I/O at interrupt time. + * The jfsIO thread can do it + */ + lbmRedrive(nextbp); + } + } + } + + /* + * synchronous pageout: + * + * buffer has not necessarily been removed from write queue + * (e.g., synchronous write of partial-page with COMMIT): + * leave buffer for i/o initiator to dispose + */ + if (bp->l_flag & lbmSYNC) { + LCACHE_UNLOCK(flags); /* unlock+enable */ + + /* wakeup I/O initiator */ + LCACHE_WAKEUP(&bp->l_ioevent); + } + + /* + * Group Commit pageout: + */ + else if (bp->l_flag & lbmGC) { + LCACHE_UNLOCK(flags); + lmPostGC(bp); + } + + /* + * asynchronous pageout: + * + * buffer must have been removed from write queue: + * insert buffer at head of freelist where it can be recycled + */ + else { + assert(bp->l_flag & lbmRELEASE); + assert(bp->l_flag & lbmFREE); + lbmfree(bp); + + LCACHE_UNLOCK(flags); /* unlock+enable */ + } +} + +int jfsIOWait(void *arg) +{ + lbuf_t *bp; + + jFYI(1, ("jfsIOWait is here!\n")); + + lock_kernel(); + + daemonize(); + current->tty = NULL; + strcpy(current->comm, "jfsIO"); + + unlock_kernel(); + + jfsIOtask = current; + + spin_lock_irq(¤t->sigmask_lock); + siginitsetinv(¤t->blocked, + sigmask(SIGHUP) | sigmask(SIGKILL) | sigmask(SIGSTOP) + | sigmask(SIGCONT)); + spin_unlock_irq(¤t->sigmask_lock); + + complete(&jfsIOwait); + + do { + spin_lock_irq(&log_redrive_lock); + while ((bp = log_redrive_list)) { + log_redrive_list = bp->l_redrive_next; + bp->l_redrive_next = NULL; + spin_unlock_irq(&log_redrive_lock); + lbmStartIO(bp); + spin_lock_irq(&log_redrive_lock); + } + spin_unlock_irq(&log_redrive_lock); + + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + } while (!jfs_thread_stopped()); + + jFYI(1,("jfsIOWait being killed!\n")); + complete(&jfsIOwait); + return 0; +} + + +#ifdef _STILL_TO_PORT +/* + * NAME: lmLogFormat()/jfs_logform() + * + * FUNCTION: format file system log (ref. jfs_logform()). + * + * PARAMETERS: + * log - log inode (with common mount inode base); + * logAddress - start address of log space in FS block; + * logSize - length of log space in FS block; + * + * RETURN: 0 - success + * -1 - i/o error + */ +int lmLogFormat(inode_t * ipmnt, s64 logAddress, int logSize) +{ + int rc = 0; + cbuf_t *bp; + logsuper_t *logsuper; + logpage_t *lp; + int lspn; /* log sequence page number */ + struct lrd *lrd_ptr; + int npbperpage, npages; + + jFYI(0, ("lmLogFormat: logAddress:%Ld logSize:%d\n", + logAddress, logSize)); + + /* allocate a JFS buffer */ + bp = rawAllocate(); + + /* map the logical block address to physical block address */ + bp->cm_blkno = logAddress << ipmnt->i_l2bfactor; + + npbperpage = LOGPSIZE >> ipmnt->i_l2pbsize; + npages = logSize / (LOGPSIZE >> ipmnt->i_l2bsize); + + /* + * log space: + * + * page 0 - reserved; + * page 1 - log superblock; + * page 2 - log data page: A SYNC log record is written + * into this page at logform time; + * pages 3-N - log data page: set to empty log data pages; + */ + /* + * init log superblock: log page 1 + */ + logsuper = (logsuper_t *) bp->cm_cdata; + + logsuper->magic = cpu_to_le32(LOGMAGIC); + logsuper->version = cpu_to_le32(LOGVERSION); + logsuper->state = cpu_to_le32(LOGREDONE); + logsuper->flag = cpu_to_le32(ipmnt->i_mntflag); /* ? */ + logsuper->size = cpu_to_le32(npages); + logsuper->bsize = cpu_to_le32(ipmnt->i_bsize); + logsuper->l2bsize = cpu_to_le32(ipmnt->i_l2bsize); + logsuper->end = + cpu_to_le32(2 * LOGPSIZE + LOGPHDRSIZE + LOGRDSIZE); + + bp->cm_blkno += npbperpage; + rawWrite(ipmnt, bp, 0); + + /* + * init pages 2 to npages-1 as log data pages: + * + * log page sequence number (lpsn) initialization: + * + * pn: 0 1 2 3 n-1 + * +-----+-----+=====+=====+===.....===+=====+ + * lspn: N-1 0 1 N-2 + * <--- N page circular file ----> + * + * the N (= npages-2) data pages of the log is maintained as + * a circular file for the log records; + * lpsn grows by 1 monotonically as each log page is written + * to the circular file of the log; + * Since the AIX DUMMY log record is dropped for this XJFS, + * and setLogpage() will not reset the page number even if + * the eor is equal to LOGPHDRSIZE. In order for binary search + * still work in find log end process, we have to simulate the + * log wrap situation at the log format time. + * The 1st log page written will have the highest lpsn. Then + * the succeeding log pages will have ascending order of + * the lspn starting from 0, ... (N-2) + */ + lp = (logpage_t *) bp->cm_cdata; + + /* + * initialize 1st log page to be written: lpsn = N - 1, + * write a SYNCPT log record is written to this page + */ + lp->h.page = lp->t.page = cpu_to_le32(npages - 3); + lp->h.eor = lp->t.eor = cpu_to_le16(LOGPHDRSIZE + LOGRDSIZE); + + lrd_ptr = (struct lrd *) &lp->data; + lrd_ptr->logtid = 0; + lrd_ptr->backchain = 0; + lrd_ptr->type = cpu_to_le16(LOG_SYNCPT); + lrd_ptr->length = 0; + lrd_ptr->log.syncpt.sync = 0; + + bp->cm_blkno += npbperpage; + rawWrite(ipmnt, bp, 0); + + /* + * initialize succeeding log pages: lpsn = 0, 1, ..., (N-2) + */ + for (lspn = 0; lspn < npages - 3; lspn++) { + lp->h.page = lp->t.page = cpu_to_le32(lspn); + lp->h.eor = lp->t.eor = cpu_to_le16(LOGPHDRSIZE); + + bp->cm_blkno += npbperpage; + rawWrite(ipmnt, bp, 0); + } + + /* + * finalize log + */ + /* release the buffer */ + rawRelease(bp); + + return rc; +} +#endif /* _STILL_TO_PORT */ + + +#ifdef CONFIG_JFS_STATISTICS +int jfs_lmstats_read(char *buffer, char **start, off_t offset, int length, + int *eof, void *data) +{ + int len = 0; + off_t begin; + + len += sprintf(buffer, + "JFS Logmgr stats\n" + "================\n" + "commits = %d\n" + "writes submitted = %d\n" + "writes completed = %d\n", + lmStat.commit, + lmStat.submitted, + lmStat.pagedone); + + begin = offset; + *start = buffer + begin; + len -= begin; + + if (len > length) + len = length; + else + *eof = 1; + + if (len < 0) + len = 0; + + return len; +} +#endif /* CONFIG_JFS_STATISTICS */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_logmgr.h linux.19pre5-ac1/fs/jfs/jfs_logmgr.h --- linux.19p5/fs/jfs/jfs_logmgr.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_logmgr.h Thu Apr 4 16:04:13 2002 @@ -0,0 +1,500 @@ +/* + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _H_JFS_LOGMGR +#define _H_JFS_LOGMGR + + +#include "jfs_filsys.h" +#include "jfs_lock.h" + +/* + * log manager configuration parameters + */ + +/* log page size */ +#define LOGPSIZE 4096 +#define L2LOGPSIZE 12 + +#define LOGPAGES 16 /* Log pages per mounted file system */ + +/* + * log logical volume + * + * a log is used to make the commit operation on journalled + * files within the same logical volume group atomic. + * a log is implemented with a logical volume. + * there is one log per logical volume group. + * + * block 0 of the log logical volume is not used (ipl etc). + * block 1 contains a log "superblock" and is used by logFormat(), + * lmLogInit(), lmLogShutdown(), and logRedo() to record status + * of the log but is not otherwise used during normal processing. + * blocks 2 - (N-1) are used to contain log records. + * + * when a volume group is varied-on-line, logRedo() must have + * been executed before the file systems (logical volumes) in + * the volume group can be mounted. + */ +/* + * log superblock (block 1 of logical volume) + */ +#define LOGSUPER_B 1 +#define LOGSTART_B 2 + +#define LOGMAGIC 0x87654321 +#define LOGVERSION 1 + +typedef struct { + u32 magic; /* 4: log lv identifier */ + s32 version; /* 4: version number */ + s32 serial; /* 4: log open/mount counter */ + s32 size; /* 4: size in number of LOGPSIZE blocks */ + s32 bsize; /* 4: logical block size in byte */ + s32 l2bsize; /* 4: log2 of bsize */ + + u32 flag; /* 4: option */ + u32 state; /* 4: state - see below */ + + s32 end; /* 4: addr of last log record set by logredo */ + u32 active[8]; /* 32: active file systems bit vector */ + s32 rsrvd[LOGPSIZE / 4 - 17]; +} logsuper_t; + +/* log flag: commit option (see jfs_filsys.h) */ + +/* log state */ +#define LOGMOUNT 0 /* log mounted by lmLogInit() */ +#define LOGREDONE 1 /* log shutdown by lmLogShutdown(). + * log redo completed by logredo(). + */ +#define LOGWRAP 2 /* log wrapped */ +#define LOGREADERR 3 /* log read error detected in logredo() */ + + +/* + * log logical page + * + * (this comment should be rewritten !) + * the header and trailer structures (h,t) will normally have + * the same page and eor value. + * An exception to this occurs when a complete page write is not + * accomplished on a power failure. Since the hardware may "split write" + * sectors in the page, any out of order sequence may occur during powerfail + * and needs to be recognized during log replay. The xor value is + * an "exclusive or" of all log words in the page up to eor. This + * 32 bit eor is stored with the top 16 bits in the header and the + * bottom 16 bits in the trailer. logredo can easily recognize pages + * that were not completed by reconstructing this eor and checking + * the log page. + * + * Previous versions of the operating system did not allow split + * writes and detected partially written records in logredo by + * ordering the updates to the header, trailer, and the move of data + * into the logdata area. The order: (1) data is moved (2) header + * is updated (3) trailer is updated. In logredo, when the header + * differed from the trailer, the header and trailer were reconciled + * as follows: if h.page != t.page they were set to the smaller of + * the two and h.eor and t.eor set to 8 (i.e. empty page). if (only) + * h.eor != t.eor they were set to the smaller of their two values. + */ +typedef struct { + struct { /* header */ + s32 page; /* 4: log sequence page number */ + s16 rsrvd; /* 2: */ + s16 eor; /* 2: end-of-log offset of lasrt record write */ + } h; + + s32 data[LOGPSIZE / 4 - 4]; /* log record area */ + + struct { /* trailer */ + s32 page; /* 4: normally the same as h.page */ + s16 rsrvd; /* 2: */ + s16 eor; /* 2: normally the same as h.eor */ + } t; +} logpage_t; + +#define LOGPHDRSIZE 8 /* log page header size */ +#define LOGPTLRSIZE 8 /* log page trailer size */ + + +/* + * log record + * + * (this comment should be rewritten !) + * jfs uses only "after" log records (only a single writer is allowed + * in a page, pages are written to temporary paging space if + * if they must be written to disk before commit, and i/o is + * scheduled for modified pages to their home location after + * the log records containing the after values and the commit + * record is written to the log on disk, undo discards the copy + * in main-memory.) + * + * a log record consists of a data area of variable length followed by + * a descriptor of fixed size LOGRDSIZE bytes. + * the data area is rounded up to an integral number of 4-bytes and + * must be no longer than LOGPSIZE. + * the descriptor is of size of multiple of 4-bytes and aligned on a + * 4-byte boundary. + * records are packed one after the other in the data area of log pages. + * (sometimes a DUMMY record is inserted so that at least one record ends + * on every page or the longest record is placed on at most two pages). + * the field eor in page header/trailer points to the byte following + * the last record on a page. + */ + +/* log record types */ +#define LOG_COMMIT 0x8000 +#define LOG_SYNCPT 0x4000 +#define LOG_MOUNT 0x2000 +#define LOG_REDOPAGE 0x0800 +#define LOG_NOREDOPAGE 0x0080 +#define LOG_NOREDOINOEXT 0x0040 +#define LOG_UPDATEMAP 0x0008 +#define LOG_NOREDOFILE 0x0001 + +/* REDOPAGE/NOREDOPAGE log record data type */ +#define LOG_INODE 0x0001 +#define LOG_XTREE 0x0002 +#define LOG_DTREE 0x0004 +#define LOG_BTROOT 0x0010 +#define LOG_EA 0x0020 +#define LOG_ACL 0x0040 +#define LOG_DATA 0x0080 +#define LOG_NEW 0x0100 +#define LOG_EXTEND 0x0200 +#define LOG_RELOCATE 0x0400 +#define LOG_DIR_XTREE 0x0800 /* Xtree is in directory inode */ + +/* UPDATEMAP log record descriptor type */ +#define LOG_ALLOCXADLIST 0x0080 +#define LOG_ALLOCPXDLIST 0x0040 +#define LOG_ALLOCXAD 0x0020 +#define LOG_ALLOCPXD 0x0010 +#define LOG_FREEXADLIST 0x0008 +#define LOG_FREEPXDLIST 0x0004 +#define LOG_FREEXAD 0x0002 +#define LOG_FREEPXD 0x0001 + + +typedef struct lrd { + /* + * type independent area + */ + s32 logtid; /* 4: log transaction identifier */ + s32 backchain; /* 4: ptr to prev record of same transaction */ + u16 type; /* 2: record type */ + s16 length; /* 2: length of data in record (in byte) */ + s32 aggregate; /* 4: file system lv/aggregate */ + /* (16) */ + + /* + * type dependent area (20) + */ + union { + + /* + * COMMIT: commit + * + * transaction commit: no type-dependent information; + */ + + /* + * REDOPAGE: after-image + * + * apply after-image; + * + * N.B. REDOPAGE, NOREDOPAGE, and UPDATEMAP must be same format; + */ + struct { + u32 fileset; /* 4: fileset number */ + u32 inode; /* 4: inode number */ + u16 type; /* 2: REDOPAGE record type */ + s16 l2linesize; /* 2: log2 of line size */ + pxd_t pxd; /* 8: on-disk page pxd */ + } redopage; /* (20) */ + + /* + * NOREDOPAGE: the page is freed + * + * do not apply after-image records which precede this record + * in the log with the same page block number to this page. + * + * N.B. REDOPAGE, NOREDOPAGE, and UPDATEMAP must be same format; + */ + struct { + s32 fileset; /* 4: fileset number */ + u32 inode; /* 4: inode number */ + u16 type; /* 2: NOREDOPAGE record type */ + s16 rsrvd; /* 2: reserved */ + pxd_t pxd; /* 8: on-disk page pxd */ + } noredopage; /* (20) */ + + /* + * UPDATEMAP: update block allocation map + * + * either in-line PXD, + * or out-of-line XADLIST; + * + * N.B. REDOPAGE, NOREDOPAGE, and UPDATEMAP must be same format; + */ + struct { + u32 fileset; /* 4: fileset number */ + u32 inode; /* 4: inode number */ + u16 type; /* 2: UPDATEMAP record type */ + s16 nxd; /* 2: number of extents */ + pxd_t pxd; /* 8: pxd */ + } updatemap; /* (20) */ + + /* + * NOREDOINOEXT: the inode extent is freed + * + * do not apply after-image records which precede this + * record in the log with the any of the 4 page block + * numbers in this inode extent. + * + * NOTE: The fileset and pxd fields MUST remain in + * the same fields in the REDOPAGE record format. + * + */ + struct { + s32 fileset; /* 4: fileset number */ + s32 iagnum; /* 4: IAG number */ + s32 inoext_idx; /* 4: inode extent index */ + pxd_t pxd; /* 8: on-disk page pxd */ + } noredoinoext; /* (20) */ + + /* + * SYNCPT: log sync point + * + * replay log upto syncpt address specified; + */ + struct { + s32 sync; /* 4: syncpt address (0 = here) */ + } syncpt; + + /* + * MOUNT: file system mount + * + * file system mount: no type-dependent information; + */ + + /* + * ? FREEXTENT: free specified extent(s) + * + * free specified extent(s) from block allocation map + * N.B.: nextents should be length of data/sizeof(xad_t) + */ + struct { + s32 type; /* 4: FREEXTENT record type */ + s32 nextent; /* 4: number of extents */ + + /* data: PXD or XAD list */ + } freextent; + + /* + * ? NOREDOFILE: this file is freed + * + * do not apply records which precede this record in the log + * with the same inode number. + * + * NOREDILE must be the first to be written at commit + * (last to be read in logredo()) - it prevents + * replay of preceding updates of all preceding generations + * of the inumber esp. the on-disk inode itself, + * but does NOT prevent + * replay of the + */ + struct { + s32 fileset; /* 4: fileset number */ + u32 inode; /* 4: inode number */ + } noredofile; + + /* + * ? NEWPAGE: + * + * metadata type dependent + */ + struct { + s32 fileset; /* 4: fileset number */ + u32 inode; /* 4: inode number */ + s32 type; /* 4: NEWPAGE record type */ + pxd_t pxd; /* 8: on-disk page pxd */ + } newpage; + + /* + * ? DUMMY: filler + * + * no type-dependent information + */ + } log; +} lrd_t; /* (36) */ + +#define LOGRDSIZE (sizeof(struct lrd)) + +/* + * line vector descriptor + */ +typedef struct { + s16 offset; + s16 length; +} lvd_t; + + +/* + * log logical volume + */ +typedef struct jfs_log { + + struct super_block *sb; /* 4: This is used to sync metadata + * before writing syncpt. Will + * need to be a list if we share + * the log between fs's + */ + kdev_t dev; /* 4: log lv number */ + struct file *devfp; /* 4: log device file */ + s32 serial; /* 4: log mount serial number */ + + s64 base; /* @8: log extent address (inline log ) */ + int size; /* 4: log size in log page (in page) */ + int l2bsize; /* 4: log2 of bsize */ + + uint flag; /* 4: flag */ + uint state; /* 4: state */ + + struct lbuf *lbuf_free; /* 4: free lbufs */ + wait_queue_head_t free_wait; /* 4: */ + + /* log write */ + int logtid; /* 4: log tid */ + int page; /* 4: page number of eol page */ + int eor; /* 4: eor of last record in eol page */ + struct lbuf *bp; /* 4: current log page buffer */ + + struct semaphore loglock; /* 4: log write serialization lock */ + + /* syncpt */ + int nextsync; /* 4: bytes to write before next syncpt */ + int active; /* 4: */ + int syncbarrier; /* 4: */ + wait_queue_head_t syncwait; /* 4: */ + + /* commit */ + uint cflag; /* 4: */ + struct { /* 8: FIFO commit queue header */ + struct tblock *head; + struct tblock *tail; + } cqueue; + int gcrtc; /* 4: GC_READY transaction count */ + struct tblock *gclrt; /* 4: latest GC_READY transaction */ + spinlock_t gclock; /* 4: group commit lock */ + int logsize; /* 4: log data area size in byte */ + int lsn; /* 4: end-of-log */ + int clsn; /* 4: clsn */ + int syncpt; /* 4: addr of last syncpt record */ + int sync; /* 4: addr from last logsync() */ + struct list_head synclist; /* 8: logsynclist anchor */ + spinlock_t synclock; /* 4: synclist lock */ + struct lbuf *wqueue; /* 4: log pageout queue */ + int count; /* 4: count */ +} log_t; + +/* + * group commit flag + */ +/* log_t */ +#define logGC_PAGEOUT 0x00000001 + +/* tblock_t/lbuf_t */ +#define tblkGC_QUEUE 0x0001 +#define tblkGC_READY 0x0002 +#define tblkGC_COMMIT 0x0004 +#define tblkGC_COMMITTED 0x0008 +#define tblkGC_EOP 0x0010 +#define tblkGC_FREE 0x0020 +#define tblkGC_LEADER 0x0040 +#define tblkGC_ERROR 0x0080 +#define tblkGC_LAZY 0x0100 // D230860 +#define tblkGC_UNLOCKED 0x0200 // D230860 + +/* + * log cache buffer header + */ +typedef struct lbuf { + struct buffer_head l_bh; /* for doing I/O */ + log_t *l_log; /* 4: log associated with buffer */ + + /* + * data buffer base area + */ + uint l_flag; /* 4: pageout control flags */ + + struct lbuf *l_wqnext; /* 4: write queue link */ + struct lbuf *l_freelist; /* 4: freelistlink */ + + int l_pn; /* 4: log page number */ + int l_eor; /* 4: log record eor */ + int l_ceor; /* 4: committed log record eor */ + + s64 l_blkno; /* 8: log page block number */ + caddr_t l_ldata; /* 4: data page */ + + wait_queue_head_t l_ioevent; /* 4: i/o done event */ + struct page *l_page; /* The page itself */ +} lbuf_t; + +/* Reuse l_freelist for redrive list */ +#define l_redrive_next l_freelist + +/* + * logsynclist block + * + * common logsyncblk prefix for jbuf_t and tblock_t + */ +typedef struct logsyncblk { + u16 xflag; /* flags */ + u16 flag; /* only meaninful in tblock_t */ + lid_t lid; /* lock id */ + s32 lsn; /* log sequence number */ + struct list_head synclist; /* log sync list link */ +} logsyncblk_t; + +/* + * logsynclist serialization (per log) + */ + +#define LOGSYNC_LOCK_INIT(log) spin_lock_init(&(log)->synclock) +#define LOGSYNC_LOCK(log) spin_lock(&(log)->synclock) +#define LOGSYNC_UNLOCK(log) spin_unlock(&(log)->synclock) + +/* compute the difference in bytes of lsn from sync point */ +#define logdiff(diff, lsn, log)\ +{\ + diff = (lsn) - (log)->syncpt;\ + if (diff < 0)\ + diff += (log)->logsize;\ +} + +extern int lmLogOpen(struct super_block *sb, log_t ** log); +extern int lmLogClose(struct super_block *sb, log_t * log); +extern int lmLogSync(log_t * log, int nosyncwait); +extern int lmLogQuiesce(log_t * log); +extern int lmLogResume(log_t * log, struct super_block *sb); +extern int lmLogFormat(struct super_block *sb, s64 logAddress, int logSize); + +#endif /* _H_JFS_LOGMGR */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_metapage.c linux.19pre5-ac1/fs/jfs/jfs_metapage.c --- linux.19p5/fs/jfs/jfs_metapage.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_metapage.c Thu Feb 14 20:46:53 2002 @@ -0,0 +1,688 @@ +/* + * + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + * + * Module: jfs/jfs_metapage.c + * + */ + +#include +#include +#include "jfs_incore.h" +#include "jfs_filsys.h" +#include "jfs_metapage.h" +#include "jfs_txnmgr.h" +#include "jfs_debug.h" + +extern struct task_struct *jfsCommitTask; +static unsigned int metapages = 1024; /* ??? Need a better number */ +static unsigned int free_metapages; +static metapage_t *metapage_buf; +static unsigned long meta_order; +static metapage_t *meta_free_list = NULL; +static spinlock_t meta_lock = SPIN_LOCK_UNLOCKED; +static wait_queue_head_t meta_wait; + +#ifdef CONFIG_JFS_STATISTICS +struct { + uint pagealloc; /* # of page allocations */ + uint pagefree; /* # of page frees */ + uint lockwait; /* # of sleeping lock_metapage() calls */ + uint allocwait; /* # of sleeping alloc_metapage() calls */ +} mpStat; +#endif + + +#define HASH_BITS 10 /* This makes hash_table 1 4K page */ +#define HASH_SIZE (1 << HASH_BITS) +static metapage_t **hash_table = NULL; +static unsigned long hash_order; + + +static inline int metapage_locked(struct metapage *mp) +{ + return test_bit(META_locked, &mp->flag); +} + +static inline int trylock_metapage(struct metapage *mp) +{ + return test_and_set_bit(META_locked, &mp->flag); +} + +static inline void unlock_metapage(struct metapage *mp) +{ + clear_bit(META_locked, &mp->flag); + wake_up(&mp->wait); +} + +static void __lock_metapage(struct metapage *mp) +{ + DECLARE_WAITQUEUE(wait, current); + + INCREMENT(mpStat.lockwait); + + add_wait_queue_exclusive(&mp->wait, &wait); + do { + set_current_state(TASK_UNINTERRUPTIBLE); + if (metapage_locked(mp)) { + spin_unlock(&meta_lock); + schedule(); + spin_lock(&meta_lock); + } + } while (trylock_metapage(mp)); + __set_current_state(TASK_RUNNING); + remove_wait_queue(&mp->wait, &wait); +} + +/* needs meta_lock */ +static inline void lock_metapage(struct metapage *mp) +{ + if (trylock_metapage(mp)) + __lock_metapage(mp); +} + +/* We're currently re-evaluating the method we use to write metadata + * pages. Currently, we have to make sure there no dirty buffer_heads + * hanging around after we free the metadata page, since the same + * physical disk blocks may be used in a different address space and we + * can't write old data over the good data. + * + * The best way to do this now is with block_invalidate_page. However, + * this is only available in the newer kernels and is not exported + * to modules. block_flushpage is the next best, but it too is not exported + * to modules. + * + * In a module, about the best we have is generic_buffer_fdatasync. This + * synchronously writes any dirty buffers. This is not optimal, but it will + * keep old dirty buffers from overwriting newer data. + */ +static inline void invalidate_page(metapage_t *mp) +{ +#ifdef MODULE + generic_buffer_fdatasync(mp->mapping->host, mp->index, mp->index + 1); +#else + lock_page(mp->page); + block_flushpage(mp->page, 0); + UnlockPage(mp->page); +#endif +} + +int __init metapage_init(void) +{ + int i; + metapage_t *last = NULL; + metapage_t *mp; + + /* + * Initialize wait queue + */ + init_waitqueue_head(&meta_wait); + + /* + * Allocate the metapage structures + */ + for (meta_order = 0; + ((PAGE_SIZE << meta_order) / sizeof(metapage_t)) < metapages; + meta_order++); + metapages = (PAGE_SIZE << meta_order) / sizeof(metapage_t); + + jFYI(1, ("metapage_init: metapage size = %Zd, metapages = %d\n", + sizeof(metapage_t), metapages)); + + metapage_buf = + (metapage_t *) __get_free_pages(GFP_KERNEL, meta_order); + assert(metapage_buf); + memset(metapage_buf, 0, PAGE_SIZE << meta_order); + + mp = metapage_buf; + for (i = 0; i < metapages; i++, mp++) { + mp->flag = 0; + set_bit(META_free, &mp->flag); + init_waitqueue_head(&mp->wait); + mp->hash_next = last; + last = mp; + } + meta_free_list = last; + free_metapages = metapages; + + /* + * Now the hash list + */ + for (hash_order = 0; + ((PAGE_SIZE << hash_order) / sizeof(void *)) < HASH_SIZE; + hash_order++); + hash_table = + (metapage_t **) __get_free_pages(GFP_KERNEL, hash_order); + assert(hash_table); + memset(hash_table, 0, PAGE_SIZE << hash_order); + + return 0; +} + +void metapage_exit(void) +{ + free_pages((unsigned long) metapage_buf, meta_order); + free_pages((unsigned long) hash_table, hash_order); + metapage_buf = 0; /* This is a signal to the jfsIOwait thread */ +} + +/* + * Get metapage structure from freelist + * + * Caller holds meta_lock + */ +static metapage_t *alloc_metapage(int *dropped_lock) +{ + metapage_t *new; + + *dropped_lock = FALSE; + + /* + * Reserve two metapages for the lazy commit thread. Otherwise + * we may deadlock with holders of metapages waiting for tlocks + * that lazy thread should be freeing. + */ + if ((free_metapages < 3) && (current != jfsCommitTask)) { + INCREMENT(mpStat.allocwait); + *dropped_lock = TRUE; + __SLEEP_COND(meta_wait, (free_metapages > 2), + spin_lock(&meta_lock), spin_unlock(&meta_lock)); + } + + assert(meta_free_list); + + new = meta_free_list; + meta_free_list = new->hash_next; + free_metapages--; + + return new; +} + +/* + * Put metapage on freelist (holding meta_lock) + */ +static inline void __free_metapage(metapage_t * mp) +{ + mp->flag = 0; + set_bit(META_free, &mp->flag); + mp->hash_next = meta_free_list; + meta_free_list = mp; + free_metapages++; + wake_up(&meta_wait); +} + +/* + * Put metapage on freelist (not holding meta_lock) + */ +static inline void free_metapage(metapage_t * mp) +{ + spin_lock(&meta_lock); + __free_metapage(mp); + spin_unlock(&meta_lock); +} + +/* + * Basically same hash as in pagemap.h, but using our hash table + */ +static metapage_t **meta_hash(struct address_space *mapping, + unsigned long index) +{ +#define i (((unsigned long)mapping)/ \ + (sizeof(struct inode) & ~(sizeof(struct inode) -1 ))) +#define s(x) ((x) + ((x) >> HASH_BITS)) + return hash_table + (s(i + index) & (HASH_SIZE - 1)); +#undef i +#undef s +} + +static metapage_t *search_hash(metapage_t ** hash_ptr, + struct address_space *mapping, + unsigned long index) +{ + metapage_t *ptr; + + for (ptr = *hash_ptr; ptr; ptr = ptr->hash_next) { + if ((ptr->mapping == mapping) && (ptr->index == index)) + return ptr; + } + + return NULL; +} + +static void add_to_hash(metapage_t * mp, metapage_t ** hash_ptr) +{ + if (*hash_ptr) + (*hash_ptr)->hash_prev = mp; + + mp->hash_prev = NULL; + mp->hash_next = *hash_ptr; + *hash_ptr = mp; + list_add(&mp->inode_list, &JFS_IP(mp->mapping->host)->mp_list); +} + +static void remove_from_hash(metapage_t * mp, metapage_t ** hash_ptr) +{ + list_del(&mp->inode_list); + + if (mp->hash_prev) + mp->hash_prev->hash_next = mp->hash_next; + else { + assert(*hash_ptr == mp); + *hash_ptr = mp->hash_next; + } + + if (mp->hash_next) + mp->hash_next->hash_prev = mp->hash_prev; +} + +/* + * Direct address space operations + */ + +static int direct_get_block(struct inode *ip, long lblock, + struct buffer_head *bh_result, int create) +{ + bh_result->b_dev = ip->i_dev; + bh_result->b_blocknr = lblock; + if (create) + bh_result->b_state |= (1UL << BH_Mapped) | (1UL << BH_New); + else + bh_result->b_state |= (1UL << BH_Mapped); + + return 0; +} + +static int direct_writepage(struct page *page) +{ + return block_write_full_page(page, direct_get_block); +} + +static int direct_readpage(struct file *fp, struct page *page) +{ + return block_read_full_page(page, direct_get_block); +} + +static int direct_prepare_write(struct file *file, struct page *page, + unsigned from, unsigned to) +{ + return block_prepare_write(page, from, to, direct_get_block); +} + +static int direct_bmap(struct address_space *mapping, long block) +{ + return generic_block_bmap(mapping, block, direct_get_block); +} + +struct address_space_operations direct_aops = { + readpage: direct_readpage, + writepage: direct_writepage, + sync_page: block_sync_page, + prepare_write: direct_prepare_write, + commit_write: generic_commit_write, + bmap: direct_bmap, +}; + +metapage_t *__get_metapage(struct inode *inode, + unsigned long lblock, unsigned int size, + int absolute, unsigned long new) +{ + int dropped_lock; + metapage_t **hash_ptr; + int l2BlocksPerPage; + int l2bsize; + struct address_space *mapping; + metapage_t *mp; + unsigned long page_index; + unsigned long page_offset; + + jFYI(1, ("__get_metapage: inode = 0x%p, lblock = 0x%lx\n", + inode, lblock)); + + if (absolute) + mapping = JFS_SBI(inode->i_sb)->direct_mapping; + else + mapping = inode->i_mapping; + + spin_lock(&meta_lock); + + hash_ptr = meta_hash(mapping, lblock); + + mp = search_hash(hash_ptr, mapping, lblock); + if (mp) { + page_found: + if (test_bit(META_discard, &mp->flag)) { + assert(new); /* It's okay to reuse a discarded + * if we expect it to be empty + */ + clear_bit(META_discard, &mp->flag); + } + mp->count++; + jFYI(1, ("__get_metapage: found 0x%p, in hash\n", mp)); + assert(mp->logical_size == size); + lock_metapage(mp); + spin_unlock(&meta_lock); + } else { + l2bsize = inode->i_sb->s_blocksize_bits; + l2BlocksPerPage = PAGE_CACHE_SHIFT - l2bsize; + page_index = lblock >> l2BlocksPerPage; + page_offset = (lblock - (page_index << l2BlocksPerPage)) << + l2bsize; + if ((page_offset + size) > PAGE_SIZE) { + spin_unlock(&meta_lock); + jERROR(1, ("MetaData crosses page boundary!!\n")); + return NULL; + } + + mp = alloc_metapage(&dropped_lock); + if (dropped_lock) { + /* alloc_metapage blocked, we need to search the hash + * again. (The goto is ugly, maybe we'll clean this + * up in the future.) + */ + metapage_t *mp2; + mp2 = search_hash(hash_ptr, mapping, lblock); + if (mp2) { + __free_metapage(mp); + mp = mp2; + goto page_found; + } + } + mp->flag = 0; + lock_metapage(mp); + if (absolute) + set_bit(META_absolute, &mp->flag); + mp->xflag = COMMIT_PAGE; + mp->count = 1; + atomic_set(&mp->nohomeok,0); + mp->mapping = mapping; + mp->index = lblock; + mp->page = 0; + mp->logical_size = size; + add_to_hash(mp, hash_ptr); + spin_unlock(&meta_lock); + + if (new) { + jFYI(1, + ("__get_metapage: Calling grab_cache_page\n")); + mp->page = grab_cache_page(mapping, page_index); + if (!mp->page) { + jERROR(1, ("grab_cache_page failed!\n")); + spin_lock(&meta_lock); + remove_from_hash(mp, hash_ptr); + __free_metapage(mp); + spin_unlock(&meta_lock); + return NULL; + } else + INCREMENT(mpStat.pagealloc); + } else { + jFYI(1, + ("__get_metapage: Calling read_cache_page\n")); + mp->page = + read_cache_page(mapping, lblock, + (filler_t *) mapping->a_ops-> + readpage, NULL); + if (IS_ERR(mp->page)) { + jERROR(1, ("read_cache_page failed!\n")); + spin_lock(&meta_lock); + remove_from_hash(mp, hash_ptr); + __free_metapage(mp); + spin_unlock(&meta_lock); + return NULL; + } else + INCREMENT(mpStat.pagealloc); + lock_page(mp->page); + } + mp->data = (void *) (kmap(mp->page) + page_offset); + } + jFYI(1, ("__get_metapage: returning = 0x%p\n", mp)); + return mp; +} + +void hold_metapage(metapage_t * mp, int force) +{ + spin_lock(&meta_lock); + + mp->count++; + + if (force) { + ASSERT (!(test_bit(META_forced, &mp->flag))); + if (trylock_metapage(mp)) + set_bit(META_forced, &mp->flag); + } else + lock_metapage(mp); + + spin_unlock(&meta_lock); +} + +static void __write_metapage(metapage_t * mp) +{ + struct inode *ip = (struct inode *) mp->mapping->host; + unsigned long page_index; + unsigned long page_offset; + int rc; + int l2bsize = ip->i_sb->s_blocksize_bits; + int l2BlocksPerPage = PAGE_CACHE_SHIFT - l2bsize; + + jFYI(1, ("__write_metapage: mp = 0x%p\n", mp)); + + if (test_bit(META_discard, &mp->flag)) { + /* + * This metadata is no longer valid + */ + clear_bit(META_dirty, &mp->flag); + return; + } + + page_index = mp->page->index; + page_offset = + (mp->index - (page_index << l2BlocksPerPage)) << l2bsize; + + rc = mp->mapping->a_ops->prepare_write(NULL, mp->page, page_offset, + page_offset + + mp->logical_size); + if (rc) { + jERROR(1, ("prepare_write return %d!\n", rc)); + ClearPageUptodate(mp->page); + kunmap(mp->page); + clear_bit(META_dirty, &mp->flag); + return; + } + rc = mp->mapping->a_ops->commit_write(NULL, mp->page, page_offset, + page_offset + + mp->logical_size); + if (rc) { + jERROR(1, ("commit_write returned %d\n", rc)); + } + + clear_bit(META_dirty, &mp->flag); + + jFYI(1, ("__write_metapage done\n")); +} + +void release_metapage(metapage_t * mp) +{ + log_t *log; + struct inode *ip; + + jFYI(1, + ("release_metapage: mp = 0x%p, flag = 0x%lx\n", mp, + mp->flag)); + + spin_lock(&meta_lock); + if (test_bit(META_forced, &mp->flag)) { + clear_bit(META_forced, &mp->flag); + mp->count--; + spin_unlock(&meta_lock); + return; + } + + ip = (struct inode *) mp->mapping->host; + + assert(mp->count); + if (--mp->count || atomic_read(&mp->nohomeok)) { + unlock_metapage(mp); + spin_unlock(&meta_lock); + } else { + remove_from_hash(mp, meta_hash(mp->mapping, mp->index)); + spin_unlock(&meta_lock); + + if (mp->page) { + kunmap(mp->page); + mp->data = 0; + if (test_bit(META_dirty, &mp->flag)) + __write_metapage(mp); + UnlockPage(mp->page); + if (test_bit(META_sync, &mp->flag)) { + sync_metapage(mp); + clear_bit(META_sync, &mp->flag); + } + + if (test_bit(META_discard, &mp->flag)) + invalidate_page(mp); + + page_cache_release(mp->page); + INCREMENT(mpStat.pagefree); + } + + if (mp->lsn) { + /* + * Remove metapage from logsynclist. + */ + log = mp->log; + LOGSYNC_LOCK(log); + mp->log = 0; + mp->lsn = 0; + mp->clsn = 0; + log->count--; + list_del(&mp->synclist); + LOGSYNC_UNLOCK(log); + } + + free_metapage(mp); + } + jFYI(1, ("release_metapage: done\n")); +} + +void invalidate_metapages(struct inode *ip, unsigned long addr, + unsigned long len) +{ + metapage_t **hash_ptr; + unsigned long lblock; + int l2BlocksPerPage = PAGE_CACHE_SHIFT - ip->i_sb->s_blocksize_bits; + struct address_space *mapping = ip->i_mapping; + metapage_t *mp; +#ifndef MODULE + struct page *page; +#endif + + /* + * First, mark metapages to discard. They will eventually be + * released, but should not be written. + */ + for (lblock = addr; lblock < addr + len; + lblock += 1 << l2BlocksPerPage) { + hash_ptr = meta_hash(mapping, lblock); + spin_lock(&meta_lock); + mp = search_hash(hash_ptr, mapping, lblock); + if (mp) { + set_bit(META_discard, &mp->flag); + spin_unlock(&meta_lock); + /* + * If in the metapage cache, we've got the page locked + */ +#ifdef MODULE + UnlockPage(mp->page); + generic_buffer_fdatasync(mp->mapping->host, mp->index, + mp->index+1); + lock_page(mp->page); +#else + block_flushpage(mp->page, 0); +#endif + } else { + spin_unlock(&meta_lock); +#ifdef MODULE + generic_buffer_fdatasync(ip, lblock << l2BlocksPerPage, + (lblock + 1) << l2BlocksPerPage); +#else + page = find_lock_page(mapping, + lblock >> l2BlocksPerPage); + if (page) { + block_flushpage(page, 0); + UnlockPage(page); + } +#endif + } + } +} + +void invalidate_inode_metapages(struct inode *inode) +{ + struct list_head *ptr; + metapage_t *mp; + + spin_lock(&meta_lock); + list_for_each(ptr, &JFS_IP(inode)->mp_list) { + mp = list_entry(ptr, metapage_t, inode_list); + clear_bit(META_dirty, &mp->flag); + set_bit(META_discard, &mp->flag); + kunmap(mp->page); + UnlockPage(mp->page); + page_cache_release(mp->page); + INCREMENT(mpStat.pagefree); + mp->data = 0; + mp->page = 0; + } + spin_unlock(&meta_lock); + truncate_inode_pages(inode->i_mapping, 0); +} + +#ifdef CONFIG_JFS_STATISTICS +int jfs_mpstat_read(char *buffer, char **start, off_t offset, int length, + int *eof, void *data) +{ + int len = 0; + off_t begin; + + len += sprintf(buffer, + "JFS Metapage statistics\n" + "=======================\n" + "metapages in use = %d\n" + "page allocations = %d\n" + "page frees = %d\n" + "lock waits = %d\n" + "allocation waits = %d\n", + metapages - free_metapages, + mpStat.pagealloc, + mpStat.pagefree, + mpStat.lockwait, + mpStat.allocwait); + + begin = offset; + *start = buffer + begin; + len -= begin; + + if (len > length) + len = length; + else + *eof = 1; + + if (len < 0) + len = 0; + + return len; +} +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_metapage.h linux.19pre5-ac1/fs/jfs/jfs_metapage.h --- linux.19p5/fs/jfs/jfs_metapage.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_metapage.h Thu Apr 4 16:04:13 2002 @@ -0,0 +1,123 @@ +/* + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _H_JFS_METAPAGE +#define _H_JFS_METAPAGE + +#include + +typedef struct metapage { + /* Common logsyncblk prefix (see jfs_logmgr.h) */ + u16 xflag; + u16 unused; + lid_t lid; + int lsn; + struct list_head synclist; + /* End of logsyncblk prefix */ + + unsigned long flag; /* See Below */ + unsigned long count; /* Reference count */ + void *data; /* Data pointer */ + + /* list management stuff */ + struct metapage *hash_prev; + struct metapage *hash_next; /* Also used for free list */ + + struct list_head inode_list; /* per-inode metapage list */ + /* + * mapping & index become redundant, but we need these here to + * add the metapage to the hash before we have the real page + */ + struct address_space *mapping; + unsigned long index; + wait_queue_head_t wait; + + /* implementation */ + struct page *page; + unsigned long logical_size; + + /* Journal management */ + int clsn; + atomic_t nohomeok; + struct jfs_log *log; +} metapage_t; + +/* + * Direct-access address space operations + */ +extern struct address_space_operations direct_aops; + +/* metapage flag */ +#define META_locked 0 +#define META_absolute 1 +#define META_free 2 +#define META_dirty 3 +#define META_sync 4 +#define META_discard 5 +#define META_forced 6 + +#define mark_metapage_dirty(mp) set_bit(META_dirty, &(mp)->flag) + +/* function prototypes */ +extern metapage_t *__get_metapage(struct inode *inode, + unsigned long lblock, unsigned int size, + int absolute, unsigned long new); + +#define read_metapage(inode, lblock, size, absolute)\ + __get_metapage(inode, lblock, size, absolute, FALSE) + +#define get_metapage(inode, lblock, size, absolute)\ + __get_metapage(inode, lblock, size, absolute, TRUE) + +extern void release_metapage(metapage_t *); + +#define flush_metapage(mp) \ +{\ + set_bit(META_dirty, &(mp)->flag);\ + set_bit(META_sync, &(mp)->flag);\ + release_metapage(mp);\ +} + +#define sync_metapage(mp) \ + generic_buffer_fdatasync((struct inode *)mp->mapping->host,\ + mp->page->index, mp->page->index + 1) + +#define write_metapage(mp) \ +{\ + set_bit(META_dirty, &(mp)->flag);\ + release_metapage(mp);\ +} + +#define discard_metapage(mp) \ +{\ + clear_bit(META_dirty, &(mp)->flag);\ + set_bit(META_discard, &(mp)->flag);\ + release_metapage(mp);\ +} + +extern void hold_metapage(metapage_t *, int); + +/* + * This routine uses hash to explicitly find small number of pages + */ +extern void invalidate_metapages(struct inode *, unsigned long, unsigned long); + +/* + * This one uses mp_list to invalidate all pages for an inode + */ +extern void invalidate_inode_metapages(struct inode *inode); +#endif /* _H_JFS_METAPAGE */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_mount.c linux.19pre5-ac1/fs/jfs/jfs_mount.c --- linux.19p5/fs/jfs/jfs_mount.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_mount.c Thu Mar 14 22:44:22 2002 @@ -0,0 +1,541 @@ +/* + * MODULE_NAME: jfs_mount.c + * + * COMPONENT_NAME: sysjfs + * + * + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + */ + +/* + * Change History : + * + */ + +/* + * Module: jfs_mount.c + * + * note: file system in transition to aggregate/fileset: + * + * file system mount is interpreted as the mount of aggregate, + * if not already mounted, and mount of the single/only fileset in + * the aggregate; + * + * a file system/aggregate is represented by an internal inode + * (aka mount inode) initialized with aggregate superblock; + * each vfs represents a fileset, and points to its "fileset inode + * allocation map inode" (aka fileset inode): + * (an aggregate itself is structured recursively as a filset: + * an internal vfs is constructed and points to its "fileset inode + * allocation map inode" (aka aggregate inode) where each inode + * represents a fileset inode) so that inode number is mapped to + * on-disk inode in uniform way at both aggregate and fileset level; + * + * each vnode/inode of a fileset is linked to its vfs (to facilitate + * per fileset inode operations, e.g., unmount of a fileset, etc.); + * each inode points to the mount inode (to facilitate access to + * per aggregate information, e.g., block size, etc.) as well as + * its file set inode. + * + * aggregate + * ipmnt + * mntvfs -> fileset ipimap+ -> aggregate ipbmap -> aggregate ipaimap; + * fileset vfs -> vp(1) <-> ... <-> vp(n) <->vproot; + */ + +#include +#include "jfs_incore.h" +#include "jfs_filsys.h" +#include "jfs_superblock.h" +#include "jfs_dmap.h" +#include "jfs_imap.h" +#include "jfs_metapage.h" +#include "jfs_debug.h" + + +/* + * forward references + */ +static int chkSuper(struct super_block *); +static int logMOUNT(struct super_block *sb); + +/* + * NAME: jfs_mount(sb) + * + * FUNCTION: vfs_mount() + * + * PARAMETER: sb - super block + * + * RETURN: EBUSY - device already mounted or open for write + * EBUSY - cvrdvp already mounted; + * EBUSY - mount table full + * ENOTDIR - cvrdvp not directory on a device mount + * ENXIO - device open failure + */ +int jfs_mount(struct super_block *sb) +{ + int rc = 0; /* Return code */ + struct jfs_sb_info *sbi = JFS_SBI(sb); + struct inode *ipaimap = NULL; + struct inode *ipaimap2 = NULL; + struct inode *ipimap = NULL; + struct inode *ipbmap = NULL; + + jFYI(1, ("\nMount JFS\n")); + + /* + * read/validate superblock + * (initialize mount inode from the superblock) + */ + if ((rc = chkSuper(sb))) { + goto errout20; + } + + ipaimap = diReadSpecial(sb, AGGREGATE_I); + if (ipaimap == NULL) { + jERROR(1, ("jfs_mount: Faild to read AGGREGATE_I\n")); + rc = EIO; + goto errout20; + } + sbi->ipaimap = ipaimap; + + jFYI(1, ("jfs_mount: ipaimap:0x%p\n", ipaimap)); + + /* + * initialize aggregate inode allocation map + */ + if ((rc = diMount(ipaimap))) { + jERROR(1, + ("jfs_mount: diMount(ipaimap) failed w/rc = %d\n", + rc)); + goto errout21; + } + + /* + * open aggregate block allocation map + */ + ipbmap = diReadSpecial(sb, BMAP_I); + if (ipbmap == NULL) { + rc = EIO; + goto errout22; + } + + jFYI(1, ("jfs_mount: ipbmap:0x%p\n", ipbmap)); + + sbi->ipbmap = ipbmap; + + /* + * initialize aggregate block allocation map + */ + if ((rc = dbMount(ipbmap))) { + jERROR(1, ("jfs_mount: dbMount failed w/rc = %d\n", rc)); + goto errout22; + } + + /* + * open the secondary aggregate inode allocation map + * + * This is a duplicate of the aggregate inode allocation map. + * + * hand craft a vfs in the same fashion as we did to read ipaimap. + * By adding INOSPEREXT (32) to the inode number, we are telling + * diReadSpecial that we are reading from the secondary aggregate + * inode table. This also creates a unique entry in the inode hash + * table. + */ + if ((sbi->mntflag & JFS_BAD_SAIT) == 0) { + ipaimap2 = diReadSpecial(sb, AGGREGATE_I + INOSPEREXT); + if (ipaimap2 == 0) { + jERROR(1, + ("jfs_mount: Faild to read AGGREGATE_I\n")); + rc = EIO; + goto errout35; + } + sbi->ipaimap2 = ipaimap2; + + jFYI(1, ("jfs_mount: ipaimap2:0x%p\n", ipaimap2)); + + /* + * initialize secondary aggregate inode allocation map + */ + if ((rc = diMount(ipaimap2))) { + jERROR(1, + ("jfs_mount: diMount(ipaimap2) failed, rc = %d\n", + rc)); + goto errout35; + } + } else + /* Secondary aggregate inode table is not valid */ + sbi->ipaimap2 = 0; + + /* + * mount (the only/single) fileset + */ + /* + * open fileset inode allocation map (aka fileset inode) + */ + ipimap = diReadSpecial(sb, FILESYSTEM_I); + if (ipimap == NULL) { + jERROR(1, ("jfs_mount: Failed to read FILESYSTEM_I\n")); + /* open fileset secondary inode allocation map */ + rc = EIO; + goto errout40; + } + jFYI(1, ("jfs_mount: ipimap:0x%p\n", ipimap)); + + /* map further access of per fileset inodes by the fileset inode */ + sbi->ipimap = ipimap; + + /* initialize fileset inode allocation map */ + if ((rc = diMount(ipimap))) { + jERROR(1, ("jfs_mount: diMount failed w/rc = %d\n", rc)); + goto errout41; + } + + jFYI(1, ("Mount JFS Complete.\n")); + goto out; + + /* + * unwind on error + */ +//errout42: /* close fileset inode allocation map */ + diUnmount(ipimap, 1); + + errout41: /* close fileset inode allocation map inode */ + diFreeSpecial(ipimap); + + errout40: /* fileset closed */ + + /* close secondary aggregate inode allocation map */ + if (ipaimap2) { + diUnmount(ipaimap2, 1); + diFreeSpecial(ipaimap2); + } + + errout35: + + /* close aggregate block allocation map */ + dbUnmount(ipbmap, 1); + diFreeSpecial(ipbmap); + + errout22: /* close aggregate inode allocation map */ + + diUnmount(ipaimap, 1); + + errout21: /* close aggregate inodes */ + diFreeSpecial(ipaimap); + errout20: /* aggregate closed */ + + out: + + if (rc) { + jERROR(1, ("Mount JFS Failure: %d\n", rc)); + } + return rc; +} + +/* + * NAME: jfs_mount_rw(sb, remount) + * + * FUNCTION: Completes read-write mount, or remounts read-only volume + * as read-write + */ +int jfs_mount_rw(struct super_block *sb, int remount) +{ + struct jfs_sb_info *sbi = JFS_SBI(sb); + log_t *log; + int rc; + + /* + * If we are re-mounting a previously read-only volume, we want to + * re-read the inode and block maps, since fsck.jfs may have updated + * them. + */ + if (remount) { + if (chkSuper(sb) || (sbi->state != FM_CLEAN)) + return -EINVAL; + + truncate_inode_pages(sbi->ipimap->i_mapping, 0); + truncate_inode_pages(sbi->ipbmap->i_mapping, 0); + diUnmount(sbi->ipimap, 1); + if ((rc = diMount(sbi->ipimap))) { + jERROR(1,("jfs_mount_rw: diMount failed!\n")); + return rc; + } + + dbUnmount(sbi->ipbmap, 1); + if ((rc = dbMount(sbi->ipbmap))) { + jERROR(1,("jfs_mount_rw: dbMount failed!\n")); + return rc; + } + } +#ifdef _STILL_TO_PORT + /* + * get log device associated with the fs being mounted; + */ + if (ipmnt->i_mntflag & JFS_INLINELOG) { + vfsp->vfs_logVPB = vfsp->vfs_hVPB; + vfsp->vfs_logvpfs = vfsp->vfs_vpfsi; + } else if (vfsp->vfs_logvpfs == NULL) { + /* + * XXX: there's only one external log per system; + */ + jERROR(1, ("jfs_mount: Mount Failure! No Log Device.\n")); + goto errout30; + } + + logdev = vfsp->vfs_logvpfs->vpi_unit; + ipmnt->i_logdev = logdev; +#endif /* _STILL_TO_PORT */ + + /* + * open/initialize log + */ + if ((rc = lmLogOpen(sb, &log))) + return rc; + + JFS_SBI(sb)->log = log; + + /* + * update file system superblock; + */ + if ((rc = updateSuper(sb, FM_MOUNT))) { + jERROR(1, + ("jfs_mount: updateSuper failed w/rc = %d\n", rc)); + lmLogClose(sb, log); + JFS_SBI(sb)->log = 0; + return rc; + } + + /* + * write MOUNT log record of the file system + */ + logMOUNT(sb); + + return rc; +} + +/* + * chkSuper() + * + * validate the superblock of the file system to be mounted and + * get the file system parameters. + * + * returns + * 0 with fragsize set if check successful + * error code if not successful + */ +static int chkSuper(struct super_block *sb) +{ + int rc = 0; + metapage_t *mp; + struct jfs_sb_info *sbi = JFS_SBI(sb); + struct jfs_superblock *j_sb; + int AIM_bytesize, AIT_bytesize; + int expected_AIM_bytesize, expected_AIT_bytesize; + s64 AIM_byte_addr, AIT_byte_addr, fsckwsp_addr; + s64 byte_addr_diff0, byte_addr_diff1; + s32 bsize; + + if ((rc = readSuper(sb, &mp))) + return rc; + j_sb = (struct jfs_superblock *) (mp->data); + + /* + * validate superblock + */ + /* validate fs signature */ + if (strncmp(j_sb->s_magic, JFS_MAGIC, 4) || + j_sb->s_version != cpu_to_le32(JFS_VERSION)) { + //rc = EFORMAT; + rc = EINVAL; + goto out; + } + + bsize = le32_to_cpu(j_sb->s_bsize); +#ifdef _JFS_4K + if (bsize != PSIZE) { + jERROR(1, ("Currently only 4K block size supported!\n")); + rc = EINVAL; + goto out; + } +#endif /* _JFS_4K */ + + jFYI(1, ("superblock: flag:0x%08x state:0x%08x size:0x%Lx\n", + le32_to_cpu(j_sb->s_flag), le32_to_cpu(j_sb->s_state), + (unsigned long long) le64_to_cpu(j_sb->s_size))); + + /* validate the descriptors for Secondary AIM and AIT */ + if ((j_sb->s_flag & cpu_to_le32(JFS_BAD_SAIT)) != + cpu_to_le32(JFS_BAD_SAIT)) { + expected_AIM_bytesize = 2 * PSIZE; + AIM_bytesize = lengthPXD(&(j_sb->s_aim2)) * bsize; + expected_AIT_bytesize = 4 * PSIZE; + AIT_bytesize = lengthPXD(&(j_sb->s_ait2)) * bsize; + AIM_byte_addr = addressPXD(&(j_sb->s_aim2)) * bsize; + AIT_byte_addr = addressPXD(&(j_sb->s_ait2)) * bsize; + byte_addr_diff0 = AIT_byte_addr - AIM_byte_addr; + fsckwsp_addr = addressPXD(&(j_sb->s_fsckpxd)) * bsize; + byte_addr_diff1 = fsckwsp_addr - AIT_byte_addr; + if ((AIM_bytesize != expected_AIM_bytesize) || + (AIT_bytesize != expected_AIT_bytesize) || + (byte_addr_diff0 != AIM_bytesize) || + (byte_addr_diff1 <= AIT_bytesize)) + j_sb->s_flag |= cpu_to_le32(JFS_BAD_SAIT); + } + + /* in release 1, the flag MUST reflect inline log, and group commit */ + if ((j_sb->s_flag & cpu_to_le32(JFS_INLINELOG)) != + cpu_to_le32(JFS_INLINELOG)) + j_sb->s_flag |= cpu_to_le32(JFS_INLINELOG); + if ((j_sb->s_flag & cpu_to_le32(JFS_GROUPCOMMIT)) != + cpu_to_le32(JFS_GROUPCOMMIT)) + j_sb->s_flag |= cpu_to_le32(JFS_GROUPCOMMIT); + jFYI(0, ("superblock: flag:0x%08x state:0x%08x size:0x%Lx\n", + le32_to_cpu(j_sb->s_flag), le32_to_cpu(j_sb->s_state), + (unsigned long long) le64_to_cpu(j_sb->s_size))); + + /* validate fs state */ + if (j_sb->s_state != cpu_to_le32(FM_CLEAN) && + !(sb->s_flags & MS_RDONLY)) { + jERROR(1, + ("jfs_mount: Mount Failure: File System Dirty.\n")); + rc = EINVAL; + goto out; + } + + sbi->state = le32_to_cpu(j_sb->s_state); + sbi->mntflag = le32_to_cpu(j_sb->s_flag); + + /* + * JFS always does I/O by 4K pages. Don't tell the buffer cache + * that we use anything else (leave s_blocksize alone). + */ + sbi->bsize = bsize; + sbi->l2bsize = le16_to_cpu(j_sb->s_l2bsize); + + /* + * For now, ignore s_pbsize, l2bfactor. All I/O going through buffer + * cache. + */ + sbi->nbperpage = PSIZE >> sbi->l2bsize; + sbi->l2nbperpage = L2PSIZE - sbi->l2bsize; + sbi->l2niperblk = sbi->l2bsize - L2DISIZE; + if (sbi->mntflag & JFS_INLINELOG) + sbi->logpxd = j_sb->s_logpxd; + sbi->ait2 = j_sb->s_ait2; + + out: + release_metapage(mp); + + return rc; +} + + +/* + * updateSuper() + * + * update synchronously superblock if it is mounted read-write. + */ +int updateSuper(struct super_block *sb, uint state) +{ + int rc; + metapage_t *mp; + struct jfs_superblock *j_sb; + + /* + * Only fsck can fix dirty state + */ + if (JFS_SBI(sb)->state == FM_DIRTY) + return 0; + + if ((rc = readSuper(sb, &mp))) + return rc; + + j_sb = (struct jfs_superblock *) (mp->data); + + j_sb->s_state = cpu_to_le32(state); + JFS_SBI(sb)->state = state; + + if (state == FM_MOUNT) { + /* record log's dev_t and mount serial number */ + j_sb->s_logdev = + cpu_to_le32(kdev_t_to_nr(JFS_SBI(sb)->log->dev)); + j_sb->s_logserial = cpu_to_le32(JFS_SBI(sb)->log->serial); + } else if (state == FM_CLEAN) { + /* + * If this volume is shared with OS/2, OS/2 will need to + * recalculate DASD usage, since we don't deal with it. + */ + if (j_sb->s_flag & cpu_to_le32(JFS_DASD_ENABLED)) + j_sb->s_flag |= cpu_to_le32(JFS_DASD_PRIME); + } + + flush_metapage(mp); + + return 0; +} + + +/* + * readSuper() + * + * read superblock by raw sector address + */ +int readSuper(struct super_block *sb, metapage_t ** mpp) +{ + /* read in primary superblock */ + *mpp = read_metapage(JFS_SBI(sb)->direct_inode, + SUPER1_OFF >> sb->s_blocksize_bits, PSIZE, 1); + if (*mpp == NULL) { + /* read in secondary/replicated superblock */ + *mpp = read_metapage(JFS_SBI(sb)->direct_inode, + SUPER2_OFF >> sb->s_blocksize_bits, + PSIZE, 1); + } + return *mpp ? 0 : 1; +} + + +/* + * logMOUNT() + * + * function: write a MOUNT log record for file system. + * + * MOUNT record keeps logredo() from processing log records + * for this file system past this point in log. + * it is harmless if mount fails. + * + * note: MOUNT record is at aggregate level, not at fileset level, + * since log records of previous mounts of a fileset + * (e.g., AFTER record of extent allocation) have to be processed + * to update block allocation map at aggregate level. + */ +static int logMOUNT(struct super_block *sb) +{ + log_t *log = JFS_SBI(sb)->log; + lrd_t lrd; + + lrd.logtid = 0; + lrd.backchain = 0; + lrd.type = cpu_to_le16(LOG_MOUNT); + lrd.length = 0; + lrd.aggregate = cpu_to_le32(kdev_t_to_nr(sb->s_dev)); + lmLog(log, NULL, &lrd, NULL); + + return 0; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_superblock.h linux.19pre5-ac1/fs/jfs/jfs_superblock.h --- linux.19p5/fs/jfs/jfs_superblock.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_superblock.h Thu Feb 14 20:46:53 2002 @@ -0,0 +1,143 @@ +/* + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef _H_JFS_SUPERBLOCK +#define _H_JFS_SUPERBLOCK +/* + * jfs_superblock.h + */ + +/* + * make the magic number something a human could read + */ +#define JFS_MAGIC "JFS1" /* Magic word: Version 1 */ + +#define JFS_VERSION 1 /* Version number: Version 1 */ + +#define LV_NAME_SIZE 11 /* MUST BE 11 for OS/2 boot sector */ + +/* + * aggregate superblock + * + * The name superblock is too close to super_block, so the name has been + * changed to jfs_superblock. The utilities are still using the old name. + */ +struct jfs_superblock { + char s_magic[4]; /* 4: magic number */ + u32 s_version; /* 4: version number */ + + s64 s_size; /* 8: aggregate size in hardware/LVM blocks; + * VFS: number of blocks + */ + s32 s_bsize; /* 4: aggregate block size in bytes; + * VFS: fragment size + */ + s16 s_l2bsize; /* 2: log2 of s_bsize */ + s16 s_l2bfactor; /* 2: log2(s_bsize/hardware block size) */ + s32 s_pbsize; /* 4: hardware/LVM block size in bytes */ + s16 s_l2pbsize; /* 2: log2 of s_pbsize */ + s16 pad; /* 2: padding necessary for alignment */ + + u32 s_agsize; /* 4: allocation group size in aggr. blocks */ + + u32 s_flag; /* 4: aggregate attributes: + * see jfs_filsys.h + */ + u32 s_state; /* 4: mount/unmount/recovery state: + * see jfs_filsys.h + */ + s32 s_compress; /* 4: > 0 if data compression */ + + pxd_t s_ait2; /* 8: first extent of secondary + * aggregate inode table + */ + + pxd_t s_aim2; /* 8: first extent of secondary + * aggregate inode map + */ + u32 s_logdev; /* 4: device address of log */ + s32 s_logserial; /* 4: log serial number at aggregate mount */ + pxd_t s_logpxd; /* 8: inline log extent */ + + pxd_t s_fsckpxd; /* 8: inline fsck work space extent */ + + struct timestruc_t s_time; /* 8: time last updated */ + + s32 s_fsckloglen; /* 4: Number of filesystem blocks reserved for + * the fsck service log. + * N.B. These blocks are divided among the + * versions kept. This is not a per + * version size. + * N.B. These blocks are included in the + * length field of s_fsckpxd. + */ + s8 s_fscklog; /* 1: which fsck service log is most recent + * 0 => no service log data yet + * 1 => the first one + * 2 => the 2nd one + */ + char s_fpack[11]; /* 11: file system volume name + * N.B. This must be 11 bytes to + * conform with the OS/2 BootSector + * requirements + */ + + /* extendfs() parameter under s_state & FM_EXTENDFS */ + s64 s_xsize; /* 8: extendfs s_size */ + pxd_t s_xfsckpxd; /* 8: extendfs fsckpxd */ + pxd_t s_xlogpxd; /* 8: extendfs logpxd */ + /* - 128 byte boundary - */ + + /* + * DFS VFS support (preliminary) + */ + char s_attach; /* 1: VFS: flag: set when aggregate is attached + */ + u8 rsrvd4[7]; /* 7: reserved - set to 0 */ + + u64 totalUsable; /* 8: VFS: total of 1K blocks which are + * available to "normal" (non-root) users. + */ + u64 minFree; /* 8: VFS: # of 1K blocks held in reserve for + * exclusive use of root. This value can be 0, + * and if it is then totalUsable will be equal + * to # of blocks in aggregate. I believe this + * means that minFree + totalUsable = # blocks. + * In that case, we don't need to store both + * totalUsable and minFree since we can compute + * one from the other. I would guess minFree + * would be the one we should store, and + * totalUsable would be the one we should + * compute. (Just a guess...) + */ + + u64 realFree; /* 8: VFS: # of free 1K blocks can be used by + * "normal" users. It may be this is something + * we should compute when asked for instead of + * storing in the superblock. I don't know how + * often this information is needed. + */ + /* + * graffiti area + */ +}; + +extern int readSuper(struct super_block *, struct metapage **); +extern int updateSuper(struct super_block *, uint); + +#endif /*_H_JFS_SUPERBLOCK */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_txnmgr.c linux.19pre5-ac1/fs/jfs/jfs_txnmgr.c --- linux.19p5/fs/jfs/jfs_txnmgr.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_txnmgr.c Wed Mar 20 15:54:16 2002 @@ -0,0 +1,3020 @@ +/* + * + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + */ + +/* + * jfs_txnmgr.c: transaction manager + * + * notes: + * transaction starts with txBegin() and ends with txCommit() + * or txAbort(). + * + * tlock is acquired at the time of update; + * (obviate scan at commit time for xtree and dtree) + * tlock and mp points to each other; + * (no hashlist for mp -> tlock). + * + * special cases: + * tlock on in-memory inode: + * in-place tlock in the in-memory inode itself; + * converted to page lock by iWrite() at commit time. + * + * tlock during write()/mmap() under anonymous transaction (tid = 0): + * transferred (?) to transaction at commit time. + * + * use the page itself to update allocation maps + * (obviate intermediate replication of allocation/deallocation data) + * hold on to mp+lock thru update of maps + */ + + +#include +#include +#include +#include +#include +#include "jfs_incore.h" +#include "jfs_filsys.h" +#include "jfs_metapage.h" +#include "jfs_dinode.h" +#include "jfs_imap.h" +#include "jfs_dmap.h" +#include "jfs_superblock.h" +#include "jfs_debug.h" + +/* + * transaction management structures + */ +static struct { + /* tblock */ + int freetid; /* 4: index of a free tid structure */ + wait_queue_head_t freewait; /* 4: eventlist of free tblock */ + + /* tlock */ + int freelock; /* 4: index first free lock word */ + wait_queue_head_t freelockwait; /* 4: eventlist of free tlock */ + wait_queue_head_t lowlockwait; /* 4: eventlist of ample tlocks */ + int tlocksInUse; /* 4: Number of tlocks in use */ + spinlock_t LazyLock; /* 4: synchronize sync_queue & unlock_queue */ +/* tblock_t *sync_queue; * 4: Transactions waiting for data sync */ + tblock_t *unlock_queue; /* 4: Transactions waiting to be released */ + tblock_t *unlock_tail; /* 4: Tail of unlock_queue */ + struct list_head anon_list; /* inodes having anonymous txns */ + struct list_head anon_list2; /* inodes having anonymous txns + that couldn't be sync'ed */ +} TxAnchor; + +static int nTxBlock = 512; /* number of transaction blocks */ +struct tblock *TxBlock; /* transaction block table */ + +static int nTxLock = 2048; /* number of transaction locks */ +static int TxLockLWM = 2048*.4; /* Low water mark for number of txLocks used */ +static int TxLockHWM = 2048*.8; /* High water mark for number of txLocks used */ +struct tlock *TxLock; /* transaction lock table */ +static int TlocksLow = 0; /* Indicates low number of available tlocks */ + + +/* + * transaction management lock + */ +static spinlock_t jfsTxnLock = SPIN_LOCK_UNLOCKED; + +#define TXN_LOCK() spin_lock(&jfsTxnLock) +#define TXN_UNLOCK() spin_unlock(&jfsTxnLock) + +#define LAZY_LOCK_INIT() spin_lock_init(&TxAnchor.LazyLock); +#define LAZY_LOCK(flags) spin_lock_irqsave(&TxAnchor.LazyLock, flags) +#define LAZY_UNLOCK(flags) spin_unlock_irqrestore(&TxAnchor.LazyLock, flags) + +/* + * Retry logic exist outside these macros to protect from spurrious wakeups. + */ +static inline void TXN_SLEEP_DROP_LOCK(wait_queue_head_t * event) +{ + DECLARE_WAITQUEUE(wait, current); + + add_wait_queue(event, &wait); + set_current_state(TASK_UNINTERRUPTIBLE); + TXN_UNLOCK(); + schedule(); + current->state = TASK_RUNNING; + remove_wait_queue(event, &wait); +} + +#define TXN_SLEEP(event)\ +{\ + TXN_SLEEP_DROP_LOCK(event);\ + TXN_LOCK();\ +} + +#define TXN_WAKEUP(event) wake_up_all(event) + + +/* + * statistics + */ +struct { + tid_t maxtid; /* 4: biggest tid ever used */ + lid_t maxlid; /* 4: biggest lid ever used */ + int ntid; /* 4: # of transactions performed */ + int nlid; /* 4: # of tlocks acquired */ + int waitlock; /* 4: # of tlock wait */ +} stattx; + + +/* + * external references + */ +extern int lmGroupCommit(log_t * log, tblock_t * tblk); +extern void lmSync(log_t *); +extern int readSuper(struct super_block *sb, metapage_t ** bpp); +extern int jfs_commit_inode(struct inode *, int); +extern int jfs_thread_stopped(void); + +extern struct task_struct *jfsCommitTask; +extern struct completion jfsIOwait; +extern struct task_struct *jfsSyncTask; + +/* + * forward references + */ +int diLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck, + commit_t * cd); +int dataLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck); +void dtLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck); +void inlineLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck); +void mapLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck); +void txAbortCommit(commit_t * cd, int exval); +static void txAllocPMap(struct inode *ip, maplock_t * maplock, + tblock_t * tblk); +void txForce(tblock_t * tblk); +static int txLog(log_t * log, tblock_t * tblk, commit_t * cd); +int txMoreLock(void); +static void txUpdateMap(tblock_t * tblk); +static void txRelease(tblock_t * tblk); +void xtLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck); +static void LogSyncRelease(metapage_t * mp); + +/* + * transaction block/lock management + * --------------------------------- + */ + +/* + * Get a transaction lock from the free list. If the number in use is + * greater than the high water mark, wake up the sync daemon. This should + * free some anonymous transaction locks. (TXN_LOCK must be held.) + */ +static lid_t txLockAlloc(void) +{ + lid_t lid; + + while (!(lid = TxAnchor.freelock)) + TXN_SLEEP(&TxAnchor.freelockwait); + TxAnchor.freelock = TxLock[lid].next; + HIGHWATERMARK(stattx.maxlid, lid); + if ((++TxAnchor.tlocksInUse > TxLockHWM) && (TlocksLow == 0)) { + jEVENT(0,("txLockAlloc TlocksLow\n")); + TlocksLow = 1; + wake_up_process(jfsSyncTask); + } + + return lid; +} + +static void txLockFree(lid_t lid) +{ + TxLock[lid].next = TxAnchor.freelock; + TxAnchor.freelock = lid; + TxAnchor.tlocksInUse--; + if (TlocksLow && (TxAnchor.tlocksInUse < TxLockLWM)) { + jEVENT(0,("txLockFree TlocksLow no more\n")); + TlocksLow = 0; + TXN_WAKEUP(&TxAnchor.lowlockwait); + } + TXN_WAKEUP(&TxAnchor.freelockwait); +} + +/* + * NAME: txInit() + * + * FUNCTION: initialize transaction management structures + * + * RETURN: + * + * serialization: single thread at jfs_init() + */ +int txInit(void) +{ + int k, size; + + /* + * initialize transaction block (tblock) table + * + * transaction id (tid) = tblock index + * tid = 0 is reserved. + */ + size = sizeof(tblock_t) * nTxBlock; + TxBlock = (tblock_t *) vmalloc(size); + if (TxBlock == NULL) + return ENOMEM; + + for (k = 1; k < nTxBlock - 1; k++) { + TxBlock[k].next = k + 1; + init_waitqueue_head(&TxBlock[k].gcwait); + init_waitqueue_head(&TxBlock[k].waitor); + } + TxBlock[k].next = 0; + init_waitqueue_head(&TxBlock[k].gcwait); + init_waitqueue_head(&TxBlock[k].waitor); + + TxAnchor.freetid = 1; + init_waitqueue_head(&TxAnchor.freewait); + + stattx.maxtid = 1; /* statistics */ + + /* + * initialize transaction lock (tlock) table + * + * transaction lock id = tlock index + * tlock id = 0 is reserved. + */ + size = sizeof(tlock_t) * nTxLock; + TxLock = (tlock_t *) vmalloc(size); + if (TxLock == NULL) { + vfree(TxBlock); + return ENOMEM; + } + + /* initialize tlock table */ + for (k = 1; k < nTxLock - 1; k++) + TxLock[k].next = k + 1; + TxLock[k].next = 0; + init_waitqueue_head(&TxAnchor.freelockwait); + init_waitqueue_head(&TxAnchor.lowlockwait); + + TxAnchor.freelock = 1; + TxAnchor.tlocksInUse = 0; + INIT_LIST_HEAD(&TxAnchor.anon_list); + INIT_LIST_HEAD(&TxAnchor.anon_list2); + + stattx.maxlid = 1; /* statistics */ + + return 0; +} + +/* + * NAME: txExit() + * + * FUNCTION: clean up when module is unloaded + */ +void txExit(void) +{ + vfree(TxLock); + TxLock = 0; + vfree(TxBlock); + TxBlock = 0; +} + + +/* + * NAME: txBegin() + * + * FUNCTION: start a transaction. + * + * PARAMETER: sb - superblock + * flag - force for nested tx; + * + * RETURN: tid - transaction id + * + * note: flag force allows to start tx for nested tx + * to prevent deadlock on logsync barrier; + */ +tid_t txBegin(struct super_block *sb, int flag) +{ + tid_t t; + tblock_t *tblk; + log_t *log; + + jFYI(1, ("txBegin: flag = 0x%x\n", flag)); + log = (log_t *) JFS_SBI(sb)->log; + + TXN_LOCK(); + + retry: + if (flag != COMMIT_FORCE) { + /* + * synchronize with logsync barrier + */ + if (log->syncbarrier) { + TXN_SLEEP(&log->syncwait); + goto retry; + } + } + if (flag == 0) { + /* + * Don't begin transaction if we're getting starved for tlocks + * unless COMMIT_FORCE (imap changes) or COMMIT_INODE (which + * may ultimately free tlocks) + */ + if (TlocksLow) { + TXN_SLEEP(&TxAnchor.lowlockwait); + goto retry; + } + } + + /* + * allocate transaction id/block + */ + if ((t = TxAnchor.freetid) == 0) { + jFYI(1, ("txBegin: waiting for free tid\n")); + TXN_SLEEP(&TxAnchor.freewait); + goto retry; + } + + tblk = tid_to_tblock(t); + + if ((tblk->next == 0) && (current != jfsCommitTask)) { + /* Save one tblk for jfsCommit thread */ + jFYI(1, ("txBegin: waiting for free tid\n")); + TXN_SLEEP(&TxAnchor.freewait); + goto retry; + } + + TxAnchor.freetid = tblk->next; + + /* + * initialize transaction + */ + + /* + * We can't zero the whole thing or we screw up another thread being + * awakened after sleeping on tblk->waitor + * + * memset(tblk, 0, sizeof(tblock_t)); + */ + tblk->next = tblk->last = tblk->xflag = tblk->flag = tblk->lsn = 0; + + tblk->sb = sb; + ++log->logtid; + tblk->logtid = log->logtid; + + ++log->active; + + HIGHWATERMARK(stattx.maxtid, t); /* statistics */ + INCREMENT(stattx.ntid); /* statistics */ + + TXN_UNLOCK(); + + jFYI(1, ("txBegin: returning tid = %d\n", t)); + + return t; +} + + +/* + * NAME: txBeginAnon() + * + * FUNCTION: start an anonymous transaction. + * Blocks if logsync or available tlocks are low to prevent + * anonymous tlocks from depleting supply. + * + * PARAMETER: sb - superblock + * + * RETURN: none + */ +void txBeginAnon(struct super_block *sb) +{ + log_t *log; + + log = (log_t *) JFS_SBI(sb)->log; + + TXN_LOCK(); + + retry: + /* + * synchronize with logsync barrier + */ + if (log->syncbarrier) { + TXN_SLEEP(&log->syncwait); + goto retry; + } + + /* + * Don't begin transaction if we're getting starved for tlocks + */ + if (TlocksLow) { + TXN_SLEEP(&TxAnchor.lowlockwait); + goto retry; + } + TXN_UNLOCK(); +} + + +/* + * txEnd() + * + * function: free specified transaction block. + * + * logsync barrier processing: + * + * serialization: + */ +void txEnd(tid_t tid) +{ + tblock_t *tblk = tid_to_tblock(tid); + log_t *log; + + jFYI(1, ("txEnd: tid = %d\n", tid)); + TXN_LOCK(); + + /* + * wakeup transactions waiting on the page locked + * by the current transaction + */ + TXN_WAKEUP(&tblk->waitor); + + log = (log_t *) JFS_SBI(tblk->sb)->log; + + /* + * Lazy commit thread can't free this guy until we mark it UNLOCKED, + * otherwise, we would be left with a transaction that may have been + * reused. + * + * Lazy commit thread will turn off tblkGC_LAZY before calling this + * routine. + */ + if (tblk->flag & tblkGC_LAZY) { + jFYI(1, + ("txEnd called w/lazy tid: %d, tblk = 0x%p\n", + tid, tblk)); + TXN_UNLOCK(); + + spin_lock_irq(&log->gclock); // LOGGC_LOCK + tblk->flag |= tblkGC_UNLOCKED; + spin_unlock_irq(&log->gclock); // LOGGC_UNLOCK + return; + } + + jFYI(1, ("txEnd: tid: %d, tblk = 0x%p\n", tid, tblk)); + + assert(tblk->next == 0); + + /* + * insert tblock back on freelist + */ + tblk->next = TxAnchor.freetid; + TxAnchor.freetid = tid; + + /* + * mark the tblock not active + */ + --log->active; + + /* + * synchronize with logsync barrier + */ + if (log->syncbarrier && log->active == 0) { + /* forward log syncpt */ + /* lmSync(log); */ + + jFYI(1, (" log barrier off: 0x%x\n", log->lsn)); + + /* enable new transactions start */ + log->syncbarrier = 0; + + /* wakeup all waitors for logsync barrier */ + TXN_WAKEUP(&log->syncwait); + } + + /* + * wakeup all waitors for a free tblock + */ + TXN_WAKEUP(&TxAnchor.freewait); + + TXN_UNLOCK(); + jFYI(1, ("txEnd: exitting\n")); +} + + +/* + * txLock() + * + * function: acquire a transaction lock on the specified + * + * parameter: + * + * return: transaction lock id + * + * serialization: + */ +tlock_t *txLock(tid_t tid, struct inode *ip, metapage_t * mp, int type) +{ + struct jfs_inode_info *jfs_ip = JFS_IP(ip); + int dir_xtree = 0; + lid_t lid; + tid_t xtid; + tlock_t *tlck; + xtlock_t *xtlck; + linelock_t *linelock; + xtpage_t *p; + tblock_t *tblk; + + TXN_LOCK(); + + if (S_ISDIR(ip->i_mode) && (type & tlckXTREE) && + !(mp->xflag & COMMIT_PAGE)) { + /* + * Directory inode is special. It can have both an xtree tlock + * and a dtree tlock associated with it. + */ + dir_xtree = 1; + lid = jfs_ip->xtlid; + } else + lid = mp->lid; + + /* is page not locked by a transaction ? */ + if (lid == 0) + goto allocateLock; + + jFYI(1, ("txLock: tid:%d ip:0x%p mp:0x%p lid:%d\n", + tid, ip, mp, lid)); + + /* is page locked by the requester transaction ? */ + tlck = lid_to_tlock(lid); + if ((xtid = tlck->tid) == tid) + goto grantLock; + + /* + * is page locked by anonymous transaction/lock ? + * + * (page update without transaction (i.e., file write) is + * locked under anonymous transaction tid = 0: + * anonymous tlocks maintained on anonymous tlock list of + * the inode of the page and available to all anonymous + * transactions until txCommit() time at which point + * they are transferred to the transaction tlock list of + * the commiting transaction of the inode) + */ + if (xtid == 0) { + tlck->tid = tid; + tblk = tid_to_tblock(tid); + /* + * The order of the tlocks in the transaction is important + * (during truncate, child xtree pages must be freed before + * parent's tlocks change the working map). + * Take tlock off anonymous list and add to tail of + * transaction list + * + * Note: We really need to get rid of the tid & lid and + * use list_head's. This code is getting UGLY! + */ + if (jfs_ip->atlhead == lid) { + if (jfs_ip->atltail == lid) { + /* only anonymous txn. + * Remove from anon_list + */ + list_del_init(&jfs_ip->anon_inode_list); + } + jfs_ip->atlhead = tlck->next; + } else { + lid_t last; + for (last = jfs_ip->atlhead; + lid_to_tlock(last)->next != lid; + last = lid_to_tlock(last)->next) { + assert(last); + } + lid_to_tlock(last)->next = tlck->next; + if (jfs_ip->atltail == lid) + jfs_ip->atltail = last; + } + + /* insert the tlock at tail of transaction tlock list */ + + if (tblk->next) + lid_to_tlock(tblk->last)->next = lid; + else + tblk->next = lid; + tlck->next = 0; + tblk->last = lid; + + goto grantLock; + } + + goto waitLock; + + /* + * allocate a tlock + */ + allocateLock: + lid = txLockAlloc(); + tlck = lid_to_tlock(lid); + + /* + * initialize tlock + */ + tlck->tid = tid; + + /* mark tlock for meta-data page */ + if (mp->xflag & COMMIT_PAGE) { + + tlck->flag = tlckPAGELOCK; + + /* mark the page dirty and nohomeok */ + mark_metapage_dirty(mp); + atomic_inc(&mp->nohomeok); + + jFYI(1, + ("locking mp = 0x%p, nohomeok = %d tid = %d tlck = 0x%p\n", + mp, atomic_read(&mp->nohomeok), tid, tlck)); + + /* if anonymous transaction, and buffer is on the group + * commit synclist, mark inode to show this. This will + * prevent the buffer from being marked nohomeok for too + * long a time. + */ + if ((tid == 0) && mp->lsn) + set_cflag(COMMIT_Synclist, ip); + } + /* mark tlock for in-memory inode */ + else + tlck->flag = tlckINODELOCK; + + tlck->type = 0; + + /* bind the tlock and the page */ + tlck->ip = ip; + tlck->mp = mp; + if (dir_xtree) + jfs_ip->xtlid = lid; + else + mp->lid = lid; + + /* + * enqueue transaction lock to transaction/inode + */ + /* insert the tlock at tail of transaction tlock list */ + if (tid) { + tblk = tid_to_tblock(tid); + if (tblk->next) + lid_to_tlock(tblk->last)->next = lid; + else + tblk->next = lid; + tlck->next = 0; + tblk->last = lid; + } + /* anonymous transaction: + * insert the tlock at head of inode anonymous tlock list + */ + else { + tlck->next = jfs_ip->atlhead; + jfs_ip->atlhead = lid; + if (tlck->next == 0) { + /* This inode's first anonymous transaction */ + jfs_ip->atltail = lid; + list_add_tail(&jfs_ip->anon_inode_list, + &TxAnchor.anon_list); + } + } + + /* initialize type dependent area for linelock */ + linelock = (linelock_t *) & tlck->lock; + linelock->next = 0; + linelock->flag = tlckLINELOCK; + linelock->maxcnt = TLOCKSHORT; + linelock->index = 0; + + switch (type & tlckTYPE) { + case tlckDTREE: + linelock->l2linesize = L2DTSLOTSIZE; + break; + + case tlckXTREE: + linelock->l2linesize = L2XTSLOTSIZE; + + xtlck = (xtlock_t *) linelock; + xtlck->header.offset = 0; + xtlck->header.length = 2; + + if (type & tlckNEW) { + xtlck->lwm.offset = XTENTRYSTART; + } else { + if (mp->xflag & COMMIT_PAGE) + p = (xtpage_t *) mp->data; + else + p = &jfs_ip->i_xtroot; + xtlck->lwm.offset = + le16_to_cpu(p->header.nextindex); + } + xtlck->lwm.length = 0; /* ! */ + + xtlck->index = 2; + break; + + case tlckINODE: + linelock->l2linesize = L2INODESLOTSIZE; + break; + + case tlckDATA: + linelock->l2linesize = L2DATASLOTSIZE; + break; + + default: + jERROR(1, ("UFO tlock:0x%p\n", tlck)); + } + + /* + * update tlock vector + */ + grantLock: + tlck->type |= type; + + TXN_UNLOCK(); + + return tlck; + + /* + * page is being locked by another transaction: + */ + waitLock: + /* Only locks on ipimap or ipaimap should reach here */ + /* assert(jfs_ip->fileset == AGGREGATE_I); */ + if (jfs_ip->fileset != AGGREGATE_I) { + jERROR(1, ("txLock: trying to lock locked page!\n")); + dump_mem("ip", ip, sizeof(struct inode)); + dump_mem("mp", mp, sizeof(metapage_t)); + dump_mem("Locker's tblk", tid_to_tblock(tid), + sizeof(tblock_t)); + dump_mem("Tlock", tlck, sizeof(tlock_t)); + BUG(); + } + INCREMENT(stattx.waitlock); /* statistics */ + release_metapage(mp); + + jEVENT(0, ("txLock: in waitLock, tid = %d, xtid = %d, lid = %d\n", + tid, xtid, lid)); + TXN_SLEEP_DROP_LOCK(&tid_to_tblock(xtid)->waitor); + jEVENT(0, ("txLock: awakened tid = %d, lid = %d\n", tid, lid)); + + return NULL; +} + + +/* + * NAME: txRelease() + * + * FUNCTION: Release buffers associated with transaction locks, but don't + * mark homeok yet. The allows other transactions to modify + * buffers, but won't let them go to disk until commit record + * actually gets written. + * + * PARAMETER: + * tblk - + * + * RETURN: Errors from subroutines. + */ +static void txRelease(tblock_t * tblk) +{ + metapage_t *mp; + lid_t lid; + tlock_t *tlck; + + TXN_LOCK(); + + for (lid = tblk->next; lid; lid = tlck->next) { + tlck = lid_to_tlock(lid); + if ((mp = tlck->mp) != NULL && + (tlck->type & tlckBTROOT) == 0) { + assert(mp->xflag & COMMIT_PAGE); + mp->lid = 0; + } + } + + /* + * wakeup transactions waiting on a page locked + * by the current transaction + */ + TXN_WAKEUP(&tblk->waitor); + + TXN_UNLOCK(); +} + + +/* + * NAME: txUnlock() + * + * FUNCTION: Initiates pageout of pages modified by tid in journalled + * objects and frees their lockwords. + * + * PARAMETER: + * flag - + * + * RETURN: Errors from subroutines. + */ +static void txUnlock(tblock_t * tblk, int flag) +{ + tlock_t *tlck; + linelock_t *linelock; + lid_t lid, next, llid, k; + metapage_t *mp; + log_t *log; + int force; + int difft, diffp; + + jFYI(1, ("txUnlock: tblk = 0x%p\n", tblk)); + log = (log_t *) JFS_SBI(tblk->sb)->log; + force = flag & COMMIT_FLUSH; + if (log->syncbarrier) + force |= COMMIT_FORCE; + + /* + * mark page under tlock homeok (its log has been written): + * if caller has specified FORCE (e.g., iRecycle()), or + * if syncwait for the log is set (i.e., the log sync point + * has fallen behind), or + * if syncpt is set for the page, or + * if the page is new, initiate pageout; + * otherwise, leave the page in memory. + */ + for (lid = tblk->next; lid; lid = next) { + tlck = lid_to_tlock(lid); + next = tlck->next; + + jFYI(1, ("unlocking lid = %d, tlck = 0x%p\n", lid, tlck)); + + /* unbind page from tlock */ + if ((mp = tlck->mp) != NULL && + (tlck->type & tlckBTROOT) == 0) { + assert(mp->xflag & COMMIT_PAGE); + + /* hold buffer + * + * It's possible that someone else has the metapage. + * The only things were changing are nohomeok, which + * is handled atomically, and clsn which is protected + * by the LOGSYNC_LOCK. + */ + hold_metapage(mp, 1); + + assert(atomic_read(&mp->nohomeok) > 0); + atomic_dec(&mp->nohomeok); + + /* inherit younger/larger clsn */ + LOGSYNC_LOCK(log); + if (mp->clsn) { + logdiff(difft, tblk->clsn, log); + logdiff(diffp, mp->clsn, log); + if (difft > diffp) + mp->clsn = tblk->clsn; + } else + mp->clsn = tblk->clsn; + LOGSYNC_UNLOCK(log); + + assert(!(tlck->flag & tlckFREEPAGE)); + + if (tlck->flag & tlckWRITEPAGE) { + write_metapage(mp); + } else { + /* release page which has been forced */ + release_metapage(mp); + } + } + + /* insert tlock, and linelock(s) of the tlock if any, + * at head of freelist + */ + TXN_LOCK(); + + llid = ((linelock_t *) & tlck->lock)->next; + while (llid) { + linelock = (linelock_t *) lid_to_tlock(llid); + k = linelock->next; + txLockFree(llid); + llid = k; + } + txLockFree(lid); + + TXN_UNLOCK(); + } + tblk->next = tblk->last = 0; + + /* + * remove tblock from logsynclist + * (allocation map pages inherited lsn of tblk and + * has been inserted in logsync list at txUpdateMap()) + */ + if (tblk->lsn) { + LOGSYNC_LOCK(log); + log->count--; + list_del(&tblk->synclist); + LOGSYNC_UNLOCK(log); + } +} + + +/* + * txMaplock() + * + * function: allocate a transaction lock for freed page/entry; + * for freed page, maplock is used as xtlock/dtlock type; + */ +tlock_t *txMaplock(tid_t tid, struct inode *ip, int type) +{ + struct jfs_inode_info *jfs_ip = JFS_IP(ip); + lid_t lid; + tblock_t *tblk; + tlock_t *tlck; + maplock_t *maplock; + + TXN_LOCK(); + + /* + * allocate a tlock + */ + lid = txLockAlloc(); + tlck = lid_to_tlock(lid); + + /* + * initialize tlock + */ + tlck->tid = tid; + + /* bind the tlock and the object */ + tlck->flag = tlckINODELOCK; + tlck->ip = ip; + tlck->mp = NULL; + + tlck->type = type; + + /* + * enqueue transaction lock to transaction/inode + */ + /* insert the tlock at tail of transaction tlock list */ + if (tid) { + tblk = tid_to_tblock(tid); + if (tblk->next) + lid_to_tlock(tblk->last)->next = lid; + else + tblk->next = lid; + tlck->next = 0; + tblk->last = lid; + } + /* anonymous transaction: + * insert the tlock at head of inode anonymous tlock list + */ + else { + tlck->next = jfs_ip->atlhead; + jfs_ip->atlhead = lid; + if (tlck->next == 0) { + /* This inode's first anonymous transaction */ + jfs_ip->atltail = lid; + list_add_tail(&jfs_ip->anon_inode_list, + &TxAnchor.anon_list); + } + } + + TXN_UNLOCK(); + + /* initialize type dependent area for maplock */ + maplock = (maplock_t *) & tlck->lock; + maplock->next = 0; + maplock->maxcnt = 0; + maplock->index = 0; + + return tlck; +} + + +/* + * txLinelock() + * + * function: allocate a transaction lock for log vector list + */ +linelock_t *txLinelock(linelock_t * tlock) +{ + lid_t lid; + tlock_t *tlck; + linelock_t *linelock; + + TXN_LOCK(); + + /* allocate a TxLock structure */ + lid = txLockAlloc(); + tlck = lid_to_tlock(lid); + + TXN_UNLOCK(); + + /* initialize linelock */ + linelock = (linelock_t *) tlck; + linelock->next = 0; + linelock->flag = tlckLINELOCK; + linelock->maxcnt = TLOCKLONG; + linelock->index = 0; + + /* append linelock after tlock */ + linelock->next = tlock->next; + tlock->next = lid; + + return linelock; +} + + + +/* + * transaction commit management + * ----------------------------- + */ + +/* + * NAME: txCommit() + * + * FUNCTION: commit the changes to the objects specified in + * clist. For journalled segments only the + * changes of the caller are committed, ie by tid. + * for non-journalled segments the data are flushed to + * disk and then the change to the disk inode and indirect + * blocks committed (so blocks newly allocated to the + * segment will be made a part of the segment atomically). + * + * all of the segments specified in clist must be in + * one file system. no more than 6 segments are needed + * to handle all unix svcs. + * + * if the i_nlink field (i.e. disk inode link count) + * is zero, and the type of inode is a regular file or + * directory, or symbolic link , the inode is truncated + * to zero length. the truncation is committed but the + * VM resources are unaffected until it is closed (see + * iput and iclose). + * + * PARAMETER: + * + * RETURN: + * + * serialization: + * on entry the inode lock on each segment is assumed + * to be held. + * + * i/o error: + */ +int txCommit(tid_t tid, /* transaction identifier */ + int nip, /* number of inodes to commit */ + struct inode **iplist, /* list of inode to commit */ + int flag) +{ + int rc = 0, rc1 = 0; + commit_t cd; + log_t *log; + tblock_t *tblk; + lrd_t *lrd; + int lsn; + struct inode *ip; + struct jfs_inode_info *jfs_ip; + int k, n; + ino_t top; + struct super_block *sb; + + jFYI(1, ("txCommit, tid = %d, flag = %d\n", tid, flag)); + /* is read-only file system ? */ + if (isReadOnly(iplist[0])) { + rc = EROFS; + goto TheEnd; + } + + sb = cd.sb = iplist[0]->i_sb; + cd.tid = tid; + + if (tid == 0) + tid = txBegin(sb, 0); + tblk = tid_to_tblock(tid); + + /* + * initialize commit structure + */ + log = (log_t *) JFS_SBI(sb)->log; + cd.log = log; + + /* initialize log record descriptor in commit */ + lrd = &cd.lrd; + lrd->logtid = cpu_to_le32(tblk->logtid); + lrd->backchain = 0; + + tblk->xflag |= flag; + + if ((flag & (COMMIT_FORCE | COMMIT_SYNC)) == 0) + tblk->xflag |= COMMIT_LAZY; + /* + * prepare non-journaled objects for commit + * + * flush data pages of non-journaled file + * to prevent the file getting non-initialized disk blocks + * in case of crash. + * (new blocks - ) + */ + cd.iplist = iplist; + cd.nip = nip; + + /* + * acquire transaction lock on (on-disk) inodes + * + * update on-disk inode from in-memory inode + * acquiring transaction locks for AFTER records + * on the on-disk inode of file object + * + * sort the inodes array by inode number in descending order + * to prevent deadlock when acquiring transaction lock + * of on-disk inodes on multiple on-disk inode pages by + * multiple concurrent transactions + */ + for (k = 0; k < cd.nip; k++) { + top = (cd.iplist[k])->i_ino; + for (n = k + 1; n < cd.nip; n++) { + ip = cd.iplist[n]; + if (ip->i_ino > top) { + top = ip->i_ino; + cd.iplist[n] = cd.iplist[k]; + cd.iplist[k] = ip; + } + } + + ip = cd.iplist[k]; + jfs_ip = JFS_IP(ip); + + /* + * BUGBUG - Should we call filemap_fdatasync here instead + * of fsync_inode_data? + * If we do, we have a deadlock condition since we may end + * up recursively calling jfs_get_block with the IWRITELOCK + * held. We may be able to do away with IWRITELOCK while + * committing transactions and use i_sem instead. + */ + if ((!S_ISDIR(ip->i_mode)) + && (tblk->flag & COMMIT_DELETE) == 0) + fsync_inode_data_buffers(ip); + + /* + * Mark inode as not dirty. It will still be on the dirty + * inode list, but we'll know not to commit it again unless + * it gets marked dirty again + */ + clear_cflag(COMMIT_Dirty, ip); + + /* inherit anonymous tlock(s) of inode */ + if (jfs_ip->atlhead) { + lid_to_tlock(jfs_ip->atltail)->next = tblk->next; + tblk->next = jfs_ip->atlhead; + if (!tblk->last) + tblk->last = jfs_ip->atltail; + jfs_ip->atlhead = jfs_ip->atltail = 0; + TXN_LOCK(); + list_del_init(&jfs_ip->anon_inode_list); + TXN_UNLOCK(); + } + + /* + * acquire transaction lock on on-disk inode page + * (become first tlock of the tblk's tlock list) + */ + if (((rc = diWrite(tid, ip)))) + goto out; + } + + /* + * write log records from transaction locks + * + * txUpdateMap() resets XAD_NEW in XAD. + */ + if ((rc = txLog(log, tblk, &cd))) + goto TheEnd; + + /* + * Ensure that inode isn't reused before + * lazy commit thread finishes processing + */ + if (tblk->xflag & (COMMIT_CREATE | COMMIT_DELETE)) + atomic_inc(&tblk->ip->i_count); + if (tblk->xflag & COMMIT_DELETE) { + ip = tblk->ip; + assert((ip->i_nlink == 0) && !test_cflag(COMMIT_Nolink, ip)); + set_cflag(COMMIT_Nolink, ip); + } + + /* + * write COMMIT log record + */ + lrd->type = cpu_to_le16(LOG_COMMIT); + lrd->length = 0; + lsn = lmLog(log, tblk, lrd, NULL); + + lmGroupCommit(log, tblk); + + /* + * - transaction is now committed - + */ + + /* + * force pages in careful update + * (imap addressing structure update) + */ + if (flag & COMMIT_FORCE) + txForce(tblk); + + /* + * update allocation map. + * + * update inode allocation map and inode: + * free pager lock on memory object of inode if any. + * update block allocation map. + * + * txUpdateMap() resets XAD_NEW in XAD. + */ + if (tblk->xflag & COMMIT_FORCE) + txUpdateMap(tblk); + + /* + * free transaction locks and pageout/free pages + */ + txRelease(tblk); + + if ((tblk->flag & tblkGC_LAZY) == 0) + txUnlock(tblk, flag); + + + /* + * reset in-memory object state + */ + for (k = 0; k < cd.nip; k++) { + ip = cd.iplist[k]; + jfs_ip = JFS_IP(ip); + + /* + * reset in-memory inode state + */ + jfs_ip->bxflag = 0; + jfs_ip->blid = 0; + } + + out: + if (rc != 0) + txAbortCommit(&cd, rc); + else + rc = rc1; + + TheEnd: + jFYI(1, ("txCommit: tid = %d, returning %d\n", tid, rc)); + return rc; +} + + +/* + * NAME: txLog() + * + * FUNCTION: Writes AFTER log records for all lines modified + * by tid for segments specified by inodes in comdata. + * Code assumes only WRITELOCKS are recorded in lockwords. + * + * PARAMETERS: + * + * RETURN : + */ +static int txLog(log_t * log, tblock_t * tblk, commit_t * cd) +{ + int rc = 0; + struct inode *ip; + lid_t lid; + tlock_t *tlck; + lrd_t *lrd = &cd->lrd; + + /* + * write log record(s) for each tlock of transaction, + */ + for (lid = tblk->next; lid; lid = tlck->next) { + tlck = lid_to_tlock(lid); + + tlck->flag |= tlckLOG; + + /* initialize lrd common */ + ip = tlck->ip; + lrd->aggregate = cpu_to_le32(kdev_t_to_nr(ip->i_dev)); + lrd->log.redopage.fileset = cpu_to_le32(JFS_IP(ip)->fileset); + lrd->log.redopage.inode = cpu_to_le32(ip->i_ino); + + if (tlck->mp) + hold_metapage(tlck->mp, 0); + + /* write log record of page from the tlock */ + switch (tlck->type & tlckTYPE) { + case tlckXTREE: + xtLog(log, tblk, lrd, tlck); + break; + + case tlckDTREE: + dtLog(log, tblk, lrd, tlck); + break; + + case tlckINODE: + diLog(log, tblk, lrd, tlck, cd); + break; + + case tlckMAP: + mapLog(log, tblk, lrd, tlck); + break; + + case tlckDATA: + dataLog(log, tblk, lrd, tlck); + break; + + default: + jERROR(1, ("UFO tlock:0x%p\n", tlck)); + } + if (tlck->mp) + release_metapage(tlck->mp); + } + + return rc; +} + + +/* + * diLog() + * + * function: log inode tlock and format maplock to update bmap; + */ +int diLog(log_t * log, + tblock_t * tblk, lrd_t * lrd, tlock_t * tlck, commit_t * cd) +{ + int rc = 0; + metapage_t *mp; + pxd_t *pxd; + pxdlock_t *pxdlock; + + mp = tlck->mp; + + /* initialize as REDOPAGE record format */ + lrd->log.redopage.type = cpu_to_le16(LOG_INODE); + lrd->log.redopage.l2linesize = cpu_to_le16(L2INODESLOTSIZE); + + pxd = &lrd->log.redopage.pxd; + + /* + * inode after image + */ + if (tlck->type & tlckENTRY) { + /* log after-image for logredo(): */ + lrd->type = cpu_to_le16(LOG_REDOPAGE); +// *pxd = mp->cm_pxd; + PXDaddress(pxd, mp->index); + PXDlength(pxd, + mp->logical_size >> tblk->sb->s_blocksize_bits); + lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck)); + + /* mark page as homeward bound */ + tlck->flag |= tlckWRITEPAGE; + } else if (tlck->type & tlckFREE) { + /* + * free inode extent + * + * (pages of the freed inode extent have been invalidated and + * a maplock for free of the extent has been formatted at + * txLock() time); + * + * the tlock had been acquired on the inode allocation map page + * (iag) that specifies the freed extent, even though the map + * page is not itself logged, to prevent pageout of the map + * page before the log; + */ + assert(tlck->type & tlckFREE); + + /* log LOG_NOREDOINOEXT of the freed inode extent for + * logredo() to start NoRedoPage filters, and to update + * imap and bmap for free of the extent; + */ + lrd->type = cpu_to_le16(LOG_NOREDOINOEXT); + /* + * For the LOG_NOREDOINOEXT record, we need + * to pass the IAG number and inode extent + * index (within that IAG) from which the + * the extent being released. These have been + * passed to us in the iplist[1] and iplist[2]. + */ + lrd->log.noredoinoext.iagnum = + cpu_to_le32((u32) (size_t) cd->iplist[1]); + lrd->log.noredoinoext.inoext_idx = + cpu_to_le32((u32) (size_t) cd->iplist[2]); + + pxdlock = (pxdlock_t *) & tlck->lock; + *pxd = pxdlock->pxd; + lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, NULL)); + + /* update bmap */ + tlck->flag |= tlckUPDATEMAP; + + /* mark page as homeward bound */ + tlck->flag |= tlckWRITEPAGE; + } else { + jERROR(2, ("diLog: UFO type tlck:0x%p\n", tlck)); + } +#ifdef _JFS_WIP + /* + * alloc/free external EA extent + * + * a maplock for txUpdateMap() to update bPWMAP for alloc/free + * of the extent has been formatted at txLock() time; + */ + else { + assert(tlck->type & tlckEA); + + /* log LOG_UPDATEMAP for logredo() to update bmap for + * alloc of new (and free of old) external EA extent; + */ + lrd->type = cpu_to_le16(LOG_UPDATEMAP); + pxdlock = (pxdlock_t *) & tlck->lock; + nlock = pxdlock->index; + for (i = 0; i < nlock; i++, pxdlock++) { + if (pxdlock->flag & mlckALLOCPXD) + lrd->log.updatemap.type = + cpu_to_le16(LOG_ALLOCPXD); + else + lrd->log.updatemap.type = + cpu_to_le16(LOG_FREEPXD); + lrd->log.updatemap.nxd = cpu_to_le16(1); + lrd->log.updatemap.pxd = pxdlock->pxd; + lrd->backchain = + cpu_to_le32(lmLog(log, tblk, lrd, NULL)); + } + + /* update bmap */ + tlck->flag |= tlckUPDATEMAP; + } +#endif /* _JFS_WIP */ + + return rc; +} + + +/* + * dataLog() + * + * function: log data tlock + */ +int dataLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck) +{ + metapage_t *mp; + pxd_t *pxd; + int rc; + s64 xaddr; + int xflag; + s32 xlen; + + mp = tlck->mp; + + /* initialize as REDOPAGE record format */ + lrd->log.redopage.type = cpu_to_le16(LOG_DATA); + lrd->log.redopage.l2linesize = cpu_to_le16(L2DATASLOTSIZE); + + pxd = &lrd->log.redopage.pxd; + + /* log after-image for logredo(): */ + lrd->type = cpu_to_le16(LOG_REDOPAGE); + + if (JFS_IP(tlck->ip)->next_index < MAX_INLINE_DIRTABLE_ENTRY) { + /* + * The table has been truncated, we've must have deleted + * the last entry, so don't bother logging this + */ + mp->lid = 0; + atomic_dec(&mp->nohomeok); + discard_metapage(mp); + tlck->mp = 0; + return 0; + } + + rc = xtLookup(tlck->ip, mp->index, 1, &xflag, &xaddr, &xlen, 1); + if (rc || (xlen == 0)) { + jERROR(1, ("dataLog: can't find physical address\n")); + return 0; + } + + PXDaddress(pxd, xaddr); + PXDlength(pxd, mp->logical_size >> tblk->sb->s_blocksize_bits); + + lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck)); + + /* mark page as homeward bound */ + tlck->flag |= tlckWRITEPAGE; + + return 0; +} + + +/* + * dtLog() + * + * function: log dtree tlock and format maplock to update bmap; + */ +void dtLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck) +{ + struct inode *ip; + metapage_t *mp; + pxdlock_t *pxdlock; + pxd_t *pxd; + + ip = tlck->ip; + mp = tlck->mp; + + /* initialize as REDOPAGE/NOREDOPAGE record format */ + lrd->log.redopage.type = cpu_to_le16(LOG_DTREE); + lrd->log.redopage.l2linesize = cpu_to_le16(L2DTSLOTSIZE); + + pxd = &lrd->log.redopage.pxd; + + if (tlck->type & tlckBTROOT) + lrd->log.redopage.type |= cpu_to_le16(LOG_BTROOT); + + /* + * page extension via relocation: entry insertion; + * page extension in-place: entry insertion; + * new right page from page split, reinitialized in-line + * root from root page split: entry insertion; + */ + if (tlck->type & (tlckNEW | tlckEXTEND)) { + /* log after-image of the new page for logredo(): + * mark log (LOG_NEW) for logredo() to initialize + * freelist and update bmap for alloc of the new page; + */ + lrd->type = cpu_to_le16(LOG_REDOPAGE); + if (tlck->type & tlckEXTEND) + lrd->log.redopage.type |= cpu_to_le16(LOG_EXTEND); + else + lrd->log.redopage.type |= cpu_to_le16(LOG_NEW); +// *pxd = mp->cm_pxd; + PXDaddress(pxd, mp->index); + PXDlength(pxd, + mp->logical_size >> tblk->sb->s_blocksize_bits); + lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck)); + + /* format a maplock for txUpdateMap() to update bPMAP for + * alloc of the new page; + */ + if (tlck->type & tlckBTROOT) + return; + tlck->flag |= tlckUPDATEMAP; + pxdlock = (pxdlock_t *) & tlck->lock; + pxdlock->flag = mlckALLOCPXD; + pxdlock->pxd = *pxd; + + pxdlock->index = 1; + + /* mark page as homeward bound */ + tlck->flag |= tlckWRITEPAGE; + return; + } + + /* + * entry insertion/deletion, + * sibling page link update (old right page before split); + */ + if (tlck->type & (tlckENTRY | tlckRELINK)) { + /* log after-image for logredo(): */ + lrd->type = cpu_to_le16(LOG_REDOPAGE); + PXDaddress(pxd, mp->index); + PXDlength(pxd, + mp->logical_size >> tblk->sb->s_blocksize_bits); + lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck)); + + /* mark page as homeward bound */ + tlck->flag |= tlckWRITEPAGE; + return; + } + + /* + * page deletion: page has been invalidated + * page relocation: source extent + * + * a maplock for free of the page has been formatted + * at txLock() time); + */ + if (tlck->type & (tlckFREE | tlckRELOCATE)) { + /* log LOG_NOREDOPAGE of the deleted page for logredo() + * to start NoRedoPage filter and to update bmap for free + * of the deletd page + */ + lrd->type = cpu_to_le16(LOG_NOREDOPAGE); + pxdlock = (pxdlock_t *) & tlck->lock; + *pxd = pxdlock->pxd; + lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, NULL)); + + /* a maplock for txUpdateMap() for free of the page + * has been formatted at txLock() time; + */ + tlck->flag |= tlckUPDATEMAP; + } + return; +} + + +/* + * xtLog() + * + * function: log xtree tlock and format maplock to update bmap; + */ +void xtLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck) +{ + struct inode *ip; + metapage_t *mp; + xtpage_t *p; + xtlock_t *xtlck; + maplock_t *maplock; + xdlistlock_t *xadlock; + pxdlock_t *pxdlock; + pxd_t *pxd; + int next, lwm, hwm; + + ip = tlck->ip; + mp = tlck->mp; + + /* initialize as REDOPAGE/NOREDOPAGE record format */ + lrd->log.redopage.type = cpu_to_le16(LOG_XTREE); + lrd->log.redopage.l2linesize = cpu_to_le16(L2XTSLOTSIZE); + + pxd = &lrd->log.redopage.pxd; + + if (tlck->type & tlckBTROOT) { + lrd->log.redopage.type |= cpu_to_le16(LOG_BTROOT); + p = &JFS_IP(ip)->i_xtroot; + if (S_ISDIR(ip->i_mode)) + lrd->log.redopage.type |= + cpu_to_le16(LOG_DIR_XTREE); + } else + p = (xtpage_t *) mp->data; + next = le16_to_cpu(p->header.nextindex); + + xtlck = (xtlock_t *) & tlck->lock; + + maplock = (maplock_t *) & tlck->lock; + xadlock = (xdlistlock_t *) maplock; + + /* + * entry insertion/extension; + * sibling page link update (old right page before split); + */ + if (tlck->type & (tlckNEW | tlckGROW | tlckRELINK)) { + /* log after-image for logredo(): + * logredo() will update bmap for alloc of new/extended + * extents (XAD_NEW|XAD_EXTEND) of XAD[lwm:next) from + * after-image of XADlist; + * logredo() resets (XAD_NEW|XAD_EXTEND) flag when + * applying the after-image to the meta-data page. + */ + lrd->type = cpu_to_le16(LOG_REDOPAGE); +// *pxd = mp->cm_pxd; + PXDaddress(pxd, mp->index); + PXDlength(pxd, + mp->logical_size >> tblk->sb->s_blocksize_bits); + lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck)); + + /* format a maplock for txUpdateMap() to update bPMAP + * for alloc of new/extended extents of XAD[lwm:next) + * from the page itself; + * txUpdateMap() resets (XAD_NEW|XAD_EXTEND) flag. + */ + lwm = xtlck->lwm.offset; + if (lwm == 0) + lwm = XTPAGEMAXSLOT; + + if (lwm == next) + goto out; + assert(lwm < next); + tlck->flag |= tlckUPDATEMAP; + xadlock->flag = mlckALLOCXADLIST; + xadlock->count = next - lwm; + if ((xadlock->count <= 2) && (tblk->xflag & COMMIT_LAZY)) { + int i; + /* + * Lazy commit may allow xtree to be modified before + * txUpdateMap runs. Copy xad into linelock to + * preserve correct data. + */ + xadlock->xdlist = &xtlck->pxdlock; + memcpy(xadlock->xdlist, &p->xad[lwm], + sizeof(xad_t) * xadlock->count); + + for (i = 0; i < xadlock->count; i++) + p->xad[lwm + i].flag &= + ~(XAD_NEW | XAD_EXTENDED); + } else { + /* + * xdlist will point to into inode's xtree, ensure + * that transaction is not committed lazily. + */ + xadlock->xdlist = &p->xad[lwm]; + tblk->xflag &= ~COMMIT_LAZY; + } + jFYI(1, + ("xtLog: alloc ip:0x%p mp:0x%p tlck:0x%p lwm:%d count:%d\n", + tlck->ip, mp, tlck, lwm, xadlock->count)); + + maplock->index = 1; + + out: + /* mark page as homeward bound */ + tlck->flag |= tlckWRITEPAGE; + + return; + } + + /* + * page deletion: file deletion/truncation (ref. xtTruncate()) + * + * (page will be invalidated after log is written and bmap + * is updated from the page); + */ + if (tlck->type & tlckFREE) { + /* LOG_NOREDOPAGE log for NoRedoPage filter: + * if page free from file delete, NoRedoFile filter from + * inode image of zero link count will subsume NoRedoPage + * filters for each page; + * if page free from file truncattion, write NoRedoPage + * filter; + * + * upadte of block allocation map for the page itself: + * if page free from deletion and truncation, LOG_UPDATEMAP + * log for the page itself is generated from processing + * its parent page xad entries; + */ + /* if page free from file truncation, log LOG_NOREDOPAGE + * of the deleted page for logredo() to start NoRedoPage + * filter for the page; + */ + if (tblk->xflag & COMMIT_TRUNCATE) { + /* write NOREDOPAGE for the page */ + lrd->type = cpu_to_le16(LOG_NOREDOPAGE); + PXDaddress(pxd, mp->index); + PXDlength(pxd, + mp->logical_size >> tblk->sb-> + s_blocksize_bits); + lrd->backchain = + cpu_to_le32(lmLog(log, tblk, lrd, NULL)); + + if (tlck->type & tlckBTROOT) { + /* Empty xtree must be logged */ + lrd->type = cpu_to_le16(LOG_REDOPAGE); + lrd->backchain = + cpu_to_le32(lmLog(log, tblk, lrd, tlck)); + } + } + + /* init LOG_UPDATEMAP of the freed extents + * XAD[XTENTRYSTART:hwm) from the deleted page itself + * for logredo() to update bmap; + */ + lrd->type = cpu_to_le16(LOG_UPDATEMAP); + lrd->log.updatemap.type = cpu_to_le16(LOG_FREEXADLIST); + xtlck = (xtlock_t *) & tlck->lock; + hwm = xtlck->hwm.offset; + lrd->log.updatemap.nxd = + cpu_to_le16(hwm - XTENTRYSTART + 1); + /* reformat linelock for lmLog() */ + xtlck->header.offset = XTENTRYSTART; + xtlck->header.length = hwm - XTENTRYSTART + 1; + xtlck->index = 1; + lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck)); + + /* format a maplock for txUpdateMap() to update bmap + * to free extents of XAD[XTENTRYSTART:hwm) from the + * deleted page itself; + */ + tlck->flag |= tlckUPDATEMAP; + xadlock->flag = mlckFREEXADLIST; + xadlock->count = hwm - XTENTRYSTART + 1; + if ((xadlock->count <= 2) && (tblk->xflag & COMMIT_LAZY)) { + /* + * Lazy commit may allow xtree to be modified before + * txUpdateMap runs. Copy xad into linelock to + * preserve correct data. + */ + xadlock->xdlist = &xtlck->pxdlock; + memcpy(xadlock->xdlist, &p->xad[XTENTRYSTART], + sizeof(xad_t) * xadlock->count); + } else { + /* + * xdlist will point to into inode's xtree, ensure + * that transaction is not committed lazily unless + * we're deleting the inode (unlink). In that case + * we have special logic for the inode to be + * unlocked by the lazy commit thread. + */ + xadlock->xdlist = &p->xad[XTENTRYSTART]; + if ((tblk->xflag & COMMIT_LAZY) && + (tblk->xflag & COMMIT_DELETE) && + (tblk->ip == ip)) + set_cflag(COMMIT_Holdlock, ip); + else + tblk->xflag &= ~COMMIT_LAZY; + } + jFYI(1, + ("xtLog: free ip:0x%p mp:0x%p count:%d lwm:2\n", + tlck->ip, mp, xadlock->count)); + + maplock->index = 1; + + /* mark page as invalid */ + if (((tblk->xflag & COMMIT_PWMAP) || S_ISDIR(ip->i_mode)) + && !(tlck->type & tlckBTROOT)) + tlck->flag |= tlckFREEPAGE; + /* + else (tblk->xflag & COMMIT_PMAP) + ? release the page; + */ + return; + } + + /* + * page/entry truncation: file truncation (ref. xtTruncate()) + * + * |----------+------+------+---------------| + * | | | + * | | hwm - hwm before truncation + * | next - truncation point + * lwm - lwm before truncation + * header ? + */ + if (tlck->type & tlckTRUNCATE) { + pxd_t tpxd; /* truncated extent of xad */ + + /* + * For truncation the entire linelock may be used, so it would + * be difficult to store xad list in linelock itself. + * Therefore, we'll just force transaction to be committed + * synchronously, so that xtree pages won't be changed before + * txUpdateMap runs. + */ + tblk->xflag &= ~COMMIT_LAZY; + lwm = xtlck->lwm.offset; + if (lwm == 0) + lwm = XTPAGEMAXSLOT; + hwm = xtlck->hwm.offset; + + /* + * write log records + */ + /* + * allocate entries XAD[lwm:next]: + */ + if (lwm < next) { + /* log after-image for logredo(): + * logredo() will update bmap for alloc of new/extended + * extents (XAD_NEW|XAD_EXTEND) of XAD[lwm:next) from + * after-image of XADlist; + * logredo() resets (XAD_NEW|XAD_EXTEND) flag when + * applying the after-image to the meta-data page. + */ + lrd->type = cpu_to_le16(LOG_REDOPAGE); + PXDaddress(pxd, mp->index); + PXDlength(pxd, + mp->logical_size >> tblk->sb-> + s_blocksize_bits); + lrd->backchain = + cpu_to_le32(lmLog(log, tblk, lrd, tlck)); + } + + /* + * truncate entry XAD[hwm == next - 1]: + */ + if (hwm == next - 1) { + /* init LOG_UPDATEMAP for logredo() to update bmap for + * free of truncated delta extent of the truncated + * entry XAD[next - 1]: + * (xtlck->pxdlock = truncated delta extent); + */ + pxdlock = (pxdlock_t *) & xtlck->pxdlock; + /* assert(pxdlock->type & tlckTRUNCATE); */ + lrd->type = cpu_to_le16(LOG_UPDATEMAP); + lrd->log.updatemap.type = cpu_to_le16(LOG_FREEPXD); + lrd->log.updatemap.nxd = cpu_to_le16(1); + lrd->log.updatemap.pxd = pxdlock->pxd; + tpxd = pxdlock->pxd; /* save to format maplock */ + lrd->backchain = + cpu_to_le32(lmLog(log, tblk, lrd, NULL)); + } + + /* + * free entries XAD[next:hwm]: + */ + if (hwm >= next) { + /* init LOG_UPDATEMAP of the freed extents + * XAD[next:hwm] from the deleted page itself + * for logredo() to update bmap; + */ + lrd->type = cpu_to_le16(LOG_UPDATEMAP); + lrd->log.updatemap.type = + cpu_to_le16(LOG_FREEXADLIST); + xtlck = (xtlock_t *) & tlck->lock; + hwm = xtlck->hwm.offset; + lrd->log.updatemap.nxd = + cpu_to_le16(hwm - next + 1); + /* reformat linelock for lmLog() */ + xtlck->header.offset = next; + xtlck->header.length = hwm - next + 1; + xtlck->index = 1; + lrd->backchain = + cpu_to_le32(lmLog(log, tblk, lrd, tlck)); + } + + /* + * format maplock(s) for txUpdateMap() to update bmap + */ + maplock->index = 0; + + /* + * allocate entries XAD[lwm:next): + */ + if (lwm < next) { + /* format a maplock for txUpdateMap() to update bPMAP + * for alloc of new/extended extents of XAD[lwm:next) + * from the page itself; + * txUpdateMap() resets (XAD_NEW|XAD_EXTEND) flag. + */ + tlck->flag |= tlckUPDATEMAP; + xadlock->flag = mlckALLOCXADLIST; + xadlock->count = next - lwm; + xadlock->xdlist = &p->xad[lwm]; + + jFYI(1, + ("xtLog: alloc ip:0x%p mp:0x%p count:%d lwm:%d next:%d\n", + tlck->ip, mp, xadlock->count, lwm, next)); + maplock->index++; + xadlock++; + } + + /* + * truncate entry XAD[hwm == next - 1]: + */ + if (hwm == next - 1) { + pxdlock_t *pxdlock; + + /* format a maplock for txUpdateMap() to update bmap + * to free truncated delta extent of the truncated + * entry XAD[next - 1]; + * (xtlck->pxdlock = truncated delta extent); + */ + tlck->flag |= tlckUPDATEMAP; + pxdlock = (pxdlock_t *) xadlock; + pxdlock->flag = mlckFREEPXD; + pxdlock->count = 1; + pxdlock->pxd = tpxd; + + jFYI(1, + ("xtLog: truncate ip:0x%p mp:0x%p count:%d hwm:%d\n", + ip, mp, pxdlock->count, hwm)); + maplock->index++; + xadlock++; + } + + /* + * free entries XAD[next:hwm]: + */ + if (hwm >= next) { + /* format a maplock for txUpdateMap() to update bmap + * to free extents of XAD[next:hwm] from thedeleted + * page itself; + */ + tlck->flag |= tlckUPDATEMAP; + xadlock->flag = mlckFREEXADLIST; + xadlock->count = hwm - next + 1; + xadlock->xdlist = &p->xad[next]; + + jFYI(1, + ("xtLog: free ip:0x%p mp:0x%p count:%d next:%d hwm:%d\n", + tlck->ip, mp, xadlock->count, next, hwm)); + maplock->index++; + } + + /* mark page as homeward bound */ + tlck->flag |= tlckWRITEPAGE; + } + return; +} + + +/* + * mapLog() + * + * function: log from maplock of freed data extents; + */ +void mapLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck) +{ + pxdlock_t *pxdlock; + int i, nlock; + pxd_t *pxd; + + /* + * page relocation: free the source page extent + * + * a maplock for txUpdateMap() for free of the page + * has been formatted at txLock() time saving the src + * relocated page address; + */ + if (tlck->type & tlckRELOCATE) { + /* log LOG_NOREDOPAGE of the old relocated page + * for logredo() to start NoRedoPage filter; + */ + lrd->type = cpu_to_le16(LOG_NOREDOPAGE); + pxdlock = (pxdlock_t *) & tlck->lock; + pxd = &lrd->log.redopage.pxd; + *pxd = pxdlock->pxd; + lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, NULL)); + + /* (N.B. currently, logredo() does NOT update bmap + * for free of the page itself for (LOG_XTREE|LOG_NOREDOPAGE); + * if page free from relocation, LOG_UPDATEMAP log is + * specifically generated now for logredo() + * to update bmap for free of src relocated page; + * (new flag LOG_RELOCATE may be introduced which will + * inform logredo() to start NORedoPage filter and also + * update block allocation map at the same time, thus + * avoiding an extra log write); + */ + lrd->type = cpu_to_le16(LOG_UPDATEMAP); + lrd->log.updatemap.type = cpu_to_le16(LOG_FREEPXD); + lrd->log.updatemap.nxd = cpu_to_le16(1); + lrd->log.updatemap.pxd = pxdlock->pxd; + lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, NULL)); + + /* a maplock for txUpdateMap() for free of the page + * has been formatted at txLock() time; + */ + tlck->flag |= tlckUPDATEMAP; + return; + } + /* + + * Otherwise it's not a relocate request + * + */ + else { + /* log LOG_UPDATEMAP for logredo() to update bmap for + * free of truncated/relocated delta extent of the data; + * e.g.: external EA extent, relocated/truncated extent + * from xtTailgate(); + */ + lrd->type = cpu_to_le16(LOG_UPDATEMAP); + pxdlock = (pxdlock_t *) & tlck->lock; + nlock = pxdlock->index; + for (i = 0; i < nlock; i++, pxdlock++) { + if (pxdlock->flag & mlckALLOCPXD) + lrd->log.updatemap.type = + cpu_to_le16(LOG_ALLOCPXD); + else + lrd->log.updatemap.type = + cpu_to_le16(LOG_FREEPXD); + lrd->log.updatemap.nxd = cpu_to_le16(1); + lrd->log.updatemap.pxd = pxdlock->pxd; + lrd->backchain = + cpu_to_le32(lmLog(log, tblk, lrd, NULL)); + jFYI(1, ("mapLog: xaddr:0x%lx xlen:0x%x\n", + (ulong) addressPXD(&pxdlock->pxd), + lengthPXD(&pxdlock->pxd))); + } + + /* update bmap */ + tlck->flag |= tlckUPDATEMAP; + } +} + + +/* + * txEA() + * + * function: acquire maplock for EA/ACL extents or + * set COMMIT_INLINE flag; + */ +void txEA(tid_t tid, struct inode *ip, dxd_t * oldea, dxd_t * newea) +{ + tlock_t *tlck = NULL; + pxdlock_t *maplock = NULL, *pxdlock = NULL; + + /* + * format maplock for alloc of new EA extent + */ + if (newea) { + /* Since the newea could be a completely zeroed entry we need to + * check for the two flags which indicate we should actually + * commit new EA data + */ + if (newea->flag & DXD_EXTENT) { + tlck = txMaplock(tid, ip, tlckMAP); + maplock = (pxdlock_t *) & tlck->lock; + pxdlock = (pxdlock_t *) maplock; + pxdlock->flag = mlckALLOCPXD; + PXDaddress(&pxdlock->pxd, addressDXD(newea)); + PXDlength(&pxdlock->pxd, lengthDXD(newea)); + pxdlock++; + maplock->index = 1; + } else if (newea->flag & DXD_INLINE) { + tlck = NULL; + + set_cflag(COMMIT_Inlineea, ip); + } + } + + /* + * format maplock for free of old EA extent + */ + if (!test_cflag(COMMIT_Nolink, ip) && oldea->flag & DXD_EXTENT) { + if (tlck == NULL) { + tlck = txMaplock(tid, ip, tlckMAP); + maplock = (pxdlock_t *) & tlck->lock; + pxdlock = (pxdlock_t *) maplock; + maplock->index = 0; + } + pxdlock->flag = mlckFREEPXD; + PXDaddress(&pxdlock->pxd, addressDXD(oldea)); + PXDlength(&pxdlock->pxd, lengthDXD(oldea)); + maplock->index++; + } +} + + +/* + * txForce() + * + * function: synchronously write pages locked by transaction + * after txLog() but before txUpdateMap(); + */ +void txForce(tblock_t * tblk) +{ + tlock_t *tlck; + lid_t lid, next; + metapage_t *mp; + + /* + * reverse the order of transaction tlocks in + * careful update order of address index pages + * (right to left, bottom up) + */ + tlck = lid_to_tlock(tblk->next); + lid = tlck->next; + tlck->next = 0; + while (lid) { + tlck = lid_to_tlock(lid); + next = tlck->next; + tlck->next = tblk->next; + tblk->next = lid; + lid = next; + } + + /* + * synchronously write the page, and + * hold the page for txUpdateMap(); + */ + for (lid = tblk->next; lid; lid = next) { + tlck = lid_to_tlock(lid); + next = tlck->next; + + if ((mp = tlck->mp) != NULL && + (tlck->type & tlckBTROOT) == 0) { + assert(mp->xflag & COMMIT_PAGE); + + if (tlck->flag & tlckWRITEPAGE) { + tlck->flag &= ~tlckWRITEPAGE; + + /* do not release page to freelist */ + assert(atomic_read(&mp->nohomeok)); + hold_metapage(mp, 0); + write_metapage(mp); + } + } + } +} + + +/* + * txUpdateMap() + * + * function: update persistent allocation map (and working map + * if appropriate); + * + * parameter: + */ +static void txUpdateMap(tblock_t * tblk) +{ + struct inode *ip; + struct inode *ipimap; + lid_t lid; + tlock_t *tlck; + maplock_t *maplock; + pxdlock_t pxdlock; + int maptype; + int k, nlock; + metapage_t *mp = 0; + + ipimap = JFS_SBI(tblk->sb)->ipimap; + + maptype = (tblk->xflag & COMMIT_PMAP) ? COMMIT_PMAP : COMMIT_PWMAP; + + + /* + * update block allocation map + * + * update allocation state in pmap (and wmap) and + * update lsn of the pmap page; + */ + /* + * scan each tlock/page of transaction for block allocation/free: + * + * for each tlock/page of transaction, update map. + * ? are there tlock for pmap and pwmap at the same time ? + */ + for (lid = tblk->next; lid; lid = tlck->next) { + tlck = lid_to_tlock(lid); + + if ((tlck->flag & tlckUPDATEMAP) == 0) + continue; + + if (tlck->flag & tlckFREEPAGE) { + /* + * Another thread may attempt to reuse freed space + * immediately, so we want to get rid of the metapage + * before anyone else has a chance to get it. + * Lock metapage, update maps, then invalidate + * the metapage. + */ + mp = tlck->mp; + ASSERT(mp->xflag & COMMIT_PAGE); + hold_metapage(mp, 0); + } + + /* + * extent list: + * . in-line PXD list: + * . out-of-line XAD list: + */ + maplock = (maplock_t *) & tlck->lock; + nlock = maplock->index; + + for (k = 0; k < nlock; k++, maplock++) { + /* + * allocate blocks in persistent map: + * + * blocks have been allocated from wmap at alloc time; + */ + if (maplock->flag & mlckALLOC) { + txAllocPMap(ipimap, maplock, tblk); + } + /* + * free blocks in persistent and working map: + * blocks will be freed in pmap and then in wmap; + * + * ? tblock specifies the PMAP/PWMAP based upon + * transaction + * + * free blocks in persistent map: + * blocks will be freed from wmap at last reference + * release of the object for regular files; + * + * Alway free blocks from both persistent & working + * maps for directories + */ + else { /* (maplock->flag & mlckFREE) */ + + if (S_ISDIR(tlck->ip->i_mode)) + txFreeMap(ipimap, maplock, + tblk, COMMIT_PWMAP); + else + txFreeMap(ipimap, maplock, + tblk, maptype); + } + } + if (tlck->flag & tlckFREEPAGE) { + if (!(tblk->flag & tblkGC_LAZY)) { + /* This is equivalent to txRelease */ + ASSERT(mp->lid == lid); + tlck->mp->lid = 0; + } + assert(atomic_read(&mp->nohomeok) == 1); + atomic_dec(&mp->nohomeok); + discard_metapage(mp); + tlck->mp = 0; + } + } + /* + * update inode allocation map + * + * update allocation state in pmap and + * update lsn of the pmap page; + * update in-memory inode flag/state + * + * unlock mapper/write lock + */ + if (tblk->xflag & COMMIT_CREATE) { + ip = tblk->ip; + + ASSERT(test_cflag(COMMIT_New, ip)); + clear_cflag(COMMIT_New, ip); + + diUpdatePMap(ipimap, ip->i_ino, FALSE, tblk); + ipimap->i_state |= I_DIRTY; + /* update persistent block allocation map + * for the allocation of inode extent; + */ + pxdlock.flag = mlckALLOCPXD; + pxdlock.pxd = JFS_IP(ip)->ixpxd; + pxdlock.index = 1; + txAllocPMap(ip, (maplock_t *) & pxdlock, tblk); + iput(ip); + } else if (tblk->xflag & COMMIT_DELETE) { + ip = tblk->ip; + diUpdatePMap(ipimap, ip->i_ino, TRUE, tblk); + ipimap->i_state |= I_DIRTY; + if (test_and_clear_cflag(COMMIT_Holdlock, ip)) { + if (tblk->flag & tblkGC_LAZY) + IWRITE_UNLOCK(ip); + } + iput(ip); + } +} + + +/* + * txAllocPMap() + * + * function: allocate from persistent map; + * + * parameter: + * ipbmap - + * malock - + * xad list: + * pxd: + * + * maptype - + * allocate from persistent map; + * free from persistent map; + * (e.g., tmp file - free from working map at releae + * of last reference); + * free from persistent and working map; + * + * lsn - log sequence number; + */ +static void txAllocPMap(struct inode *ip, maplock_t * maplock, + tblock_t * tblk) +{ + struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap; + xdlistlock_t *xadlistlock; + xad_t *xad; + s64 xaddr; + int xlen; + pxdlock_t *pxdlock; + xdlistlock_t *pxdlistlock; + pxd_t *pxd; + int n; + + /* + * allocate from persistent map; + */ + if (maplock->flag & mlckALLOCXADLIST) { + xadlistlock = (xdlistlock_t *) maplock; + xad = xadlistlock->xdlist; + for (n = 0; n < xadlistlock->count; n++, xad++) { + if (xad->flag & (XAD_NEW | XAD_EXTENDED)) { + xaddr = addressXAD(xad); + xlen = lengthXAD(xad); + dbUpdatePMap(ipbmap, FALSE, xaddr, + (s64) xlen, tblk); + xad->flag &= ~(XAD_NEW | XAD_EXTENDED); + jFYI(1, + ("allocPMap: xaddr:0x%lx xlen:%d\n", + (ulong) xaddr, xlen)); + } + } + } else if (maplock->flag & mlckALLOCPXD) { + pxdlock = (pxdlock_t *) maplock; + xaddr = addressPXD(&pxdlock->pxd); + xlen = lengthPXD(&pxdlock->pxd); + dbUpdatePMap(ipbmap, FALSE, xaddr, (s64) xlen, tblk); + jFYI(1, + ("allocPMap: xaddr:0x%lx xlen:%d\n", (ulong) xaddr, + xlen)); + } else { /* (maplock->flag & mlckALLOCPXDLIST) */ + + pxdlistlock = (xdlistlock_t *) maplock; + pxd = pxdlistlock->xdlist; + for (n = 0; n < pxdlistlock->count; n++, pxd++) { + xaddr = addressPXD(pxd); + xlen = lengthPXD(pxd); + dbUpdatePMap(ipbmap, FALSE, xaddr, (s64) xlen, + tblk); + jFYI(1, + ("allocPMap: xaddr:0x%lx xlen:%d\n", + (ulong) xaddr, xlen)); + } + } +} + + +/* + * txFreeMap() + * + * function: free from persistent and/or working map; + * + * todo: optimization + */ +void txFreeMap(struct inode *ip, + maplock_t * maplock, tblock_t * tblk, int maptype) +{ + struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap; + xdlistlock_t *xadlistlock; + xad_t *xad; + s64 xaddr; + int xlen; + pxdlock_t *pxdlock; + xdlistlock_t *pxdlistlock; + pxd_t *pxd; + int n; + + jFYI(1, + ("txFreeMap: tblk:0x%p maplock:0x%p maptype:0x%x\n", + tblk, maplock, maptype)); + + /* + * free from persistent map; + */ + if (maptype == COMMIT_PMAP || maptype == COMMIT_PWMAP) { + if (maplock->flag & mlckFREEXADLIST) { + xadlistlock = (xdlistlock_t *) maplock; + xad = xadlistlock->xdlist; + for (n = 0; n < xadlistlock->count; n++, xad++) { + if (!(xad->flag & XAD_NEW)) { + xaddr = addressXAD(xad); + xlen = lengthXAD(xad); + dbUpdatePMap(ipbmap, TRUE, xaddr, + (s64) xlen, tblk); + jFYI(1, + ("freePMap: xaddr:0x%lx xlen:%d\n", + (ulong) xaddr, xlen)); + } + } + } else if (maplock->flag & mlckFREEPXD) { + pxdlock = (pxdlock_t *) maplock; + xaddr = addressPXD(&pxdlock->pxd); + xlen = lengthPXD(&pxdlock->pxd); + dbUpdatePMap(ipbmap, TRUE, xaddr, (s64) xlen, + tblk); + jFYI(1, + ("freePMap: xaddr:0x%lx xlen:%d\n", + (ulong) xaddr, xlen)); + } else { /* (maplock->flag & mlckALLOCPXDLIST) */ + + pxdlistlock = (xdlistlock_t *) maplock; + pxd = pxdlistlock->xdlist; + for (n = 0; n < pxdlistlock->count; n++, pxd++) { + xaddr = addressPXD(pxd); + xlen = lengthPXD(pxd); + dbUpdatePMap(ipbmap, TRUE, xaddr, + (s64) xlen, tblk); + jFYI(1, + ("freePMap: xaddr:0x%lx xlen:%d\n", + (ulong) xaddr, xlen)); + } + } + } + + /* + * free from working map; + */ + if (maptype == COMMIT_PWMAP || maptype == COMMIT_WMAP) { + if (maplock->flag & mlckFREEXADLIST) { + xadlistlock = (xdlistlock_t *) maplock; + xad = xadlistlock->xdlist; + for (n = 0; n < xadlistlock->count; n++, xad++) { + xaddr = addressXAD(xad); + xlen = lengthXAD(xad); + dbFree(ip, xaddr, (s64) xlen); + xad->flag = 0; + jFYI(1, + ("freeWMap: xaddr:0x%lx xlen:%d\n", + (ulong) xaddr, xlen)); + } + } else if (maplock->flag & mlckFREEPXD) { + pxdlock = (pxdlock_t *) maplock; + xaddr = addressPXD(&pxdlock->pxd); + xlen = lengthPXD(&pxdlock->pxd); + dbFree(ip, xaddr, (s64) xlen); + jFYI(1, + ("freeWMap: xaddr:0x%lx xlen:%d\n", + (ulong) xaddr, xlen)); + } else { /* (maplock->flag & mlckFREEPXDLIST) */ + + pxdlistlock = (xdlistlock_t *) maplock; + pxd = pxdlistlock->xdlist; + for (n = 0; n < pxdlistlock->count; n++, pxd++) { + xaddr = addressPXD(pxd); + xlen = lengthPXD(pxd); + dbFree(ip, xaddr, (s64) xlen); + jFYI(1, + ("freeWMap: xaddr:0x%lx xlen:%d\n", + (ulong) xaddr, xlen)); + } + } + } +} + + +/* + * txFreelock() + * + * function: remove tlock from inode anonymous locklist + */ +void txFreelock(struct inode *ip) +{ + struct jfs_inode_info *jfs_ip = JFS_IP(ip); + tlock_t *xtlck, *tlck; + lid_t xlid = 0, lid; + + if (!jfs_ip->atlhead) + return; + + xtlck = (tlock_t *) &jfs_ip->atlhead; + + while ((lid = xtlck->next)) { + tlck = lid_to_tlock(lid); + if (tlck->flag & tlckFREELOCK) { + xtlck->next = tlck->next; + txLockFree(lid); + } else { + xtlck = tlck; + xlid = lid; + } + } + + if (jfs_ip->atlhead) + jfs_ip->atltail = xlid; + else { + jfs_ip->atltail = 0; + /* + * If inode was on anon_list, remove it + */ + TXN_LOCK(); + list_del_init(&jfs_ip->anon_inode_list); + TXN_UNLOCK(); + } +} + + +/* + * txAbort() + * + * function: abort tx before commit; + * + * frees line-locks and segment locks for all + * segments in comdata structure. + * Optionally sets state of file-system to FM_DIRTY in super-block. + * log age of page-frames in memory for which caller has + * are reset to 0 (to avoid logwarap). + */ +void txAbort(tid_t tid, int dirty) +{ + lid_t lid, next; + metapage_t *mp; + tblock_t *tblk = tid_to_tblock(tid); + + jEVENT(1, ("txAbort: tid:%d dirty:0x%x\n", tid, dirty)); + + /* + * free tlocks of the transaction + */ + for (lid = tblk->next; lid; lid = next) { + next = lid_to_tlock(lid)->next; + + mp = lid_to_tlock(lid)->mp; + + if (mp) { + mp->lid = 0; + + /* + * reset lsn of page to avoid logwarap: + * + * (page may have been previously committed by another + * transaction(s) but has not been paged, i.e., + * it may be on logsync list even though it has not + * been logged for the current tx.) + */ + if (mp->xflag & COMMIT_PAGE && mp->lsn) + LogSyncRelease(mp); + } + /* insert tlock at head of freelist */ + TXN_LOCK(); + txLockFree(lid); + TXN_UNLOCK(); + } + + /* caller will free the transaction block */ + + tblk->next = tblk->last = 0; + + /* + * mark filesystem dirty + */ + if (dirty) + updateSuper(tblk->sb, FM_DIRTY); + + return; +} + + +/* + * txAbortCommit() + * + * function: abort commit. + * + * frees tlocks of transaction; line-locks and segment locks for all + * segments in comdata structure. frees malloc storage + * sets state of file-system to FM_MDIRTY in super-block. + * log age of page-frames in memory for which caller has + * are reset to 0 (to avoid logwarap). + */ +void txAbortCommit(commit_t * cd, int exval) +{ + tblock_t *tblk; + tid_t tid; + lid_t lid, next; + metapage_t *mp; + + assert(exval == EIO || exval == ENOMEM); + jEVENT(1, ("txAbortCommit: cd:0x%p\n", cd)); + + /* + * free tlocks of the transaction + */ + tid = cd->tid; + tblk = tid_to_tblock(tid); + for (lid = tblk->next; lid; lid = next) { + next = lid_to_tlock(lid)->next; + + mp = lid_to_tlock(lid)->mp; + if (mp) { + mp->lid = 0; + + /* + * reset lsn of page to avoid logwarap; + */ + if (mp->xflag & COMMIT_PAGE) + LogSyncRelease(mp); + } + + /* insert tlock at head of freelist */ + TXN_LOCK(); + txLockFree(lid); + TXN_UNLOCK(); + } + + tblk->next = tblk->last = 0; + + /* free the transaction block */ + txEnd(tid); + + /* + * mark filesystem dirty + */ + updateSuper(cd->sb, FM_DIRTY); +} + + +/* + * txLazyCommit(void) + * + * All transactions except those changing ipimap (COMMIT_FORCE) are + * processed by this routine. This insures that the inode and block + * allocation maps are updated in order. For synchronous transactions, + * let the user thread finish processing after txUpdateMap() is called. + */ +void txLazyCommit(tblock_t * tblk) +{ + log_t *log; + + while (((tblk->flag & tblkGC_READY) == 0) && + ((tblk->flag & tblkGC_UNLOCKED) == 0)) { + /* We must have gotten ahead of the user thread + */ + jFYI(1, + ("jfs_lazycommit: tblk 0x%p not unlocked\n", tblk)); + schedule(); + } + + jFYI(1, ("txLazyCommit: processing tblk 0x%p\n", tblk)); + + txUpdateMap(tblk); + + log = (log_t *) JFS_SBI(tblk->sb)->log; + + spin_lock_irq(&log->gclock); // LOGGC_LOCK + + tblk->flag |= tblkGC_COMMITTED; + + if ((tblk->flag & tblkGC_READY) || (tblk->flag & tblkGC_LAZY)) + log->gcrtc--; + + if (tblk->flag & tblkGC_READY) + wake_up(&tblk->gcwait); // LOGGC_WAKEUP + + spin_unlock_irq(&log->gclock); // LOGGC_UNLOCK + + if (tblk->flag & tblkGC_LAZY) { + txUnlock(tblk, 0); + tblk->flag &= ~tblkGC_LAZY; + txEnd(tblk - TxBlock); /* Convert back to tid */ + } + + jFYI(1, ("txLazyCommit: done: tblk = 0x%p\n", tblk)); +} + +/* + * jfs_lazycommit(void) + * + * To be run as a kernel daemon. If lbmIODone is called in an interrupt + * context, or where blocking is not wanted, this routine will process + * committed transactions from the unlock queue. + */ +int jfs_lazycommit(void) +{ + int WorkDone; + tblock_t *tblk; + unsigned long flags; + + lock_kernel(); + + daemonize(); + current->tty = NULL; + strcpy(current->comm, "jfsCommit"); + + unlock_kernel(); + + jfsCommitTask = current; + + spin_lock_irq(¤t->sigmask_lock); + siginitsetinv(¤t->blocked, + sigmask(SIGHUP) | sigmask(SIGKILL) | sigmask(SIGSTOP) + | sigmask(SIGCONT)); + spin_unlock_irq(¤t->sigmask_lock); + + LAZY_LOCK_INIT(); + TxAnchor.unlock_queue = TxAnchor.unlock_tail = 0; + + complete(&jfsIOwait); + + do { + LAZY_LOCK(flags); +restart: + WorkDone = 0; + while ((tblk = TxAnchor.unlock_queue)) { + /* + * We can't get ahead of user thread. Spinning is + * simpler than blocking/waking. We shouldn't spin + * very long, since user thread shouldn't be blocking + * between lmGroupCommit & txEnd. + */ + WorkDone = 1; + + /* + * Remove first transaction from queue + */ + TxAnchor.unlock_queue = tblk->cqnext; + tblk->cqnext = 0; + if (TxAnchor.unlock_tail == tblk) + TxAnchor.unlock_tail = 0; + + LAZY_UNLOCK(flags); + txLazyCommit(tblk); + + /* + * We can be running indefinately if other processors + * are adding transactions to this list + */ + if (current->need_resched) + schedule(); + LAZY_LOCK(flags); + } + + if (WorkDone) + goto restart; + + LAZY_UNLOCK(flags); + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + } while (!jfs_thread_stopped()); + + if (TxAnchor.unlock_queue) + jERROR(1, ("jfs_lazycommit being killed with pending transactions!\n")); + else + jFYI(1, ("jfs_lazycommit being killed\n")); + complete(&jfsIOwait); + return 0; +} + +void txLazyUnlock(tblock_t * tblk) +{ + unsigned long flags; + + LAZY_LOCK(flags); + + if (TxAnchor.unlock_tail) + TxAnchor.unlock_tail->cqnext = tblk; + else + TxAnchor.unlock_queue = tblk; + TxAnchor.unlock_tail = tblk; + tblk->cqnext = 0; + LAZY_UNLOCK(flags); + wake_up_process(jfsCommitTask); +} + +static void LogSyncRelease(metapage_t * mp) +{ + log_t *log = mp->log; + + assert(atomic_read(&mp->nohomeok)); + assert(log); + atomic_dec(&mp->nohomeok); + + if (atomic_read(&mp->nohomeok)) + return; + + hold_metapage(mp, 0); + + LOGSYNC_LOCK(log); + mp->log = NULL; + mp->lsn = 0; + mp->clsn = 0; + log->count--; + list_del_init(&mp->synclist); + LOGSYNC_UNLOCK(log); + + release_metapage(mp); +} + +/* + * jfs_sync(void) + * + * To be run as a kernel daemon. This is awakened when tlocks run low. + * We write any inodes that have anonymous tlocks so they will become + * available. + */ +int jfs_sync(void) +{ + struct inode *ip; + struct jfs_inode_info *jfs_ip; + + lock_kernel(); + + daemonize(); + current->tty = NULL; + strcpy(current->comm, "jfsSync"); + + unlock_kernel(); + + jfsSyncTask = current; + + spin_lock_irq(¤t->sigmask_lock); + siginitsetinv(¤t->blocked, + sigmask(SIGHUP) | sigmask(SIGKILL) | sigmask(SIGSTOP) + | sigmask(SIGCONT)); + spin_unlock_irq(¤t->sigmask_lock); + + complete(&jfsIOwait); + + do { + /* + * write each inode on the anonymous inode list + */ + TXN_LOCK(); + while (TlocksLow && !list_empty(&TxAnchor.anon_list)) { + jfs_ip = list_entry(TxAnchor.anon_list.next, + struct jfs_inode_info, + anon_inode_list); + ip = jfs_ip->inode; + + /* + * We must release the TXN_LOCK since our + * IWRITE_TRYLOCK implementation may still block + */ + TXN_UNLOCK(); + if (IWRITE_TRYLOCK(ip)) { + /* + * inode will be removed from anonymous list + * when it is committed + */ + jfs_commit_inode(ip, 0); + IWRITE_UNLOCK(ip); + /* + * Just to be safe. I don't know how + * long we can run without blocking + */ + if (current->need_resched) + schedule(); + TXN_LOCK(); + } else { + /* We can't get the write lock. It may + * be held by a thread waiting for tlock's + * so let's not block here. Save it to + * put back on the anon_list. + */ + + /* + * We released TXN_LOCK, let's make sure + * this inode is still there + */ + TXN_LOCK(); + if (TxAnchor.anon_list.next != + &jfs_ip->anon_inode_list) + continue; + + /* Take off anon_list */ + list_del(&jfs_ip->anon_inode_list); + + /* Put on anon_list2 */ + list_add(&jfs_ip->anon_inode_list, + &TxAnchor.anon_list2); + } + } + /* Add anon_list2 back to anon_list */ + if (!list_empty(&TxAnchor.anon_list2)) { + list_splice(&TxAnchor.anon_list2, &TxAnchor.anon_list); + INIT_LIST_HEAD(&TxAnchor.anon_list2); + } + TXN_UNLOCK(); + + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + } while (!jfs_thread_stopped()); + + jFYI(1, ("jfs_sync being killed\n")); + complete(&jfsIOwait); + return 0; +} + +#if CONFIG_PROC_FS +int jfs_txanchor_read(char *buffer, char **start, off_t offset, int length, + int *eof, void *data) +{ + int len = 0; + off_t begin; + char *freewait; + char *freelockwait; + char *lowlockwait; + + freewait = + waitqueue_active(&TxAnchor.freewait) ? "active" : "empty"; + freelockwait = + waitqueue_active(&TxAnchor.freelockwait) ? "active" : "empty"; + lowlockwait = + waitqueue_active(&TxAnchor.lowlockwait) ? "active" : "empty"; + + len += sprintf(buffer, + "JFS TxAnchor\n" + "============\n" + "freetid = %d\n" + "freewait = %s\n" + "freelock = %d\n" + "freelockwait = %s\n" + "lowlockwait = %s\n" + "tlocksInUse = %d\n" + "unlock_queue = 0x%p\n" + "unlock_tail = 0x%p\n", + TxAnchor.freetid, + freewait, + TxAnchor.freelock, + freelockwait, + lowlockwait, + TxAnchor.tlocksInUse, + TxAnchor.unlock_queue, + TxAnchor.unlock_tail); + + begin = offset; + *start = buffer + begin; + len -= begin; + + if (len > length) + len = length; + else + *eof = 1; + + if (len < 0) + len = 0; + + return len; +} +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_txnmgr.h linux.19pre5-ac1/fs/jfs/jfs_txnmgr.h --- linux.19p5/fs/jfs/jfs_txnmgr.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_txnmgr.h Thu Apr 4 16:04:13 2002 @@ -0,0 +1,315 @@ +/* + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + */ + +/* + * Change History : + * + */ + +#ifndef _H_JFS_TXNMGR +#define _H_JFS_TXNMGR +/* + * jfs_txnmgr.h: transaction manager + */ + +#include "jfs_logmgr.h" + +/* + * Hide implementation of TxBlock and TxLock + */ +#define tid_to_tblock(tid) (&TxBlock[tid]) + +#define lid_to_tlock(lid) (&TxLock[lid]) + +/* + * transaction block + */ +typedef struct tblock { + /* + * tblock_t and jbuf_t common area: struct logsyncblk + * + * the following 5 fields are the same as struct logsyncblk + * which is common to tblock and jbuf to form logsynclist + */ + u16 xflag; /* tx commit type */ + u16 flag; /* tx commit state */ + lid_t dummy; /* Must keep structures common */ + s32 lsn; /* recovery lsn */ + struct list_head synclist; /* logsynclist link */ + + /* lock management */ + struct super_block *sb; /* 4: super block */ + lid_t next; /* 2: index of first tlock of tid */ + lid_t last; /* 2: index of last tlock of tid */ + wait_queue_head_t waitor; /* 4: tids waiting on this tid */ + + /* log management */ + u32 logtid; /* 4: log transaction id */ + /* (32) */ + + /* commit management */ + struct tblock *cqnext; /* 4: commit queue link */ + s32 clsn; /* 4: commit lsn */ + struct lbuf *bp; /* 4: */ + s32 pn; /* 4: commit record log page number */ + s32 eor; /* 4: commit record eor */ + wait_queue_head_t gcwait; /* 4: group commit event list: + * ready transactions wait on this + * event for group commit completion. + */ + struct inode *ip; /* 4: inode being created or deleted */ + s32 rsrvd; /* 4: */ +} tblock_t; /* (64) */ + +extern struct tblock *TxBlock; /* transaction block table */ + +/* commit flags: tblk->xflag */ +#define COMMIT_SYNC 0x0001 /* synchronous commit */ +#define COMMIT_FORCE 0x0002 /* force pageout at end of commit */ +#define COMMIT_FLUSH 0x0004 /* init flush at end of commit */ +#define COMMIT_MAP 0x00f0 +#define COMMIT_PMAP 0x0010 /* update pmap */ +#define COMMIT_WMAP 0x0020 /* update wmap */ +#define COMMIT_PWMAP 0x0040 /* update pwmap */ +#define COMMIT_FREE 0x0f00 +#define COMMIT_DELETE 0x0100 /* inode delete */ +#define COMMIT_TRUNCATE 0x0200 /* file truncation */ +#define COMMIT_CREATE 0x0400 /* inode create */ +#define COMMIT_LAZY 0x0800 /* lazy commit */ +#define COMMIT_PAGE 0x1000 /* Identifies element as metapage */ +#define COMMIT_INODE 0x2000 /* Identifies element as inode */ + +/* group commit flags tblk->flag: see jfs_logmgr.h */ + +/* + * transaction lock + */ +typedef struct tlock { + lid_t next; /* index next lockword on tid locklist + * next lockword on freelist + */ + tid_t tid; /* transaction id holding lock */ + + u16 flag; /* 2: lock control */ + u16 type; /* 2: log type */ + + struct metapage *mp; /* 4: object page buffer locked */ + struct inode *ip; /* 4: object */ + /* (16) */ + + s16 lock[24]; /* 48: overlay area */ +} tlock_t; /* (64) */ + +extern struct tlock *TxLock; /* transaction lock table */ + +/* + * tlock flag + */ +/* txLock state */ +#define tlckPAGELOCK 0x8000 +#define tlckINODELOCK 0x4000 +#define tlckLINELOCK 0x2000 +#define tlckINLINELOCK 0x1000 +/* lmLog state */ +#define tlckLOG 0x0800 +/* updateMap state */ +#define tlckUPDATEMAP 0x0080 +/* freeLock state */ +#define tlckFREELOCK 0x0008 +#define tlckWRITEPAGE 0x0004 +#define tlckFREEPAGE 0x0002 + +/* + * tlock type + */ +#define tlckTYPE 0xfe00 +#define tlckINODE 0x8000 +#define tlckXTREE 0x4000 +#define tlckDTREE 0x2000 +#define tlckMAP 0x1000 +#define tlckEA 0x0800 +#define tlckACL 0x0400 +#define tlckDATA 0x0200 +#define tlckBTROOT 0x0100 + +#define tlckOPERATION 0x00ff +#define tlckGROW 0x0001 /* file grow */ +#define tlckREMOVE 0x0002 /* file delete */ +#define tlckTRUNCATE 0x0004 /* file truncate */ +#define tlckRELOCATE 0x0008 /* file/directory relocate */ +#define tlckENTRY 0x0001 /* directory insert/delete */ +#define tlckEXTEND 0x0002 /* directory extend in-line */ +#define tlckSPLIT 0x0010 /* splited page */ +#define tlckNEW 0x0020 /* new page from split */ +#define tlckFREE 0x0040 /* free page */ +#define tlckRELINK 0x0080 /* update sibling pointer */ + +/* + * linelock for lmLog() + * + * note: linelock_t and its variations are overlaid + * at tlock.lock: watch for alignment; + */ +typedef struct { + u8 offset; /* 1: */ + u8 length; /* 1: */ +} lv_t; /* (2) */ + +#define TLOCKSHORT 20 +#define TLOCKLONG 28 + +typedef struct { + u16 next; /* 2: next linelock */ + + s8 maxcnt; /* 1: */ + s8 index; /* 1: */ + + u16 flag; /* 2: */ + u8 type; /* 1: */ + u8 l2linesize; /* 1: log2 of linesize */ + /* (8) */ + + lv_t lv[20]; /* 40: */ +} linelock_t; /* (48) */ + +#define dtlock_t linelock_t +#define itlock_t linelock_t + +typedef struct { + u16 next; /* 2: */ + + s8 maxcnt; /* 1: */ + s8 index; /* 1: */ + + u16 flag; /* 2: */ + u8 type; /* 1: */ + u8 l2linesize; /* 1: log2 of linesize */ + /* (8) */ + + lv_t header; /* 2: */ + lv_t lwm; /* 2: low water mark */ + lv_t hwm; /* 2: high water mark */ + lv_t twm; /* 2: */ + /* (16) */ + + s32 pxdlock[8]; /* 32: */ +} xtlock_t; /* (48) */ + + +/* + * maplock for txUpdateMap() + * + * note: maplock_t and its variations are overlaid + * at tlock.lock/linelock: watch for alignment; + * N.B. next field may be set by linelock, and should not + * be modified by maplock; + * N.B. index of the first pxdlock specifies index of next + * free maplock (i.e., number of maplock) in the tlock; + */ +typedef struct { + u16 next; /* 2: */ + + u8 maxcnt; /* 2: */ + u8 index; /* 2: next free maplock index */ + + u16 flag; /* 2: */ + u8 type; /* 1: */ + u8 count; /* 1: number of pxd/xad */ + /* (8) */ + + pxd_t pxd; /* 8: */ +} maplock_t; /* (16): */ + +/* maplock flag */ +#define mlckALLOC 0x00f0 +#define mlckALLOCXADLIST 0x0080 +#define mlckALLOCPXDLIST 0x0040 +#define mlckALLOCXAD 0x0020 +#define mlckALLOCPXD 0x0010 +#define mlckFREE 0x000f +#define mlckFREEXADLIST 0x0008 +#define mlckFREEPXDLIST 0x0004 +#define mlckFREEXAD 0x0002 +#define mlckFREEPXD 0x0001 + +#define pxdlock_t maplock_t + +typedef struct { + u16 next; /* 2: */ + + u8 maxcnt; /* 2: */ + u8 index; /* 2: */ + + u16 flag; /* 2: */ + u8 type; /* 1: */ + u8 count; /* 1: number of pxd/xad */ + /* (8) */ + + void *xdlist; /* 4: pxd/xad list */ + s32 rsrvd; /* 4: */ +} xdlistlock_t; /* (16): */ + + +/* + * commit + * + * parameter to the commit manager routines + */ +typedef struct commit { + tid_t tid; /* 4: tid = index of tblock */ + int flag; /* 4: flags */ + log_t *log; /* 4: log */ + struct super_block *sb; /* 4: superblock */ + + int nip; /* 4: number of entries in iplist */ + struct inode **iplist; /* 4: list of pointers to inodes */ + /* (32) */ + + /* log record descriptor on 64-bit boundary */ + lrd_t lrd; /* : log record descriptor */ +} commit_t; + +/* + * external declarations + */ +extern tlock_t *txLock(tid_t tid, struct inode *ip, struct metapage *mp, int flag); + +extern tlock_t *txMaplock(tid_t tid, struct inode *ip, int flag); + +extern int txCommit(tid_t tid, int nip, struct inode **iplist, int flag); + +extern tid_t txBegin(struct super_block *sb, int flag); + +extern void txBeginAnon(struct super_block *sb); + +extern void txEnd(tid_t tid); + +extern void txAbort(tid_t tid, int dirty); + +extern linelock_t *txLinelock(linelock_t * tlock); + +extern void txFreeMap(struct inode *ip, + maplock_t * maplock, tblock_t * tblk, int maptype); + +extern void txEA(tid_t tid, struct inode *ip, dxd_t * oldea, dxd_t * newea); + +extern void txFreelock(struct inode *ip); + +extern int lmLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck); + +#endif /* _H_JFS_TXNMGR */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_types.h linux.19pre5-ac1/fs/jfs/jfs_types.h --- linux.19p5/fs/jfs/jfs_types.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_types.h Wed Apr 3 01:20:49 2002 @@ -0,0 +1,187 @@ +/* + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _H_JFS_TYPES +#define _H_JFS_TYPES + +/* + * jfs_types.h: + * + * basic type/utility definitions + * + * note: this header file must be the 1st include file + * of JFS include list in all JFS .c file. + */ + +#include +#include + +#include "endian24.h" + +/* + * transaction and lock id's + */ +typedef uint tid_t; +typedef uint lid_t; + +/* + * Almost identical to Linux's timespec, but not quite + */ +struct timestruc_t { + u32 tv_sec; + u32 tv_nsec; +}; + +/* + * handy + */ + +#define LEFTMOSTONE 0x80000000 +#define HIGHORDER 0x80000000u /* high order bit on */ +#define ONES 0xffffffffu /* all bit on */ + +typedef int boolean_t; +#define TRUE 1 +#define FALSE 0 + +/* + * logical xd (lxd) + */ +typedef struct { + unsigned len:24; + unsigned off1:8; + u32 off2; +} lxd_t; + +/* lxd_t field construction */ +#define LXDlength(lxd, length32) ( (lxd)->len = length32 ) +#define LXDoffset(lxd, offset64)\ +{\ + (lxd)->off1 = ((s64)offset64) >> 32;\ + (lxd)->off2 = (offset64) & 0xffffffff;\ +} + +/* lxd_t field extraction */ +#define lengthLXD(lxd) ( (lxd)->len ) +#define offsetLXD(lxd)\ + ( ((s64)((lxd)->off1)) << 32 | (lxd)->off2 ) + +/* lxd list */ +typedef struct { + s16 maxnlxd; + s16 nlxd; + lxd_t *lxd; +} lxdlist_t; + +/* + * physical xd (pxd) + */ +typedef struct { + unsigned len:24; + unsigned addr1:8; + u32 addr2; +} pxd_t; + +/* xd_t field construction */ + +#define PXDlength(pxd, length32) ((pxd)->len = __cpu_to_le24(length32)) +#define PXDaddress(pxd, address64)\ +{\ + (pxd)->addr1 = ((s64)address64) >> 32;\ + (pxd)->addr2 = __cpu_to_le32((address64) & 0xffffffff);\ +} + +/* xd_t field extraction */ +#define lengthPXD(pxd) __le24_to_cpu((pxd)->len) +#define addressPXD(pxd)\ + ( ((s64)((pxd)->addr1)) << 32 | __le32_to_cpu((pxd)->addr2)) + +/* pxd list */ +typedef struct { + s16 maxnpxd; + s16 npxd; + pxd_t pxd[8]; +} pxdlist_t; + + +/* + * data extent descriptor (dxd) + */ +typedef struct { + unsigned flag:8; /* 1: flags */ + unsigned rsrvd:24; /* 3: */ + u32 size; /* 4: size in byte */ + unsigned len:24; /* 3: length in unit of fsblksize */ + unsigned addr1:8; /* 1: address in unit of fsblksize */ + u32 addr2; /* 4: address in unit of fsblksize */ +} dxd_t; /* - 16 - */ + +/* dxd_t flags */ +#define DXD_INDEX 0x80 /* B+-tree index */ +#define DXD_INLINE 0x40 /* in-line data extent */ +#define DXD_EXTENT 0x20 /* out-of-line single extent */ +#define DXD_FILE 0x10 /* out-of-line file (inode) */ +#define DXD_CORRUPT 0x08 /* Inconsistency detected */ + +/* dxd_t field construction + * Conveniently, the PXD macros work for DXD + */ +#define DXDlength PXDlength +#define DXDaddress PXDaddress +#define lengthDXD lengthPXD +#define addressDXD addressPXD + +/* + * directory entry argument + */ +typedef struct component_name { + int namlen; + wchar_t *name; +} component_t; + + +/* + * DASD limit information - stored in directory inode + */ +typedef struct dasd { + u8 thresh; /* Alert Threshold (in percent) */ + u8 delta; /* Alert Threshold delta (in percent) */ + u8 rsrvd1; + u8 limit_hi; /* DASD limit (in logical blocks) */ + u32 limit_lo; /* DASD limit (in logical blocks) */ + u8 rsrvd2[3]; + u8 used_hi; /* DASD usage (in logical blocks) */ + u32 used_lo; /* DASD usage (in logical blocks) */ +} dasd_t; + +#define DASDLIMIT(dasdp) \ + (((u64)((dasdp)->limit_hi) << 32) + __le32_to_cpu((dasdp)->limit_lo)) +#define setDASDLIMIT(dasdp, limit)\ +{\ + (dasdp)->limit_hi = ((u64)limit) >> 32;\ + (dasdp)->limit_lo = __cpu_to_le32(limit);\ +} +#define DASDUSED(dasdp) \ + (((u64)((dasdp)->used_hi) << 32) + __le32_to_cpu((dasdp)->used_lo)) +#define setDASDUSED(dasdp, used)\ +{\ + (dasdp)->used_hi = ((u64)used) >> 32;\ + (dasdp)->used_lo = __cpu_to_le32(used);\ +} + +#endif /* !_H_JFS_TYPES */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_umount.c linux.19pre5-ac1/fs/jfs/jfs_umount.c --- linux.19p5/fs/jfs/jfs_umount.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_umount.c Thu Feb 14 20:46:53 2002 @@ -0,0 +1,158 @@ +/* + * + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + */ + +/* + * Change History : + */ + +/* + * jfs_umount.c + * + * note: file system in transition to aggregate/fileset: + * (ref. jfs_mount.c) + * + * file system unmount is interpreted as mount of the single/only + * fileset in the aggregate and, if unmount of the last fileset, + * as unmount of the aggerate; + */ + +#include +#include "jfs_incore.h" +#include "jfs_filsys.h" +#include "jfs_superblock.h" +#include "jfs_dmap.h" +#include "jfs_imap.h" +#include "jfs_metapage.h" +#include "jfs_debug.h" + +/* + * NAME: jfs_umount(vfsp, flags, crp) + * + * FUNCTION: vfs_umount() + * + * PARAMETERS: vfsp - virtual file system pointer + * flags - unmount for shutdown + * crp - credential + * + * RETURN : EBUSY - device has open files + */ +int jfs_umount(struct super_block *sb) +{ + int rc = 0; + log_t *log; + struct jfs_sb_info *sbi = JFS_SBI(sb); + struct inode *ipbmap = sbi->ipbmap; + struct inode *ipimap = sbi->ipimap; + struct inode *ipaimap = sbi->ipaimap; + struct inode *ipaimap2 = sbi->ipaimap2; + + jFYI(1, ("\n UnMount JFS: sb:0x%p\n", sb)); + + /* + * update superblock and close log + * + * if mounted read-write and log based recovery was enabled + */ + if ((log = sbi->log)) { + /* + * close log: + * + * remove file system from log active file system list. + */ + log = sbi->log; + rc = lmLogClose(sb, log); + } + + /* + * close fileset inode allocation map (aka fileset inode) + */ + jEVENT(0, ("jfs_umount: close ipimap:0x%p\n", ipimap)); + diUnmount(ipimap, 0); + + diFreeSpecial(ipimap); + sbi->ipimap = NULL; + + /* + * close secondary aggregate inode allocation map + */ + ipaimap2 = sbi->ipaimap2; + if (ipaimap2) { + jEVENT(0, ("jfs_umount: close ipaimap2:0x%p\n", ipaimap2)); + diUnmount(ipaimap2, 0); + diFreeSpecial(ipaimap2); + sbi->ipaimap2 = NULL; + } + + /* + * close aggregate inode allocation map + */ + ipaimap = sbi->ipaimap; + jEVENT(0, ("jfs_umount: close ipaimap:0x%p\n", ipaimap)); + diUnmount(ipaimap, 0); + diFreeSpecial(ipaimap); + sbi->ipaimap = NULL; + + /* + * close aggregate block allocation map + */ + jEVENT(0, ("jfs_umount: close ipbmap:%p\n", ipbmap)); + dbUnmount(ipbmap, 0); + + diFreeSpecial(ipbmap); + sbi->ipimap = NULL; + + /* + * ensure all file system file pages are propagated to their + * home blocks on disk (and their in-memory buffer pages are + * invalidated) BEFORE updating file system superblock state + * (to signify file system is unmounted cleanly, and thus in + * consistent state) and log superblock active file system + * list (to signify skip logredo()). + */ + if (log) /* log = NULL if read-only mount */ + rc = updateSuper(sb, FM_CLEAN); + + + jFYI(0, (" UnMount JFS Complete: %d\n", rc)); + return rc; +} + + +int jfs_umount_rw(struct super_block *sb) +{ + struct jfs_sb_info *sbi = JFS_SBI(sb); + + if (!sbi->log) + return 0; + + /* + * close log: + * + * remove file system from log active file system list. + */ + lmLogClose(sb, sbi->log); + + dbSync(sbi->ipbmap); + diSync(sbi->ipimap); + + sbi->log = 0; + + return updateSuper(sb, FM_CLEAN); + +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_unicode.c linux.19pre5-ac1/fs/jfs/jfs_unicode.c --- linux.19p5/fs/jfs/jfs_unicode.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_unicode.c Thu Feb 14 20:46:53 2002 @@ -0,0 +1,110 @@ +/* + * + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include "jfs_types.h" +#include "jfs_filsys.h" +#include "jfs_unicode.h" +#include "jfs_debug.h" + +/* + * NAME: jfs_strfromUCS() + * + * FUNCTION: Convert little-endian unicode string to character string + * + */ +int jfs_strfromUCS_le(char *to, const wchar_t * from, /* LITTLE ENDIAN */ + int len, struct nls_table *codepage) +{ + int i; + int outlen = 0; + + for (i = 0; (i < len) && from[i]; i++) { + int charlen; + charlen = + codepage->uni2char(le16_to_cpu(from[i]), &to[outlen], + NLS_MAX_CHARSET_SIZE); + if (charlen > 0) { + outlen += charlen; + } else { + to[outlen++] = '?'; + } + } + to[outlen] = 0; + jEVENT(0, ("jfs_strfromUCS returning %d - '%s'\n", outlen, to)); + return outlen; +} + +/* + * NAME: jfs_strtoUCS() + * + * FUNCTION: Convert character string to unicode string + * + */ +int jfs_strtoUCS(wchar_t * to, + const char *from, int len, struct nls_table *codepage) +{ + int charlen; + int i; + + jEVENT(0, ("jfs_strtoUCS - '%s'\n", from)); + + for (i = 0; len && *from; i++, from += charlen, len -= charlen) { + charlen = codepage->char2uni(from, len, &to[i]); + if (charlen < 1) { + jERROR(1, ("jfs_strtoUCS: char2uni returned %d.\n", + charlen)); + jERROR(1, ("charset = %s, char = 0x%x\n", + codepage->charset, (unsigned char) *from)); + to[i] = 0x003f; /* a question mark */ + charlen = 1; + } + } + + jEVENT(0, (" returning %d\n", i)); + + to[i] = 0; + return i; +} + +/* + * NAME: get_UCSname() + * + * FUNCTION: Allocate and translate to unicode string + * + */ +int get_UCSname(component_t * uniName, struct dentry *dentry, + struct nls_table *nls_tab) +{ + int length = dentry->d_name.len; + + if (length > JFS_NAME_MAX) + return ENAMETOOLONG; + + uniName->name = + kmalloc((length + 1) * sizeof(wchar_t), GFP_NOFS); + + if (uniName->name == NULL) + return ENOSPC; + + uniName->namlen = jfs_strtoUCS(uniName->name, dentry->d_name.name, + length, nls_tab); + + return 0; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_unicode.h linux.19pre5-ac1/fs/jfs/jfs_unicode.h --- linux.19p5/fs/jfs/jfs_unicode.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_unicode.h Wed Apr 3 01:20:49 2002 @@ -0,0 +1,143 @@ +/* + * unistrk: Unicode kernel case support + * + * Function: + * Convert a unicode character to upper or lower case using + * compressed tables. + * + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + */ + +#include +#include "jfs_types.h" + +typedef struct { + wchar_t start; + wchar_t end; + signed char *table; +} UNICASERANGE; + +extern signed char UniUpperTable[512]; +extern UNICASERANGE UniUpperRange[]; +extern int get_UCSname(component_t *, struct dentry *, struct nls_table *); +extern int jfs_strfromUCS_le(char *, const wchar_t *, int, struct nls_table *); + +#define free_UCSname(COMP) kfree((COMP)->name) + +/* + * UniStrcpy: Copy a string + */ +static inline wchar_t *UniStrcpy(wchar_t * ucs1, const wchar_t * ucs2) +{ + wchar_t *anchor = ucs1; /* save the start of result string */ + + while ((*ucs1++ = *ucs2++)); + return anchor; +} + + + +/* + * UniStrncpy: Copy length limited string with pad + */ +static inline wchar_t *UniStrncpy(wchar_t * ucs1, const wchar_t * ucs2, + size_t n) +{ + wchar_t *anchor = ucs1; + + while (n-- && *ucs2) /* Copy the strings */ + *ucs1++ = *ucs2++; + + n++; + while (n--) /* Pad with nulls */ + *ucs1++ = 0; + return anchor; +} + +/* + * UniStrncmp_le: Compare length limited string - native to little-endian + */ +static inline int UniStrncmp_le(const wchar_t * ucs1, const wchar_t * ucs2, + size_t n) +{ + if (!n) + return 0; /* Null strings are equal */ + while ((*ucs1 == __le16_to_cpu(*ucs2)) && *ucs1 && --n) { + ucs1++; + ucs2++; + } + return (int) *ucs1 - (int) __le16_to_cpu(*ucs2); +} + +/* + * UniStrncpy_le: Copy length limited string with pad to little-endian + */ +static inline wchar_t *UniStrncpy_le(wchar_t * ucs1, const wchar_t * ucs2, + size_t n) +{ + wchar_t *anchor = ucs1; + + while (n-- && *ucs2) /* Copy the strings */ + *ucs1++ = __le16_to_cpu(*ucs2++); + + n++; + while (n--) /* Pad with nulls */ + *ucs1++ = 0; + return anchor; +} + + +/* + * UniToupper: Convert a unicode character to upper case + */ +static inline wchar_t UniToupper(register wchar_t uc) +{ + register UNICASERANGE *rp; + + if (uc < sizeof(UniUpperTable)) { /* Latin characters */ + return uc + UniUpperTable[uc]; /* Use base tables */ + } else { + rp = UniUpperRange; /* Use range tables */ + while (rp->start) { + if (uc < rp->start) /* Before start of range */ + return uc; /* Uppercase = input */ + if (uc <= rp->end) /* In range */ + return uc + rp->table[uc - rp->start]; + rp++; /* Try next range */ + } + } + return uc; /* Past last range */ +} + + +/* + * UniStrupr: Upper case a unicode string + */ +static inline wchar_t *UniStrupr(register wchar_t * upin) +{ + register wchar_t *up; + + up = upin; + while (*up) { /* For all characters */ + *up = UniToupper(*up); + up++; + } + return upin; /* Return input pointer */ +} + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_uniupr.c linux.19pre5-ac1/fs/jfs/jfs_uniupr.c --- linux.19p5/fs/jfs/jfs_uniupr.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_uniupr.c Thu Feb 14 20:46:53 2002 @@ -0,0 +1,137 @@ +/* + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + * + * jfs_uniupr.c - Unicode compressed case ranges + * +*/ + +#include +#include "jfs_unicode.h" + +/* + * Latin upper case + */ +signed char UniUpperTable[512] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 000-00f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 010-01f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 020-02f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 030-03f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 040-04f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 050-05f */ + 0,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32, /* 060-06f */ + -32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32, 0, 0, 0, 0, 0, /* 070-07f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 080-08f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 090-09f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0a0-0af */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0b0-0bf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0c0-0cf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0d0-0df */ + -32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32, /* 0e0-0ef */ + -32,-32,-32,-32,-32,-32,-32, 0,-32,-32,-32,-32,-32,-32,-32,121, /* 0f0-0ff */ + 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 100-10f */ + 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 110-11f */ + 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 120-12f */ + 0, 0, 0, -1, 0, -1, 0, -1, 0, 0, -1, 0, -1, 0, -1, 0, /* 130-13f */ + -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, 0, -1, 0, -1, 0, -1, /* 140-14f */ + 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 150-15f */ + 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 160-16f */ + 0, -1, 0, -1, 0, -1, 0, -1, 0, 0, -1, 0, -1, 0, -1, 0, /* 170-17f */ + 0, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, /* 180-18f */ + 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, /* 190-19f */ + 0, -1, 0, -1, 0, -1, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, /* 1a0-1af */ + -1, 0, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, /* 1b0-1bf */ + 0, 0, 0, 0, 0, -1, -2, 0, -1, -2, 0, -1, -2, 0, -1, 0, /* 1c0-1cf */ + -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,-79, 0, -1, /* 1d0-1df */ + 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1e0-1ef */ + 0, 0, -1, -2, 0, -1, 0, 0, 0, -1, 0, -1, 0, -1, 0, -1, /* 1f0-1ff */ +}; + +/* Upper case range - Greek */ +static signed char UniCaseRangeU03a0[47] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-38,-37,-37,-37, /* 3a0-3af */ + 0,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32, /* 3b0-3bf */ + -32,-32,-31,-32,-32,-32,-32,-32,-32,-32,-32,-32,-64,-63,-63, +}; + +/* Upper case range - Cyrillic */ +static signed char UniCaseRangeU0430[48] = { + -32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32, /* 430-43f */ + -32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32, /* 440-44f */ + 0,-80,-80,-80,-80,-80,-80,-80,-80,-80,-80,-80,-80, 0,-80,-80, /* 450-45f */ +}; + +/* Upper case range - Extended cyrillic */ +static signed char UniCaseRangeU0490[61] = { + 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 490-49f */ + 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 4a0-4af */ + 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 4b0-4bf */ + 0, 0, -1, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1, +}; + +/* Upper case range - Extended latin and greek */ +static signed char UniCaseRangeU1e00[509] = { + 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1e00-1e0f */ + 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1e10-1e1f */ + 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1e20-1e2f */ + 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1e30-1e3f */ + 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1e40-1e4f */ + 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1e50-1e5f */ + 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1e60-1e6f */ + 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1e70-1e7f */ + 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1e80-1e8f */ + 0, -1, 0, -1, 0, -1, 0, 0, 0, 0, 0,-59, 0, -1, 0, -1, /* 1e90-1e9f */ + 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1ea0-1eaf */ + 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1eb0-1ebf */ + 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1ec0-1ecf */ + 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1ed0-1edf */ + 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1ee0-1eef */ + 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, /* 1ef0-1eff */ + 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, /* 1f00-1f0f */ + 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1f10-1f1f */ + 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, /* 1f20-1f2f */ + 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, /* 1f30-1f3f */ + 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1f40-1f4f */ + 0, 8, 0, 8, 0, 8, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, /* 1f50-1f5f */ + 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, /* 1f60-1f6f */ + 74, 74, 86, 86, 86, 86,100,100, 0, 0,112,112,126,126, 0, 0, /* 1f70-1f7f */ + 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, /* 1f80-1f8f */ + 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, /* 1f90-1f9f */ + 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, /* 1fa0-1faf */ + 8, 8, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1fb0-1fbf */ + 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1fc0-1fcf */ + 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1fd0-1fdf */ + 8, 8, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1fe0-1fef */ + 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +/* Upper case range - Wide latin */ +static signed char UniCaseRangeUff40[27] = { + 0,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32, /* ff40-ff4f */ + -32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32, +}; + +/* + * Upper Case Range + */ +UNICASERANGE UniUpperRange[] = { + { 0x03a0, 0x03ce, UniCaseRangeU03a0 }, + { 0x0430, 0x045f, UniCaseRangeU0430 }, + { 0x0490, 0x04cc, UniCaseRangeU0490 }, + { 0x1e00, 0x1ffc, UniCaseRangeU1e00 }, + { 0xff40, 0xff5a, UniCaseRangeUff40 }, + { 0, 0, 0 } +}; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_xtree.c linux.19pre5-ac1/fs/jfs/jfs_xtree.c --- linux.19p5/fs/jfs/jfs_xtree.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_xtree.c Thu Feb 21 15:24:50 2002 @@ -0,0 +1,4444 @@ +/* + * + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + */ +/* + * jfs_xtree.c: extent allocation descriptor B+-tree manager + */ + +#include +#include +#include "jfs_incore.h" +#include "jfs_filsys.h" +#include "jfs_metapage.h" +#include "jfs_dmap.h" +#include "jfs_dinode.h" +#include "jfs_superblock.h" +#include "jfs_debug.h" + +/* + * xtree local flag + */ +#define XT_INSERT 0x00000001 + +/* + * xtree key/entry comparison: extent offset + * + * return: + * -1: k < start of extent + * 0: start_of_extent <= k <= end_of_extent + * 1: k > end_of_extent + */ +#define XT_CMP(CMP, K, X, OFFSET64)\ +{\ + OFFSET64 = offsetXAD(X);\ + (CMP) = ((K) >= OFFSET64 + lengthXAD(X)) ? 1 :\ + ((K) < OFFSET64) ? -1 : 0;\ +} + +/* write a xad entry */ +#define XT_PUTENTRY(XAD, FLAG, OFF, LEN, ADDR)\ +{\ + (XAD)->flag = (FLAG);\ + XADoffset((XAD), (OFF));\ + XADlength((XAD), (LEN));\ + XADaddress((XAD), (ADDR));\ +} + +#define XT_PAGE(IP, MP) BT_PAGE(IP, MP, xtpage_t, i_xtroot) + +/* get page buffer for specified block address */ +#define XT_GETPAGE(IP, BN, MP, SIZE, P, RC)\ +{\ + BT_GETPAGE(IP, BN, MP, xtpage_t, SIZE, P, RC, i_xtroot)\ + if (!(RC))\ + {\ + if ((le16_to_cpu((P)->header.nextindex) < XTENTRYSTART) ||\ + (le16_to_cpu((P)->header.nextindex) > le16_to_cpu((P)->header.maxentry)) ||\ + (le16_to_cpu((P)->header.maxentry) > (((BN)==0)?XTROOTMAXSLOT:PSIZE>>L2XTSLOTSIZE)))\ + {\ + jERROR(1,("XT_GETPAGE: xtree page corrupt\n"));\ + BT_PUTPAGE(MP);\ + updateSuper((IP)->i_sb, FM_DIRTY);\ + MP = NULL;\ + RC = EIO;\ + }\ + }\ +} + +/* for consistency */ +#define XT_PUTPAGE(MP) BT_PUTPAGE(MP) + +#define XT_GETSEARCH(IP, LEAF, BN, MP, P, INDEX) \ + BT_GETSEARCH(IP, LEAF, BN, MP, xtpage_t, P, INDEX, i_xtroot) +/* xtree entry parameter descriptor */ +typedef struct { + metapage_t *mp; + s16 index; + u8 flag; + s64 off; + s64 addr; + int len; + pxdlist_t *pxdlist; +} xtsplit_t; + + +/* + * statistics + */ +#ifdef CONFIG_JFS_STATISTICS +static struct { + uint search; + uint fastSearch; + uint split; +} xtStat; +#endif + + +/* + * forward references + */ +static int xtSearch(struct inode *ip, + s64 xoff, int *cmpp, btstack_t * btstack, int flag); + +static int xtSplitUp(tid_t tid, + struct inode *ip, + xtsplit_t * split, btstack_t * btstack); + +static int xtSplitPage(tid_t tid, + struct inode *ip, + xtsplit_t * split, metapage_t ** rmpp, s64 * rbnp); + +static int xtSplitRoot(tid_t tid, + struct inode *ip, + xtsplit_t * split, metapage_t ** rmpp); + +#ifdef _STILL_TO_PORT +static int xtDeleteUp(tid_t tid, + struct inode *ip, + metapage_t * fmp, + xtpage_t * fp, btstack_t * btstack); + +static int xtSearchNode(struct inode *ip, + xad_t * xad, + int *cmpp, btstack_t * btstack, int flag); + +static int xtRelink(tid_t tid, struct inode *ip, xtpage_t * fp); +#endif /* _STILL_TO_PORT */ + +/* External references */ + +/* + * debug control + */ +/* #define _JFS_DEBUG_XTREE 1 */ + + +/* + * xtLookup() + * + * function: map a single page into a physical extent; + */ +int xtLookup(struct inode *ip, s64 lstart, + s64 llen, int *pflag, s64 * paddr, s32 * plen, int no_check) +{ + int rc = 0; + btstack_t btstack; + int cmp; + s64 bn; + metapage_t *mp; + xtpage_t *p; + int index; + xad_t *xad; + s64 size, xoff, xend; + int xlen; + s64 xaddr; + + *plen = 0; + + if (!no_check) { + /* is lookup offset beyond eof ? */ + size = ((u64) ip->i_size + (JFS_SBI(ip->i_sb)->bsize - 1)) >> + JFS_SBI(ip->i_sb)->l2bsize; + if (lstart >= size) { + jERROR(1, + ("xtLookup: lstart (0x%lx) >= size (0x%lx)\n", + (ulong) lstart, (ulong) size)); + return 0; + } + } + + /* + * search for the xad entry covering the logical extent + */ +//search: + if ((rc = xtSearch(ip, lstart, &cmp, &btstack, 0))) { + jERROR(1, ("xtLookup: xtSearch returned %d\n", rc)); + return rc; + } + + /* + * compute the physical extent covering logical extent + * + * N.B. search may have failed (e.g., hole in sparse file), + * and returned the index of the next entry. + */ + /* retrieve search result */ + XT_GETSEARCH(ip, btstack.top, bn, mp, p, index); + + /* is xad found covering start of logical extent ? + * lstart is a page start address, + * i.e., lstart cannot start in a hole; + */ + if (cmp) { + jFYI(1, ("xtLookup: cmp = %d\n", cmp)); + goto out; + } + + /* + * lxd covered by xad + */ + xad = &p->xad[index]; + xoff = offsetXAD(xad); + xlen = lengthXAD(xad); + xend = xoff + xlen; + xaddr = addressXAD(xad); + + jEVENT(0, + ("index = %d, xoff = 0x%lx, xlen = 0x%x, xaddr = 0x%lx\n", + index, (ulong) xoff, xlen, (ulong) xaddr)); + + /* initialize new pxd */ + *pflag = xad->flag; + *paddr = xaddr + (lstart - xoff); + /* a page must be fully covered by an xad */ + *plen = min(xend - lstart, llen); + + out: + XT_PUTPAGE(mp); + + return rc; +} + + +/* + * xtLookupList() + * + * function: map a single logical extent into a list of physical extent; + * + * parameter: + * struct inode *ip, + * lxdlist_t *lxdlist, lxd list (in) + * xadlist_t *xadlist, xad list (in/out) + * int flag) + * + * coverage of lxd by xad under assumption of + * . lxd's are ordered and disjoint. + * . xad's are ordered and disjoint. + * + * return: + * 0: success + * + * note: a page being written (even a single byte) is backed fully, + * except the last page which is only backed with blocks + * required to cover the last byte; + * the extent backing a page is fully contained within an xad; + */ +int xtLookupList(struct inode *ip, lxdlist_t * lxdlist, /* lxd list (in) */ + xadlist_t * xadlist, /* xad list (in/out) */ + int flag) +{ + int rc = 0; + btstack_t btstack; + int cmp; + s64 bn; + metapage_t *mp; + xtpage_t *p; + int index; + lxd_t *lxd; + xad_t *xad, *pxd; + s64 size, lstart, lend, xstart, xend, pstart; + s64 llen, xlen, plen; + s64 xaddr, paddr; + int nlxd, npxd, maxnpxd; + + npxd = xadlist->nxad = 0; + maxnpxd = xadlist->maxnxad; + pxd = xadlist->xad; + + nlxd = lxdlist->nlxd; + lxd = lxdlist->lxd; + + lstart = offsetLXD(lxd); + llen = lengthLXD(lxd); + lend = lstart + llen; + + size = (ip->i_size + (JFS_SBI(ip->i_sb)->bsize - 1)) >> + JFS_SBI(ip->i_sb)->l2bsize; + + /* + * search for the xad entry covering the logical extent + */ + search: + if (lstart >= size) + return 0; + + if ((rc = xtSearch(ip, lstart, &cmp, &btstack, 0))) + return rc; + + /* + * compute the physical extent covering logical extent + * + * N.B. search may have failed (e.g., hole in sparse file), + * and returned the index of the next entry. + */ +//map: + /* retrieve search result */ + XT_GETSEARCH(ip, btstack.top, bn, mp, p, index); + + /* is xad on the next sibling page ? */ + if (index == le16_to_cpu(p->header.nextindex)) { + if (p->header.flag & BT_ROOT) + goto mapend; + + if ((bn = le64_to_cpu(p->header.next)) == 0) + goto mapend; + + XT_PUTPAGE(mp); + + /* get next sibling page */ + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) + return rc; + + index = XTENTRYSTART; + } + + xad = &p->xad[index]; + + /* + * is lxd covered by xad ? + */ + compare: + xstart = offsetXAD(xad); + xlen = lengthXAD(xad); + xend = xstart + xlen; + xaddr = addressXAD(xad); + + compare1: + if (xstart < lstart) + goto compare2; + + /* (lstart <= xstart) */ + + /* lxd is NOT covered by xad */ + if (lend <= xstart) { + /* + * get next lxd + */ + if (--nlxd == 0) + goto mapend; + lxd++; + + lstart = offsetLXD(lxd); + llen = lengthLXD(lxd); + lend = lstart + llen; + if (lstart >= size) + goto mapend; + + /* compare with the current xad */ + goto compare1; + } + /* lxd is covered by xad */ + else { /* (xstart < lend) */ + + /* initialize new pxd */ + pstart = xstart; + plen = min(lend - xstart, xlen); + paddr = xaddr; + + goto cover; + } + + /* (xstart < lstart) */ + compare2: + /* lxd is covered by xad */ + if (lstart < xend) { + /* initialize new pxd */ + pstart = lstart; + plen = min(xend - lstart, llen); + paddr = xaddr + (lstart - xstart); + + goto cover; + } + /* lxd is NOT covered by xad */ + else { /* (xend <= lstart) */ + + /* + * get next xad + * + * linear search next xad covering lxd on + * the current xad page, and then tree search + */ + if (index == le16_to_cpu(p->header.nextindex) - 1) { + if (p->header.flag & BT_ROOT) + goto mapend; + + XT_PUTPAGE(mp); + goto search; + } else { + index++; + xad++; + + /* compare with new xad */ + goto compare; + } + } + + /* + * lxd is covered by xad and a new pxd has been initialized + * (lstart <= xstart < lend) or (xstart < lstart < xend) + */ + cover: + /* finalize pxd corresponding to current xad */ + XT_PUTENTRY(pxd, xad->flag, pstart, plen, paddr); + + if (++npxd >= maxnpxd) + goto mapend; + pxd++; + + /* + * lxd is fully covered by xad + */ + if (lend <= xend) { + /* + * get next lxd + */ + if (--nlxd == 0) + goto mapend; + lxd++; + + lstart = offsetLXD(lxd); + llen = lengthLXD(lxd); + lend = lstart + llen; + if (lstart >= size) + goto mapend; + + /* + * test for old xad covering new lxd + * (old xstart < new lstart) + */ + goto compare2; + } + /* + * lxd is partially covered by xad + */ + else { /* (xend < lend) */ + + /* + * get next xad + * + * linear search next xad covering lxd on + * the current xad page, and then next xad page search + */ + if (index == le16_to_cpu(p->header.nextindex) - 1) { + if (p->header.flag & BT_ROOT) + goto mapend; + + if ((bn = le64_to_cpu(p->header.next)) == 0) + goto mapend; + + XT_PUTPAGE(mp); + + /* get next sibling page */ + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) + return rc; + + index = XTENTRYSTART; + xad = &p->xad[index]; + } else { + index++; + xad++; + } + + /* + * test for new xad covering old lxd + * (old lstart < new xstart) + */ + goto compare; + } + + mapend: + xadlist->nxad = npxd; + +//out: + XT_PUTPAGE(mp); + + return rc; +} + + +/* + * xtSearch() + * + * function: search for the xad entry covering specified offset. + * + * parameters: + * ip - file object; + * xoff - extent offset; + * cmpp - comparison result: + * btstack - traverse stack; + * flag - search process flag (XT_INSERT); + * + * returns: + * btstack contains (bn, index) of search path traversed to the entry. + * *cmpp is set to result of comparison with the entry returned. + * the page containing the entry is pinned at exit. + */ +static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */ + int *cmpp, btstack_t * btstack, int flag) +{ + struct jfs_inode_info *jfs_ip = JFS_IP(ip); + int rc = 0; + int cmp = 1; /* init for empty page */ + s64 bn; /* block number */ + metapage_t *mp; /* page buffer */ + xtpage_t *p; /* page */ + xad_t *xad; + int base, index, lim, btindex; + btframe_t *btsp; + int nsplit = 0; /* number of pages to split */ + s64 t64; + + INCREMENT(xtStat.search); + + BT_CLR(btstack); + + btstack->nsplit = 0; + + /* + * search down tree from root: + * + * between two consecutive entries of and of + * internal page, child page Pi contains entry with k, Ki <= K < Kj. + * + * if entry with search key K is not found + * internal page search find the entry with largest key Ki + * less than K which point to the child page to search; + * leaf page search find the entry with smallest key Kj + * greater than K so that the returned index is the position of + * the entry to be shifted right for insertion of new entry. + * for empty tree, search key is greater than any key of the tree. + * + * by convention, root bn = 0. + */ + for (bn = 0;;) { + /* get/pin the page to search */ + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) + return rc; + + /* try sequential access heuristics with the previous + * access entry in target leaf page: + * once search narrowed down into the target leaf, + * key must either match an entry in the leaf or + * key entry does not exist in the tree; + */ +//fastSearch: + if ((jfs_ip->btorder & BT_SEQUENTIAL) && + (p->header.flag & BT_LEAF) && + (index = jfs_ip->btindex) < + le16_to_cpu(p->header.nextindex)) { + xad = &p->xad[index]; + t64 = offsetXAD(xad); + if (xoff < t64 + lengthXAD(xad)) { + if (xoff >= t64) { + *cmpp = 0; + goto out; + } + + /* stop sequential access heuristics */ + goto binarySearch; + } else { /* (t64 + lengthXAD(xad)) <= xoff */ + + /* try next sequential entry */ + index++; + if (index < + le16_to_cpu(p->header.nextindex)) { + xad++; + t64 = offsetXAD(xad); + if (xoff < t64 + lengthXAD(xad)) { + if (xoff >= t64) { + *cmpp = 0; + goto out; + } + + /* miss: key falls between + * previous and this entry + */ + *cmpp = 1; + goto out; + } + + /* (xoff >= t64 + lengthXAD(xad)); + * matching entry may be further out: + * stop heuristic search + */ + /* stop sequential access heuristics */ + goto binarySearch; + } + + /* (index == p->header.nextindex); + * miss: key entry does not exist in + * the target leaf/tree + */ + *cmpp = 1; + goto out; + } + + /* + * if hit, return index of the entry found, and + * if miss, where new entry with search key is + * to be inserted; + */ + out: + /* compute number of pages to split */ + if (flag & XT_INSERT) { + if (p->header.nextindex == /* little-endian */ + p->header.maxentry) + nsplit++; + else + nsplit = 0; + btstack->nsplit = nsplit; + } + + /* save search result */ + btsp = btstack->top; + btsp->bn = bn; + btsp->index = index; + btsp->mp = mp; + + /* update sequential access heuristics */ + jfs_ip->btindex = index; + + INCREMENT(xtStat.fastSearch); + return 0; + } + + /* well, ... full search now */ + binarySearch: + lim = le16_to_cpu(p->header.nextindex) - XTENTRYSTART; + + /* + * binary search with search key K on the current page + */ + for (base = XTENTRYSTART; lim; lim >>= 1) { + index = base + (lim >> 1); + + XT_CMP(cmp, xoff, &p->xad[index], t64); + if (cmp == 0) { + /* + * search hit + */ + /* search hit - leaf page: + * return the entry found + */ + if (p->header.flag & BT_LEAF) { + *cmpp = cmp; + + /* compute number of pages to split */ + if (flag & XT_INSERT) { + if (p->header.nextindex == + p->header.maxentry) + nsplit++; + else + nsplit = 0; + btstack->nsplit = nsplit; + } + + /* save search result */ + btsp = btstack->top; + btsp->bn = bn; + btsp->index = index; + btsp->mp = mp; + + /* init sequential access heuristics */ + btindex = jfs_ip->btindex; + if (index == btindex || + index == btindex + 1) + jfs_ip->btorder = BT_SEQUENTIAL; + else + jfs_ip->btorder = BT_RANDOM; + jfs_ip->btindex = index; + + return 0; + } + + /* search hit - internal page: + * descend/search its child page + */ + goto next; + } + + if (cmp > 0) { + base = index + 1; + --lim; + } + } + + /* + * search miss + * + * base is the smallest index with key (Kj) greater than + * search key (K) and may be zero or maxentry index. + */ + /* + * search miss - leaf page: + * + * return location of entry (base) where new entry with + * search key K is to be inserted. + */ + if (p->header.flag & BT_LEAF) { + *cmpp = cmp; + + /* compute number of pages to split */ + if (flag & XT_INSERT) { + if (p->header.nextindex == + p->header.maxentry) + nsplit++; + else + nsplit = 0; + btstack->nsplit = nsplit; + } + + /* save search result */ + btsp = btstack->top; + btsp->bn = bn; + btsp->index = base; + btsp->mp = mp; + + /* init sequential access heuristics */ + btindex = jfs_ip->btindex; + if (base == btindex || base == btindex + 1) + jfs_ip->btorder = BT_SEQUENTIAL; + else + jfs_ip->btorder = BT_RANDOM; + jfs_ip->btindex = base; + + return 0; + } + + /* + * search miss - non-leaf page: + * + * if base is non-zero, decrement base by one to get the parent + * entry of the child page to search. + */ + index = base ? base - 1 : base; + + /* + * go down to child page + */ + next: + /* update number of pages to split */ + if (p->header.nextindex == p->header.maxentry) + nsplit++; + else + nsplit = 0; + + /* push (bn, index) of the parent page/entry */ + BT_PUSH(btstack, bn, index); + + /* get the child page block number */ + bn = addressXAD(&p->xad[index]); + + /* unpin the parent page */ + XT_PUTPAGE(mp); + } +} + +/* + * xtInsert() + * + * function: + * + * parameter: + * tid - transaction id; + * ip - file object; + * xflag - extent flag (XAD_NOTRECORDED): + * xoff - extent offset; + * xlen - extent length; + * xaddrp - extent address pointer (in/out): + * if (*xaddrp) + * caller allocated data extent at *xaddrp; + * else + * allocate data extent and return its xaddr; + * flag - + * + * return: + */ +int xtInsert(tid_t tid, /* transaction id */ + struct inode *ip, int xflag, s64 xoff, s32 xlen, s64 * xaddrp, + int flag) +{ + int rc = 0; + s64 xaddr, hint; + metapage_t *mp; /* meta-page buffer */ + xtpage_t *p; /* base B+-tree index page */ + s64 bn; + int index, nextindex; + btstack_t btstack; /* traverse stack */ + xtsplit_t split; /* split information */ + xad_t *xad; + int cmp; + tlock_t *tlck; + xtlock_t *xtlck; + + jFYI(1, + ("xtInsert: nxoff:0x%lx nxlen:0x%x\n", (ulong) xoff, xlen)); + + /* + * search for the entry location at which to insert: + * + * xtFastSearch() and xtSearch() both returns (leaf page + * pinned, index at which to insert). + * n.b. xtSearch() may return index of maxentry of + * the full page. + */ + if ((rc = xtSearch(ip, xoff, &cmp, &btstack, XT_INSERT))) + return rc; + + /* retrieve search result */ + XT_GETSEARCH(ip, btstack.top, bn, mp, p, index); + + /* This test must follow XT_GETSEARCH since mp must be valid if + * we branch to out: */ + if (cmp == 0) { + rc = EEXIST; + goto out; + } + + /* + * allocate data extent requested + * + * allocation hint: last xad + */ + if ((xaddr = *xaddrp) == 0) { + if (index > XTENTRYSTART) { + xad = &p->xad[index - 1]; + hint = addressXAD(xad) + lengthXAD(xad) - 1; + } else + hint = 0; + if ((rc = dbAlloc(ip, hint, (s64) xlen, &xaddr))) + goto out; + } + + /* + * insert entry for new extent + */ + xflag |= XAD_NEW; + + /* + * if the leaf page is full, split the page and + * propagate up the router entry for the new page from split + * + * The xtSplitUp() will insert the entry and unpin the leaf page. + */ + nextindex = le16_to_cpu(p->header.nextindex); + if (nextindex == le16_to_cpu(p->header.maxentry)) { + split.mp = mp; + split.index = index; + split.flag = xflag; + split.off = xoff; + split.len = xlen; + split.addr = xaddr; + split.pxdlist = NULL; + if ((rc = xtSplitUp(tid, ip, &split, &btstack))) { + /* undo data extent allocation */ + if (*xaddrp == 0) + dbFree(ip, xaddr, (s64) xlen); + return rc; + } + + *xaddrp = xaddr; + return 0; + } + + /* + * insert the new entry into the leaf page + */ + /* + * acquire a transaction lock on the leaf page; + * + * action: xad insertion/extension; + */ + BT_MARK_DIRTY(mp, ip); + + /* if insert into middle, shift right remaining entries. */ + if (index < nextindex) + memmove(&p->xad[index + 1], &p->xad[index], + (nextindex - index) * sizeof(xad_t)); + + /* insert the new entry: mark the entry NEW */ + xad = &p->xad[index]; + XT_PUTENTRY(xad, xflag, xoff, xlen, xaddr); + + /* advance next available entry index */ + p->header.nextindex = + cpu_to_le16(le16_to_cpu(p->header.nextindex) + 1); + + /* Don't log it if there are no links to the file */ + if (!test_cflag(COMMIT_Nolink, ip)) { + tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW); + xtlck = (xtlock_t *) & tlck->lock; + xtlck->lwm.offset = + (xtlck->lwm.offset) ? min(index, + (int)xtlck->lwm.offset) : index; + xtlck->lwm.length = + le16_to_cpu(p->header.nextindex) - xtlck->lwm.offset; + } + + *xaddrp = xaddr; + + out: + /* unpin the leaf page */ + XT_PUTPAGE(mp); + + return rc; +} + + +/* + * xtSplitUp() + * + * function: + * split full pages as propagating insertion up the tree + * + * parameter: + * tid - transaction id; + * ip - file object; + * split - entry parameter descriptor; + * btstack - traverse stack from xtSearch() + * + * return: + */ +static int +xtSplitUp(tid_t tid, + struct inode *ip, xtsplit_t * split, btstack_t * btstack) +{ + int rc = 0; + metapage_t *smp; + xtpage_t *sp; /* split page */ + metapage_t *rmp; + s64 rbn; /* new right page block number */ + metapage_t *rcmp; + xtpage_t *rcp; /* right child page */ + s64 rcbn; /* right child page block number */ + int skip; /* index of entry of insertion */ + int nextindex; /* next available entry index of p */ + btframe_t *parent; /* parent page entry on traverse stack */ + xad_t *xad; + s64 xaddr; + int xlen; + int nsplit; /* number of pages split */ + pxdlist_t pxdlist; + pxd_t *pxd; + tlock_t *tlck; + xtlock_t *xtlck; + + smp = split->mp; + sp = XT_PAGE(ip, smp); + + /* is inode xtree root extension/inline EA area free ? */ + if ((sp->header.flag & BT_ROOT) && (!S_ISDIR(ip->i_mode)) && + (sp->header.maxentry < cpu_to_le16(XTROOTMAXSLOT)) && + (JFS_IP(ip)->mode2 & INLINEEA)) { + sp->header.maxentry = cpu_to_le16(XTROOTMAXSLOT); + JFS_IP(ip)->mode2 &= ~INLINEEA; + + BT_MARK_DIRTY(smp, ip); + /* + * acquire a transaction lock on the leaf page; + * + * action: xad insertion/extension; + */ + + /* if insert into middle, shift right remaining entries. */ + skip = split->index; + nextindex = le16_to_cpu(sp->header.nextindex); + if (skip < nextindex) + memmove(&sp->xad[skip + 1], &sp->xad[skip], + (nextindex - skip) * sizeof(xad_t)); + + /* insert the new entry: mark the entry NEW */ + xad = &sp->xad[skip]; + XT_PUTENTRY(xad, split->flag, split->off, split->len, + split->addr); + + /* advance next available entry index */ + sp->header.nextindex = + cpu_to_le16(le16_to_cpu(sp->header.nextindex) + 1); + + /* Don't log it if there are no links to the file */ + if (!test_cflag(COMMIT_Nolink, ip)) { + tlck = txLock(tid, ip, smp, tlckXTREE | tlckGROW); + xtlck = (xtlock_t *) & tlck->lock; + xtlck->lwm.offset = (xtlck->lwm.offset) ? + min(skip, (int)xtlck->lwm.offset) : skip; + xtlck->lwm.length = + le16_to_cpu(sp->header.nextindex) - + xtlck->lwm.offset; + } + + return 0; + } + + /* + * allocate new index blocks to cover index page split(s) + * + * allocation hint: ? + */ + if (split->pxdlist == NULL) { + nsplit = btstack->nsplit; + split->pxdlist = &pxdlist; + pxdlist.maxnpxd = pxdlist.npxd = 0; + pxd = &pxdlist.pxd[0]; + xlen = JFS_SBI(ip->i_sb)->nbperpage; + for (; nsplit > 0; nsplit--, pxd++) { + if ((rc = dbAlloc(ip, (s64) 0, (s64) xlen, &xaddr)) + == 0) { + PXDaddress(pxd, xaddr); + PXDlength(pxd, xlen); + + pxdlist.maxnpxd++; + + continue; + } + + /* undo allocation */ + + XT_PUTPAGE(smp); + return rc; + } + } + + /* + * Split leaf page into and a new right page . + * + * The split routines insert the new entry into the leaf page, + * and acquire txLock as appropriate. + * return pinned and its block number . + */ + rc = (sp->header.flag & BT_ROOT) ? + xtSplitRoot(tid, ip, split, &rmp) : + xtSplitPage(tid, ip, split, &rmp, &rbn); + if (rc) + return EIO; + + XT_PUTPAGE(smp); + + /* + * propagate up the router entry for the leaf page just split + * + * insert a router entry for the new page into the parent page, + * propagate the insert/split up the tree by walking back the stack + * of (bn of parent page, index of child page entry in parent page) + * that were traversed during the search for the page that split. + * + * the propagation of insert/split up the tree stops if the root + * splits or the page inserted into doesn't have to split to hold + * the new entry. + * + * the parent entry for the split page remains the same, and + * a new entry is inserted at its right with the first key and + * block number of the new right page. + * + * There are a maximum of 3 pages pinned at any time: + * right child, left parent and right parent (when the parent splits) + * to keep the child page pinned while working on the parent. + * make sure that all pins are released at exit. + */ + while ((parent = BT_POP(btstack)) != NULL) { + /* parent page specified by stack frame */ + + /* keep current child pages pinned */ + rcmp = rmp; + rcbn = rbn; + rcp = XT_PAGE(ip, rcmp); + + /* + * insert router entry in parent for new right child page + */ + /* get/pin the parent page */ + XT_GETPAGE(ip, parent->bn, smp, PSIZE, sp, rc); + if (rc) + goto errout2; + + /* + * The new key entry goes ONE AFTER the index of parent entry, + * because the split was to the right. + */ + skip = parent->index + 1; + + /* + * split or shift right remaining entries of the parent page + */ + nextindex = le16_to_cpu(sp->header.nextindex); + /* + * parent page is full - split the parent page + */ + if (nextindex == le16_to_cpu(sp->header.maxentry)) { + /* init for parent page split */ + split->mp = smp; + split->index = skip; /* index at insert */ + split->flag = XAD_NEW; + split->off = offsetXAD(&rcp->xad[XTENTRYSTART]); + split->len = JFS_SBI(ip->i_sb)->nbperpage; + split->addr = rcbn; + + /* unpin previous right child page */ + XT_PUTPAGE(rcmp); + + /* The split routines insert the new entry, + * and acquire txLock as appropriate. + * return pinned and its block number . + */ + rc = (sp->header.flag & BT_ROOT) ? + xtSplitRoot(tid, ip, split, &rmp) : + xtSplitPage(tid, ip, split, &rmp, &rbn); + if (rc) + goto errout1; + + XT_PUTPAGE(smp); + /* keep new child page pinned */ + } + /* + * parent page is not full - insert in parent page + */ + else { + /* + * insert router entry in parent for the right child + * page from the first entry of the right child page: + */ + /* + * acquire a transaction lock on the parent page; + * + * action: router xad insertion; + */ + BT_MARK_DIRTY(smp, ip); + + /* + * if insert into middle, shift right remaining entries + */ + if (skip < nextindex) + memmove(&sp->xad[skip + 1], &sp->xad[skip], + (nextindex - + skip) << L2XTSLOTSIZE); + + /* insert the router entry */ + xad = &sp->xad[skip]; + XT_PUTENTRY(xad, XAD_NEW, + offsetXAD(&rcp->xad[XTENTRYSTART]), + JFS_SBI(ip->i_sb)->nbperpage, rcbn); + + /* advance next available entry index. */ + sp->header.nextindex = + cpu_to_le16(le16_to_cpu(sp->header.nextindex) + + 1); + + /* Don't log it if there are no links to the file */ + if (!test_cflag(COMMIT_Nolink, ip)) { + tlck = txLock(tid, ip, smp, + tlckXTREE | tlckGROW); + xtlck = (xtlock_t *) & tlck->lock; + xtlck->lwm.offset = (xtlck->lwm.offset) ? + min(skip, (int)xtlck->lwm.offset) : skip; + xtlck->lwm.length = + le16_to_cpu(sp->header.nextindex) - + xtlck->lwm.offset; + } + + /* unpin parent page */ + XT_PUTPAGE(smp); + + /* exit propagate up */ + break; + } + } + + /* unpin current right page */ + XT_PUTPAGE(rmp); + + return 0; + + /* + * If something fails in the above loop we were already walking back + * up the tree and the tree is now inconsistent. + * release all pages we're holding. + */ + errout1: + XT_PUTPAGE(smp); + + errout2: + XT_PUTPAGE(rcmp); + + return rc; +} + + +/* + * xtSplitPage() + * + * function: + * split a full non-root page into + * original/split/left page and new right page + * i.e., the original/split page remains as left page. + * + * parameter: + * int tid, + * struct inode *ip, + * xtsplit_t *split, + * metapage_t **rmpp, + * u64 *rbnp, + * + * return: + * Pointer to page in which to insert or NULL on error. + */ +static int +xtSplitPage(tid_t tid, struct inode *ip, + xtsplit_t * split, metapage_t ** rmpp, s64 * rbnp) +{ + int rc = 0; + metapage_t *smp; + xtpage_t *sp; + metapage_t *rmp; + xtpage_t *rp; /* new right page allocated */ + s64 rbn; /* new right page block number */ + metapage_t *mp; + xtpage_t *p; + s64 nextbn; + int skip, maxentry, middle, righthalf, n; + xad_t *xad; + pxdlist_t *pxdlist; + pxd_t *pxd; + tlock_t *tlck; + xtlock_t *sxtlck = 0, *rxtlck = 0; + + smp = split->mp; + sp = XT_PAGE(ip, smp); + + INCREMENT(xtStat.split); + + /* + * allocate the new right page for the split + */ + pxdlist = split->pxdlist; + pxd = &pxdlist->pxd[pxdlist->npxd]; + pxdlist->npxd++; + rbn = addressPXD(pxd); + rmp = get_metapage(ip, rbn, PSIZE, 1); + if (rmp == NULL) + return EIO; + + jEVENT(0, + ("xtSplitPage: ip:0x%p smp:0x%p rmp:0x%p\n", ip, smp, rmp)); + + BT_MARK_DIRTY(rmp, ip); + /* + * action: new page; + */ + + rp = (xtpage_t *) rmp->data; + rp->header.self = *pxd; + rp->header.flag = sp->header.flag & BT_TYPE; + rp->header.maxentry = sp->header.maxentry; /* little-endian */ + rp->header.nextindex = cpu_to_le16(XTENTRYSTART); + + BT_MARK_DIRTY(smp, ip); + /* Don't log it if there are no links to the file */ + if (!test_cflag(COMMIT_Nolink, ip)) { + /* + * acquire a transaction lock on the new right page; + */ + tlck = txLock(tid, ip, rmp, tlckXTREE | tlckNEW); + rxtlck = (xtlock_t *) & tlck->lock; + rxtlck->lwm.offset = XTENTRYSTART; + /* + * acquire a transaction lock on the split page + */ + tlck = txLock(tid, ip, smp, tlckXTREE | tlckGROW); + sxtlck = (xtlock_t *) & tlck->lock; + } + + /* + * initialize/update sibling pointers of and + */ + nextbn = le64_to_cpu(sp->header.next); + rp->header.next = cpu_to_le64(nextbn); + rp->header.prev = cpu_to_le64(addressPXD(&sp->header.self)); + sp->header.next = cpu_to_le64(rbn); + + skip = split->index; + + /* + * sequential append at tail (after last entry of last page) + * + * if splitting the last page on a level because of appending + * a entry to it (skip is maxentry), it's likely that the access is + * sequential. adding an empty page on the side of the level is less + * work and can push the fill factor much higher than normal. + * if we're wrong it's no big deal - we will do the split the right + * way next time. + * (it may look like it's equally easy to do a similar hack for + * reverse sorted data, that is, split the tree left, but it's not. + * Be my guest.) + */ + if (nextbn == 0 && skip == le16_to_cpu(sp->header.maxentry)) { + /* + * acquire a transaction lock on the new/right page; + * + * action: xad insertion; + */ + /* insert entry at the first entry of the new right page */ + xad = &rp->xad[XTENTRYSTART]; + XT_PUTENTRY(xad, split->flag, split->off, split->len, + split->addr); + + rp->header.nextindex = cpu_to_le16(XTENTRYSTART + 1); + + if (!test_cflag(COMMIT_Nolink, ip)) { + /* rxtlck->lwm.offset = XTENTRYSTART; */ + rxtlck->lwm.length = 1; + } + + *rmpp = rmp; + *rbnp = rbn; + + ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd)); + + jEVENT(0, ("xtSplitPage: sp:0x%p rp:0x%p\n", sp, rp)); + return 0; + } + + /* + * non-sequential insert (at possibly middle page) + */ + + /* + * update previous pointer of old next/right page of + */ + if (nextbn != 0) { + XT_GETPAGE(ip, nextbn, mp, PSIZE, p, rc); + if (rc) { + XT_PUTPAGE(rmp); + return rc; + } + + BT_MARK_DIRTY(mp, ip); + /* + * acquire a transaction lock on the next page; + * + * action:sibling pointer update; + */ + if (!test_cflag(COMMIT_Nolink, ip)) + tlck = txLock(tid, ip, mp, tlckXTREE | tlckRELINK); + + p->header.prev = cpu_to_le64(rbn); + + /* sibling page may have been updated previously, or + * it may be updated later; + */ + + XT_PUTPAGE(mp); + } + + /* + * split the data between the split and new/right pages + */ + maxentry = le16_to_cpu(sp->header.maxentry); + middle = maxentry >> 1; + righthalf = maxentry - middle; + + /* + * skip index in old split/left page - insert into left page: + */ + if (skip <= middle) { + /* move right half of split page to the new right page */ + memmove(&rp->xad[XTENTRYSTART], &sp->xad[middle], + righthalf << L2XTSLOTSIZE); + + /* shift right tail of left half to make room for new entry */ + if (skip < middle) + memmove(&sp->xad[skip + 1], &sp->xad[skip], + (middle - skip) << L2XTSLOTSIZE); + + /* insert new entry */ + xad = &sp->xad[skip]; + XT_PUTENTRY(xad, split->flag, split->off, split->len, + split->addr); + + /* update page header */ + sp->header.nextindex = cpu_to_le16(middle + 1); + if (!test_cflag(COMMIT_Nolink, ip)) { + sxtlck->lwm.offset = (sxtlck->lwm.offset) ? + min(skip, (int)sxtlck->lwm.offset) : skip; + } + + rp->header.nextindex = + cpu_to_le16(XTENTRYSTART + righthalf); + } + /* + * skip index in new right page - insert into right page: + */ + else { + /* move left head of right half to right page */ + n = skip - middle; + memmove(&rp->xad[XTENTRYSTART], &sp->xad[middle], + n << L2XTSLOTSIZE); + + /* insert new entry */ + n += XTENTRYSTART; + xad = &rp->xad[n]; + XT_PUTENTRY(xad, split->flag, split->off, split->len, + split->addr); + + /* move right tail of right half to right page */ + if (skip < maxentry) + memmove(&rp->xad[n + 1], &sp->xad[skip], + (maxentry - skip) << L2XTSLOTSIZE); + + /* update page header */ + sp->header.nextindex = cpu_to_le16(middle); + if (!test_cflag(COMMIT_Nolink, ip)) { + sxtlck->lwm.offset = (sxtlck->lwm.offset) ? + min(middle, (int)sxtlck->lwm.offset) : middle; + } + + rp->header.nextindex = cpu_to_le16(XTENTRYSTART + + righthalf + 1); + } + + if (!test_cflag(COMMIT_Nolink, ip)) { + sxtlck->lwm.length = le16_to_cpu(sp->header.nextindex) - + sxtlck->lwm.offset; + + /* rxtlck->lwm.offset = XTENTRYSTART; */ + rxtlck->lwm.length = le16_to_cpu(rp->header.nextindex) - + XTENTRYSTART; + } + + *rmpp = rmp; + *rbnp = rbn; + + ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd)); + + jEVENT(0, ("xtSplitPage: sp:0x%p rp:0x%p\n", sp, rp)); + return rc; +} + + +/* + * xtSplitRoot() + * + * function: + * split the full root page into + * original/root/split page and new right page + * i.e., root remains fixed in tree anchor (inode) and + * the root is copied to a single new right child page + * since root page << non-root page, and + * the split root page contains a single entry for the + * new right child page. + * + * parameter: + * int tid, + * struct inode *ip, + * xtsplit_t *split, + * metapage_t **rmpp) + * + * return: + * Pointer to page in which to insert or NULL on error. + */ +static int +xtSplitRoot(tid_t tid, + struct inode *ip, xtsplit_t * split, metapage_t ** rmpp) +{ + xtpage_t *sp; + metapage_t *rmp; + xtpage_t *rp; + s64 rbn; + int skip, nextindex; + xad_t *xad; + pxd_t *pxd; + pxdlist_t *pxdlist; + tlock_t *tlck; + xtlock_t *xtlck; + + sp = &JFS_IP(ip)->i_xtroot; + + INCREMENT(xtStat.split); + + /* + * allocate a single (right) child page + */ + pxdlist = split->pxdlist; + pxd = &pxdlist->pxd[pxdlist->npxd]; + pxdlist->npxd++; + rbn = addressPXD(pxd); + rmp = get_metapage(ip, rbn, PSIZE, 1); + if (rmp == NULL) + return EIO; + + jEVENT(0, ("xtSplitRoot: ip:0x%p rmp:0x%p\n", ip, rmp)); + + /* + * acquire a transaction lock on the new right page; + * + * action: new page; + */ + BT_MARK_DIRTY(rmp, ip); + + rp = (xtpage_t *) rmp->data; + rp->header.flag = + (sp->header.flag & BT_LEAF) ? BT_LEAF : BT_INTERNAL; + rp->header.self = *pxd; + rp->header.nextindex = cpu_to_le16(XTENTRYSTART); + rp->header.maxentry = cpu_to_le16(PSIZE >> L2XTSLOTSIZE); + + /* initialize sibling pointers */ + rp->header.next = 0; + rp->header.prev = 0; + + /* + * copy the in-line root page into new right page extent + */ + nextindex = le16_to_cpu(sp->header.maxentry); + memmove(&rp->xad[XTENTRYSTART], &sp->xad[XTENTRYSTART], + (nextindex - XTENTRYSTART) << L2XTSLOTSIZE); + + /* + * insert the new entry into the new right/child page + * (skip index in the new right page will not change) + */ + skip = split->index; + /* if insert into middle, shift right remaining entries */ + if (skip != nextindex) + memmove(&rp->xad[skip + 1], &rp->xad[skip], + (nextindex - skip) * sizeof(xad_t)); + + xad = &rp->xad[skip]; + XT_PUTENTRY(xad, split->flag, split->off, split->len, split->addr); + + /* update page header */ + rp->header.nextindex = cpu_to_le16(nextindex + 1); + + if (!test_cflag(COMMIT_Nolink, ip)) { + tlck = txLock(tid, ip, rmp, tlckXTREE | tlckNEW); + xtlck = (xtlock_t *) & tlck->lock; + xtlck->lwm.offset = XTENTRYSTART; + xtlck->lwm.length = le16_to_cpu(rp->header.nextindex) - + XTENTRYSTART; + } + + /* + * reset the root + * + * init root with the single entry for the new right page + * set the 1st entry offset to 0, which force the left-most key + * at any level of the tree to be less than any search key. + */ + /* + * acquire a transaction lock on the root page (in-memory inode); + * + * action: root split; + */ + BT_MARK_DIRTY(split->mp, ip); + + xad = &sp->xad[XTENTRYSTART]; + XT_PUTENTRY(xad, XAD_NEW, 0, JFS_SBI(ip->i_sb)->nbperpage, rbn); + + /* update page header of root */ + sp->header.flag &= ~BT_LEAF; + sp->header.flag |= BT_INTERNAL; + + sp->header.nextindex = cpu_to_le16(XTENTRYSTART + 1); + + if (!test_cflag(COMMIT_Nolink, ip)) { + tlck = txLock(tid, ip, split->mp, tlckXTREE | tlckGROW); + xtlck = (xtlock_t *) & tlck->lock; + xtlck->lwm.offset = XTENTRYSTART; + xtlck->lwm.length = 1; + } + + *rmpp = rmp; + + ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd)); + + jEVENT(0, ("xtSplitRoot: sp:0x%p rp:0x%p\n", sp, rp)); + return 0; +} + + +/* + * xtExtend() + * + * function: extend in-place; + * + * note: existing extent may or may not have been committed. + * caller is responsible for pager buffer cache update, and + * working block allocation map update; + * update pmap: alloc whole extended extent; + */ +int xtExtend(tid_t tid, /* transaction id */ + struct inode *ip, s64 xoff, /* delta extent offset */ + s32 xlen, /* delta extent length */ + int flag) +{ + int rc = 0; + int cmp; + metapage_t *mp; /* meta-page buffer */ + xtpage_t *p; /* base B+-tree index page */ + s64 bn; + int index, nextindex, len; + btstack_t btstack; /* traverse stack */ + xtsplit_t split; /* split information */ + xad_t *xad; + s64 xaddr; + tlock_t *tlck; + xtlock_t *xtlck = 0; + int rootsplit = 0; + + jFYI(1, + ("xtExtend: nxoff:0x%lx nxlen:0x%x\n", (ulong) xoff, xlen)); + + /* there must exist extent to be extended */ + if ((rc = xtSearch(ip, xoff - 1, &cmp, &btstack, XT_INSERT))) + return rc; + assert(cmp == 0); + + /* retrieve search result */ + XT_GETSEARCH(ip, btstack.top, bn, mp, p, index); + + /* extension must be contiguous */ + xad = &p->xad[index]; + jFYI(0, ("xtExtend: xoff:0x%lx xlen:0x%x xaddr:0x%lx\n", + (ulong) offsetXAD(xad), lengthXAD(xad), + (ulong) addressXAD(xad))); + assert((offsetXAD(xad) + lengthXAD(xad)) == xoff); + + /* + * acquire a transaction lock on the leaf page; + * + * action: xad insertion/extension; + */ + BT_MARK_DIRTY(mp, ip); + if (!test_cflag(COMMIT_Nolink, ip)) { + tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW); + xtlck = (xtlock_t *) & tlck->lock; + } + + /* extend will overflow extent ? */ + xlen = lengthXAD(xad) + xlen; + if ((len = xlen - MAXXLEN) <= 0) + goto extendOld; + + /* + * extent overflow: insert entry for new extent + */ +//insertNew: + xoff = offsetXAD(xad) + MAXXLEN; + xaddr = addressXAD(xad) + MAXXLEN; + nextindex = le16_to_cpu(p->header.nextindex); + + /* + * if the leaf page is full, insert the new entry and + * propagate up the router entry for the new page from split + * + * The xtSplitUp() will insert the entry and unpin the leaf page. + */ + if (nextindex == le16_to_cpu(p->header.maxentry)) { + rootsplit = p->header.flag & BT_ROOT; + + /* xtSpliUp() unpins leaf pages */ + split.mp = mp; + split.index = index + 1; + split.flag = XAD_NEW; + split.off = xoff; /* split offset */ + split.len = len; + split.addr = xaddr; + split.pxdlist = NULL; + if ((rc = xtSplitUp(tid, ip, &split, &btstack))) + return rc; + + /* + * if leaf root has been split, original root has been + * copied to new child page, i.e., original entry now + * resides on the new child page; + */ + if (rootsplit) { + if (p->header.nextindex == + cpu_to_le16(XTENTRYSTART + 1)) { + xad = &p->xad[XTENTRYSTART]; + bn = addressXAD(xad); + + /* get new child page */ + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + + BT_MARK_DIRTY(mp, ip); + if (!test_cflag(COMMIT_Nolink, ip)) { + tlck = txLock(tid, ip, mp, + tlckXTREE | + tlckGROW); + xtlck = (xtlock_t *) & tlck->lock; + } + } + } else + /* get back old page */ + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + } + /* + * insert the new entry into the leaf page + */ + else { + /* insert the new entry: mark the entry NEW */ + xad = &p->xad[index + 1]; + XT_PUTENTRY(xad, XAD_NEW, xoff, len, xaddr); + + /* advance next available entry index */ + p->header.nextindex = + cpu_to_le16(le16_to_cpu(p->header.nextindex) + 1); + } + + /* get back old entry */ + xad = &p->xad[index]; + xlen = MAXXLEN; + + /* + * extend old extent + */ + extendOld: + XADlength(xad, xlen); + if (!(xad->flag & XAD_NEW)) + xad->flag |= XAD_EXTENDED; + + if (!test_cflag(COMMIT_Nolink, ip)) { + xtlck->lwm.offset = + (xtlck->lwm.offset) ? min(index, + (int)xtlck->lwm.offset) : index; + xtlck->lwm.length = + le16_to_cpu(p->header.nextindex) - xtlck->lwm.offset; + } + + /* unpin the leaf page */ + XT_PUTPAGE(mp); + + return rc; +} + + +/* + * xtTailgate() + * + * function: split existing 'tail' extent + * (split offset >= start offset of tail extent), and + * relocate and extend the split tail half; + * + * note: existing extent may or may not have been committed. + * caller is responsible for pager buffer cache update, and + * working block allocation map update; + * update pmap: free old split tail extent, alloc new extent; + */ +int xtTailgate(tid_t tid, /* transaction id */ + struct inode *ip, s64 xoff, /* split/new extent offset */ + s32 xlen, /* new extent length */ + s64 xaddr, /* new extent address */ + int flag) +{ + int rc = 0; + int cmp; + metapage_t *mp; /* meta-page buffer */ + xtpage_t *p; /* base B+-tree index page */ + s64 bn; + int index, nextindex, llen, rlen; + btstack_t btstack; /* traverse stack */ + xtsplit_t split; /* split information */ + xad_t *xad; + tlock_t *tlck; + xtlock_t *xtlck = 0; + tlock_t *mtlck; + maplock_t *pxdlock; + int rootsplit = 0; + +/* +printf("xtTailgate: nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n", + (ulong)xoff, xlen, (ulong)xaddr); +*/ + + /* there must exist extent to be tailgated */ + if ((rc = xtSearch(ip, xoff, &cmp, &btstack, XT_INSERT))) + return rc; + assert(cmp == 0); + + /* retrieve search result */ + XT_GETSEARCH(ip, btstack.top, bn, mp, p, index); + + /* entry found must be last entry */ + nextindex = le16_to_cpu(p->header.nextindex); + assert(index == nextindex - 1); + + BT_MARK_DIRTY(mp, ip); + /* + * acquire tlock of the leaf page containing original entry + */ + if (!test_cflag(COMMIT_Nolink, ip)) { + tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW); + xtlck = (xtlock_t *) & tlck->lock; + } + + /* completely replace extent ? */ + xad = &p->xad[index]; +/* +printf("xtTailgate: xoff:0x%lx xlen:0x%x xaddr:0x%lx\n", + (ulong)offsetXAD(xad), lengthXAD(xad), (ulong)addressXAD(xad)); +*/ + if ((llen = xoff - offsetXAD(xad)) == 0) + goto updateOld; + + /* + * partially replace extent: insert entry for new extent + */ +//insertNew: + /* + * if the leaf page is full, insert the new entry and + * propagate up the router entry for the new page from split + * + * The xtSplitUp() will insert the entry and unpin the leaf page. + */ + if (nextindex == le16_to_cpu(p->header.maxentry)) { + rootsplit = p->header.flag & BT_ROOT; + + /* xtSpliUp() unpins leaf pages */ + split.mp = mp; + split.index = index + 1; + split.flag = XAD_NEW; + split.off = xoff; /* split offset */ + split.len = xlen; + split.addr = xaddr; + split.pxdlist = NULL; + if ((rc = xtSplitUp(tid, ip, &split, &btstack))) + return rc; + + /* + * if leaf root has been split, original root has been + * copied to new child page, i.e., original entry now + * resides on the new child page; + */ + if (rootsplit) { + if (p->header.nextindex == + cpu_to_le16(XTENTRYSTART + 1)) { + xad = &p->xad[XTENTRYSTART]; + bn = addressXAD(xad); + + /* get new child page */ + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + + BT_MARK_DIRTY(mp, ip); + if (!test_cflag(COMMIT_Nolink, ip)) { + tlck = txLock(tid, ip, mp, + tlckXTREE | + tlckGROW); + xtlck = (xtlock_t *) & tlck->lock; + } + } + } else + /* get back old page */ + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + } + /* + * insert the new entry into the leaf page + */ + else { + /* insert the new entry: mark the entry NEW */ + xad = &p->xad[index + 1]; + XT_PUTENTRY(xad, XAD_NEW, xoff, xlen, xaddr); + + /* advance next available entry index */ + p->header.nextindex = + cpu_to_le16(le16_to_cpu(p->header.nextindex) + 1); + } + + /* get back old XAD */ + xad = &p->xad[index]; + + /* + * truncate/relocate old extent at split offset + */ + updateOld: + /* update dmap for old/committed/truncated extent */ + rlen = lengthXAD(xad) - llen; + if (!(xad->flag & XAD_NEW)) { + /* free from PWMAP at commit */ + if (!test_cflag(COMMIT_Nolink, ip)) { + mtlck = txMaplock(tid, ip, tlckMAP); + pxdlock = (maplock_t *) & mtlck->lock; + pxdlock->flag = mlckFREEPXD; + PXDaddress(&pxdlock->pxd, addressXAD(xad) + llen); + PXDlength(&pxdlock->pxd, rlen); + pxdlock->index = 1; + } + jEVENT(0, + ("xtTailgate: free extent xaddr:0x%lx xlen:0x%x\n", + (ulong) addressPXD(&pxdlock->pxd), + lengthPXD(&pxdlock->pxd))); + } else + /* free from WMAP */ + dbFree(ip, addressXAD(xad) + llen, (s64) rlen); + + if (llen) + /* truncate */ + XADlength(xad, llen); + else + /* replace */ + XT_PUTENTRY(xad, XAD_NEW, xoff, xlen, xaddr); + + if (!test_cflag(COMMIT_Nolink, ip)) { + xtlck->lwm.offset = (xtlck->lwm.offset) ? + min(index, (int)xtlck->lwm.offset) : index; + xtlck->lwm.length = le16_to_cpu(p->header.nextindex) - + xtlck->lwm.offset; + } + + /* unpin the leaf page */ + XT_PUTPAGE(mp); + + return rc; +} + + +/* + * xtUpdate() + * + * function: update XAD; + * + * update extent for allocated_but_not_recorded or + * compressed extent; + * + * parameter: + * nxad - new XAD; + * logical extent of the specified XAD must be completely + * contained by an existing XAD; + */ +int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad) +{ /* new XAD */ + int rc = 0; + int cmp; + metapage_t *mp; /* meta-page buffer */ + xtpage_t *p; /* base B+-tree index page */ + s64 bn; + int index0, index, newindex, nextindex; + btstack_t btstack; /* traverse stack */ + xtsplit_t split; /* split information */ + xad_t *xad, *lxad, *rxad; + int xflag; + s64 nxoff, xoff; + int nxlen, xlen, lxlen, rxlen; + s64 nxaddr, xaddr; + tlock_t *tlck; + xtlock_t *xtlck = 0; + int rootsplit = 0, newpage = 0; + + /* there must exist extent to be tailgated */ + nxoff = offsetXAD(nxad); + nxlen = lengthXAD(nxad); + nxaddr = addressXAD(nxad); +/* +printf("xtUpdate: nxflag:0x%x nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n", + nxad->flag, (ulong)nxoff, nxlen, (ulong)nxaddr); +*/ + if ((rc = xtSearch(ip, nxoff, &cmp, &btstack, XT_INSERT))) + return rc; + assert(cmp == 0); + + /* retrieve search result */ + XT_GETSEARCH(ip, btstack.top, bn, mp, p, index0); + + BT_MARK_DIRTY(mp, ip); + /* + * acquire tlock of the leaf page containing original entry + */ + if (!test_cflag(COMMIT_Nolink, ip)) { + tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW); + xtlck = (xtlock_t *) & tlck->lock; + } + + xad = &p->xad[index0]; + xflag = xad->flag; + xoff = offsetXAD(xad); + xlen = lengthXAD(xad); + xaddr = addressXAD(xad); +/* +printf("xtUpdate: xflag:0x%x xoff:0x%lx xlen:0x%x xaddr:0x%lx\n", + xflag, (ulong)xoff, xlen, (ulong)xaddr); +*/ + + /* nXAD must be completely contained within XAD */ + assert(xoff <= nxoff); + assert(nxoff + nxlen <= xoff + xlen); + + index = index0; + newindex = index + 1; + nextindex = le16_to_cpu(p->header.nextindex); + +#ifdef _JFS_WIP_NOCOALESCE + if (xoff < nxoff) + goto updateRight; + + /* + * replace XAD with nXAD + */ + replace: /* (nxoff == xoff) */ + if (nxlen == xlen) { + /* replace XAD with nXAD:recorded */ + *xad = *nxad; + xad->flag = xflag & ~XAD_NOTRECORDED; + + goto out; + } else /* (nxlen < xlen) */ + goto updateLeft; +#endif /* _JFS_WIP_NOCOALESCE */ + +/* #ifdef _JFS_WIP_COALESCE */ + if (xoff < nxoff) + goto coalesceRight; + + /* + * coalesce with left XAD + */ +//coalesceLeft: /* (xoff == nxoff) */ + /* is XAD first entry of page ? */ + if (index == XTENTRYSTART) + goto replace; + + /* is nXAD logically and physically contiguous with lXAD ? */ + lxad = &p->xad[index - 1]; + lxlen = lengthXAD(lxad); + if (!(lxad->flag & XAD_NOTRECORDED) && + (nxoff == offsetXAD(lxad) + lxlen) && + (nxaddr == addressXAD(lxad) + lxlen) && + (lxlen + nxlen < MAXXLEN)) { + /* extend right lXAD */ + index0 = index - 1; + XADlength(lxad, lxlen + nxlen); + + /* If we just merged two extents together, need to make sure the + * right extent gets logged. If the left one is marked XAD_NEW, + * then we know it will be logged. Otherwise, mark as + * XAD_EXTENDED + */ + if (!(lxad->flag & XAD_NEW)) + lxad->flag |= XAD_EXTENDED; + + if (xlen > nxlen) { + /* truncate XAD */ + XADoffset(xad, xoff + nxlen); + XADlength(xad, xlen - nxlen); + XADaddress(xad, xaddr + nxlen); + goto out; + } else { /* (xlen == nxlen) */ + + /* remove XAD */ + if (index < nextindex - 1) + memmove(&p->xad[index], &p->xad[index + 1], + (nextindex - index - + 1) << L2XTSLOTSIZE); + + p->header.nextindex = + cpu_to_le16(le16_to_cpu(p->header.nextindex) - + 1); + + index = index0; + newindex = index + 1; + nextindex = le16_to_cpu(p->header.nextindex); + xoff = nxoff = offsetXAD(lxad); + xlen = nxlen = lxlen + nxlen; + xaddr = nxaddr = addressXAD(lxad); + goto coalesceRight; + } + } + + /* + * replace XAD with nXAD + */ + replace: /* (nxoff == xoff) */ + if (nxlen == xlen) { + /* replace XAD with nXAD:recorded */ + *xad = *nxad; + xad->flag = xflag & ~XAD_NOTRECORDED; + + goto coalesceRight; + } else /* (nxlen < xlen) */ + goto updateLeft; + + /* + * coalesce with right XAD + */ + coalesceRight: /* (xoff <= nxoff) */ + /* is XAD last entry of page ? */ + if (newindex == nextindex) { + if (xoff == nxoff) + goto out; + goto updateRight; + } + + /* is nXAD logically and physically contiguous with rXAD ? */ + rxad = &p->xad[index + 1]; + rxlen = lengthXAD(rxad); + if (!(rxad->flag & XAD_NOTRECORDED) && + (nxoff + nxlen == offsetXAD(rxad)) && + (nxaddr + nxlen == addressXAD(rxad)) && + (rxlen + nxlen < MAXXLEN)) { + /* extend left rXAD */ + XADoffset(rxad, nxoff); + XADlength(rxad, rxlen + nxlen); + XADaddress(rxad, nxaddr); + + /* If we just merged two extents together, need to make sure + * the left extent gets logged. If the right one is marked + * XAD_NEW, then we know it will be logged. Otherwise, mark as + * XAD_EXTENDED + */ + if (!(rxad->flag & XAD_NEW)) + rxad->flag |= XAD_EXTENDED; + + if (xlen > nxlen) + /* truncate XAD */ + XADlength(xad, xlen - nxlen); + else { /* (xlen == nxlen) */ + + /* remove XAD */ + memmove(&p->xad[index], &p->xad[index + 1], + (nextindex - index - 1) << L2XTSLOTSIZE); + + p->header.nextindex = + cpu_to_le16(le16_to_cpu(p->header.nextindex) - + 1); + } + + goto out; + } else if (xoff == nxoff) + goto out; + + assert(xoff < nxoff); +/* #endif _JFS_WIP_COALESCE */ + + /* + * split XAD into (lXAD, nXAD): + * + * |---nXAD---> + * --|----------XAD----------|-- + * |-lXAD-| + */ + updateRight: /* (xoff < nxoff) */ + /* truncate old XAD as lXAD:not_recorded */ + xad = &p->xad[index]; + XADlength(xad, nxoff - xoff); + + /* insert nXAD:recorded */ + if (nextindex == le16_to_cpu(p->header.maxentry)) { +/* +printf("xtUpdate.updateRight.split p:0x%p\n", p); +*/ + rootsplit = p->header.flag & BT_ROOT; + + /* xtSpliUp() unpins leaf pages */ + split.mp = mp; + split.index = newindex; + split.flag = xflag & ~XAD_NOTRECORDED; + split.off = nxoff; + split.len = nxlen; + split.addr = nxaddr; + split.pxdlist = NULL; + if ((rc = xtSplitUp(tid, ip, &split, &btstack))) + return rc; + + /* + * if leaf root has been split, original root has been + * copied to new child page, i.e., original entry now + * resides on the new child page; + */ + if (rootsplit) { + if (p->header.nextindex == + cpu_to_le16(XTENTRYSTART + 1)) { + xad = &p->xad[XTENTRYSTART]; + bn = addressXAD(xad); + + /* get new child page */ + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + + BT_MARK_DIRTY(mp, ip); + if (!test_cflag(COMMIT_Nolink, ip)) { + tlck = txLock(tid, ip, mp, + tlckXTREE | + tlckGROW); + xtlck = (xtlock_t *) & tlck->lock; + } + } + } else { + /* get back old page */ + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + + /* is nXAD on new page ? */ + if (newindex > + (le16_to_cpu(p->header.maxentry) >> 1)) { + newindex = + newindex - + le16_to_cpu(p->header.nextindex) + + XTENTRYSTART; + newpage = 1; + } + } + } else { + /* if insert into middle, shift right remaining entries */ + if (newindex < nextindex) + memmove(&p->xad[newindex + 1], &p->xad[newindex], + (nextindex - newindex) << L2XTSLOTSIZE); + + /* insert the entry */ + xad = &p->xad[newindex]; + *xad = *nxad; + xad->flag = xflag & ~XAD_NOTRECORDED; + + /* advance next available entry index. */ + p->header.nextindex = + cpu_to_le16(le16_to_cpu(p->header.nextindex) + 1); + } + + /* + * does nXAD force 3-way split ? + * + * |---nXAD--->| + * --|----------XAD-------------|-- + * |-lXAD-| |-rXAD -| + */ + if (nxoff + nxlen == xoff + xlen) + goto out; + + /* reorient nXAD as XAD for further split XAD into (nXAD, rXAD) */ + if (newpage) { + /* close out old page */ + if (!test_cflag(COMMIT_Nolink, ip)) { + xtlck->lwm.offset = (xtlck->lwm.offset) ? + min(index0, (int)xtlck->lwm.offset) : index0; + xtlck->lwm.length = + le16_to_cpu(p->header.nextindex) - + xtlck->lwm.offset; + } + + bn = le64_to_cpu(p->header.next); + XT_PUTPAGE(mp); + + /* get new right page */ + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + + BT_MARK_DIRTY(mp, ip); + if (!test_cflag(COMMIT_Nolink, ip)) { + tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW); + xtlck = (xtlock_t *) & tlck->lock; + } + + index0 = index = newindex; + } else + index++; + + newindex = index + 1; + nextindex = le16_to_cpu(p->header.nextindex); + xlen = xlen - (nxoff - xoff); + xoff = nxoff; + xaddr = nxaddr; + + /* recompute split pages */ + if (nextindex == le16_to_cpu(p->header.maxentry)) { +/* +printf("xtUpdate: updateRight+Left recompute split pages: p:0x%p\n", p); +*/ + XT_PUTPAGE(mp); + + if ((rc = xtSearch(ip, nxoff, &cmp, &btstack, XT_INSERT))) + return rc; + assert(cmp == 0); + + /* retrieve search result */ + XT_GETSEARCH(ip, btstack.top, bn, mp, p, index0); + assert(index0 == index); + } + + /* + * split XAD into (nXAD, rXAD) + * + * ---nXAD---| + * --|----------XAD----------|-- + * |-rXAD-| + */ + updateLeft: /* (nxoff == xoff) && (nxlen < xlen) */ + /* update old XAD with nXAD:recorded */ + xad = &p->xad[index]; + *xad = *nxad; + xad->flag = xflag & ~XAD_NOTRECORDED; + + /* insert rXAD:not_recorded */ + xoff = xoff + nxlen; + xlen = xlen - nxlen; + xaddr = xaddr + nxlen; + if (nextindex == le16_to_cpu(p->header.maxentry)) { + rootsplit = p->header.flag & BT_ROOT; + +/* +printf("xtUpdate.updateLeft.split p:0x%p\n", p); +*/ + /* xtSpliUp() unpins leaf pages */ + split.mp = mp; + split.index = newindex; + split.flag = xflag; + split.off = xoff; + split.len = xlen; + split.addr = xaddr; + split.pxdlist = NULL; + if ((rc = xtSplitUp(tid, ip, &split, &btstack))) + return rc; + + /* + * if leaf root has been split, original root has been + * copied to new child page, i.e., original entry now + * resides on the new child page; + */ + if (rootsplit) { + if (p->header.nextindex == + cpu_to_le16(XTENTRYSTART + 1)) { + xad = &p->xad[XTENTRYSTART]; + bn = addressXAD(xad); + + /* get new child page */ + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + + BT_MARK_DIRTY(mp, ip); + if (!test_cflag(COMMIT_Nolink, ip)) { + tlck = txLock(tid, ip, mp, + tlckXTREE | + tlckGROW); + xtlck = (xtlock_t *) & tlck->lock; + } + } + } else + /* get back old page */ + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + } else { + /* if insert into middle, shift right remaining entries */ + if (newindex < nextindex) + memmove(&p->xad[newindex + 1], &p->xad[newindex], + (nextindex - newindex) << L2XTSLOTSIZE); + + /* insert the entry */ + xad = &p->xad[newindex]; + XT_PUTENTRY(xad, xflag, xoff, xlen, xaddr); + + /* advance next available entry index. */ + p->header.nextindex = + cpu_to_le16(le16_to_cpu(p->header.nextindex) + 1); + } + + out: + if (!test_cflag(COMMIT_Nolink, ip)) { + xtlck->lwm.offset = (xtlck->lwm.offset) ? + min(index0, (int)xtlck->lwm.offset) : index0; + xtlck->lwm.length = le16_to_cpu(p->header.nextindex) - + xtlck->lwm.offset; + } + + /* unpin the leaf page */ + XT_PUTPAGE(mp); + + return rc; +} + + +#ifdef _STILL_TO_PORT +/* + * xtAppend() + * + * function: grow in append mode from contiguous region specified ; + * + * parameter: + * tid - transaction id; + * ip - file object; + * xflag - extent flag: + * xoff - extent offset; + * maxblocks - max extent length; + * xlen - extent length (in/out); + * xaddrp - extent address pointer (in/out): + * flag - + * + * return: + */ +int xtAppend(tid_t tid, /* transaction id */ + struct inode *ip, int xflag, s64 xoff, s32 maxblocks, /* @GD1 */ + s32 * xlenp, /* (in/out) */ + s64 * xaddrp, /* (in/out) */ + int flag) +{ + int rc = 0; + metapage_t *mp; /* meta-page buffer */ + xtpage_t *p; /* base B+-tree index page */ + s64 bn, xaddr; + int index, nextindex; + btstack_t btstack; /* traverse stack */ + xtsplit_t split; /* split information */ + xad_t *xad; + int cmp; + tlock_t *tlck; + xtlock_t *xtlck; + int nsplit, nblocks, xlen; + pxdlist_t pxdlist; + pxd_t *pxd; + + xaddr = *xaddrp; + xlen = *xlenp; + jEVENT(0, + ("xtAppend: xoff:0x%lx maxblocks:%d xlen:%d xaddr:0x%lx\n", + (ulong) xoff, maxblocks, xlen, (ulong) xaddr)); + + /* + * search for the entry location at which to insert: + * + * xtFastSearch() and xtSearch() both returns (leaf page + * pinned, index at which to insert). + * n.b. xtSearch() may return index of maxentry of + * the full page. + */ + if ((rc = xtSearch(ip, xoff, &cmp, &btstack, XT_INSERT))) + return rc; + + /* retrieve search result */ + XT_GETSEARCH(ip, btstack.top, bn, mp, p, index); + + if (cmp == 0) { + rc = EEXIST; + goto out; + } +//insert: + /* + * insert entry for new extent + */ + xflag |= XAD_NEW; + + /* + * if the leaf page is full, split the page and + * propagate up the router entry for the new page from split + * + * The xtSplitUp() will insert the entry and unpin the leaf page. + */ + nextindex = le16_to_cpu(p->header.nextindex); + if (nextindex < le16_to_cpu(p->header.maxentry)) + goto insertLeaf; + + /* + * allocate new index blocks to cover index page split(s) + */ + nsplit = btstack.nsplit; + split.pxdlist = &pxdlist; + pxdlist.maxnpxd = pxdlist.npxd = 0; + pxd = &pxdlist.pxd[0]; + nblocks = JFS_SBI(ip->i_sb)->nbperpage; + for (; nsplit > 0; nsplit--, pxd++, xaddr += nblocks, maxblocks -= nblocks) { /* @GD1 */ + if ((rc = dbAllocBottomUp(ip, xaddr, (s64) nblocks)) == 0) { + PXDaddress(pxd, xaddr); + PXDlength(pxd, nblocks); + + pxdlist.maxnpxd++; + + continue; + } + + /* undo allocation */ + + goto out; + } + + xlen = min(xlen, maxblocks); /* @GD1 */ + + /* + * allocate data extent requested + */ + if ((rc = dbAllocBottomUp(ip, xaddr, (s64) xlen))) + goto out; + + split.mp = mp; + split.index = index; + split.flag = xflag; + split.off = xoff; + split.len = xlen; + split.addr = xaddr; + if ((rc = xtSplitUp(tid, ip, &split, &btstack))) { + /* undo data extent allocation */ + dbFree(ip, *xaddrp, (s64) * xlenp); + + return rc; + } + + *xaddrp = xaddr; + *xlenp = xlen; + return 0; + + /* + * insert the new entry into the leaf page + */ + insertLeaf: + /* + * allocate data extent requested + */ + if ((rc = dbAllocBottomUp(ip, xaddr, (s64) xlen))) + goto out; + + BT_MARK_DIRTY(mp, ip); + /* + * acquire a transaction lock on the leaf page; + * + * action: xad insertion/extension; + */ + tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW); + xtlck = (xtlock_t *) & tlck->lock; + + /* insert the new entry: mark the entry NEW */ + xad = &p->xad[index]; + XT_PUTENTRY(xad, xflag, xoff, xlen, xaddr); + + /* advance next available entry index */ + p->header.nextindex = + cpu_to_le16(le16_to_cpu(p->header.nextindex) + 1); + + xtlck->lwm.offset = + (xtlck->lwm.offset) ? min(index, xtlck->lwm.offset) : index; + xtlck->lwm.length = le16_to_cpu(p->header.nextindex) - + xtlck->lwm.offset; + + *xaddrp = xaddr; + *xlenp = xlen; + + out: + /* unpin the leaf page */ + XT_PUTPAGE(mp); + + return rc; +} + + +/* - TBD for defragmentaion/reorganization - + * + * xtDelete() + * + * function: + * delete the entry with the specified key. + * + * N.B.: whole extent of the entry is assumed to be deleted. + * + * parameter: + * + * return: + * ENOENT: if the entry is not found. + * + * exception: + */ +int xtDelete(tid_t tid, struct inode *ip, s64 xoff, s32 xlen, int flag) +{ + int rc = 0; + btstack_t btstack; + int cmp; + s64 bn; + metapage_t *mp; + xtpage_t *p; + int index, nextindex; + tlock_t *tlck; + xtlock_t *xtlck; + + /* + * find the matching entry; xtSearch() pins the page + */ + if ((rc = xtSearch(ip, xoff, &cmp, &btstack, 0))) + return rc; + + XT_GETSEARCH(ip, btstack.top, bn, mp, p, index); + if (cmp) { + /* unpin the leaf page */ + XT_PUTPAGE(mp); + return ENOENT; + } + + /* + * delete the entry from the leaf page + */ + nextindex = le16_to_cpu(p->header.nextindex); + p->header.nextindex = + cpu_to_le16(le16_to_cpu(p->header.nextindex) - 1); + + /* + * if the leaf page bocome empty, free the page + */ + if (p->header.nextindex == cpu_to_le16(XTENTRYSTART)) + return (xtDeleteUp(tid, ip, mp, p, &btstack)); + + BT_MARK_DIRTY(mp, ip); + /* + * acquire a transaction lock on the leaf page; + * + * action:xad deletion; + */ + tlck = txLock(tid, ip, mp, tlckXTREE); + xtlck = (xtlock_t *) & tlck->lock; + xtlck->lwm.offset = + (xtlck->lwm.offset) ? min(index, xtlck->lwm.offset) : index; + + /* if delete from middle, shift left/compact the remaining entries */ + if (index < nextindex - 1) + memmove(&p->xad[index], &p->xad[index + 1], + (nextindex - index - 1) * sizeof(xad_t)); + + XT_PUTPAGE(mp); + + return 0; +} + + +/* - TBD for defragmentaion/reorganization - + * + * xtDeleteUp() + * + * function: + * free empty pages as propagating deletion up the tree + * + * parameter: + * + * return: + */ +static int +xtDeleteUp(tid_t tid, + struct inode *ip, + metapage_t * fmp, xtpage_t * fp, btstack_t * btstack) +{ + int rc = 0; + metapage_t *mp; + xtpage_t *p; + int index, nextindex; + s64 xaddr; + int xlen; + btframe_t *parent; + tlock_t *tlck; + xtlock_t *xtlck; + + /* + * keep root leaf page which has become empty + */ + if (fp->header.flag & BT_ROOT) { + /* keep the root page */ + fp->header.flag &= ~BT_INTERNAL; + fp->header.flag |= BT_LEAF; + fp->header.nextindex = cpu_to_le16(XTENTRYSTART); + + /* XT_PUTPAGE(fmp); */ + + return 0; + } + + /* + * free non-root leaf page + */ + if ((rc = xtRelink(tid, ip, fp))) + return rc; + + xaddr = addressPXD(&fp->header.self); + xlen = lengthPXD(&fp->header.self); + /* free the page extent */ + dbFree(ip, xaddr, (s64) xlen); + + /* free the buffer page */ + discard_metapage(fmp); + + /* + * propagate page deletion up the index tree + * + * If the delete from the parent page makes it empty, + * continue all the way up the tree. + * stop if the root page is reached (which is never deleted) or + * if the entry deletion does not empty the page. + */ + while ((parent = BT_POP(btstack)) != NULL) { + /* get/pin the parent page */ + XT_GETPAGE(ip, parent->bn, mp, PSIZE, p, rc); + if (rc) + return rc; + + index = parent->index; + + /* delete the entry for the freed child page from parent. + */ + nextindex = le16_to_cpu(p->header.nextindex); + + /* + * the parent has the single entry being deleted: + * free the parent page which has become empty. + */ + if (nextindex == 1) { + if (p->header.flag & BT_ROOT) { + /* keep the root page */ + p->header.flag &= ~BT_INTERNAL; + p->header.flag |= BT_LEAF; + p->header.nextindex = + cpu_to_le16(XTENTRYSTART); + + /* XT_PUTPAGE(fmp); */ + + break; + } else { + /* free the parent page */ + if ((rc = xtRelink(tid, ip, p))) + return rc; + + xaddr = addressPXD(&p->header.self); + /* free the page extent */ + dbFree(ip, xaddr, + (s64) JFS_SBI(ip->i_sb)->nbperpage); + + /* unpin/free the buffer page */ + discard_metapage(fmp); + + /* propagate up */ + continue; + } + } + /* + * the parent has other entries remaining: + * delete the router entry from the parent page. + */ + else { + BT_MARK_DIRTY(mp, ip); + /* + * acquire a transaction lock on the leaf page; + * + * action:xad deletion; + */ + tlck = txLock(tid, ip, mp, tlckXTREE); + xtlck = (xtlock_t *) & tlck->lock; + xtlck->lwm.offset = + (xtlck->lwm.offset) ? min(index, + xtlck->lwm. + offset) : index; + + /* if delete from middle, + * shift left/compact the remaining entries in the page + */ + if (index < nextindex - 1) + memmove(&p->xad[index], &p->xad[index + 1], + (nextindex - index - + 1) << L2XTSLOTSIZE); + + p->header.nextindex = + cpu_to_le16(le16_to_cpu(p->header.nextindex) - + 1); + jEVENT(0, + ("xtDeleteUp(entry): 0x%lx[%d]\n", + (ulong) parent->bn, index)); + } + + /* unpin the parent page */ + XT_PUTPAGE(mp); + + /* exit propagation up */ + break; + } + + return 0; +} + + +/* + * NAME: xtRelocate() + * + * FUNCTION: relocate xtpage or data extent of regular file; + * This function is mainly used by defragfs utility. + * + * NOTE: This routine does not have the logic to handle + * uncommitted allocated extent. The caller should call + * txCommit() to commit all the allocation before call + * this routine. + */ +xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ + s64 nxaddr, /* new xaddr */ + int xtype) +{ /* extent type: XTPAGE or DATAEXT */ + int rc = 0; + tblock_t *tblk; + tlock_t *tlck; + xtlock_t *xtlck; + metapage_t *mp, *pmp, *lmp, *rmp; /* meta-page buffer */ + xtpage_t *p, *pp, *rp, *lp; /* base B+-tree index page */ + xad_t *xad; + pxd_t *pxd; + s64 xoff, xsize; + int xlen; + s64 oxaddr, sxaddr, dxaddr, nextbn, prevbn; + cbuf_t *cp; + s64 offset, nbytes, nbrd, pno; + int nb, npages, nblks; + s64 bn; + int cmp; + int index; + pxdlock_t *pxdlock; + btstack_t btstack; /* traverse stack */ + + xtype = xtype & EXTENT_TYPE; + + xoff = offsetXAD(oxad); + oxaddr = addressXAD(oxad); + xlen = lengthXAD(oxad); + + /* validate extent offset */ + offset = xoff << JFS_SBI(ip->i_sb)->l2bsize; + if (offset >= ip->i_size) + return ESTALE; /* stale extent */ + + jEVENT(0, + ("xtRelocate: xtype:%d xoff:0x%lx xlen:0x%x xaddr:0x%lx:0x%lx\n", + xtype, (ulong) xoff, xlen, (ulong) oxaddr, + (ulong) nxaddr)); + + /* + * 1. get and validate the parent xtpage/xad entry + * covering the source extent to be relocated; + */ + if (xtype == DATAEXT) { + /* search in leaf entry */ + rc = xtSearch(ip, xoff, &cmp, &btstack, 0); + if (rc) + return rc; + if (cmp) { + XT_PUTPAGE(pmp); + return ESTALE; + } + + /* retrieve search result */ + XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index); + + /* validate for exact match with a single entry */ + xad = &pp->xad[index]; + if (addressXAD(xad) != oxaddr || lengthXAD(xad) != xlen) { + XT_PUTPAGE(pmp); + return ESTALE; + } + } else { /* (xtype == XTPAGE) */ + + /* search in internal entry */ + rc = xtSearchNode(ip, oxad, &cmp, &btstack, 0); + if (rc) + return rc; + if (cmp) { + XT_PUTPAGE(pmp); + return ESTALE; + } + + /* retrieve search result */ + XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index); + + /* xtSearchNode() validated for exact match with a single entry + */ + xad = &pp->xad[index]; + } + jEVENT(0, ("xtRelocate: parent xad entry validated.\n")); + + /* + * 2. relocate the extent + */ + if (xtype == DATAEXT) { + /* if the extent is allocated-but-not-recorded + * there is no real data to be moved in this extent, + */ + if (xad->flag & XAD_NOTRECORDED) + goto out; + else + /* release xtpage for cmRead()/xtLookup() */ + XT_PUTPAGE(pmp); + + /* + * cmRelocate() + * + * copy target data pages to be relocated; + * + * data extent must start at page boundary and + * multiple of page size (except the last data extent); + * read in each page of the source data extent into cbuf, + * update the cbuf extent descriptor of the page to be + * homeward bound to new dst data extent + * copy the data from the old extent to new extent. + * copy is essential for compressed files to avoid problems + * that can arise if there was a change in compression + * algorithms. + * it is a good strategy because it may disrupt cache + * policy to keep the pages in memory afterwards. + */ + offset = xoff << JFS_SBI(ip->i_sb)->l2bsize; + assert((offset & CM_OFFSET) == 0); + nbytes = xlen << JFS_SBI(ip->i_sb)->l2bsize; + pno = offset >> CM_L2BSIZE; + npages = (nbytes + (CM_BSIZE - 1)) >> CM_L2BSIZE; +/* + npages = ((offset + nbytes - 1) >> CM_L2BSIZE) - + (offset >> CM_L2BSIZE) + 1; +*/ + sxaddr = oxaddr; + dxaddr = nxaddr; + + /* process the request one cache buffer at a time */ + for (nbrd = 0; nbrd < nbytes; nbrd += nb, + offset += nb, pno++, npages--) { + /* compute page size */ + nb = min(nbytes - nbrd, CM_BSIZE); + + /* get the cache buffer of the page */ + if (rc = cmRead(ip, offset, npages, &cp)) + break; + + assert(addressPXD(&cp->cm_pxd) == sxaddr); + assert(!cp->cm_modified); + + /* bind buffer with the new extent address */ + nblks = nb >> JFS_IP(ip->i_sb)->l2bsize; + cmSetXD(ip, cp, pno, dxaddr, nblks); + + /* release the cbuf, mark it as modified */ + cmPut(cp, TRUE); + + dxaddr += nblks; + sxaddr += nblks; + } + + /* get back parent page */ + rc = xtSearch(ip, xoff, &cmp, &btstack, 0); + XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index); + jEVENT(0, ("xtRelocate: target data extent relocated.\n")); + } else { /* (xtype == XTPAGE) */ + + /* + * read in the target xtpage from the source extent; + */ + XT_GETPAGE(ip, oxaddr, mp, PSIZE, p, rc); + if (rc) { + XT_PUTPAGE(pmp); + return rc; + } + + /* + * read in sibling pages if any to update sibling pointers; + */ + rmp = NULL; + if (p->header.next) { + nextbn = le64_to_cpu(p->header.next); + XT_GETPAGE(ip, nextbn, rmp, PSIZE, rp, rc); + if (rc) { + XT_PUTPAGE(pmp); + XT_PUTPAGE(mp); + return (rc); + } + } + + lmp = NULL; + if (p->header.prev) { + prevbn = le64_to_cpu(p->header.prev); + XT_GETPAGE(ip, prevbn, lmp, PSIZE, lp, rc); + if (rc) { + XT_PUTPAGE(pmp); + XT_PUTPAGE(mp); + if (rmp) + XT_PUTPAGE(rmp); + return (rc); + } + } + + /* at this point, all xtpages to be updated are in memory */ + + /* + * update sibling pointers of sibling xtpages if any; + */ + if (lmp) { + BT_MARK_DIRTY(lmp, ip); + tlck = + txLock(tid, ip, lmp, tlckXTREE | tlckRELINK); + lp->header.next = cpu_to_le64(nxaddr); + XT_PUTPAGE(lmp); + } + + if (rmp) { + BT_MARK_DIRTY(rmp, ip); + tlck = + txLock(tid, ip, rmp, tlckXTREE | tlckRELINK); + rp->header.prev = cpu_to_le64(nxaddr); + XT_PUTPAGE(rmp); + } + + /* + * update the target xtpage to be relocated + * + * update the self address of the target page + * and write to destination extent; + * redo image covers the whole xtpage since it is new page + * to the destination extent; + * update of bmap for the free of source extent + * of the target xtpage itself: + * update of bmap for the allocation of destination extent + * of the target xtpage itself: + * update of bmap for the extents covered by xad entries in + * the target xtpage is not necessary since they are not + * updated; + * if not committed before this relocation, + * target page may contain XAD_NEW entries which must + * be scanned for bmap update (logredo() always + * scan xtpage REDOPAGE image for bmap update); + * if committed before this relocation (tlckRELOCATE), + * scan may be skipped by commit() and logredo(); + */ + BT_MARK_DIRTY(mp, ip); + /* tlckNEW init xtlck->lwm.offset = XTENTRYSTART; */ + tlck = txLock(tid, ip, mp, tlckXTREE | tlckNEW); + xtlck = (xtlock_t *) & tlck->lock; + + /* update the self address in the xtpage header */ + pxd = &p->header.self; + PXDaddress(pxd, nxaddr); + + /* linelock for the after image of the whole page */ + xtlck->lwm.length = + le16_to_cpu(p->header.nextindex) - xtlck->lwm.offset; + + /* update the buffer extent descriptor of target xtpage */ + xsize = xlen << JFS_SBI(ip->i_sb)->l2bsize; + bmSetXD(mp, nxaddr, xsize); + + /* unpin the target page to new homeward bound */ + XT_PUTPAGE(mp); + jEVENT(0, ("xtRelocate: target xtpage relocated.\n")); + } + + /* + * 3. acquire maplock for the source extent to be freed; + * + * acquire a maplock saving the src relocated extent address; + * to free of the extent at commit time; + */ + out: + /* if DATAEXT relocation, write a LOG_UPDATEMAP record for + * free PXD of the source data extent (logredo() will update + * bmap for free of source data extent), and update bmap for + * free of the source data extent; + */ + if (xtype == DATAEXT) + tlck = txMaplock(tid, ip, tlckMAP); + /* if XTPAGE relocation, write a LOG_NOREDOPAGE record + * for the source xtpage (logredo() will init NoRedoPage + * filter and will also update bmap for free of the source + * xtpage), and update bmap for free of the source xtpage; + * N.B. We use tlckMAP instead of tlkcXTREE because there + * is no buffer associated with this lock since the buffer + * has been redirected to the target location. + */ + else /* (xtype == XTPAGE) */ + tlck = txMaplock(tid, ip, tlckMAP | tlckRELOCATE); + + pxdlock = (pxdlock_t *) & tlck->lock; + pxdlock->flag = mlckFREEPXD; + PXDaddress(&pxdlock->pxd, oxaddr); + PXDlength(&pxdlock->pxd, xlen); + pxdlock->index = 1; + + /* + * 4. update the parent xad entry for relocation; + * + * acquire tlck for the parent entry with XAD_NEW as entry + * update which will write LOG_REDOPAGE and update bmap for + * allocation of XAD_NEW destination extent; + */ + jEVENT(0, ("xtRelocate: update parent xad entry.\n")); + BT_MARK_DIRTY(pmp, ip); + tlck = txLock(tid, ip, pmp, tlckXTREE | tlckGROW); + xtlck = (xtlock_t *) & tlck->lock; + + /* update the XAD with the new destination extent; */ + xad = &pp->xad[index]; + xad->flag |= XAD_NEW; + XADaddress(xad, nxaddr); + + xtlck->lwm.offset = min(index, xtlck->lwm.offset); + xtlck->lwm.length = le16_to_cpu(pp->header.nextindex) - + xtlck->lwm.offset; + + /* unpin the parent xtpage */ + XT_PUTPAGE(pmp); + + return rc; +} + + +/* + * xtSearchNode() + * + * function: search for the internal xad entry covering specified extent. + * This function is mainly used by defragfs utility. + * + * parameters: + * ip - file object; + * xad - extent to find; + * cmpp - comparison result: + * btstack - traverse stack; + * flag - search process flag; + * + * returns: + * btstack contains (bn, index) of search path traversed to the entry. + * *cmpp is set to result of comparison with the entry returned. + * the page containing the entry is pinned at exit. + */ +static int xtSearchNode(struct inode *ip, xad_t * xad, /* required XAD entry */ + int *cmpp, btstack_t * btstack, int flag) +{ + int rc = 0; + s64 xoff, xaddr; + int xlen; + int cmp = 1; /* init for empty page */ + s64 bn; /* block number */ + metapage_t *mp; /* meta-page buffer */ + xtpage_t *p; /* page */ + int base, index, lim; + btframe_t *btsp; + s64 t64; + + BT_CLR(btstack); + + xoff = offsetXAD(xad); + xlen = lengthXAD(xad); + xaddr = addressXAD(xad); + + /* + * search down tree from root: + * + * between two consecutive entries of and of + * internal page, child page Pi contains entry with k, Ki <= K < Kj. + * + * if entry with search key K is not found + * internal page search find the entry with largest key Ki + * less than K which point to the child page to search; + * leaf page search find the entry with smallest key Kj + * greater than K so that the returned index is the position of + * the entry to be shifted right for insertion of new entry. + * for empty tree, search key is greater than any key of the tree. + * + * by convention, root bn = 0. + */ + for (bn = 0;;) { + /* get/pin the page to search */ + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) + return rc; + if (p->header.flag & BT_LEAF) + return ESTALE; + + lim = le16_to_cpu(p->header.nextindex) - XTENTRYSTART; + + /* + * binary search with search key K on the current page + */ + for (base = XTENTRYSTART; lim; lim >>= 1) { + index = base + (lim >> 1); + + XT_CMP(cmp, xoff, &p->xad[index], t64); + if (cmp == 0) { + /* + * search hit + * + * verify for exact match; + */ + if (xaddr == addressXAD(&p->xad[index]) && + xoff == offsetXAD(&p->xad[index])) { + *cmpp = cmp; + + /* save search result */ + btsp = btstack->top; + btsp->bn = bn; + btsp->index = index; + btsp->mp = mp; + + return 0; + } + + /* descend/search its child page */ + goto next; + } + + if (cmp > 0) { + base = index + 1; + --lim; + } + } + + /* + * search miss - non-leaf page: + * + * base is the smallest index with key (Kj) greater than + * search key (K) and may be zero or maxentry index. + * if base is non-zero, decrement base by one to get the parent + * entry of the child page to search. + */ + index = base ? base - 1 : base; + + /* + * go down to child page + */ + next: + /* get the child page block number */ + bn = addressXAD(&p->xad[index]); + + /* unpin the parent page */ + XT_PUTPAGE(mp); + } +} + + +/* + * xtRelink() + * + * function: + * link around a freed page. + * + * Parameter: + * int tid, + * struct inode *ip, + * xtpage_t *p) + * + * returns: + */ +static int xtRelink(tid_t tid, struct inode *ip, xtpage_t * p) +{ + int rc = 0; + metapage_t *mp; + s64 nextbn, prevbn; + tlock_t *tlck; + + nextbn = le64_to_cpu(p->header.next); + prevbn = le64_to_cpu(p->header.prev); + + /* update prev pointer of the next page */ + if (nextbn != 0) { + XT_GETPAGE(ip, nextbn, mp, PSIZE, p, rc); + if (rc) + return rc; + + /* + * acquire a transaction lock on the page; + * + * action: update prev pointer; + */ + BT_MARK_DIRTY(mp, ip); + tlck = txLock(tid, ip, mp, tlckXTREE | tlckRELINK); + + /* the page may already have been tlock'd */ + + p->header.prev = cpu_to_le64(prevbn); + + XT_PUTPAGE(mp); + } + + /* update next pointer of the previous page */ + if (prevbn != 0) { + XT_GETPAGE(ip, prevbn, mp, PSIZE, p, rc); + if (rc) + return rc; + + /* + * acquire a transaction lock on the page; + * + * action: update next pointer; + */ + BT_MARK_DIRTY(mp, ip); + tlck = txLock(tid, ip, mp, tlckXTREE | tlckRELINK); + + /* the page may already have been tlock'd */ + + p->header.next = le64_to_cpu(nextbn); + + XT_PUTPAGE(mp); + } + + return 0; +} +#endif /* _STILL_TO_PORT */ + + +/* + * xtInitRoot() + * + * initialize file root (inline in inode) + */ +void xtInitRoot(tid_t tid, struct inode *ip) +{ + xtpage_t *p; + tlock_t *tlck; + + /* + * acquire a transaction lock on the root + * + * action: + */ + tlck = txLock(tid, ip, (metapage_t *) &JFS_IP(ip)->bxflag, + tlckXTREE | tlckNEW); + p = &JFS_IP(ip)->i_xtroot; + + p->header.flag = DXD_INDEX | BT_ROOT | BT_LEAF; + p->header.nextindex = cpu_to_le16(XTENTRYSTART); + + if (S_ISDIR(ip->i_mode)) + p->header.maxentry = cpu_to_le16(XTROOTINITSLOT_DIR); + else { + p->header.maxentry = cpu_to_le16(XTROOTINITSLOT); + ip->i_size = 0; + } + + + return; +} + + +/* + * We can run into a deadlock truncating a file with a large number of + * xtree pages (large fragmented file). A robust fix would entail a + * reservation system where we would reserve a number of metadata pages + * and tlocks which we would be guaranteed without a deadlock. Without + * this, a partial fix is to limit number of metadata pages we will lock + * in a single transaction. Currently we will truncate the file so that + * no more than 50 leaf pages will be locked. The caller of xtTruncate + * will be responsible for ensuring that the current transaction gets + * committed, and that subsequent transactions are created to truncate + * the file further if needed. + */ +#define MAX_TRUNCATE_LEAVES 50 + +/* + * xtTruncate() + * + * function: + * traverse for truncation logging backward bottom up; + * terminate at the last extent entry at the current subtree + * root page covering new down size. + * truncation may occur within the last extent entry. + * + * parameter: + * int tid, + * struct inode *ip, + * s64 newsize, + * int type) {PWMAP, PMAP, WMAP; DELETE, TRUNCATE} + * + * return: + * + * note: + * PWMAP: + * 1. truncate (non-COMMIT_NOLINK file) + * by jfs_truncate() or jfs_open(O_TRUNC): + * xtree is updated; + * 2. truncate index table of directory when last entry removed + * map update via tlock at commit time; + * PMAP: + * Call xtTruncate_pmap instead + * WMAP: + * 1. remove (free zero link count) on last reference release + * (pmap has been freed at commit zero link count); + * 2. truncate (COMMIT_NOLINK file, i.e., tmp file): + * xtree is updated; + * map update directly at truncation time; + * + * if (DELETE) + * no LOG_NOREDOPAGE is required (NOREDOFILE is sufficient); + * else if (TRUNCATE) + * must write LOG_NOREDOPAGE for deleted index page; + * + * pages may already have been tlocked by anonymous transactions + * during file growth (i.e., write) before truncation; + * + * except last truncated entry, deleted entries remains as is + * in the page (nextindex is updated) for other use + * (e.g., log/update allocation map): this avoid copying the page + * info but delay free of pages; + * + */ +s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag) +{ + int rc = 0; + s64 teof; + metapage_t *mp; + xtpage_t *p; + s64 bn; + int index, nextindex; + xad_t *xad; + s64 xoff, xaddr; + int xlen, len, freexlen; + btstack_t btstack; + btframe_t *parent; + tblock_t *tblk = 0; + tlock_t *tlck = 0; + xtlock_t *xtlck = 0; + xdlistlock_t xadlock; /* maplock for COMMIT_WMAP */ + pxdlock_t *pxdlock; /* maplock for COMMIT_WMAP */ + s64 nfreed; + int freed, log; + int locked_leaves = 0; + + /* save object truncation type */ + if (tid) { + tblk = tid_to_tblock(tid); + tblk->xflag |= flag; + } + + nfreed = 0; + + flag &= COMMIT_MAP; + assert(flag != COMMIT_PMAP); + + if (flag == COMMIT_PWMAP) + log = 1; + else { + log = 0; + xadlock.flag = mlckFREEXADLIST; + xadlock.index = 1; + } + + /* + * if the newsize is not an integral number of pages, + * the file between newsize and next page boundary will + * be cleared. + * if truncating into a file hole, it will cause + * a full block to be allocated for the logical block. + */ + + /* + * release page blocks of truncated region + * + * free the data blocks from the leaf index blocks. + * delete the parent index entries corresponding to + * the freed child data/index blocks. + * free the index blocks themselves which aren't needed + * in new sized file. + * + * index blocks are updated only if the blocks are to be + * retained in the new sized file. + * if type is PMAP, the data and index pages are NOT + * freed, and the data and index blocks are NOT freed + * from working map. + * (this will allow continued access of data/index of + * temporary file (zerolink count file truncated to zero-length)). + */ + teof = (newsize + (JFS_SBI(ip->i_sb)->bsize - 1)) >> + JFS_SBI(ip->i_sb)->l2bsize; + + /* clear stack */ + BT_CLR(&btstack); + + /* + * start with root + * + * root resides in the inode + */ + bn = 0; + + /* + * first access of each page: + */ + getPage: + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) + return -rc; + + /* process entries backward from last index */ + index = le16_to_cpu(p->header.nextindex) - 1; + + if (p->header.flag & BT_INTERNAL) + goto getChild; + + /* + * leaf page + */ + + /* Since this is the rightmost leaf, and we may have already freed + * a page that was formerly to the right, let's make sure that the + * next pointer is zero. + */ + p->header.next = 0; + + freed = 0; + + /* does region covered by leaf page precede Teof ? */ + xad = &p->xad[index]; + xoff = offsetXAD(xad); + xlen = lengthXAD(xad); + if (teof >= xoff + xlen) { + XT_PUTPAGE(mp); + goto getParent; + } + + /* (re)acquire tlock of the leaf page */ + if (log) { + if (++locked_leaves > MAX_TRUNCATE_LEAVES) { + /* + * We need to limit the size of the transaction + * to avoid exhausting pagecache & tlocks + */ + XT_PUTPAGE(mp); + newsize = (xoff + xlen) << JFS_SBI(ip->i_sb)->l2bsize; + goto getParent; + } + tlck = txLock(tid, ip, mp, tlckXTREE); + tlck->type = tlckXTREE | tlckTRUNCATE; + xtlck = (xtlock_t *) & tlck->lock; + xtlck->hwm.offset = le16_to_cpu(p->header.nextindex) - 1; + } + BT_MARK_DIRTY(mp, ip); + + /* + * scan backward leaf page entries + */ + for (; index >= XTENTRYSTART; index--) { + xad = &p->xad[index]; + xoff = offsetXAD(xad); + xlen = lengthXAD(xad); + xaddr = addressXAD(xad); + + /* + * entry beyond eof: continue scan of current page + * xad + * ---|---=======-------> + * eof + */ + if (teof < xoff) { + nfreed += xlen; + continue; + } + + /* + * (xoff <= teof): last entry to be deleted from page; + * If other entries remain in page: keep and update the page. + */ + + /* + * eof == entry_start: delete the entry + * xad + * -------|=======-------> + * eof + * + */ + if (teof == xoff) { + nfreed += xlen; + + if (index == XTENTRYSTART) + break; + + nextindex = index; + } + /* + * eof within the entry: truncate the entry. + * xad + * -------===|===-------> + * eof + */ + else if (teof < xoff + xlen) { + /* update truncated entry */ + len = teof - xoff; + freexlen = xlen - len; + XADlength(xad, len); + + /* save pxd of truncated extent in tlck */ + xaddr += len; + if (log) { /* COMMIT_PWMAP */ + xtlck->lwm.offset = (xtlck->lwm.offset) ? + min(index, (int)xtlck->lwm.offset) : index; + xtlck->lwm.length = index + 1 - + xtlck->lwm.offset; + pxdlock = (pxdlock_t *) & xtlck->pxdlock; + pxdlock->flag = mlckFREEPXD; + PXDaddress(&pxdlock->pxd, xaddr); + PXDlength(&pxdlock->pxd, freexlen); + } + /* free truncated extent */ + else { /* COMMIT_WMAP */ + + pxdlock = (pxdlock_t *) & xadlock; + pxdlock->flag = mlckFREEPXD; + PXDaddress(&pxdlock->pxd, xaddr); + PXDlength(&pxdlock->pxd, freexlen); + txFreeMap(ip, pxdlock, 0, COMMIT_WMAP); + + /* reset map lock */ + xadlock.flag = mlckFREEXADLIST; + } + + /* current entry is new last entry; */ + nextindex = index + 1; + + nfreed += freexlen; + } + /* + * eof beyond the entry: + * xad + * -------=======---|---> + * eof + */ + else { /* (xoff + xlen < teof) */ + + nextindex = index + 1; + } + + if (nextindex < le16_to_cpu(p->header.nextindex)) { + if (!log) { /* COMMIT_WAMP */ + xadlock.xdlist = &p->xad[nextindex]; + xadlock.count = + le16_to_cpu(p->header.nextindex) - + nextindex; + txFreeMap(ip, (maplock_t *) & xadlock, 0, + COMMIT_WMAP); + } + p->header.nextindex = cpu_to_le16(nextindex); + } + + XT_PUTPAGE(mp); + + /* assert(freed == 0); */ + goto getParent; + } /* end scan of leaf page entries */ + + freed = 1; + + /* + * leaf page become empty: free the page if type != PMAP + */ + if (log) { /* COMMIT_PWMAP */ + /* txCommit() with tlckFREE: + * free data extents covered by leaf [XTENTRYSTART:hwm); + * invalidate leaf if COMMIT_PWMAP; + * if (TRUNCATE), will write LOG_NOREDOPAGE; + */ + tlck->type = tlckXTREE | tlckFREE; + } else { /* COMMIT_WAMP */ + + /* free data extents covered by leaf */ + xadlock.xdlist = &p->xad[XTENTRYSTART]; + xadlock.count = + le16_to_cpu(p->header.nextindex) - XTENTRYSTART; + txFreeMap(ip, (maplock_t *) & xadlock, 0, COMMIT_WMAP); + } + + if (p->header.flag & BT_ROOT) { + p->header.flag &= ~BT_INTERNAL; + p->header.flag |= BT_LEAF; + p->header.nextindex = cpu_to_le16(XTENTRYSTART); + + XT_PUTPAGE(mp); /* debug */ + goto out; + } else { + if (log) { /* COMMIT_PWMAP */ + /* page will be invalidated at tx completion + */ + XT_PUTPAGE(mp); + } else { /* COMMIT_WMAP */ + + if (mp->lid) + lid_to_tlock(mp->lid)->flag |= tlckFREELOCK; + + /* invalidate empty leaf page */ + discard_metapage(mp); + } + } + + /* + * the leaf page become empty: delete the parent entry + * for the leaf page if the parent page is to be kept + * in the new sized file. + */ + + /* + * go back up to the parent page + */ + getParent: + /* pop/restore parent entry for the current child page */ + if ((parent = BT_POP(&btstack)) == NULL) + /* current page must have been root */ + goto out; + + /* get back the parent page */ + bn = parent->bn; + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) + return -rc; + + index = parent->index; + + /* + * child page was not empty: + */ + if (freed == 0) { + /* has any entry deleted from parent ? */ + if (index < le16_to_cpu(p->header.nextindex) - 1) { + /* (re)acquire tlock on the parent page */ + if (log) { /* COMMIT_PWMAP */ + /* txCommit() with tlckTRUNCATE: + * free child extents covered by parent [); + */ + tlck = txLock(tid, ip, mp, tlckXTREE); + xtlck = (xtlock_t *) & tlck->lock; + xtlck->twm.offset = index; + if (!(tlck->type & tlckTRUNCATE)) { + xtlck->hwm.offset = + le16_to_cpu(p->header. + nextindex) - 1; + tlck->type = + tlckXTREE | tlckTRUNCATE; + } + } else { /* COMMIT_WMAP */ + + /* free child extents covered by parent */ + xadlock.xdlist = &p->xad[index + 1]; + xadlock.count = + le16_to_cpu(p->header.nextindex) - + index - 1; + txFreeMap(ip, (maplock_t *) & xadlock, 0, + COMMIT_WMAP); + } + BT_MARK_DIRTY(mp, ip); + + p->header.nextindex = cpu_to_le16(index + 1); + } + XT_PUTPAGE(mp); + goto getParent; + } + + /* + * child page was empty: + */ + nfreed += lengthXAD(&p->xad[index]); + + /* + * During working map update, child page's tlock must be handled + * before parent's. This is because the parent's tlock will cause + * the child's disk space to be marked available in the wmap, so + * it's important that the child page be released by that time. + * + * ToDo: tlocks should be on doubly-linked list, so we can + * quickly remove it and add it to the end. + */ + + /* + * Move parent page's tlock to the end of the tid's tlock list + */ + if (log && mp->lid && (tblk->last != mp->lid) && + lid_to_tlock(mp->lid)->tid) { + lid_t lid = mp->lid; + tlock_t *prev; + + tlck = lid_to_tlock(lid); + + if (tblk->next == lid) + tblk->next = tlck->next; + else { + for (prev = lid_to_tlock(tblk->next); + prev->next != lid; + prev = lid_to_tlock(prev->next)) { + assert(prev->next); + } + prev->next = tlck->next; + } + lid_to_tlock(tblk->last)->next = lid; + tlck->next = 0; + tblk->last = lid; + } + + /* + * parent page become empty: free the page + */ + if (index == XTENTRYSTART) { + if (log) { /* COMMIT_PWMAP */ + /* txCommit() with tlckFREE: + * free child extents covered by parent; + * invalidate parent if COMMIT_PWMAP; + */ + tlck = txLock(tid, ip, mp, tlckXTREE); + xtlck = (xtlock_t *) & tlck->lock; + xtlck->twm.offset = index; + xtlck->hwm.offset = + le16_to_cpu(p->header.nextindex) - 1; + tlck->type = tlckXTREE | tlckFREE; + } else { /* COMMIT_WMAP */ + + /* free child extents covered by parent */ + xadlock.xdlist = &p->xad[XTENTRYSTART]; + xadlock.count = + le16_to_cpu(p->header.nextindex) - + XTENTRYSTART; + txFreeMap(ip, (maplock_t *) & xadlock, 0, + COMMIT_WMAP); + } + BT_MARK_DIRTY(mp, ip); + + if (p->header.flag & BT_ROOT) { + p->header.flag &= ~BT_INTERNAL; + p->header.flag |= BT_LEAF; + p->header.nextindex = cpu_to_le16(XTENTRYSTART); + if (le16_to_cpu(p->header.maxentry) == XTROOTMAXSLOT) { + /* + * Shrink root down to allow inline + * EA (otherwise fsck complains) + */ + p->header.maxentry = + cpu_to_le16(XTROOTINITSLOT); + JFS_IP(ip)->mode2 |= INLINEEA; + } + + XT_PUTPAGE(mp); /* debug */ + goto out; + } else { + if (log) { /* COMMIT_PWMAP */ + /* page will be invalidated at tx completion + */ + XT_PUTPAGE(mp); + } else { /* COMMIT_WMAP */ + + if (mp->lid) + lid_to_tlock(mp->lid)->flag |= + tlckFREELOCK; + + /* invalidate parent page */ + discard_metapage(mp); + } + + /* parent has become empty and freed: + * go back up to its parent page + */ + /* freed = 1; */ + goto getParent; + } + } + /* + * parent page still has entries for front region; + */ + else { + /* try truncate region covered by preceding entry + * (process backward) + */ + index--; + + /* go back down to the child page corresponding + * to the entry + */ + goto getChild; + } + + /* + * internal page: go down to child page of current entry + */ + getChild: + /* save current parent entry for the child page */ + BT_PUSH(&btstack, bn, index); + + /* get child page */ + xad = &p->xad[index]; + bn = addressXAD(xad); + + /* + * first access of each internal entry: + */ + /* release parent page */ + XT_PUTPAGE(mp); + + /* process the child page */ + goto getPage; + + out: + /* + * update file resource stat + */ + /* set size + */ + if (S_ISDIR(ip->i_mode) && !newsize) + ip->i_size = 1; /* fsck hates zero-length directories */ + else + ip->i_size = newsize; + + /* update nblocks to reflect freed blocks */ + ip->i_blocks -= LBLK2PBLK(ip->i_sb, nfreed); + + /* + * free tlock of invalidated pages + */ + if (flag == COMMIT_WMAP) + txFreelock(ip); + + return newsize; +} + + +/* + * xtTruncate_pmap() + * + * function: + * Perform truncate to zero lenghth for deleted file, leaving the + * the xtree and working map untouched. This allows the file to + * be accessed via open file handles, while the delete of the file + * is committed to disk. + * + * parameter: + * tid_t tid, + * struct inode *ip, + * s64 committed_size) + * + * return: new committed size + * + * note: + * + * To avoid deadlock by holding too many transaction locks, the + * truncation may be broken up into multiple transactions. + * The committed_size keeps track of part of the file has been + * freed from the pmaps. + */ +s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size) +{ + s64 bn; + btstack_t btstack; + int cmp; + int index; + int locked_leaves = 0; + metapage_t *mp; + xtpage_t *p; + btframe_t *parent; + int rc; + tblock_t *tblk; + tlock_t *tlck = 0; + xad_t *xad; + int xlen; + s64 xoff; + xtlock_t *xtlck = 0; + + /* save object truncation type */ + tblk = tid_to_tblock(tid); + tblk->xflag |= COMMIT_PMAP; + + /* clear stack */ + BT_CLR(&btstack); + + if (committed_size) { + xoff = (committed_size >> JFS_SBI(ip->i_sb)->l2bsize) - 1; + rc = xtSearch(ip, xoff, &cmp, &btstack, 0); + if (rc) + return -rc; + assert(cmp == 0); + XT_GETSEARCH(ip, btstack.top, bn, mp, p, index); + } else { + /* + * start with root + * + * root resides in the inode + */ + bn = 0; + + /* + * first access of each page: + */ + getPage: + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) + return -rc; + + /* process entries backward from last index */ + index = le16_to_cpu(p->header.nextindex) - 1; + + if (p->header.flag & BT_INTERNAL) + goto getChild; + } + + /* + * leaf page + */ + + if (++locked_leaves > MAX_TRUNCATE_LEAVES) { + /* + * We need to limit the size of the transaction + * to avoid exhausting pagecache & tlocks + */ + xad = &p->xad[index]; + xoff = offsetXAD(xad); + xlen = lengthXAD(xad); + XT_PUTPAGE(mp); + return (xoff + xlen) << JFS_SBI(ip->i_sb)->l2bsize; + } + tlck = txLock(tid, ip, mp, tlckXTREE); + tlck->type = tlckXTREE | tlckTRUNCATE; + xtlck = (xtlock_t *) & tlck->lock; + xtlck->hwm.offset = index; + + tlck->type = tlckXTREE | tlckFREE; + + XT_PUTPAGE(mp); + + /* + * go back up to the parent page + */ + getParent: + /* pop/restore parent entry for the current child page */ + if ((parent = BT_POP(&btstack)) == NULL) + /* current page must have been root */ + goto out; + + /* get back the parent page */ + bn = parent->bn; + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) + return -rc; + + index = parent->index; + + /* + * parent page become empty: free the page + */ + if (index == XTENTRYSTART) { + /* txCommit() with tlckFREE: + * free child extents covered by parent; + * invalidate parent if COMMIT_PWMAP; + */ + tlck = txLock(tid, ip, mp, tlckXTREE); + xtlck = (xtlock_t *) & tlck->lock; + xtlck->twm.offset = index; + xtlck->hwm.offset = + le16_to_cpu(p->header.nextindex) - 1; + tlck->type = tlckXTREE | tlckFREE; + + XT_PUTPAGE(mp); + + if (p->header.flag & BT_ROOT) { + + goto out; + } else { + goto getParent; + } + } + /* + * parent page still has entries for front region; + */ + else + index--; + /* + * internal page: go down to child page of current entry + */ + getChild: + /* save current parent entry for the child page */ + BT_PUSH(&btstack, bn, index); + + /* get child page */ + xad = &p->xad[index]; + bn = addressXAD(xad); + + /* + * first access of each internal entry: + */ + /* release parent page */ + XT_PUTPAGE(mp); + + /* process the child page */ + goto getPage; + + out: + + return 0; +} + + +#ifdef _JFS_DEBUG_XTREE +/* + * xtDisplayTree() + * + * function: traverse forward + */ +int xtDisplayTree(struct inode *ip) +{ + int rc = 0; + metapage_t *mp; + xtpage_t *p; + s64 bn, pbn; + int index, lastindex, v, h; + xad_t *xad; + btstack_t btstack; + btframe_t *btsp; + btframe_t *parent; + + printk("display B+-tree.\n"); + + /* clear stack */ + btsp = btstack.stack; + + /* + * start with root + * + * root resides in the inode + */ + bn = 0; + v = h = 0; + + /* + * first access of each page: + */ + getPage: + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) + return rc; + + /* process entries forward from first index */ + index = XTENTRYSTART; + lastindex = le16_to_cpu(p->header.nextindex) - 1; + + if (p->header.flag & BT_INTERNAL) { + /* + * first access of each internal page + */ + goto getChild; + } else { /* (p->header.flag & BT_LEAF) */ + + /* + * first access of each leaf page + */ + printf("leaf page "); + xtDisplayPage(ip, bn, p); + + /* unpin the leaf page */ + XT_PUTPAGE(mp); + } + + /* + * go back up to the parent page + */ + getParent: + /* pop/restore parent entry for the current child page */ + if ((parent = (btsp == btstack.stack ? NULL : --btsp)) == NULL) + /* current page must have been root */ + return; + + /* + * parent page scan completed + */ + if ((index = parent->index) == (lastindex = parent->lastindex)) { + /* go back up to the parent page */ + goto getParent; + } + + /* + * parent page has entries remaining + */ + /* get back the parent page */ + bn = parent->bn; + /* v = parent->level; */ + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) + return rc; + + /* get next parent entry */ + index++; + + /* + * internal page: go down to child page of current entry + */ + getChild: + /* push/save current parent entry for the child page */ + btsp->bn = pbn = bn; + btsp->index = index; + btsp->lastindex = lastindex; + /* btsp->level = v; */ + /* btsp->node = h; */ + ++btsp; + + /* get child page */ + xad = &p->xad[index]; + bn = addressXAD(xad); + + /* + * first access of each internal entry: + */ + /* release parent page */ + XT_PUTPAGE(mp); + + printk("traverse down 0x%lx[%d]->0x%lx\n", (ulong) pbn, index, + (ulong) bn); + v++; + h = index; + + /* process the child page */ + goto getPage; +} + + +/* + * xtDisplayPage() + * + * function: display page + */ +int xtDisplayPage(struct inode *ip, s64 bn, xtpage_t * p) +{ + int rc = 0; + metapage_t *mp; + xad_t *xad; + s64 xaddr, xoff; + int xlen, i, j; + + if (p == NULL) { + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) + return rc; + } + + /* display page control */ + printf("bn:0x%lx flag:0x%x nextindex:%d\n", + (ulong) bn, p->header.flag, + le16_to_cpu(p->header.nextindex)); + + /* display entries */ + xad = &p->xad[XTENTRYSTART]; + for (i = XTENTRYSTART, j = 1; i < le16_to_cpu(p->header.nextindex); + i++, xad++, j++) { + xoff = offsetXAD(xad); + xaddr = addressXAD(xad); + xlen = lengthXAD(xad); + printf("\t[%d] 0x%lx:0x%lx(0x%x)", i, (ulong) xoff, + (ulong) xaddr, xlen); + + if (j == 4) { + printf("\n"); + j = 0; + } + } + + printf("\n"); +} +#endif /* _JFS_DEBUG_XTREE */ + + +#ifdef _JFS_WIP +/* + * xtGather() + * + * function: + * traverse for allocation acquiring tlock at commit time + * (vs at the time of update) logging backward top down + * + * note: + * problem - establishing that all new allocation have been + * processed both for append and random write in sparse file + * at the current entry at the current subtree root page + * + */ +int xtGather(t) +btree_t *t; +{ + int rc = 0; + xtpage_t *p; + u64 bn; + int index; + btentry_t *e; + btstack_t btstack; + struct btsf *parent; + + /* clear stack */ + BT_CLR(&btstack); + + /* + * start with root + * + * root resides in the inode + */ + bn = 0; + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) + return rc; + + /* new root is NOT pointed by a new entry + if (p->header.flag & NEW) + allocate new page lock; + write a NEWPAGE log; + */ + + dopage: + /* + * first access of each page: + */ + /* process entries backward from last index */ + index = le16_to_cpu(p->header.nextindex) - 1; + + if (p->header.flag & BT_LEAF) { + /* + * first access of each leaf page + */ + /* process leaf page entries backward */ + for (; index >= XTENTRYSTART; index--) { + e = &p->xad[index]; + /* + * if newpage, log NEWPAGE. + * + if (e->flag & XAD_NEW) { + nfound =+ entry->length; + update current page lock for the entry; + newpage(entry); + * + * if moved, log move. + * + } else if (e->flag & XAD_MOVED) { + reset flag; + update current page lock for the entry; + } + */ + } + + /* unpin the leaf page */ + XT_PUTPAGE(mp); + + /* + * go back up to the parent page + */ + getParent: + /* restore parent entry for the current child page */ + if ((parent = BT_POP(&btstack)) == NULL) + /* current page must have been root */ + return 0; + + if ((index = parent->index) == XTENTRYSTART) { + /* + * parent page scan completed + */ + /* go back up to the parent page */ + goto getParent; + } else { + /* + * parent page has entries remaining + */ + /* get back the parent page */ + bn = parent->bn; + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) + return EIO; + + /* first subroot page which + * covers all new allocated blocks + * itself not new/modified. + * (if modified from split of descendent, + * go down path of split page) + + if (nfound == nnew && + !(p->header.flag & (NEW | MOD))) + exit scan; + */ + + /* process parent page entries backward */ + index--; + } + } else { + /* + * first access of each internal page + */ + } + + /* + * internal page: go down to child page of current entry + */ + + /* save current parent entry for the child page */ + BT_PUSH(&btstack, bn, index); + + /* get current entry for the child page */ + e = &p->xad[index]; + + /* + * first access of each internal entry: + */ + /* + * if new entry, log btree_tnewentry. + * + if (e->flag & XAD_NEW) + update parent page lock for the entry; + */ + + /* release parent page */ + XT_PUTPAGE(mp); + + /* get child page */ + bn = e->bn; + XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); + if (rc) + return rc; + + /* + * first access of each non-root page: + */ + /* + * if new, log btree_newpage. + * + if (p->header.flag & NEW) + allocate new page lock; + write a NEWPAGE log (next, prev); + */ + + /* process the child page */ + goto dopage; + + out: + return 0; +} +#endif /* _JFS_WIP */ + + +#ifdef CONFIG_JFS_STATISTICS +int jfs_xtstat_read(char *buffer, char **start, off_t offset, int length, + int *eof, void *data) +{ + int len = 0; + off_t begin; + + len += sprintf(buffer, + "JFS Xtree statistics\n" + "====================\n" + "searches = %d\n" + "fast searches = %d\n" + "splits = %d\n", + xtStat.search, + xtStat.fastSearch, + xtStat.split); + + begin = offset; + *start = buffer + begin; + len -= begin; + + if (len > length) + len = length; + else + *eof = 1; + + if (len < 0) + len = 0; + + return len; +} +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_xtree.h linux.19pre5-ac1/fs/jfs/jfs_xtree.h --- linux.19p5/fs/jfs/jfs_xtree.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/jfs_xtree.h Thu Feb 14 20:46:53 2002 @@ -0,0 +1,143 @@ +/* + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 +*/ +/* + * Change History : + * +*/ + +#ifndef _H_JFS_XTREE +#define _H_JFS_XTREE + +/* + * jfs_xtree.h: extent allocation descriptor B+-tree manager + */ + +#include "jfs_btree.h" + + +/* + * extent allocation descriptor (xad) + */ +typedef struct xad { + unsigned flag:8; /* 1: flag */ + unsigned rsvrd:16; /* 2: reserved */ + unsigned off1:8; /* 1: offset in unit of fsblksize */ + u32 off2; /* 4: offset in unit of fsblksize */ + unsigned len:24; /* 3: length in unit of fsblksize */ + unsigned addr1:8; /* 1: address in unit of fsblksize */ + u32 addr2; /* 4: address in unit of fsblksize */ +} xad_t; /* (16) */ + +#define MAXXLEN ((1 << 24) - 1) + +#define XTSLOTSIZE 16 +#define L2XTSLOTSIZE 4 + +/* xad_t field construction */ +#define XADoffset(xad, offset64)\ +{\ + (xad)->off1 = ((u64)offset64) >> 32;\ + (xad)->off2 = __cpu_to_le32((offset64) & 0xffffffff);\ +} +#define XADaddress(xad, address64)\ +{\ + (xad)->addr1 = ((u64)address64) >> 32;\ + (xad)->addr2 = __cpu_to_le32((address64) & 0xffffffff);\ +} +#define XADlength(xad, length32) (xad)->len = __cpu_to_le24(length32) + +/* xad_t field extraction */ +#define offsetXAD(xad)\ + ( ((s64)((xad)->off1)) << 32 | __le32_to_cpu((xad)->off2)) +#define addressXAD(xad)\ + ( ((s64)((xad)->addr1)) << 32 | __le32_to_cpu((xad)->addr2)) +#define lengthXAD(xad) __le24_to_cpu((xad)->len) + +/* xad list */ +typedef struct { + s16 maxnxad; + s16 nxad; + xad_t *xad; +} xadlist_t; + +/* xad_t flags */ +#define XAD_NEW 0x01 /* new */ +#define XAD_EXTENDED 0x02 /* extended */ +#define XAD_COMPRESSED 0x04 /* compressed with recorded length */ +#define XAD_NOTRECORDED 0x08 /* allocated but not recorded */ +#define XAD_COW 0x10 /* copy-on-write */ + + +/* possible values for maxentry */ +#define XTROOTINITSLOT_DIR 6 +#define XTROOTINITSLOT 10 +#define XTROOTMAXSLOT 18 +#define XTPAGEMAXSLOT 256 +#define XTENTRYSTART 2 + +/* + * xtree page: + */ +typedef union { + struct xtheader { + s64 next; /* 8: */ + s64 prev; /* 8: */ + + u8 flag; /* 1: */ + u8 rsrvd1; /* 1: */ + s16 nextindex; /* 2: next index = number of entries */ + s16 maxentry; /* 2: max number of entries */ + s16 rsrvd2; /* 2: */ + + pxd_t self; /* 8: self */ + } header; /* (32) */ + + xad_t xad[XTROOTMAXSLOT]; /* 16 * maxentry: xad array */ +} xtpage_t; + +/* + * external declaration + */ +extern int xtLookup(struct inode *ip, s64 lstart, s64 llen, + int *pflag, s64 * paddr, int *plen, int flag); +extern int xtLookupList(struct inode *ip, lxdlist_t * lxdlist, + xadlist_t * xadlist, int flag); +extern void xtInitRoot(tid_t tid, struct inode *ip); +extern int xtInsert(tid_t tid, struct inode *ip, + int xflag, s64 xoff, int xlen, s64 * xaddrp, int flag); +extern int xtExtend(tid_t tid, struct inode *ip, s64 xoff, int xlen, + int flag); +extern int xtTailgate(tid_t tid, struct inode *ip, + s64 xoff, int xlen, s64 xaddr, int flag); +extern int xtUpdate(tid_t tid, struct inode *ip, struct xad *nxad); +extern int xtDelete(tid_t tid, struct inode *ip, s64 xoff, int xlen, + int flag); +extern s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int type); +extern s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size); +extern int xtRelocate(tid_t tid, struct inode *ip, + xad_t * oxad, s64 nxaddr, int xtype); +extern int xtAppend(tid_t tid, + struct inode *ip, int xflag, s64 xoff, int maxblocks, + int *xlenp, s64 * xaddrp, int flag); + +#ifdef _JFS_DEBUG_XTREE +extern int xtDisplayTree(struct inode *ip); +extern int xtDisplayPage(struct inode *ip, s64 bn, xtpage_t * p); +#endif /* _JFS_DEBUG_XTREE */ + +#endif /* !_H_JFS_XTREE */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/namei.c linux.19pre5-ac1/fs/jfs/namei.c --- linux.19p5/fs/jfs/namei.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/namei.c Fri Mar 22 16:35:53 2002 @@ -0,0 +1,1461 @@ +/* + * + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + * + * Module: jfs/namei.c + * + */ + +/* + * Change History : + * + */ + +#include +#include +#include "jfs_incore.h" +#include "jfs_inode.h" +#include "jfs_dinode.h" +#include "jfs_dmap.h" +#include "jfs_unicode.h" +#include "jfs_metapage.h" +#include "jfs_debug.h" + +extern struct inode_operations jfs_file_inode_operations; +extern struct inode_operations jfs_symlink_inode_operations; +extern struct file_operations jfs_file_operations; +extern struct address_space_operations jfs_aops; + +extern int jfs_fsync(struct file *, struct dentry *, int); +extern void jfs_truncate_nolock(struct inode *, loff_t); + +/* + * forward references + */ +struct inode_operations jfs_dir_inode_operations; +struct file_operations jfs_dir_operations; + +s64 commitZeroLink(tid_t, struct inode *); + +/* + * NAME: jfs_create(dip, dentry, mode) + * + * FUNCTION: create a regular file in the parent directory + * with name = and mode = + * + * PARAMETER: dip - parent directory vnode + * dentry - dentry of new file + * mode - create mode (rwxrwxrwx). + * + * RETURN: Errors from subroutines + * + */ +int jfs_create(struct inode *dip, struct dentry *dentry, int mode) +{ + int rc = 0; + tid_t tid; /* transaction id */ + struct inode *ip = NULL; /* child directory inode */ + ino_t ino; + component_t dname; /* child directory name */ + btstack_t btstack; + struct inode *iplist[2]; + tblock_t *tblk; + + jFYI(1, ("jfs_create: dip:0x%p name:%s\n", dip, dentry->d_name.name)); + + IWRITE_LOCK(dip); + + /* + * search parent directory for entry/freespace + * (dtSearch() returns parent directory page pinned) + */ + if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab))) + goto out1; + + /* + * Either iAlloc() or txBegin() may block. Deadlock can occur if we + * block there while holding dtree page, so we allocate the inode & + * begin the transaction before we search the directory. + */ + ip = ialloc(dip, mode); + if (ip == NULL) { + rc = ENOSPC; + goto out2; + } + + tid = txBegin(dip->i_sb, 0); + + if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) { + jERROR(1, ("jfs_create: dtSearch returned %d\n", rc)); + ip->i_nlink = 0; + iput(ip); + txEnd(tid); + goto out2; + } + + tblk = tid_to_tblock(tid); + tblk->xflag |= COMMIT_CREATE; + tblk->ip = ip; + + iplist[0] = dip; + iplist[1] = ip; + + /* + * initialize the child XAD tree root in-line in inode + */ + xtInitRoot(tid, ip); + + /* + * create entry in parent directory for child directory + * (dtInsert() releases parent directory page) + */ + ino = ip->i_ino; + if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) { + jERROR(1, ("jfs_create: dtInsert returned %d\n", rc)); + /* discard new inode */ + ip->i_nlink = 0; + iput(ip); + + if (rc == EIO) + txAbort(tid, 1); /* Marks Filesystem dirty */ + else + txAbort(tid, 0); /* Filesystem full */ + txEnd(tid); + goto out2; + } + + ip->i_op = &jfs_file_inode_operations; + ip->i_fop = &jfs_file_operations; + ip->i_mapping->a_ops = &jfs_aops; + + insert_inode_hash(ip); + mark_inode_dirty(ip); + d_instantiate(dentry, ip); + + dip->i_version = ++event; + dip->i_ctime = dip->i_mtime = CURRENT_TIME; + + mark_inode_dirty(dip); + + rc = txCommit(tid, 2, &iplist[0], 0); + txEnd(tid); + + out2: + free_UCSname(&dname); + + out1: + + IWRITE_UNLOCK(dip); + jFYI(1, ("jfs_create: rc:%d\n", -rc)); + return -rc; +} + + +/* + * NAME: jfs_mkdir(dip, dentry, mode) + * + * FUNCTION: create a child directory in the parent directory + * with name = and mode = + * + * PARAMETER: dip - parent directory vnode + * dentry - dentry of child directory + * mode - create mode (rwxrwxrwx). + * + * RETURN: Errors from subroutines + * + * note: + * EACCESS: user needs search+write permission on the parent directory + */ +int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) +{ + int rc = 0; + tid_t tid; /* transaction id */ + struct inode *ip = NULL; /* child directory inode */ + ino_t ino; + component_t dname; /* child directory name */ + btstack_t btstack; + struct inode *iplist[2]; + tblock_t *tblk; + + jFYI(1, ("jfs_mkdir: dip:0x%p name:%s\n", dip, dentry->d_name.name)); + + IWRITE_LOCK(dip); + + /* link count overflow on parent directory ? */ + if (dip->i_nlink == JFS_LINK_MAX) { + rc = EMLINK; + goto out1; + } + + /* + * search parent directory for entry/freespace + * (dtSearch() returns parent directory page pinned) + */ + if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab))) + goto out1; + + /* + * Either iAlloc() or txBegin() may block. Deadlock can occur if we + * block there while holding dtree page, so we allocate the inode & + * begin the transaction before we search the directory. + */ + ip = ialloc(dip, S_IFDIR | mode); + if (ip == NULL) { + rc = ENOSPC; + goto out2; + } + + tid = txBegin(dip->i_sb, 0); + + if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) { + jERROR(1, ("jfs_mkdir: dtSearch returned %d\n", rc)); + ip->i_nlink = 0; + iput(ip); + txEnd(tid); + goto out2; + } + + tblk = tid_to_tblock(tid); + tblk->xflag |= COMMIT_CREATE; + tblk->ip = ip; + + iplist[0] = dip; + iplist[1] = ip; + + /* + * initialize the child directory in-line in inode + */ + dtInitRoot(tid, ip, dip->i_ino); + + /* + * create entry in parent directory for child directory + * (dtInsert() releases parent directory page) + */ + ino = ip->i_ino; + if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) { + jERROR(1, ("jfs_mkdir: dtInsert returned %d\n", rc)); + /* discard new directory inode */ + ip->i_nlink = 0; + iput(ip); + + if (rc == EIO) + txAbort(tid, 1); /* Marks Filesystem dirty */ + else + txAbort(tid, 0); /* Filesystem full */ + txEnd(tid); + goto out2; + } + + ip->i_nlink = 2; /* for '.' */ + ip->i_op = &jfs_dir_inode_operations; + ip->i_fop = &jfs_dir_operations; + ip->i_mapping->a_ops = &jfs_aops; + ip->i_mapping->gfp_mask = GFP_NOFS; + + insert_inode_hash(ip); + mark_inode_dirty(ip); + d_instantiate(dentry, ip); + + /* update parent directory inode */ + dip->i_nlink++; /* for '..' from child directory */ + dip->i_version = ++event; + dip->i_ctime = dip->i_mtime = CURRENT_TIME; + mark_inode_dirty(dip); + + rc = txCommit(tid, 2, &iplist[0], 0); + txEnd(tid); + + out2: + free_UCSname(&dname); + + out1: + + IWRITE_UNLOCK(dip); + + jFYI(1, ("jfs_mkdir: rc:%d\n", -rc)); + return -rc; +} + +/* + * NAME: jfs_rmdir(dip, dentry) + * + * FUNCTION: remove a link to child directory + * + * PARAMETER: dip - parent inode + * dentry - child directory dentry + * + * RETURN: EINVAL - if name is . or .. + * EINVAL - if . or .. exist but are invalid. + * errors from subroutines + * + * note: + * if other threads have the directory open when the last link + * is removed, the "." and ".." entries, if present, are removed before + * rmdir() returns and no new entries may be created in the directory, + * but the directory is not removed until the last reference to + * the directory is released (cf.unlink() of regular file). + */ +int jfs_rmdir(struct inode *dip, struct dentry *dentry) +{ + int rc; + tid_t tid; /* transaction id */ + struct inode *ip = dentry->d_inode; + ino_t ino; + component_t dname; + struct inode *iplist[2]; + tblock_t *tblk; + + jFYI(1, ("jfs_rmdir: dip:0x%p name:%s\n", dip, dentry->d_name.name)); + + IWRITE_LOCK_LIST(2, dip, ip); + + /* directory must be empty to be removed */ + if (!dtEmpty(ip)) { + IWRITE_UNLOCK(ip); + IWRITE_UNLOCK(dip); + rc = ENOTEMPTY; + goto out; + } + + if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab))) { + IWRITE_UNLOCK(ip); + IWRITE_UNLOCK(dip); + goto out; + } + + tid = txBegin(dip->i_sb, 0); + + iplist[0] = dip; + iplist[1] = ip; + + tblk = tid_to_tblock(tid); + tblk->xflag |= COMMIT_DELETE; + tblk->ip = ip; + + /* + * delete the entry of target directory from parent directory + */ + ino = ip->i_ino; + if ((rc = dtDelete(tid, dip, &dname, &ino, JFS_REMOVE))) { + jERROR(1, ("jfs_rmdir: dtDelete returned %d\n", rc)); + if (rc == EIO) + txAbort(tid, 1); + txEnd(tid); + + IWRITE_UNLOCK(ip); + IWRITE_UNLOCK(dip); + + goto out2; + } + + /* update parent directory's link count corresponding + * to ".." entry of the target directory deleted + */ + dip->i_nlink--; + dip->i_ctime = dip->i_mtime = CURRENT_TIME; + dip->i_version = ++event; + mark_inode_dirty(dip); + + /* + * OS/2 could have created EA and/or ACL + */ + /* free EA from both persistent and working map */ + if (JFS_IP(ip)->ea.flag & DXD_EXTENT) { + /* free EA pages */ + txEA(tid, ip, &JFS_IP(ip)->ea, NULL); + } + JFS_IP(ip)->ea.flag = 0; + + /* free ACL from both persistent and working map */ + if (JFS_IP(ip)->acl.flag & DXD_EXTENT) { + /* free ACL pages */ + txEA(tid, ip, &JFS_IP(ip)->acl, NULL); + } + JFS_IP(ip)->acl.flag = 0; + + /* mark the target directory as deleted */ + ip->i_nlink = 0; + mark_inode_dirty(ip); + + rc = txCommit(tid, 2, &iplist[0], 0); + + txEnd(tid); + + IWRITE_UNLOCK(ip); + + /* + * Truncating the directory index table is not guaranteed. It + * may need to be done iteratively + */ + if (test_cflag(COMMIT_Stale, dip)) { + if (dip->i_size > 1) + jfs_truncate_nolock(dip, 0); + + clear_cflag(COMMIT_Stale, dip); + } + + IWRITE_UNLOCK(dip); + + d_delete(dentry); + + out2: + free_UCSname(&dname); + + out: + jFYI(1, ("jfs_rmdir: rc:%d\n", rc)); + return -rc; +} + +/* + * NAME: jfs_unlink(dip, dentry) + * + * FUNCTION: remove a link to object named by + * from parent directory + * + * PARAMETER: dip - inode of parent directory + * dentry - dentry of object to be removed + * + * RETURN: errors from subroutines + * + * note: + * temporary file: if one or more processes have the file open + * when the last link is removed, the link will be removed before + * unlink() returns, but the removal of the file contents will be + * postponed until all references to the files are closed. + * + * JFS does NOT support unlink() on directories. + * + */ +int jfs_unlink(struct inode *dip, struct dentry *dentry) +{ + int rc; + tid_t tid; /* transaction id */ + struct inode *ip = dentry->d_inode; + ino_t ino; + component_t dname; /* object name */ + struct inode *iplist[2]; + tblock_t *tblk; + s64 new_size = 0; + int commit_flag; + + jFYI(1, ("jfs_unlink: dip:0x%p name:%s\n", dip, dentry->d_name.name)); + + if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab))) + goto out; + + IWRITE_LOCK_LIST(2, ip, dip); + + tid = txBegin(dip->i_sb, 0); + + iplist[0] = dip; + iplist[1] = ip; + + /* + * delete the entry of target file from parent directory + */ + ino = ip->i_ino; + if ((rc = dtDelete(tid, dip, &dname, &ino, JFS_REMOVE))) { + jERROR(1, ("jfs_unlink: dtDelete returned %d\n", rc)); + if (rc == EIO) + txAbort(tid, 1); /* Marks FS Dirty */ + txEnd(tid); + IWRITE_UNLOCK(ip); + IWRITE_UNLOCK(dip); + goto out1; + } + + ASSERT(ip->i_nlink); + + ip->i_ctime = dip->i_ctime = dip->i_mtime = CURRENT_TIME; + dip->i_version = ++event; + mark_inode_dirty(dip); + + /* update target's inode */ + ip->i_nlink--; + mark_inode_dirty(ip); + + /* + * commit zero link count object + */ + if (ip->i_nlink == 0) { + assert(!test_cflag(COMMIT_Nolink, ip)); + /* free block resources */ + if ((new_size = commitZeroLink(tid, ip)) < 0) { + txAbort(tid, 1); /* Marks FS Dirty */ + txEnd(tid); + IWRITE_UNLOCK(ip); + IWRITE_UNLOCK(dip); + rc = -new_size; /* We return -rc */ + goto out1; + } + tblk = tid_to_tblock(tid); + tblk->xflag |= COMMIT_DELETE; + tblk->ip = ip; + } + + /* + * Incomplete truncate of file data can + * result in timing problems unless we synchronously commit the + * transaction. + */ + if (new_size) + commit_flag = COMMIT_SYNC; + else + commit_flag = 0; + + /* + * If xtTruncate was incomplete, commit synchronously to avoid + * timing complications + */ + rc = txCommit(tid, 2, &iplist[0], commit_flag); + + txEnd(tid); + + while (new_size && (rc == 0)) { + tid = txBegin(dip->i_sb, 0); + new_size = xtTruncate_pmap(tid, ip, new_size); + if (new_size < 0) { + txAbort(tid, 1); /* Marks FS Dirty */ + rc = -new_size; /* We return -rc */ + } else + rc = txCommit(tid, 2, &iplist[0], COMMIT_SYNC); + txEnd(tid); + } + + if (!test_cflag(COMMIT_Holdlock, ip)) + IWRITE_UNLOCK(ip); + + /* + * Truncating the directory index table is not guaranteed. It + * may need to be done iteratively + */ + if (test_cflag(COMMIT_Stale, dip)) { + if (dip->i_size > 1) + jfs_truncate_nolock(dip, 0); + + clear_cflag(COMMIT_Stale, dip); + } + + IWRITE_UNLOCK(dip); + + d_delete(dentry); + + out1: + free_UCSname(&dname); + out: + jFYI(1, ("jfs_unlink: rc:%d\n", -rc)); + return -rc; +} + +/* + * NAME: commitZeroLink() + * + * FUNCTION: for non-directory, called by jfs_remove(), + * truncate a regular file, directory or symbolic + * link to zero length. return 0 if type is not + * one of these. + * + * if the file is currently associated with a VM segment + * only permanent disk and inode map resources are freed, + * and neither the inode nor indirect blocks are modified + * so that the resources can be later freed in the work + * map by ctrunc1. + * if there is no VM segment on entry, the resources are + * freed in both work and permanent map. + * (? for temporary file - memory object is cached even + * after no reference: + * reference count > 0 - ) + * + * PARAMETERS: cd - pointer to commit data structure. + * current inode is the one to truncate. + * + * RETURN : Errors from subroutines + */ +s64 commitZeroLink(tid_t tid, struct inode *ip) +{ + int filetype; + tblock_t *tblk; + + jFYI(1, ("commitZeroLink: tid = %d, ip = 0x%p\n", tid, ip)); + + filetype = ip->i_mode & S_IFMT; + switch (filetype) { + case S_IFREG: + break; + case S_IFLNK: + /* fast symbolic link */ + if (ip->i_size <= 256) { + ip->i_size = 0; + return 0; + } + break; + default: + assert(filetype != S_IFDIR); + return 0; + } + + set_cflag(COMMIT_Freewmap, ip); + + /* mark transaction of block map update type */ + tblk = tid_to_tblock(tid); + tblk->xflag |= COMMIT_PMAP; + + /* + * free EA + */ + if (JFS_IP(ip)->ea.flag & DXD_EXTENT) + /* acquire maplock on EA to be freed from block map */ + txEA(tid, ip, &JFS_IP(ip)->ea, NULL); + + /* + * free ACL + */ + if (JFS_IP(ip)->acl.flag & DXD_EXTENT) + /* acquire maplock on EA to be freed from block map */ + txEA(tid, ip, &JFS_IP(ip)->acl, NULL); + + /* + * free xtree/data (truncate to zero length): + * free xtree/data pages from cache if COMMIT_PWMAP, + * free xtree/data blocks from persistent block map, and + * free xtree/data blocks from working block map if COMMIT_PWMAP; + */ + if (ip->i_size) + return xtTruncate_pmap(tid, ip, 0); + + return 0; +} + + +/* + * NAME: freeZeroLink() + * + * FUNCTION: for non-directory, called by iClose(), + * free resources of a file from cache and WORKING map + * for a file previously committed with zero link count + * while associated with a pager object, + * + * PARAMETER: ip - pointer to inode of file. + * + * RETURN: 0 -ok + */ +int freeZeroLink(struct inode *ip) +{ + int rc = 0; + int type; + + jFYI(1, ("freeZeroLink: ip = 0x%p\n", ip)); + + /* return if not reg or symbolic link or if size is + * already ok. + */ + type = ip->i_mode & S_IFMT; + + switch (type) { + case S_IFREG: + break; + case S_IFLNK: + /* if its contained in inode nothing to do */ + if (ip->i_size <= 256) + return 0; + break; + default: + return 0; + } + + /* + * free EA + */ + if (JFS_IP(ip)->ea.flag & DXD_EXTENT) { + s64 xaddr; + int xlen; + maplock_t maplock; /* maplock for COMMIT_WMAP */ + pxdlock_t *pxdlock; /* maplock for COMMIT_WMAP */ + + /* free EA pages from cache */ + xaddr = addressDXD(&JFS_IP(ip)->ea); + xlen = lengthDXD(&JFS_IP(ip)->ea); +#ifdef _STILL_TO_PORT + bmExtentInvalidate(ip, xaddr, xlen); +#endif + + /* free EA extent from working block map */ + maplock.index = 1; + pxdlock = (pxdlock_t *) & maplock; + pxdlock->flag = mlckFREEPXD; + PXDaddress(&pxdlock->pxd, xaddr); + PXDlength(&pxdlock->pxd, xlen); + txFreeMap(ip, pxdlock, 0, COMMIT_WMAP); + } + + /* + * free ACL + */ + if (JFS_IP(ip)->acl.flag & DXD_EXTENT) { + s64 xaddr; + int xlen; + maplock_t maplock; /* maplock for COMMIT_WMAP */ + pxdlock_t *pxdlock; /* maplock for COMMIT_WMAP */ + + /* free ACL pages from cache */ + xaddr = addressDXD(&JFS_IP(ip)->acl); + xlen = lengthDXD(&JFS_IP(ip)->acl); +#ifdef _STILL_TO_PORT + bmExtentInvalidate(ip, xaddr, xlen); +#endif + + /* free ACL extent from working block map */ + maplock.index = 1; + pxdlock = (pxdlock_t *) & maplock; + pxdlock->flag = mlckFREEPXD; + PXDaddress(&pxdlock->pxd, xaddr); + PXDlength(&pxdlock->pxd, xlen); + txFreeMap(ip, pxdlock, 0, COMMIT_WMAP); + } + + /* + * free xtree/data (truncate to zero length): + * free xtree/data pages from cache, and + * free xtree/data blocks from working block map; + */ + if (ip->i_size) + rc = xtTruncate(0, ip, 0, COMMIT_WMAP); + + return rc; +} + +/* + * NAME: jfs_link(vp, dvp, name, crp) + * + * FUNCTION: create a link to by the name = + * in the parent directory + * + * PARAMETER: vp - target object + * dvp - parent directory of new link + * name - name of new link to target object + * crp - credential + * + * RETURN: Errors from subroutines + * + * note: + * JFS does NOT support link() on directories (to prevent circular + * path in the directory hierarchy); + * EPERM: the target object is a directory, and either the caller + * does not have appropriate privileges or the implementation prohibits + * using link() on directories [XPG4.2]. + * + * JFS does NOT support links between file systems: + * EXDEV: target object and new link are on different file systems and + * implementation does not support links between file systems [XPG4.2]. + */ +int jfs_link(struct dentry *old_dentry, + struct inode *dir, struct dentry *dentry) +{ + int rc; + tid_t tid; + struct inode *ip = old_dentry->d_inode; + ino_t ino; + component_t dname; + btstack_t btstack; + struct inode *iplist[2]; + + jFYI(1, + ("jfs_link: %s %s\n", old_dentry->d_name.name, + dentry->d_name.name)); + + /* JFS does NOT support link() on directories */ + if (S_ISDIR(ip->i_mode)) + return -EPERM; + + IWRITE_LOCK_LIST(2, dir, ip); + + tid = txBegin(ip->i_sb, 0); + + if (ip->i_nlink == JFS_LINK_MAX) { + rc = EMLINK; + goto out; + } + + /* + * scan parent directory for entry/freespace + */ + if ((rc = get_UCSname(&dname, dentry, JFS_SBI(ip->i_sb)->nls_tab))) + goto out; + + if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE))) + goto out; + + /* + * create entry for new link in parent directory + */ + ino = ip->i_ino; + if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack))) + goto out; + + dir->i_version = ++event; + + /* update object inode */ + ip->i_nlink++; /* for new link */ + ip->i_ctime = CURRENT_TIME; + mark_inode_dirty(dir); + atomic_inc(&ip->i_count); + d_instantiate(dentry, ip); + + iplist[0] = ip; + iplist[1] = dir; + rc = txCommit(tid, 2, &iplist[0], 0); + + out: + IWRITE_UNLOCK(dir); + IWRITE_UNLOCK(ip); + + txEnd(tid); + + jFYI(1, ("jfs_link: rc:%d\n", rc)); + return -rc; +} + +/* + * NAME: jfs_symlink(dip, dentry, name) + * + * FUNCTION: creates a symbolic link to by name + * in directory + * + * PARAMETER: dip - parent directory vnode + * dentry - dentry of symbolic link + * name - the path name of the existing object + * that will be the source of the link + * + * RETURN: errors from subroutines + * + * note: + * ENAMETOOLONG: pathname resolution of a symbolic link produced + * an intermediate result whose length exceeds PATH_MAX [XPG4.2] +*/ + +int jfs_symlink(struct inode *dip, struct dentry *dentry, const char *name) +{ + int rc; + tid_t tid; + ino_t ino = 0; + component_t dname; + int ssize; /* source pathname size */ + btstack_t btstack; + struct inode *ip = dentry->d_inode; + unchar *i_fastsymlink; + s64 xlen = 0; + int bmask = 0, xsize; + s64 xaddr; + metapage_t *mp; + struct super_block *sb; + tblock_t *tblk; + + struct inode *iplist[2]; + + jFYI(1, ("jfs_symlink: dip:0x%p name:%s\n", dip, name)); + + IWRITE_LOCK(dip); + + ssize = strlen(name) + 1; + + tid = txBegin(dip->i_sb, 0); + + /* + * search parent directory for entry/freespace + * (dtSearch() returns parent directory page pinned) + */ + + if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab))) + goto out1; + + if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) + goto out2; + + + + /* + * allocate on-disk/in-memory inode for symbolic link: + * (iAlloc() returns new, locked inode) + */ + + ip = ialloc(dip, S_IFLNK | 0777); + if (ip == NULL) { + BT_PUTSEARCH(&btstack); + rc = ENOSPC; + goto out2; + } + + tblk = tid_to_tblock(tid); + tblk->xflag |= COMMIT_CREATE; + tblk->ip = ip; + + /* + * create entry for symbolic link in parent directory + */ + + ino = ip->i_ino; + + + + if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) { + jERROR(1, ("jfs_symlink: dtInsert returned %d\n", rc)); + /* discard ne inode */ + ip->i_nlink = 0; + iput(ip); + goto out2; + + } + + /* fix symlink access permission + * (dir_create() ANDs in the u.u_cmask, + * but symlinks really need to be 777 access) + */ + ip->i_mode |= 0777; + + /* + * write symbolic link target path name + */ + xtInitRoot(tid, ip); + + /* + * write source path name inline in on-disk inode (fast symbolic link) + */ + + if (ssize <= IDATASIZE) { + ip->i_op = &jfs_symlink_inode_operations; + + i_fastsymlink = JFS_IP(ip)->i_inline; + memcpy(i_fastsymlink, name, ssize); + ip->i_size = ssize - 1; + jFYI(1, + ("jfs_symlink: fast symlink added ssize:%d name:%s \n", + ssize, name)); + } + /* + * write source path name in a single extent + */ + else { + jFYI(1, ("jfs_symlink: allocate extent ip:0x%p\n", ip)); + + ip->i_op = &page_symlink_inode_operations; + ip->i_mapping->a_ops = &jfs_aops; + + /* + * even though the data of symlink object (source + * path name) is treated as non-journaled user data, + * it is read/written thru buffer cache for performance. + */ + sb = ip->i_sb; + bmask = JFS_SBI(sb)->bsize - 1; + xsize = (ssize + bmask) & ~bmask; + xaddr = 0; + xlen = xsize >> JFS_SBI(sb)->l2bsize; + if ((rc = xtInsert(tid, ip, 0, 0, xlen, &xaddr, 0)) == 0) { + ip->i_size = ssize - 1; + while (ssize) { + int copy_size = min(ssize, PSIZE); + + mp = get_metapage(ip, xaddr, PSIZE, 1); + + if (mp == NULL) { + dtDelete(tid, dip, &dname, &ino, + JFS_REMOVE); + ip->i_nlink = 0; + iput(ip); + rc = EIO; + goto out2; + } + memcpy(mp->data, name, copy_size); + flush_metapage(mp); +#if 0 + mark_buffer_uptodate(bp, 1); + mark_buffer_dirty(bp, 1); + if (IS_SYNC(dip)) { + ll_rw_block(WRITE, 1, &bp); + wait_on_buffer(bp); + } + brelse(bp); +#endif /* 0 */ + ssize -= copy_size; + xaddr += JFS_SBI(sb)->nbperpage; + } + ip->i_blocks = LBLK2PBLK(sb, xlen); + } else { + dtDelete(tid, dip, &dname, &ino, JFS_REMOVE); + ip->i_nlink = 0; + iput(ip); + rc = ENOSPC; + goto out2; + } + } + dip->i_version = ++event; + + insert_inode_hash(ip); + mark_inode_dirty(ip); + d_instantiate(dentry, ip); + + /* + * commit update of parent directory and link object + * + * if extent allocation failed (ENOSPC), + * the parent inode is committed regardless to avoid + * backing out parent directory update (by dtInsert()) + * and subsequent dtDelete() which is harmless wrt + * integrity concern. + * the symlink inode will be freed by iput() at exit + * as it has a zero link count (by dtDelete()) and + * no permanant resources. + */ + + iplist[0] = dip; + if (rc == 0) { + iplist[1] = ip; + rc = txCommit(tid, 2, &iplist[0], 0); + } else + rc = txCommit(tid, 1, &iplist[0], 0); + + out2: + + free_UCSname(&dname); + out1: + IWRITE_UNLOCK(dip); + + txEnd(tid); + + jFYI(1, ("jfs_symlink: rc:%d\n", -rc)); + return -rc; +} + + +/* + * NAME: jfs_rename + * + * FUNCTION: rename a file or directory + */ +int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry) +{ + btstack_t btstack; + ino_t ino; + component_t new_dname; + struct inode *new_ip; + component_t old_dname; + struct inode *old_ip; + int rc; + tid_t tid; + tlock_t *tlck; + dtlock_t *dtlck; + lv_t *lv; + int ipcount; + struct inode *iplist[4]; + tblock_t *tblk; + s64 new_size = 0; + int commit_flag; + + + jFYI(1, + ("jfs_rename: %s %s\n", old_dentry->d_name.name, + new_dentry->d_name.name)); + + old_ip = old_dentry->d_inode; + new_ip = new_dentry->d_inode; + + if (old_dir == new_dir) { + if (new_ip) + IWRITE_LOCK_LIST(3, old_dir, old_ip, new_ip); + else + IWRITE_LOCK_LIST(2, old_dir, old_ip); + } else { + if (new_ip) + IWRITE_LOCK_LIST(4, old_dir, new_dir, old_ip, + new_ip); + else + IWRITE_LOCK_LIST(3, old_dir, new_dir, old_ip); + } + + if ((rc = get_UCSname(&old_dname, old_dentry, + JFS_SBI(old_dir->i_sb)->nls_tab))) + goto out1; + + if ((rc = get_UCSname(&new_dname, new_dentry, + JFS_SBI(old_dir->i_sb)->nls_tab))) + goto out2; + + /* + * Make sure source inode number is what we think it is + */ + rc = dtSearch(old_dir, &old_dname, &ino, &btstack, JFS_LOOKUP); + if (rc || (ino != old_ip->i_ino)) { + rc = ENOENT; + goto out3; + } + + /* + * Make sure dest inode number (if any) is what we think it is + */ + rc = dtSearch(new_dir, &new_dname, &ino, &btstack, JFS_LOOKUP); + if (rc == 0) { + if ((new_ip == 0) || (ino != new_ip->i_ino)) { + rc = ESTALE; + goto out3; + } + } else if (rc != ENOENT) + goto out3; + else if (new_ip) { + /* no entry exists, but one was expected */ + rc = ESTALE; + goto out3; + } + + if (S_ISDIR(old_ip->i_mode)) { + if (new_ip) { + if (!dtEmpty(new_ip)) { + rc = ENOTEMPTY; + goto out3; + } + } else if ((new_dir != old_dir) && + (new_dir->i_nlink == JFS_LINK_MAX)) { + rc = EMLINK; + goto out3; + } + } + + /* + * The real work starts here + */ + tid = txBegin(new_dir->i_sb, 0); + + if (new_ip) { + /* + * Change existing directory entry to new inode number + */ + ino = new_ip->i_ino; + rc = dtModify(tid, new_dir, &new_dname, &ino, + old_ip->i_ino, JFS_RENAME); + if (rc) + goto out4; + new_ip->i_nlink--; + if (S_ISDIR(new_ip->i_mode)) { + new_ip->i_nlink--; + assert(new_ip->i_nlink == 0); + tblk = tid_to_tblock(tid); + tblk->xflag |= COMMIT_DELETE; + tblk->ip = new_ip; + } else if (new_ip->i_nlink == 0) { + assert(!test_cflag(COMMIT_Nolink, new_ip)); + /* free block resources */ + if ((new_size = commitZeroLink(tid, new_ip)) < 0) { + txAbort(tid, 1); /* Marks FS Dirty */ + rc = -new_size; /* We return -rc */ + goto out4; + } + tblk = tid_to_tblock(tid); + tblk->xflag |= COMMIT_DELETE; + tblk->ip = new_ip; + } else { + new_ip->i_ctime = CURRENT_TIME; + mark_inode_dirty(new_ip); + } + } else { + /* + * Add new directory entry + */ + rc = dtSearch(new_dir, &new_dname, &ino, &btstack, + JFS_CREATE); + if (rc) { + jERROR(1, + ("jfs_rename didn't expect dtSearch to fail w/rc = %d\n", + rc)); + goto out4; + } + + ino = old_ip->i_ino; + rc = dtInsert(tid, new_dir, &new_dname, &ino, &btstack); + if (rc) { + jERROR(1, + ("jfs_rename: dtInsert failed w/rc = %d\n", + rc)); + goto out4; + } + if (S_ISDIR(old_ip->i_mode)) + new_dir->i_nlink++; + } + /* + * Remove old directory entry + */ + + ino = old_ip->i_ino; + rc = dtDelete(tid, old_dir, &old_dname, &ino, JFS_REMOVE); + if (rc) { + jERROR(1, + ("jfs_rename did not expect dtDelete to return rc = %d\n", + rc)); + txAbort(tid, 1); /* Marks Filesystem dirty */ + goto out4; + } + if (S_ISDIR(old_ip->i_mode)) { + old_dir->i_nlink--; + if (old_dir != new_dir) { + /* + * Change inode number of parent for moved directory + */ + + JFS_IP(old_ip)->i_dtroot.header.idotdot = + cpu_to_le32(new_dir->i_ino); + + /* Linelock header of dtree */ + tlck = txLock(tid, old_ip, + (metapage_t *) & JFS_IP(old_ip)->bxflag, + tlckDTREE | tlckBTROOT); + dtlck = (dtlock_t *) & tlck->lock; + ASSERT(dtlck->index == 0); + lv = (lv_t *) & dtlck->lv[0]; + lv->offset = 0; + lv->length = 1; + dtlck->index++; + } + } + + /* + * Update ctime on changed/moved inodes & mark dirty + */ + old_ip->i_ctime = CURRENT_TIME; + mark_inode_dirty(old_ip); + + new_dir->i_version = ++event; + new_dir->i_ctime = CURRENT_TIME; + mark_inode_dirty(new_dir); + + /* Build list of inodes modified by this transaction */ + ipcount = 0; + iplist[ipcount++] = old_ip; + if (new_ip) + iplist[ipcount++] = new_ip; + iplist[ipcount++] = old_dir; + + if (old_dir != new_dir) { + iplist[ipcount++] = new_dir; + old_dir->i_version = ++event; + old_dir->i_ctime = CURRENT_TIME; + mark_inode_dirty(old_dir); + } + + /* + * Incomplete truncate of file data can + * result in timing problems unless we synchronously commit the + * transaction. + */ + if (new_size) + commit_flag = COMMIT_SYNC; + else + commit_flag = 0; + + rc = txCommit(tid, ipcount, iplist, commit_flag); + + /* + * Don't unlock new_ip if COMMIT_HOLDLOCK is set + */ + if (new_ip && test_cflag(COMMIT_Holdlock, new_ip)) + new_ip = 0; + + out4: + txEnd(tid); + + while (new_size && (rc == 0)) { + tid = txBegin(new_ip->i_sb, 0); + new_size = xtTruncate_pmap(tid, new_ip, new_size); + if (new_size < 0) { + txAbort(tid, 1); + rc = -new_size; /* We return -rc */ + } else + rc = txCommit(tid, 1, &new_ip, COMMIT_SYNC); + txEnd(tid); + } + out3: + free_UCSname(&new_dname); + out2: + free_UCSname(&old_dname); + out1: + IWRITE_UNLOCK(old_ip); + if (old_dir != new_dir) + IWRITE_UNLOCK(new_dir); + if (new_ip) + IWRITE_UNLOCK(new_ip); + + /* + * Truncating the directory index table is not guaranteed. It + * may need to be done iteratively + */ + if (test_cflag(COMMIT_Stale, old_dir)) { + if (old_dir->i_size > 1) + jfs_truncate_nolock(old_dir, 0); + + clear_cflag(COMMIT_Stale, old_dir); + } + + IWRITE_UNLOCK(old_dir); + + jFYI(1, ("jfs_rename: returning %d\n", rc)); + return -rc; +} + + +/* + * NAME: jfs_mknod + * + * FUNCTION: Create a special file (device) + */ +int jfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev) +{ + btstack_t btstack; + component_t dname; + ino_t ino; + struct inode *ip; + struct inode *iplist[2]; + int rc; + tid_t tid; + tblock_t *tblk; + + jFYI(1, ("jfs_mknod: %s\n", dentry->d_name.name)); + + if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dir->i_sb)->nls_tab))) + goto out; + + IWRITE_LOCK(dir); + + ip = ialloc(dir, mode); + if (ip == NULL) { + rc = ENOSPC; + goto out1; + } + + tid = txBegin(dir->i_sb, 0); + + if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE))) { + ip->i_nlink = 0; + iput(ip); + txEnd(tid); + goto out1; + } + + tblk = tid_to_tblock(tid); + tblk->xflag |= COMMIT_CREATE; + tblk->ip = ip; + + ino = ip->i_ino; + if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack))) { + ip->i_nlink = 0; + iput(ip); + txEnd(tid); + goto out1; + } + + if (S_ISREG(ip->i_mode)) { + ip->i_op = &jfs_file_inode_operations; + ip->i_fop = &jfs_file_operations; + ip->i_mapping->a_ops = &jfs_aops; + } else + init_special_inode(ip, ip->i_mode, rdev); + + insert_inode_hash(ip); + mark_inode_dirty(ip); + d_instantiate(dentry, ip); + + dir->i_version = ++event; + dir->i_ctime = dir->i_mtime = CURRENT_TIME; + + mark_inode_dirty(dir); + + iplist[0] = dir; + iplist[1] = ip; + rc = txCommit(tid, 2, iplist, 0); + txEnd(tid); + + out1: + IWRITE_UNLOCK(dir); + free_UCSname(&dname); + + out: + jFYI(1, ("jfs_mknod: returning %d\n", rc)); + return -rc; +} + +static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry) +{ + btstack_t btstack; + ino_t inum; + struct inode *ip; + component_t key; + const char *name = dentry->d_name.name; + int len = dentry->d_name.len; + int rc; + + jFYI(1, ("jfs_lookup: name = %s\n", name)); + + + if ((name[0] == '.') && (len == 1)) + inum = dip->i_ino; + else if (strcmp(name, "..") == 0) + inum = PARENT(dip); + else { + if ((rc = + get_UCSname(&key, dentry, JFS_SBI(dip->i_sb)->nls_tab))) + return ERR_PTR(-rc); + IREAD_LOCK(dip); + rc = dtSearch(dip, &key, &inum, &btstack, JFS_LOOKUP); + IREAD_UNLOCK(dip); + free_UCSname(&key); + if (rc == ENOENT) { + d_add(dentry, NULL); + return ERR_PTR(0); + } else if (rc) { + jERROR(1, + ("jfs_lookup: dtSearch returned %d\n", rc)); + return ERR_PTR(-rc); + } + } + + ip = iget(dip->i_sb, inum); + if (ip == NULL) { + jERROR(1, + ("jfs_lookup: iget failed on inum %d\n", + (uint) inum)); + return ERR_PTR(-EACCES); + } + + d_add(dentry, ip); + + return ERR_PTR(0); +} + +struct inode_operations jfs_dir_inode_operations = { + create: jfs_create, + lookup: jfs_lookup, + link: jfs_link, + unlink: jfs_unlink, + symlink: jfs_symlink, + mkdir: jfs_mkdir, + rmdir: jfs_rmdir, + mknod: jfs_mknod, + rename: jfs_rename, +}; + +struct file_operations jfs_dir_operations = { + read: generic_read_dir, + readdir: jfs_readdir, + fsync: jfs_fsync, +}; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/super.c linux.19pre5-ac1/fs/jfs/super.c --- linux.19p5/fs/jfs/super.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/super.c Wed Mar 20 15:53:57 2002 @@ -0,0 +1,482 @@ +/* + * + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include "jfs_incore.h" +#include "jfs_filsys.h" +#include "jfs_metapage.h" +#include "jfs_superblock.h" +#include "jfs_dmap.h" +#include "jfs_imap.h" +#include "jfs_debug.h" + +MODULE_DESCRIPTION("The Journaled Filesystem (JFS)"); +MODULE_AUTHOR("Steve Best/Dave Kleikamp/Barry Arndt, IBM"); +MODULE_LICENSE("GPL"); + +static int in_shutdown; +static pid_t jfsIOthread; +static pid_t jfsCommitThread; +static pid_t jfsSyncThread; +struct task_struct *jfsIOtask; +struct task_struct *jfsCommitTask; +struct task_struct *jfsSyncTask; +DECLARE_COMPLETION(jfsIOwait); + +#ifdef CONFIG_JFS_DEBUG +int jfsloglevel = 1; +MODULE_PARM(jfsloglevel, "i"); +MODULE_PARM_DESC(jfsloglevel, "Specify JFS loglevel (0, 1 or 2)"); +#endif + +/* + * External declarations + */ +extern int jfs_mount(struct super_block *); +extern int jfs_mount_rw(struct super_block *, int); +extern int jfs_umount(struct super_block *); +extern int jfs_umount_rw(struct super_block *); + +extern int jfsIOWait(void *); +extern int jfs_lazycommit(void *); +extern int jfs_sync(void *); +extern void jfs_put_inode(struct inode *inode); +extern void jfs_read_inode(struct inode *inode); +extern void jfs_dirty_inode(struct inode *inode); +extern void jfs_delete_inode(struct inode *inode); +extern void jfs_write_inode(struct inode *inode, int wait); + +#if defined(CONFIG_JFS_DEBUG) && defined(CONFIG_PROC_FS) +extern void jfs_proc_init(void); +extern void jfs_proc_clean(void); +#endif + +int jfs_thread_stopped(void) +{ + unsigned long signr; + siginfo_t info; + + spin_lock_irq(¤t->sigmask_lock); + signr = dequeue_signal(¤t->blocked, &info); + spin_unlock_irq(¤t->sigmask_lock); + + if (signr == SIGKILL && in_shutdown) + return 1; + return 0; +} + +static int jfs_statfs(struct super_block *sb, struct statfs *buf) +{ + struct jfs_sb_info *sbi = JFS_SBI(sb); + s64 maxinodes; + imap_t *imap = JFS_IP(sbi->ipimap)->i_imap; + + jFYI(1, ("In jfs_statfs\n")); + buf->f_type = JFS_SUPER_MAGIC; + buf->f_bsize = sbi->bsize; + buf->f_blocks = sbi->bmap->db_mapsize; + buf->f_bfree = sbi->bmap->db_nfree; + buf->f_bavail = sbi->bmap->db_nfree; + /* + * If we really return the number of allocated & free inodes, some + * applications will fail because they won't see enough free inodes. + * We'll try to calculate some guess as to how may inodes we can + * really allocate + * + * buf->f_files = atomic_read(&imap->im_numinos); + * buf->f_ffree = atomic_read(&imap->im_numfree); + */ + maxinodes = min((s64) atomic_read(&imap->im_numinos) + + ((sbi->bmap->db_nfree >> imap->im_l2nbperiext) + << L2INOSPEREXT), (s64)0xffffffffLL); + buf->f_files = maxinodes; + buf->f_ffree = maxinodes - (atomic_read(&imap->im_numinos) - + atomic_read(&imap->im_numfree)); + + buf->f_namelen = JFS_NAME_MAX; + return 0; +} + +static void jfs_put_super(struct super_block *sb) +{ + struct jfs_sb_info *sbi = JFS_SBI(sb); + int rc; + + jFYI(1, ("In jfs_put_super\n")); + rc = jfs_umount(sb); + if (rc) { + jERROR(1, ("jfs_umount failed with return code %d\n", rc)); + } + unload_nls(sbi->nls_tab); + sbi->nls_tab = NULL; + + /* + * We need to clean out the direct_inode pages since this inode + * is not in the inode hash. + */ + fsync_inode_data_buffers(sbi->direct_inode); + truncate_inode_pages(sbi->direct_mapping, 0); + iput(sbi->direct_inode); + sbi->direct_inode = NULL; + sbi->direct_mapping = NULL; + + JFS_SBI(sb) = 0; + kfree(sbi); +} + +static int parse_options (char * options, struct jfs_sb_info *sbi) +{ + void *nls_map = NULL; + char * this_char; + char * value; + + if (!options) + return 1; + for (this_char = strtok (options, ","); + this_char != NULL; + this_char = strtok (NULL, ",")) { + if ((value = strchr (this_char, '=')) != NULL) + *value++ = 0; + if (!strcmp (this_char, "iocharset")) { + if (!value || !*value) + goto needs_arg; + if (nls_map) /* specified iocharset twice! */ + unload_nls(nls_map); + nls_map = load_nls(value); + if (!nls_map) { + printk(KERN_ERR "JFS: charset not found\n"); + goto cleanup; + } + /* Silently ignore the quota options */ + } else if (!strcmp (this_char, "grpquota") + || !strcmp (this_char, "noquota") + || !strcmp (this_char, "quota") + || !strcmp (this_char, "usrquota")) + /* Don't do anything ;-) */ ; + else { + printk ("jfs: Unrecognized mount option %s\n", this_char); + goto cleanup; + } + } + if (nls_map) { + /* Discard old (if remount) */ + if (sbi->nls_tab) + unload_nls(sbi->nls_tab); + sbi->nls_tab = nls_map; + } + return 1; +needs_arg: + printk(KERN_ERR "JFS: %s needs an argument\n", this_char); +cleanup: + if (nls_map) + unload_nls(nls_map); + return 0; +} + +int jfs_remount(struct super_block *sb, int *flags, char *data) +{ + struct jfs_sb_info *sbi = JFS_SBI(sb); + + if (!parse_options(data, sbi)) { + return -EINVAL; + } + + if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) { + /* + * Invalidate any previously read metadata. fsck may + * have changed the on-disk data since we mounted r/o + */ + truncate_inode_pages(sbi->direct_mapping, 0); + + return jfs_mount_rw(sb, 1); + } else if ((!(sb->s_flags & MS_RDONLY)) && (*flags & MS_RDONLY)) + return jfs_umount_rw(sb); + + return 0; +} + +static struct super_operations jfs_sops = { + read_inode: jfs_read_inode, + dirty_inode: jfs_dirty_inode, + write_inode: jfs_write_inode, + put_inode: jfs_put_inode, + delete_inode: jfs_delete_inode, + put_super: jfs_put_super, + statfs: jfs_statfs, + remount_fs: jfs_remount, + clear_inode: diClearExtension, +}; + +static struct super_block *jfs_read_super(struct super_block *sb, + void *data, int silent) +{ + struct jfs_sb_info *sbi; + struct inode *inode; + int rc; + + jFYI(1, + ("In jfs_read_super s_dev=0x%x s_flags=0x%lx\n", sb->s_dev, + sb->s_flags)); + + sbi = kmalloc(sizeof(struct jfs_sb_info), GFP_KERNEL); + JFS_SBI(sb) = sbi; + if (!sbi) + return NULL; + memset(sbi, 0, sizeof(struct jfs_sb_info)); + + if (!parse_options((char *)data, sbi)) { + kfree(sbi); + return NULL; + } + + /* + * Initialize blocksize to 4K. + */ + sb->s_blocksize = PSIZE; + sb->s_blocksize_bits = L2PSIZE; + set_blocksize(sb->s_dev, PSIZE); + + /* + * Initialize direct-mapping inode/address-space + */ + inode = new_inode(sb); + if (inode == NULL) + goto out_kfree; + inode->i_ino = 0; + inode->i_nlink = 1; + inode->i_size = 0x0000010000000000LL; + inode->i_mapping->a_ops = &direct_aops; + inode->i_mapping->gfp_mask = GFP_NOFS; + + sbi->direct_inode = inode; + sbi->direct_mapping = inode->i_mapping; + + rc = alloc_jfs_inode(inode); + if (rc) + goto out_free_inode; + + sb->s_op = &jfs_sops; + rc = jfs_mount(sb); + if (rc) { + if (!silent) { + jERROR(1, + ("jfs_mount failed w/return code = %d\n", + rc)); + } + goto out_mount_failed; + } + if (sb->s_flags & MS_RDONLY) + sbi->log = 0; + else { + rc = jfs_mount_rw(sb, 0); + if (rc) { + if (!silent) { + jERROR(1, + ("jfs_mount_rw failed w/return code = %d\n", + rc)); + } + goto out_no_rw; + } + } + + sb->s_magic = JFS_SUPER_MAGIC; + + inode = iget(sb, ROOT_I); + if (!inode || is_bad_inode(inode)) + goto out_no_root; + sb->s_root = d_alloc_root(inode); + if (!sb->s_root) + goto out_no_root; + + if (!sbi->nls_tab) + sbi->nls_tab = load_nls_default(); + + sb->s_maxbytes = ((u64) sb->s_blocksize) << 40; +#if BITS_PER_LONG == 32 + sb->s_maxbytes = min((u64)PAGE_CACHE_SIZE << 32, sb->s_maxbytes); +#endif + + return sb; + +out_no_root: + jEVENT(1, ("jfs_read_super: get root inode failed\n")); + if (inode) + iput(inode); + +out_no_rw: + rc = jfs_umount(sb); + if (rc) { + jERROR(1, ("jfs_umount failed with return code %d\n", rc)); + } +out_mount_failed: + fsync_inode_data_buffers(sbi->direct_inode); + truncate_inode_pages(sbi->direct_mapping, 0); + sb->s_op = NULL; + + free_jfs_inode(inode); + +out_free_inode: + iput(sbi->direct_inode); + sbi->direct_inode = NULL; + sbi->direct_mapping = NULL; +out_kfree: + if (sbi->nls_tab) + unload_nls(sbi->nls_tab); + kfree(sbi); + return NULL; +} + +static DECLARE_FSTYPE_DEV(jfs_fs_type, "jfs", jfs_read_super); + +extern int metapage_init(void); +extern int txInit(void); +extern void txExit(void); +extern void metapage_exit(void); + +static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +{ + struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo; + + if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == + SLAB_CTOR_CONSTRUCTOR) { + INIT_LIST_HEAD(&jfs_ip->anon_inode_list); + INIT_LIST_HEAD(&jfs_ip->mp_list); + RDWRLOCK_INIT(&jfs_ip->rdwrlock); + } +} + +static int __init init_jfs_fs(void) +{ + int rc; + + printk("JFS development version: $Name: $\n"); + + jfs_inode_cachep = + kmem_cache_create("jfs_ip", + sizeof(struct jfs_inode_info), + 0, 0, init_once, NULL); + if (jfs_inode_cachep == NULL) + return -ENOMEM; + + /* + * Metapage initialization + */ + rc = metapage_init(); + if (rc) { + jERROR(1, ("metapage_init failed w/rc = %d\n", rc)); + goto free_slab; + } + + /* + * Transaction Manager initialization + */ + rc = txInit(); + if (rc) { + jERROR(1, ("txInit failed w/rc = %d\n", rc)); + goto free_metapage; + } + + /* + * I/O completion thread (endio) + */ + jfsIOthread = kernel_thread(jfsIOWait, 0, + CLONE_FS | CLONE_FILES | + CLONE_SIGHAND); + if (jfsIOthread < 0) { + jERROR(1, + ("init_jfs_fs: fork failed w/rc = %d\n", + jfsIOthread)); + goto end_txmngr; + } + wait_for_completion(&jfsIOwait); /* Wait until IO thread starts */ + + jfsCommitThread = kernel_thread(jfs_lazycommit, 0, + CLONE_FS | CLONE_FILES | + CLONE_SIGHAND); + if (jfsCommitThread < 0) { + jERROR(1, + ("init_jfs_fs: fork failed w/rc = %d\n", + jfsCommitThread)); + goto kill_iotask; + } + wait_for_completion(&jfsIOwait); /* Wait until IO thread starts */ + + jfsSyncThread = kernel_thread(jfs_sync, 0, + CLONE_FS | CLONE_FILES | + CLONE_SIGHAND); + if (jfsSyncThread < 0) { + jERROR(1, + ("init_jfs_fs: fork failed w/rc = %d\n", + jfsSyncThread)); + goto kill_committask; + } + wait_for_completion(&jfsIOwait); /* Wait until IO thread starts */ + +#if defined(CONFIG_JFS_DEBUG) && defined(CONFIG_PROC_FS) + jfs_proc_init(); +#endif + + return register_filesystem(&jfs_fs_type); + + +kill_committask: + send_sig(SIGKILL, jfsCommitTask, 1); + wait_for_completion(&jfsIOwait); /* Wait until Commit thread exits */ +kill_iotask: + send_sig(SIGKILL, jfsIOtask, 1); + wait_for_completion(&jfsIOwait); /* Wait until IO thread exits */ +end_txmngr: + txExit(); +free_metapage: + metapage_exit(); +free_slab: + kmem_cache_destroy(jfs_inode_cachep); + return -rc; +} + +static void __exit exit_jfs_fs(void) +{ + jFYI(1, ("exit_jfs_fs called\n")); + + in_shutdown = 1; + txExit(); + metapage_exit(); + send_sig(SIGKILL, jfsIOtask, 1); + wait_for_completion(&jfsIOwait); /* Wait until IO thread exits */ + send_sig(SIGKILL, jfsCommitTask, 1); + wait_for_completion(&jfsIOwait); /* Wait until Commit thread exits */ + send_sig(SIGKILL, jfsSyncTask, 1); + wait_for_completion(&jfsIOwait); /* Wait until Sync thread exits */ +#if defined(CONFIG_JFS_DEBUG) && defined(CONFIG_PROC_FS) + jfs_proc_clean(); +#endif + unregister_filesystem(&jfs_fs_type); + kmem_cache_destroy(jfs_inode_cachep); +} + + +EXPORT_NO_SYMBOLS; + +module_init(init_jfs_fs) +module_exit(exit_jfs_fs) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/symlink.c linux.19pre5-ac1/fs/jfs/symlink.c --- linux.19p5/fs/jfs/symlink.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/fs/jfs/symlink.c Thu Feb 14 20:46:53 2002 @@ -0,0 +1,47 @@ + +/* + * + * Copyright (c) International Business Machines Corp., 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + * + * JFS fast symlink handling code + */ + +#include +#include "jfs_incore.h" + +static int jfs_readlink(struct dentry *, char *buffer, int buflen); +static int jfs_follow_link(struct dentry *dentry, struct nameidata *nd); + +/* + * symlinks can't do much... + */ +struct inode_operations jfs_symlink_inode_operations = { + readlink: jfs_readlink, + follow_link: jfs_follow_link, +}; + +static int jfs_follow_link(struct dentry *dentry, struct nameidata *nd) +{ + char *s = JFS_IP(dentry->d_inode)->i_inline; + return vfs_follow_link(nd, s); +} + +static int jfs_readlink(struct dentry *dentry, char *buffer, int buflen) +{ + char *s = JFS_IP(dentry->d_inode)->i_inline; + return vfs_readlink(dentry, buffer, buflen, s); +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/lockd/svc4proc.c linux.19pre5-ac1/fs/lockd/svc4proc.c --- linux.19p5/fs/lockd/svc4proc.c Thu Apr 4 13:18:10 2002 +++ linux.19pre5-ac1/fs/lockd/svc4proc.c Thu Mar 21 00:48:42 2002 @@ -447,11 +447,13 @@ if (nlmsvc_ops != NULL) { struct svc_client *clnt; saddr.sin_addr.s_addr = argp->addr; + nlmsvc_ops->exp_readlock(); if ((clnt = nlmsvc_ops->exp_getclient(&saddr)) != NULL && (host = nlm_lookup_host(clnt, &saddr, 0, 0)) != NULL) { nlmsvc_free_host_resources(host); } nlm_release_host(host); + nlmsvc_ops->exp_unlock(); } return rpc_success; @@ -524,7 +526,7 @@ struct nlm_void { int dummy; }; -#define PROC(name, xargt, xrest, argt, rest) \ +#define PROC(name, xargt, xrest, argt, rest, respsize) \ { (svc_procfunc) nlm4svc_proc_##name, \ (kxdrproc_t) nlm4svc_decode_##xargt, \ (kxdrproc_t) nlm4svc_encode_##xrest, \ @@ -532,33 +534,34 @@ sizeof(struct nlm_##argt), \ sizeof(struct nlm_##rest), \ 0, \ - 0 \ + 0, \ + respsize, \ } struct svc_procedure nlmsvc_procedures4[] = { - PROC(null, void, void, void, void), - PROC(test, testargs, testres, args, res), - PROC(lock, lockargs, res, args, res), - PROC(cancel, cancargs, res, args, res), - PROC(unlock, unlockargs, res, args, res), - PROC(granted, testargs, res, args, res), - PROC(test_msg, testargs, norep, args, void), - PROC(lock_msg, lockargs, norep, args, void), - PROC(cancel_msg, cancargs, norep, args, void), - PROC(unlock_msg, unlockargs, norep, args, void), - PROC(granted_msg, testargs, norep, args, void), - PROC(test_res, testres, norep, res, void), - PROC(lock_res, lockres, norep, res, void), - PROC(cancel_res, cancelres, norep, res, void), - PROC(unlock_res, unlockres, norep, res, void), - PROC(granted_res, grantedres, norep, res, void), + PROC(null, void, void, void, void, 0), + PROC(test, testargs, testres, args, res, 0), + PROC(lock, lockargs, res, args, res, 0), + PROC(cancel, cancargs, res, args, res, 0), + PROC(unlock, unlockargs, res, args, res, 0), + PROC(granted, testargs, res, args, res, 0), + PROC(test_msg, testargs, norep, args, void, 0), + PROC(lock_msg, lockargs, norep, args, void, 0), + PROC(cancel_msg, cancargs, norep, args, void, 0), + PROC(unlock_msg, unlockargs, norep, args, void, 0), + PROC(granted_msg, testargs, norep, args, void, 0), + PROC(test_res, testres, norep, res, void, 0), + PROC(lock_res, lockres, norep, res, void, 0), + PROC(cancel_res, cancelres, norep, res, void, 0), + PROC(unlock_res, unlockres, norep, res, void, 0), + PROC(granted_res, grantedres, norep, res, void, 0), /* statd callback */ - PROC(sm_notify, reboot, void, reboot, void), - PROC(none, void, void, void, void), - PROC(none, void, void, void, void), - PROC(none, void, void, void, void), - PROC(share, shareargs, shareres, args, res), - PROC(unshare, shareargs, shareres, args, res), - PROC(nm_lock, lockargs, res, args, res), - PROC(free_all, notify, void, args, void), + PROC(sm_notify, reboot, void, reboot, void, 0), + PROC(none, void, void, void, void, 0), + PROC(none, void, void, void, void, 0), + PROC(none, void, void, void, void, 0), + PROC(share, shareargs, shareres, args, res, 0), + PROC(unshare, shareargs, shareres, args, res, 0), + PROC(nm_lock, lockargs, res, args, res, 0), + PROC(free_all, notify, void, args, void, 0), }; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/lockd/svcproc.c linux.19pre5-ac1/fs/lockd/svcproc.c --- linux.19p5/fs/lockd/svcproc.c Thu Apr 4 13:18:09 2002 +++ linux.19pre5-ac1/fs/lockd/svcproc.c Thu Mar 21 00:48:42 2002 @@ -474,12 +474,14 @@ /* If we run on an NFS server, delete all locks held by the client */ if (nlmsvc_ops != NULL) { struct svc_client *clnt; - saddr.sin_addr.s_addr = argp->addr; + saddr.sin_addr.s_addr = argp->addr; + nlmsvc_ops->exp_readlock(); if ((clnt = nlmsvc_ops->exp_getclient(&saddr)) != NULL && (host = nlm_lookup_host(clnt, &saddr, 0, 0)) != NULL) { nlmsvc_free_host_resources(host); } nlm_release_host(host); + nlmsvc_ops->exp_unlock(); } return rpc_success; @@ -552,7 +554,7 @@ struct nlm_void { int dummy; }; -#define PROC(name, xargt, xrest, argt, rest) \ +#define PROC(name, xargt, xrest, argt, rest, respsize) \ { (svc_procfunc) nlmsvc_proc_##name, \ (kxdrproc_t) nlmsvc_decode_##xargt, \ (kxdrproc_t) nlmsvc_encode_##xrest, \ @@ -560,33 +562,34 @@ sizeof(struct nlm_##argt), \ sizeof(struct nlm_##rest), \ 0, \ - 0 \ + 0, \ + respsize, \ } struct svc_procedure nlmsvc_procedures[] = { - PROC(null, void, void, void, void), - PROC(test, testargs, testres, args, res), - PROC(lock, lockargs, res, args, res), - PROC(cancel, cancargs, res, args, res), - PROC(unlock, unlockargs, res, args, res), - PROC(granted, testargs, res, args, res), - PROC(test_msg, testargs, norep, args, void), - PROC(lock_msg, lockargs, norep, args, void), - PROC(cancel_msg, cancargs, norep, args, void), - PROC(unlock_msg, unlockargs, norep, args, void), - PROC(granted_msg, testargs, norep, args, void), - PROC(test_res, testres, norep, res, void), - PROC(lock_res, lockres, norep, res, void), - PROC(cancel_res, cancelres, norep, res, void), - PROC(unlock_res, unlockres, norep, res, void), - PROC(granted_res, grantedres, norep, res, void), + PROC(null, void, void, void, void, 0), + PROC(test, testargs, testres, args, res, 0), + PROC(lock, lockargs, res, args, res, 0), + PROC(cancel, cancargs, res, args, res, 0), + PROC(unlock, unlockargs, res, args, res, 0), + PROC(granted, testargs, res, args, res, 0), + PROC(test_msg, testargs, norep, args, void, 0), + PROC(lock_msg, lockargs, norep, args, void, 0), + PROC(cancel_msg, cancargs, norep, args, void, 0), + PROC(unlock_msg, unlockargs, norep, args, void, 0), + PROC(granted_msg, testargs, norep, args, void, 0), + PROC(test_res, testres, norep, res, void, 0), + PROC(lock_res, lockres, norep, res, void, 0), + PROC(cancel_res, cancelres, norep, res, void, 0), + PROC(unlock_res, unlockres, norep, res, void, 0), + PROC(granted_res, grantedres, norep, res, void, 0), /* statd callback */ - PROC(sm_notify, reboot, void, reboot, void), - PROC(none, void, void, void, void), - PROC(none, void, void, void, void), - PROC(none, void, void, void, void), - PROC(share, shareargs, shareres, args, res), - PROC(unshare, shareargs, shareres, args, res), - PROC(nm_lock, lockargs, res, args, res), - PROC(free_all, notify, void, args, void), + PROC(sm_notify, reboot, void, reboot, void, 0), + PROC(none, void, void, void, void, 0), + PROC(none, void, void, void, void, 0), + PROC(none, void, void, void, void, 0), + PROC(share, shareargs, shareres, args, res, 0), + PROC(unshare, shareargs, shareres, args, res, 0), + PROC(nm_lock, lockargs, res, args, res, 0), + PROC(free_all, notify, void, args, void, 0), }; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/locks.c linux.19pre5-ac1/fs/locks.c --- linux.19p5/fs/locks.c Thu Apr 4 13:18:06 2002 +++ linux.19pre5-ac1/fs/locks.c Wed Feb 27 18:32:03 2002 @@ -445,8 +445,7 @@ /* Let the blocked process remove waiter from the * block list when it gets scheduled. */ - current->policy |= SCHED_YIELD; - schedule(); + yield(); } else { /* Remove waiter from the block list, because by the * time it wakes up blocker won't exist any more. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/namespace.c linux.19pre5-ac1/fs/namespace.c --- linux.19p5/fs/namespace.c Thu Apr 4 13:21:14 2002 +++ linux.19pre5-ac1/fs/namespace.c Fri Mar 15 22:06:57 2002 @@ -1056,8 +1056,9 @@ nr_hash = 1UL << hash_bits; hash_mask = nr_hash-1; - printk("Mount-cache hash table entries: %d (order: %ld, %ld bytes)\n", - nr_hash, order, (PAGE_SIZE << order)); + printk(KERN_INFO "Mount cache hash table entries: %d" + " (order: %ld, %ld bytes)\n", + nr_hash, order, (PAGE_SIZE << order)); /* And initialize the newly allocated array */ d = mount_hashtable; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfs/dir.c linux.19pre5-ac1/fs/nfs/dir.c --- linux.19p5/fs/nfs/dir.c Thu Apr 4 13:21:14 2002 +++ linux.19pre5-ac1/fs/nfs/dir.c Mon Mar 25 18:12:53 2002 @@ -883,6 +883,9 @@ } } return error; +out_err: + d_drop(dentry); + return error; } static int diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfs/flushd.c linux.19pre5-ac1/fs/nfs/flushd.c --- linux.19p5/fs/nfs/flushd.c Thu Apr 4 13:21:14 2002 +++ linux.19pre5-ac1/fs/nfs/flushd.c Mon Mar 25 18:12:53 2002 @@ -50,7 +50,7 @@ /* * This is the wait queue all cluster daemons sleep on */ -static struct rpc_wait_queue flushd_queue = RPC_INIT_WAITQ("nfs_flushd"); +static RPC_WAITQ(flushd_queue, "nfs_flushd"); /* * Local function declarations. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfs/pagelist.c linux.19pre5-ac1/fs/nfs/pagelist.c --- linux.19p5/fs/nfs/pagelist.c Thu Apr 4 13:21:14 2002 +++ linux.19pre5-ac1/fs/nfs/pagelist.c Mon Mar 25 18:13:07 2002 @@ -96,8 +96,7 @@ continue; if (signalled() && (server->flags & NFS_MOUNT_INTR)) return ERR_PTR(-ERESTARTSYS); - current->policy = SCHED_YIELD; - schedule(); + yield(); } /* Initialize the request struct. Initially, we assume a diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfs/unlink.c linux.19pre5-ac1/fs/nfs/unlink.c --- linux.19p5/fs/nfs/unlink.c Thu Apr 4 13:18:07 2002 +++ linux.19pre5-ac1/fs/nfs/unlink.c Thu Mar 21 00:48:42 2002 @@ -24,7 +24,7 @@ }; static struct nfs_unlinkdata *nfs_deletes; -static struct rpc_wait_queue nfs_delete_queue = RPC_INIT_WAITQ("nfs_delete_queue"); +static RPC_WAITQ(nfs_delete_queue, "nfs_delete_queue"); /** * nfs_detach_unlinkdata - Remove asynchronous unlink from global list diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfsd/export.c linux.19pre5-ac1/fs/nfsd/export.c --- linux.19p5/fs/nfsd/export.c Thu Apr 4 13:18:10 2002 +++ linux.19pre5-ac1/fs/nfsd/export.c Thu Mar 21 00:48:42 2002 @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include @@ -31,7 +33,6 @@ typedef struct svc_client svc_client; typedef struct svc_export svc_export; -static svc_export * exp_find(svc_client *clp, kdev_t dev); static svc_export * exp_parent(svc_client *clp, kdev_t dev, struct dentry *dentry); static svc_export * exp_child(svc_client *clp, kdev_t dev, @@ -50,6 +51,7 @@ ((((a)>>24) ^ ((a)>>16) ^ ((a)>>8) ^(a)) & CLIENT_HASHMASK) /* XXX: is this adequate for 32bit kdev_t ? */ #define EXPORT_HASH(dev) ((dev) & (NFSCLNT_EXPMAX - 1)) +#define EXPORT_FSID_HASH(fsid) ((fsid) & (NFSCLNT_EXPMAX - 1)) struct svc_clnthash { struct svc_clnthash * h_next; @@ -58,48 +60,47 @@ }; static struct svc_clnthash * clnt_hash[CLIENT_HASHMAX]; static svc_client * clients; -static int initialized; - -static int hash_lock; -static int want_lock; -static int hash_count; -static DECLARE_WAIT_QUEUE_HEAD( hash_wait ); /* - * Find a client's export for a device. + * Find the client's export entry matching xdev/xino. */ -static inline svc_export * -exp_find(svc_client *clp, kdev_t dev) +svc_export * +exp_get(svc_client *clp, kdev_t dev, ino_t ino) { - svc_export * exp; + struct list_head *head, *p; + + if (!clp) + return NULL; + + head = &clp->cl_export[EXPORT_HASH(dev)]; + list_for_each(p, head) { + svc_export *exp = list_entry(p, svc_export, ex_hash); + if (exp->ex_ino == ino && exp->ex_dev == dev) + return exp; + } - exp = clp->cl_export[EXPORT_HASH(dev)]; - while (exp && exp->ex_dev != dev) - exp = exp->ex_next; - return exp; + return NULL; } /* - * Find the client's export entry matching xdev/xino. + * Find the client's export entry matching fsid */ svc_export * -exp_get(svc_client *clp, kdev_t dev, ino_t ino) +exp_get_fsid(svc_client *clp, int fsid) { - svc_export * exp; + struct list_head *head, *p; if (!clp) return NULL; - exp = clp->cl_export[EXPORT_HASH(dev)]; - if (exp) - do { - if (exp->ex_ino == ino && exp->ex_dev == dev) - goto out; - } while (NULL != (exp = exp->ex_next)); - exp = NULL; -out: - return exp; + head = &clp->cl_expfsid[EXPORT_FSID_HASH(fsid)]; + list_for_each(p, head) { + svc_export *exp = list_entry(p, svc_export, ex_fsid_hash); + if (exp->ex_fsid == fsid) + return exp; + } + return NULL; } /* @@ -108,15 +109,15 @@ static svc_export * exp_parent(svc_client *clp, kdev_t dev, struct dentry *dentry) { - svc_export *exp; + struct list_head *head = &clp->cl_export[EXPORT_HASH(dev)]; + struct list_head *p; - if (clp == NULL) - return NULL; - - for (exp = clp->cl_export[EXPORT_HASH(dev)]; exp; exp = exp->ex_next) + list_for_each(p,head) { + svc_export *exp = list_entry(p, svc_export, ex_hash); if (is_subdir(dentry, exp->ex_dentry)) - break; - return exp; + return exp; + } + return NULL; } /* @@ -127,17 +128,83 @@ static svc_export * exp_child(svc_client *clp, kdev_t dev, struct dentry *dentry) { - svc_export *exp; + struct list_head *head = &clp->cl_export[EXPORT_HASH(dev)]; + struct list_head *p; - if (clp == NULL) - return NULL; - for (exp = clp->cl_export[EXPORT_HASH(dev)]; exp; exp = exp->ex_next) { - struct dentry *ndentry = exp->ex_dentry; + list_for_each(p, head) { + svc_export *exp = list_entry(p, svc_export, ex_hash); + struct dentry *ndentry = exp->ex_dentry; + if (ndentry && is_subdir(ndentry->d_parent, dentry)) - break; + return exp; + } + return NULL; +} + +/* Update parent pointers of all exports */ +static void exp_change_parents(svc_client *clp, svc_export *old, svc_export *new) +{ + struct list_head *head = &clp->cl_list; + struct list_head *p; + + list_for_each(p, head) { + svc_export *exp = list_entry(p, svc_export, ex_list); + if (exp->ex_parent == old) + exp->ex_parent = new; } - return exp; +} + +static void exp_fsid_unhash(struct svc_export *exp) +{ + + if ((exp->ex_flags & NFSEXP_FSID) == 0) + return; + + list_del_init(&exp->ex_fsid_hash); +} + +static void exp_fsid_hash(struct svc_client *clp, struct svc_export *exp) +{ + struct list_head *head; + + if ((exp->ex_flags & NFSEXP_FSID) == 0) + return; + head = clp->cl_expfsid + EXPORT_FSID_HASH(exp->ex_fsid); + list_add(&exp->ex_fsid_hash, head); +} + +/* + * Hashtable locking. Write locks are placed only by user processes + * wanting to modify export information. + * Write locking only done in this file. Read locking + * needed externally. + */ + +static DECLARE_RWSEM(hash_sem); + +void +exp_readlock(void) +{ + down_read(&hash_sem); +} + +static inline void +exp_writelock(void) +{ + down_write(&hash_sem); +} + +void +exp_readunlock(void) +{ + up_read(&hash_sem); +} + +static inline void +exp_writeunlock(void) +{ + up_write(&hash_sem); } /* @@ -147,11 +214,11 @@ exp_export(struct nfsctl_export *nxp) { svc_client *clp; - svc_export *exp, *parent; - svc_export **head; + svc_export *exp = NULL, *parent; + svc_export *fsid_exp; struct nameidata nd; struct inode *inode = NULL; - int i, err; + int err; kdev_t dev; ino_t ino; @@ -164,29 +231,14 @@ dprintk("exp_export called for %s:%s (%x/%ld fl %x).\n", nxp->ex_client, nxp->ex_path, nxp->ex_dev, (long) nxp->ex_ino, nxp->ex_flags); - dev = to_kdev_t(nxp->ex_dev); - ino = nxp->ex_ino; /* Try to lock the export table for update */ - if ((err = exp_writelock()) < 0) - goto out; + exp_writelock(); /* Look up client info */ - err = -EINVAL; if (!(clp = exp_getclientbyname(nxp->ex_client))) goto out_unlock; - /* - * If there's already an export for this file, assume this - * is just a flag update. - */ - if ((exp = exp_get(clp, dev, ino)) != NULL) { - exp->ex_flags = nxp->ex_flags; - exp->ex_anon_uid = nxp->ex_anon_uid; - exp->ex_anon_gid = nxp->ex_anon_gid; - err = 0; - goto out_unlock; - } /* Look up the dentry */ err = 0; @@ -196,11 +248,28 @@ goto out_unlock; inode = nd.dentry->d_inode; + dev = inode->i_dev; + ino = inode->i_ino; err = -EINVAL; - if (inode->i_dev != dev || inode->i_ino != nxp->ex_ino) { - printk(KERN_DEBUG "exp_export: i_dev = %x, dev = %x\n", - inode->i_dev, dev); - /* I'm just being paranoid... */ + + exp = exp_get(clp, dev, ino); + + /* must make sure there wont be an ex_fsid clash */ + if ((nxp->ex_flags & NFSEXP_FSID) && + (fsid_exp = exp_get_fsid(clp, nxp->ex_dev)) && + fsid_exp != exp) + goto finish; + + if (exp != NULL) { + /* just a flags/id/fsid update */ + + exp_fsid_unhash(exp); + exp->ex_flags = nxp->ex_flags; + exp->ex_anon_uid = nxp->ex_anon_uid; + exp->ex_anon_gid = nxp->ex_anon_gid; + exp->ex_fsid = nxp->ex_dev; + exp_fsid_hash(clp, exp); + err = 0; goto finish; } @@ -212,7 +281,17 @@ goto finish; err = -EINVAL; - if (!(inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV) || + /* There are two requirements on a filesystem to be exportable. + * 1: We must be able to identify the filesystem from a number. + * either a device number (so FS_REQUIRES_DEV needed) + * or an FSID number (so NFSEXP_FSID needed). + * 2: We must be able to find an inode from a filehandle. + * either using fh_to_dentry (prefered) + * or using read_inode (the hack). + */ + if (!((inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV) + || (nxp->ex_flags & NFSEXP_FSID)) + || (inode->i_sb->s_op->read_inode == NULL && inode->i_sb->s_op->fh_to_dentry == NULL)) { dprintk("exp_export: export of invalid fs type.\n"); @@ -237,43 +316,33 @@ strcpy(exp->ex_path, nxp->ex_path); exp->ex_client = clp; exp->ex_parent = parent; - exp->ex_dentry = nd.dentry; - exp->ex_mnt = nd.mnt; + exp->ex_dentry = dget(nd.dentry); + exp->ex_mnt = mntget(nd.mnt); exp->ex_flags = nxp->ex_flags; exp->ex_dev = dev; exp->ex_ino = ino; exp->ex_anon_uid = nxp->ex_anon_uid; exp->ex_anon_gid = nxp->ex_anon_gid; + exp->ex_fsid = nxp->ex_dev; + /* Update parent pointers of all exports */ - if (parent) { - for (i = 0; i < NFSCLNT_EXPMAX; i++) { - svc_export *temp = clp->cl_export[i]; + if (parent) + exp_change_parents(clp, parent, exp); - while (temp) { - if (temp->ex_parent == parent) - temp->ex_parent = exp; - temp = temp->ex_next; - } - } - } + list_add(&exp->ex_hash, clp->cl_export + EXPORT_HASH(dev)); + list_add_tail(&exp->ex_list, &clp->cl_list); - head = clp->cl_export + EXPORT_HASH(dev); - exp->ex_next = *head; - *head = exp; + exp_fsid_hash(clp, exp); err = 0; - /* Unlock hashtable */ +finish: + path_release(&nd); out_unlock: - exp_unlock(); + exp_writeunlock(); out: return err; - - /* Release the dentry */ -finish: - path_release(&nd); - goto out_unlock; } /* @@ -283,20 +352,15 @@ static void exp_do_unexport(svc_export *unexp) { - svc_export *exp; - svc_client *clp; struct dentry *dentry; struct vfsmount *mnt; struct inode *inode; - int i; - /* Update parent pointers. */ - clp = unexp->ex_client; - for (i = 0; i < NFSCLNT_EXPMAX; i++) { - for (exp = clp->cl_export[i]; exp; exp = exp->ex_next) - if (exp->ex_parent == unexp) - exp->ex_parent = unexp->ex_parent; - } + list_del(&unexp->ex_hash); + list_del(&unexp->ex_list); + exp_fsid_unhash(unexp); + + exp_change_parents(unexp->ex_client, unexp, unexp->ex_parent); dentry = unexp->ex_dentry; mnt = unexp->ex_mnt; @@ -317,18 +381,13 @@ static void exp_unexport_all(svc_client *clp) { - svc_export *exp; - int i; + struct list_head *p = &clp->cl_list; dprintk("unexporting all fs's for clnt %p\n", clp); - for (i = 0; i < NFSCLNT_EXPMAX; i++) { - exp = clp->cl_export[i]; - clp->cl_export[i] = NULL; - while (exp) { - svc_export *next = exp->ex_next; - exp_do_unexport(exp); - exp = next; - } + + while (!list_empty(p)) { + svc_export *exp = list_entry(p->next, svc_export, ex_list); + exp_do_unexport(exp); } } @@ -339,35 +398,25 @@ exp_unexport(struct nfsctl_export *nxp) { svc_client *clp; - svc_export **expp, *exp = NULL; int err; /* Consistency check */ if (!exp_verify_string(nxp->ex_client, NFSCLNT_IDMAX)) return -EINVAL; - if ((err = exp_writelock()) < 0) - goto out; + exp_writelock(); err = -EINVAL; clp = exp_getclientbyname(nxp->ex_client); if (clp) { - expp = clp->cl_export + EXPORT_HASH(nxp->ex_dev); - while ((exp = *expp) != NULL) { - if (exp->ex_dev == nxp->ex_dev) { - if (exp->ex_ino == nxp->ex_ino) { - *expp = exp->ex_next; - exp_do_unexport(exp); - err = 0; - break; - } - } - expp = &(exp->ex_next); + svc_export *exp = exp_get(clp, nxp->ex_dev, nxp->ex_ino); + if (exp) { + exp_do_unexport(exp); + err = 0; } } - exp_unlock(); -out: + exp_writeunlock(); return err; } @@ -442,59 +491,6 @@ } /* - * Hashtable locking. Write locks are placed only by user processes - * wanting to modify export information. - */ -void -exp_readlock(void) -{ - while (hash_lock || want_lock) - sleep_on(&hash_wait); - hash_count++; -} - -int -exp_writelock(void) -{ - /* fast track */ - if (!hash_count && !hash_lock) { - lock_it: - hash_lock = 1; - return 0; - } - - current->sigpending = 0; - want_lock++; - while (hash_count || hash_lock) { - interruptible_sleep_on(&hash_wait); - if (signal_pending(current)) - break; - } - want_lock--; - - /* restore the task's signals */ - spin_lock_irq(¤t->sigmask_lock); - recalc_sigpending(current); - spin_unlock_irq(¤t->sigmask_lock); - - if (!hash_count && !hash_lock) - goto lock_it; - return -EINTR; -} - -void -exp_unlock(void) -{ - if (!hash_count && !hash_lock) - printk(KERN_WARNING "exp_unlock: not locked!\n"); - if (hash_count) - hash_count--; - else - hash_lock = 0; - wake_up(&hash_wait); -} - -/* * Find a valid client given an inet address. We always move the most * recently used client to the front of the hash chain to speed up * future lookups. @@ -506,20 +502,19 @@ struct svc_clnthash **hp, **head, *tmp; unsigned long addr = sin->sin_addr.s_addr; - if (!initialized) - return NULL; - head = &clnt_hash[CLIENT_HASH(addr)]; for (hp = head; (tmp = *hp) != NULL; hp = &(tmp->h_next)) { if (tmp->h_addr.s_addr == addr) { +#if 0 +/* this is not safe without BKL or some other spinlock */ /* Move client to the front */ if (head != hp) { *hp = tmp->h_next; tmp->h_next = *head; *head = tmp; } - +#endif return tmp->h_client; } } @@ -542,6 +537,68 @@ return NULL; } +/* Iterator */ + +static void *e_start(struct seq_file *m, loff_t *pos) +{ + loff_t n = *pos; + unsigned client, export; + svc_client *clp; + struct list_head *p; + + exp_readlock(); + if (!n--) + return (void *)1; + client = n >> 32; + export = n & ((1LL<<32) - 1); + for (clp = clients; client && clp; clp = clp->cl_next, client--) + ; + if (!clp) + return NULL; + list_for_each(p, &clp->cl_list) + if (!export--) + return list_entry(p, svc_export, ex_list); + n &= ~((1LL<<32) - 1); + do { + clp = clp->cl_next; + n += 1LL<<32; + } while(clp && list_empty(&clp->cl_list)); + if (!clp) + return NULL; + *pos = n+1; + return list_entry(clp->cl_list.next, svc_export, ex_list); +} + +static void *e_next(struct seq_file *m, void *p, loff_t *pos) +{ + svc_export *exp = p; + svc_client *clp; + + if (p == (void *)1) + clp = clients; + else if (exp->ex_list.next == &exp->ex_client->cl_list) { + clp = exp->ex_client->cl_next; + *pos += 1LL<<32; + } else { + ++*pos; + return list_entry(exp->ex_list.next, svc_export, ex_list); + } + *pos &= ~((1LL<<32) - 1); + while (clp && list_empty(&clp->cl_list)) { + clp = clp->cl_next; + *pos += 1LL<<32; + } + if (!clp) + return NULL; + ++*pos; + return list_entry(clp->cl_list.next, svc_export, ex_list); +} + +static void e_stop(struct seq_file *m, void *p) +{ + exp_readunlock(); +} + struct flags { int flag; char *name[2]; @@ -564,128 +621,79 @@ { 0, {"", ""}} }; -static int -exp_flags(char *buffer, int flag) +static void exp_flags(struct seq_file *m, int flag, int fsid) { - int len = 0, first = 0; - struct flags *flg = expflags; + int first = 0; + struct flags *flg; - for (;flg->flag;flg++) { - int state = (flg->flag & flag)?0:1; - if (!flg->flag) - break; - if (*flg->name[state]) { - len += sprintf(buffer + len, "%s%s", - first++?",":"", flg->name[state]); - } - } - return len; + for (flg = expflags; flg->flag; flg++) { + int state = (flg->flag & flag)?0:1; + if (*flg->name[state]) + seq_printf(m, "%s%s", first++?",":"", flg->name[state]); + } + if (flag & NFSEXP_FSID) + seq_printf(m, "%sfsid=%d", first++?",":"", fsid); } - - -/* mangling borrowed from fs/super.c */ -/* Use octal escapes, like mount does, for embedded spaces etc. */ -static unsigned char need_escaping[] = { ' ', '\t', '\n', '\\' }; - -static int -mangle(const unsigned char *s, char *buf, int len) { - char *sp; - int n; - - sp = buf; - while(*s && sp-buf < len-3) { - for (n = 0; n < sizeof(need_escaping); n++) { - if (*s == need_escaping[n]) { - *sp++ = '\\'; - *sp++ = '0' + ((*s & 0300) >> 6); - *sp++ = '0' + ((*s & 070) >> 3); - *sp++ = '0' + (*s & 07); - goto next; - } - } - *sp++ = *s; - next: - s++; - } - return sp - buf; /* no trailing NUL */ +static inline void mangle(struct seq_file *m, const char *s) +{ + seq_escape(m, s, " \t\n\\"); } -#define FREEROOM ((int)PAGE_SIZE-200-len) -#define MANGLE(s) len += mangle((s), buffer+len, FREEROOM); - -int -exp_procfs_exports(char *buffer, char **start, off_t offset, - int length, int *eof, void *data) +static int e_show(struct seq_file *m, void *p) { - struct svc_clnthash **hp, **head, *tmp; - struct svc_client *clp; - svc_export *exp; - off_t pos = 0; - off_t begin = 0; - int len = 0; - int i,j; - - len += sprintf(buffer, "# Version 1.1\n"); - len += sprintf(buffer+len, "# Path Client(Flags) # IPs\n"); + struct svc_export *exp = p; + struct svc_client *clp; + int j, first = 0; - for (clp = clients; clp; clp = clp->cl_next) { - for (i = 0; i < NFSCLNT_EXPMAX; i++) { - exp = clp->cl_export[i]; - while (exp) { - int first = 0; - MANGLE(exp->ex_path); - buffer[len++]='\t'; - MANGLE(clp->cl_ident); - buffer[len++]='('; - - len += exp_flags(buffer+len, exp->ex_flags); - len += sprintf(buffer+len, ") # "); - for (j = 0; j < clp->cl_naddr; j++) { - struct in_addr addr = clp->cl_addr[j]; - - head = &clnt_hash[CLIENT_HASH(addr.s_addr)]; - for (hp = head; (tmp = *hp) != NULL; hp = &(tmp->h_next)) { - if (tmp->h_addr.s_addr == addr.s_addr) { - if (first++) len += sprintf(buffer+len, "%s", " "); - if (tmp->h_client != clp) - len += sprintf(buffer+len, "("); - len += sprintf(buffer+len, "%d.%d.%d.%d", - htonl(addr.s_addr) >> 24 & 0xff, - htonl(addr.s_addr) >> 16 & 0xff, - htonl(addr.s_addr) >> 8 & 0xff, - htonl(addr.s_addr) >> 0 & 0xff); - if (tmp->h_client != clp) - len += sprintf(buffer+len, ")"); - break; - } - } - } - exp = exp->ex_next; - - buffer[len++]='\n'; - - pos=begin+len; - if(pos offset + length) - goto done; - } - } + if (p == (void *)1) { + seq_puts(m, "# Version 1.1\n"); + seq_puts(m, "# Path Client(Flags) # IPs\n"); + return 0; } - *eof = 1; + clp = exp->ex_client; -done: - *start = buffer + (offset - begin); - len -= (offset - begin); - if ( len > length ) - len = length; - return len; + mangle(m, exp->ex_path); + seq_putc(m, '\t'); + mangle(m, clp->cl_ident); + seq_putc(m, '('); + exp_flags(m, exp->ex_flags, exp->ex_fsid); + seq_puts(m, ") # "); + for (j = 0; j < clp->cl_naddr; j++) { + struct svc_clnthash **hp, **head, *tmp; + struct in_addr addr = clp->cl_addr[j]; + + head = &clnt_hash[CLIENT_HASH(addr.s_addr)]; + for (hp = head; (tmp = *hp) != NULL; hp = &(tmp->h_next)) { + if (tmp->h_addr.s_addr == addr.s_addr) + break; + } + if (tmp) { + if (first++) + seq_putc(m, ' '); + if (tmp->h_client != clp) + seq_putc(m, '('); + seq_printf(m, "%d.%d.%d.%d", + htonl(addr.s_addr) >> 24 & 0xff, + htonl(addr.s_addr) >> 16 & 0xff, + htonl(addr.s_addr) >> 8 & 0xff, + htonl(addr.s_addr) >> 0 & 0xff); + if (tmp->h_client != clp) + seq_putc(m, ')'); + } + } + seq_putc(m, '\n'); + return 0; } +struct seq_operations nfs_exports_op = { + start: e_start, + next: e_next, + stop: e_stop, + show: e_show, +}; + /* * Add or modify a client. * Change requests may involve the list of host addresses. The list of @@ -706,8 +714,7 @@ goto out; /* Lock the hashtable */ - if ((err = exp_writelock()) < 0) - goto out; + exp_writelock(); /* First check if this is a change request for a client. */ for (clp = clients; clp; clp = clp->cl_next) @@ -721,6 +728,11 @@ if (!(clp = kmalloc(sizeof(*clp), GFP_KERNEL))) goto out_unlock; memset(clp, 0, sizeof(*clp)); + for (i = 0; i < NFSCLNT_EXPMAX; i++) { + INIT_LIST_HEAD(&clp->cl_export[i]); + INIT_LIST_HEAD(&clp->cl_expfsid[i]); + } + INIT_LIST_HEAD(&clp->cl_list); dprintk("created client %s (%p)\n", ncp->cl_ident, clp); @@ -769,7 +781,7 @@ err = 0; out_unlock: - exp_unlock(); + exp_writeunlock(); out: return err; } @@ -788,10 +800,8 @@ goto out; /* Lock the hashtable */ - if ((err = exp_writelock()) < 0) - goto out; + exp_writelock(); - err = -EINVAL; for (clpp = &clients; (clp = *clpp); clpp = &(clp->cl_next)) if (!strcmp(ncp->cl_ident, clp->cl_ident)) break; @@ -802,7 +812,7 @@ err = 0; } - exp_unlock(); + exp_writeunlock(); out: return err; } @@ -891,13 +901,11 @@ int i; dprintk("nfsd: initializing export module.\n"); - if (initialized) - return; + for (i = 0; i < CLIENT_HASHMAX; i++) clnt_hash[i] = NULL; clients = NULL; - initialized = 1; } /* @@ -909,18 +917,15 @@ int i; dprintk("nfsd: shutting down export module.\n"); - if (!initialized) - return; - if (exp_writelock() < 0) { - printk(KERN_WARNING "Weird: hashtable locked in exp_shutdown"); - return; - } + + exp_writelock(); + for (i = 0; i < CLIENT_HASHMAX; i++) { while (clnt_hash[i]) exp_freeclient(clnt_hash[i]->h_client); } clients = NULL; /* we may be restarted before the module unloads */ - exp_unlock(); + exp_writeunlock(); dprintk("nfsd: export shutdown complete.\n"); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfsd/lockd.c linux.19pre5-ac1/fs/nfsd/lockd.c --- linux.19p5/fs/nfsd/lockd.c Thu Apr 4 13:18:10 2002 +++ linux.19pre5-ac1/fs/nfsd/lockd.c Thu Mar 21 00:48:42 2002 @@ -62,7 +62,7 @@ struct nlmsvc_binding nfsd_nlm_ops = { exp_readlock, /* lock export table for reading */ - exp_unlock, /* unlock export table */ + exp_readunlock, /* unlock export table */ exp_getclient, /* look up NFS client */ nlm_fopen, /* open file for locking */ nlm_fclose, /* close file */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfsd/nfs3proc.c linux.19pre5-ac1/fs/nfsd/nfs3proc.c --- linux.19p5/fs/nfsd/nfs3proc.c Thu Apr 4 13:18:10 2002 +++ linux.19pre5-ac1/fs/nfsd/nfs3proc.c Thu Mar 28 22:39:41 2002 @@ -183,11 +183,12 @@ */ svcbuf_reserve(&rqstp->rq_resbuf, &buffer, &avail, 1 + NFS3_POST_OP_ATTR_WORDS + 3); - resp->count = argp->count; if ((avail << 2) < resp->count) resp->count = avail << 2; + svc_reserve(rqstp, ((1 + NFS3_POST_OP_ATTR_WORDS + 3)<<2) + argp->count +4); + fh_copy(&resp->fh, &argp->fh); nfserr = nfsd_read(rqstp, &resp->fh, argp->offset, @@ -339,7 +340,7 @@ || (argp->ftype == NF3BLK && argp->major >= MAX_BLKDEV) || argp->minor > 0xFF) RETURN_STATUS(nfserr_inval); - rdev = ((argp->major) << 8) | (argp->minor); + rdev = MKDEV(argp->major, argp->minor); } else if (argp->ftype != NF3SOCK && argp->ftype != NF3FIFO) RETURN_STATUS(nfserr_inval); @@ -646,7 +647,7 @@ #define nfsd3_voidres nfsd3_voidargs struct nfsd3_voidargs { int dummy; }; -#define PROC(name, argt, rest, relt, cache) \ +#define PROC(name, argt, rest, relt, cache, respsize) \ { (svc_procfunc) nfsd3_proc_##name, \ (kxdrproc_t) nfs3svc_decode_##argt##args, \ (kxdrproc_t) nfs3svc_encode_##rest##res, \ @@ -654,29 +655,30 @@ sizeof(struct nfsd3_##argt##args), \ sizeof(struct nfsd3_##rest##res), \ 0, \ - cache \ + cache, \ + respsize, \ } struct svc_procedure nfsd_procedures3[22] = { - PROC(null, void, void, void, RC_NOCACHE), - PROC(getattr, fhandle, attrstat, fhandle, RC_NOCACHE), - PROC(setattr, sattr, wccstat, fhandle, RC_REPLBUFF), - PROC(lookup, dirop, dirop, fhandle2, RC_NOCACHE), - PROC(access, access, access, fhandle, RC_NOCACHE), - PROC(readlink, fhandle, readlink, fhandle, RC_NOCACHE), - PROC(read, read, read, fhandle, RC_NOCACHE), - PROC(write, write, write, fhandle, RC_REPLBUFF), - PROC(create, create, create, fhandle2, RC_REPLBUFF), - PROC(mkdir, mkdir, create, fhandle2, RC_REPLBUFF), - PROC(symlink, symlink, create, fhandle2, RC_REPLBUFF), - PROC(mknod, mknod, create, fhandle2, RC_REPLBUFF), - PROC(remove, dirop, wccstat, fhandle, RC_REPLBUFF), - PROC(rmdir, dirop, wccstat, fhandle, RC_REPLBUFF), - PROC(rename, rename, rename, fhandle2, RC_REPLBUFF), - PROC(link, link, link, fhandle2, RC_REPLBUFF), - PROC(readdir, readdir, readdir, fhandle, RC_NOCACHE), - PROC(readdirplus,readdirplus, readdir, fhandle, RC_NOCACHE), - PROC(fsstat, fhandle, fsstat, void, RC_NOCACHE), - PROC(fsinfo, fhandle, fsinfo, void, RC_NOCACHE), - PROC(pathconf, fhandle, pathconf, void, RC_NOCACHE), - PROC(commit, commit, commit, fhandle, RC_NOCACHE) + PROC(null, void, void, void, RC_NOCACHE, 1), + PROC(getattr, fhandle, attrstat, fhandle, RC_NOCACHE, 1+21), + PROC(setattr, sattr, wccstat, fhandle, RC_REPLBUFF, 1+7+22), + PROC(lookup, dirop, dirop, fhandle2, RC_NOCACHE, 1+17+22+22), + PROC(access, access, access, fhandle, RC_NOCACHE, 1+22+1), + PROC(readlink, fhandle, readlink, fhandle, RC_NOCACHE, 1+22+1+256), + PROC(read, read, read, fhandle, RC_NOCACHE, 1+22+4+NFSSVC_MAXBLKSIZE), + PROC(write, write, write, fhandle, RC_REPLBUFF, 1+7+22+4), + PROC(create, create, create, fhandle2, RC_REPLBUFF, 1+(1+17+22)+7+22), + PROC(mkdir, mkdir, create, fhandle2, RC_REPLBUFF, 1+(1+17+22)+7+22), + PROC(symlink, symlink, create, fhandle2, RC_REPLBUFF, 1+(1+17+22)+7+22), + PROC(mknod, mknod, create, fhandle2, RC_REPLBUFF, 1+(1+17+22)+7+22), + PROC(remove, dirop, wccstat, fhandle, RC_REPLBUFF, 1+7+22), + PROC(rmdir, dirop, wccstat, fhandle, RC_REPLBUFF, 1+7+22), + PROC(rename, rename, rename, fhandle2, RC_REPLBUFF, 1+7+22+7+22), + PROC(link, link, link, fhandle2, RC_REPLBUFF, 1+22+7+22), + PROC(readdir, readdir, readdir, fhandle, RC_NOCACHE, 0), + PROC(readdirplus,readdirplus, readdir, fhandle, RC_NOCACHE, 0), + PROC(fsstat, fhandle, fsstat, void, RC_NOCACHE, 1+14), + PROC(fsinfo, fhandle, fsinfo, void, RC_NOCACHE, 1+13), + PROC(pathconf, fhandle, pathconf, void, RC_NOCACHE, 1+7), + PROC(commit, commit, commit, fhandle, RC_NOCACHE, 1+7+22+2), }; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfsd/nfs3xdr.c linux.19pre5-ac1/fs/nfsd/nfs3xdr.c --- linux.19p5/fs/nfsd/nfs3xdr.c Thu Apr 4 13:18:10 2002 +++ linux.19pre5-ac1/fs/nfsd/nfs3xdr.c Thu Mar 21 00:48:42 2002 @@ -154,9 +154,9 @@ } static inline u32 * -encode_fattr3(struct svc_rqst *rqstp, u32 *p, struct dentry *dentry) +encode_fattr3(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) { - struct inode *inode = dentry->d_inode; + struct inode *inode = fhp->fh_dentry->d_inode; *p++ = htonl(nfs3_ftypes[(inode->i_mode & S_IFMT) >> 12]); *p++ = htonl((u32) inode->i_mode); @@ -175,7 +175,12 @@ p = xdr_encode_hyper(p, ((u64)inode->i_blocks) << 9); *p++ = htonl((u32) MAJOR(inode->i_rdev)); *p++ = htonl((u32) MINOR(inode->i_rdev)); - p = xdr_encode_hyper(p, (u64) inode->i_dev); + if (rqstp->rq_reffh->fh_version == 1 + && rqstp->rq_reffh->fh_fsid_type == 1 + && (fhp->fh_export->ex_flags & NFSEXP_FSID)) + p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid); + else + p = xdr_encode_hyper(p, (u64) inode->i_dev); p = xdr_encode_hyper(p, (u64) inode->i_ino); p = encode_time3(p, inode->i_atime); p = encode_time3(p, lease_get_mtime(inode)); @@ -205,7 +210,12 @@ p = xdr_encode_hyper(p, ((u64)fhp->fh_post_blocks) << 9); *p++ = htonl((u32) MAJOR(fhp->fh_post_rdev)); *p++ = htonl((u32) MINOR(fhp->fh_post_rdev)); - p = xdr_encode_hyper(p, (u64) inode->i_dev); + if (rqstp->rq_reffh->fh_version == 1 + && rqstp->rq_reffh->fh_fsid_type == 1 + && (fhp->fh_export->ex_flags & NFSEXP_FSID)) + p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid); + else + p = xdr_encode_hyper(p, (u64) inode->i_dev); p = xdr_encode_hyper(p, (u64) inode->i_ino); p = encode_time3(p, fhp->fh_post_atime); p = encode_time3(p, fhp->fh_post_mtime); @@ -220,11 +230,12 @@ * handle. In this case, no attributes are returned. */ static u32 * -encode_post_op_attr(struct svc_rqst *rqstp, u32 *p, struct dentry *dentry) +encode_post_op_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) { + struct dentry *dentry = fhp->fh_dentry; if (dentry && dentry->d_inode != NULL) { *p++ = xdr_one; /* attributes follow */ - return encode_fattr3(rqstp, p, dentry); + return encode_fattr3(rqstp, p, fhp); } *p++ = xdr_zero; return p; @@ -251,7 +262,7 @@ } /* no pre- or post-attrs */ *p++ = xdr_zero; - return encode_post_op_attr(rqstp, p, dentry); + return encode_post_op_attr(rqstp, p, fhp); } /* @@ -509,7 +520,7 @@ struct nfsd3_attrstat *resp) { if (resp->status == 0) - p = encode_fattr3(rqstp, p, resp->fh.fh_dentry); + p = encode_fattr3(rqstp, p, &resp->fh); return xdr_ressize_check(rqstp, p); } @@ -529,9 +540,9 @@ { if (resp->status == 0) { p = encode_fh(p, &resp->fh); - p = encode_post_op_attr(rqstp, p, resp->fh.fh_dentry); + p = encode_post_op_attr(rqstp, p, &resp->fh); } - p = encode_post_op_attr(rqstp, p, resp->dirfh.fh_dentry); + p = encode_post_op_attr(rqstp, p, &resp->dirfh); return xdr_ressize_check(rqstp, p); } @@ -540,7 +551,7 @@ nfs3svc_encode_accessres(struct svc_rqst *rqstp, u32 *p, struct nfsd3_accessres *resp) { - p = encode_post_op_attr(rqstp, p, resp->fh.fh_dentry); + p = encode_post_op_attr(rqstp, p, &resp->fh); if (resp->status == 0) *p++ = htonl(resp->access); return xdr_ressize_check(rqstp, p); @@ -551,7 +562,7 @@ nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, u32 *p, struct nfsd3_readlinkres *resp) { - p = encode_post_op_attr(rqstp, p, resp->fh.fh_dentry); + p = encode_post_op_attr(rqstp, p, &resp->fh); if (resp->status == 0) { *p++ = htonl(resp->len); p += XDR_QUADLEN(resp->len); @@ -564,7 +575,7 @@ nfs3svc_encode_readres(struct svc_rqst *rqstp, u32 *p, struct nfsd3_readres *resp) { - p = encode_post_op_attr(rqstp, p, resp->fh.fh_dentry); + p = encode_post_op_attr(rqstp, p, &resp->fh); if (resp->status == 0) { *p++ = htonl(resp->count); *p++ = htonl(resp->eof); @@ -597,7 +608,7 @@ if (resp->status == 0) { *p++ = xdr_one; p = encode_fh(p, &resp->fh); - p = encode_post_op_attr(rqstp, p, resp->fh.fh_dentry); + p = encode_post_op_attr(rqstp, p, &resp->fh); } p = encode_wcc_data(rqstp, p, &resp->dirfh); return xdr_ressize_check(rqstp, p); @@ -618,7 +629,7 @@ nfs3svc_encode_linkres(struct svc_rqst *rqstp, u32 *p, struct nfsd3_linkres *resp) { - p = encode_post_op_attr(rqstp, p, resp->fh.fh_dentry); + p = encode_post_op_attr(rqstp, p, &resp->fh); p = encode_wcc_data(rqstp, p, &resp->tfh); return xdr_ressize_check(rqstp, p); } @@ -628,7 +639,7 @@ nfs3svc_encode_readdirres(struct svc_rqst *rqstp, u32 *p, struct nfsd3_readdirres *resp) { - p = encode_post_op_attr(rqstp, p, resp->fh.fh_dentry); + p = encode_post_op_attr(rqstp, p, &resp->fh); if (resp->status == 0) { /* stupid readdir cookie */ memcpy(p, resp->verf, 8); p += 2; @@ -709,7 +720,7 @@ goto noexec; if (fh_compose(&fh, exp, dchild, cd->dirfh) != 0 || !dchild->d_inode) goto noexec; - p = encode_post_op_attr(cd->rqstp, p, fh.fh_dentry); + p = encode_post_op_attr(cd->rqstp, p, &fh); *p++ = xdr_one; /* yes, a file handle follows */ p = encode_fh(p, &fh); fh_put(&fh); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfsd/nfscache.c linux.19pre5-ac1/fs/nfsd/nfscache.c --- linux.19p5/fs/nfsd/nfscache.c Thu Apr 4 13:18:10 2002 +++ linux.19pre5-ac1/fs/nfsd/nfscache.c Thu Mar 21 00:48:42 2002 @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -38,11 +39,17 @@ static struct svc_cacherep * lru_head; static struct svc_cacherep * lru_tail; static struct svc_cacherep * nfscache; -static int cache_initialized; static int cache_disabled = 1; static int nfsd_cache_append(struct svc_rqst *rqstp, struct svc_buf *data); +/* + * locking for the reply cache: + * A cache entry is "single use" if c_state == RC_INPROG + * Otherwise, it when accessing _prev or _next, the lock must be held. + */ +static spinlock_t cache_lock = SPIN_LOCK_UNLOCKED; + void nfsd_cache_init(void) { @@ -51,8 +58,6 @@ size_t i; unsigned long order; - if (cache_initialized) - return; i = CACHESIZE * sizeof (struct svc_cacherep); for (order = 0; (PAGE_SIZE << order) < i; order++) @@ -90,7 +95,6 @@ lru_head->c_lru_prev = NULL; lru_tail->c_lru_next = NULL; - cache_initialized = 1; cache_disabled = 0; } @@ -101,15 +105,11 @@ size_t i; unsigned long order; - if (!cache_initialized) - return; - for (rp = lru_head; rp; rp = rp->c_lru_next) { if (rp->c_state == RC_DONE && rp->c_type == RC_REPLBUFF) kfree(rp->c_replbuf.buf); } - cache_initialized = 0; cache_disabled = 1; i = CACHESIZE * sizeof (struct svc_cacherep); @@ -179,6 +179,7 @@ vers = rqstp->rq_vers, proc = rqstp->rq_proc; unsigned long age; + int rtn; rqstp->rq_cacherep = NULL; if (cache_disabled || type == RC_NOCACHE) { @@ -186,6 +187,9 @@ return RC_DOIT; } + spin_lock(&cache_lock); + rtn = RC_DOIT; + rp = rh = (struct svc_cacherep *) &hash_list[REQHASH(xid)]; while ((rp = rp->c_hash_next) != rh) { if (rp->c_state != RC_UNUSED && @@ -208,7 +212,7 @@ if (safe++ > CACHESIZE) { printk("nfsd: loop in repcache LRU list\n"); cache_disabled = 1; - return RC_DOIT; + goto out; } } } @@ -222,7 +226,7 @@ printk(KERN_WARNING "nfsd: disabling repcache.\n"); cache_disabled = 1; } - return RC_DOIT; + goto out; } rqstp->rq_cacherep = rp; @@ -242,8 +246,9 @@ rp->c_replbuf.buf = NULL; } rp->c_type = RC_NOCACHE; - - return RC_DOIT; + out: + spin_unlock(&cache_lock); + return rtn; found_entry: /* We found a matching entry which is either in progress or done. */ @@ -251,33 +256,36 @@ rp->c_timestamp = jiffies; lru_put_front(rp); + rtn = RC_DROPIT; /* Request being processed or excessive rexmits */ if (rp->c_state == RC_INPROG || age < RC_DELAY) - return RC_DROPIT; + goto out; /* From the hall of fame of impractical attacks: * Is this a user who tries to snoop on the cache? */ + rtn = RC_DOIT; if (!rqstp->rq_secure && rp->c_secure) - return RC_DOIT; + goto out; /* Compose RPC reply header */ switch (rp->c_type) { case RC_NOCACHE: - return RC_DOIT; + break; case RC_REPLSTAT: svc_putlong(&rqstp->rq_resbuf, rp->c_replstat); + rtn = RC_REPLY; break; case RC_REPLBUFF: if (!nfsd_cache_append(rqstp, &rp->c_replbuf)) - return RC_DOIT; /* should not happen */ + goto out; /* should not happen */ + rtn = RC_REPLY; break; default: printk(KERN_WARNING "nfsd: bad repcache type %d\n", rp->c_type); rp->c_state = RC_UNUSED; - return RC_DOIT; } - return RC_REPLY; + goto out; } /* @@ -324,20 +332,22 @@ cachp = &rp->c_replbuf; cachp->buf = (u32 *) kmalloc(len << 2, GFP_KERNEL); if (!cachp->buf) { + spin_lock(&cache_lock); rp->c_state = RC_UNUSED; + spin_unlock(&cache_lock); return; } cachp->len = len; memcpy(cachp->buf, statp, len << 2); break; } - + spin_lock(&cache_lock); lru_put_front(rp); rp->c_secure = rqstp->rq_secure; rp->c_type = cachetype; rp->c_state = RC_DONE; rp->c_timestamp = jiffies; - + spin_unlock(&cache_lock); return; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfsd/nfsctl.c linux.19pre5-ac1/fs/nfsd/nfsctl.c --- linux.19p5/fs/nfsd/nfsctl.c Thu Apr 4 13:18:10 2002 +++ linux.19pre5-ac1/fs/nfsd/nfsctl.c Thu Mar 21 00:48:42 2002 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -44,31 +45,26 @@ static int nfsctl_ugidupdate(struct nfsctl_ugidmap *data); #endif -static int initialized; - -int exp_procfs_exports(char *buffer, char **start, off_t offset, - int length, int *eof, void *data); +extern struct seq_operations nfs_exports_op; +static int exports_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &nfs_exports_op); +} +static struct file_operations exports_operations = { + open: exports_open, + read: seq_read, + llseek: seq_lseek, + release: seq_release, +}; void proc_export_init(void) { + struct proc_dir_entry *entry; if (!proc_mkdir("fs/nfs", 0)) return; - create_proc_read_entry("fs/nfs/exports", 0, 0, exp_procfs_exports,NULL); -} - - -/* - * Initialize nfsd - */ -static void -nfsd_init(void) -{ - nfsd_stat_init(); /* Statistics */ - nfsd_cache_init(); /* RPC reply cache */ - nfsd_export_init(); /* Exports table */ - nfsd_lockd_init(); /* lockd->nfsd callbacks */ - proc_export_init(); - initialized = 1; + entry = create_proc_entry("fs/nfs/exports", 0, NULL); + if (entry) + entry->proc_fops = &exports_operations; } static inline int @@ -126,7 +122,7 @@ err = -EPERM; else err = exp_rootfh(clp, 0, 0, data->gd_path, res, data->gd_maxlen); - exp_unlock(); + exp_readunlock(); return err; } @@ -149,7 +145,7 @@ err = -EPERM; else err = exp_rootfh(clp, 0, 0, data->gd_path, &fh, NFS_FHSIZE); - exp_unlock(); + exp_readunlock(); if (err == 0) { if (fh.fh_size > NFS_FHSIZE) @@ -182,7 +178,7 @@ err = -EPERM; else err = exp_rootfh(clp, to_kdev_t(data->gf_dev), data->gf_ino, NULL, &fh, NFS_FHSIZE); - exp_unlock(); + exp_readunlock(); if (err == 0) { if (fh.fh_size > NFS_FHSIZE) @@ -225,10 +221,7 @@ int err; int argsize, respsize; - MOD_INC_USE_COUNT; - lock_kernel (); - if (!initialized) - nfsd_init(); + err = -EPERM; if (!capable(CAP_SYS_ADMIN)) { goto done; @@ -300,39 +293,47 @@ if (res) kfree(res); - unlock_kernel (); - MOD_DEC_USE_COUNT; return err; } -#ifdef MODULE -/* New-style module support since 2.1.18 */ EXPORT_NO_SYMBOLS; MODULE_AUTHOR("Olaf Kirch "); MODULE_LICENSE("GPL"); +#ifdef MODULE struct nfsd_linkage nfsd_linkage_s = { do_nfsservctl: handle_sys_nfsservctl, + owner: THIS_MODULE, }; +#endif /* * Initialize the module */ -int -init_module(void) +static int __init +nfsd_init(void) { printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n"); +#ifdef MODULE nfsd_linkage = &nfsd_linkage_s; +#endif + nfsd_stat_init(); /* Statistics */ + nfsd_cache_init(); /* RPC reply cache */ + nfsd_export_init(); /* Exports table */ + nfsd_lockd_init(); /* lockd->nfsd callbacks */ + proc_export_init(); return 0; } /* * Clean up the mess before unloading the module */ -void -cleanup_module(void) +static void __exit +nfsd_exit(void) { +#ifdef MODULE nfsd_linkage = NULL; +#endif nfsd_export_shutdown(); nfsd_cache_shutdown(); remove_proc_entry("fs/nfs/exports", NULL); @@ -340,4 +341,6 @@ nfsd_stat_shutdown(); nfsd_lockd_shutdown(); } -#endif + +module_init(nfsd_init); +module_exit(nfsd_exit); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfsd/nfsfh.c linux.19pre5-ac1/fs/nfsd/nfsfh.c --- linux.19p5/fs/nfsd/nfsfh.c Thu Apr 4 13:18:10 2002 +++ linux.19pre5-ac1/fs/nfsd/nfsfh.c Thu Mar 21 00:48:42 2002 @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -273,7 +274,9 @@ /* I'm going to assume that if the returned dentry is different, then * it is well connected. But nobody returns different dentrys do they? */ + down(&child->d_inode->i_sem); pdentry = child->d_inode->i_op->lookup(child->d_inode, tdentry); + up(&child->d_inode->i_sem); d_drop(tdentry); /* we never want ".." hashed */ if (!pdentry && tdentry->d_inode == NULL) { /* File system cannot find ".." ... sad but possible */ @@ -426,6 +429,7 @@ */ dprintk("nfs_fh: need to look harder for %d/%d\n",sb->s_dev,datap[0]); + lock_kernel(); if (!S_ISDIR(result->d_inode->i_mode)) { nfsdstats.fh_nocache_nondir++; /* need to iget dirino and make sure this inode is in that directory */ @@ -494,6 +498,7 @@ dput(dentry); dput(result); /* this will discard the whole free path, so we can up the semaphore */ up(&sb->s_nfsd_free_path_sem); + unlock_kernel(); goto retry; } dput(dentry); @@ -501,6 +506,7 @@ } dput(dentry); up(&sb->s_nfsd_free_path_sem); + unlock_kernel(); return result; err_dentry: @@ -508,6 +514,7 @@ err_result: dput(result); up(&sb->s_nfsd_free_path_sem); + unlock_kernel(); err_out: if (err == -ESTALE) nfsdstats.fh_stale++; @@ -534,12 +541,17 @@ dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp)); + /* keep this filehandle for possible reference when encoding attributes */ + rqstp->rq_reffh = fh; + if (!fhp->fh_dentry) { - kdev_t xdev; - ino_t xino; + kdev_t xdev = NODEV; + ino_t xino = 0; __u32 *datap=NULL; int data_left = fh->fh_size/4; int nfsdev; + int fsid = 0; + error = nfserr_stale; if (rqstp->rq_vers == 3) error = nfserr_badhandle; @@ -559,6 +571,10 @@ xdev = MKDEV(nfsdev>>16, nfsdev&0xFFFF); xino = *datap++; break; + case 1: + if ((data_left-=1)<0) goto out; + fsid = *datap++; + break; default: goto out; } @@ -574,13 +590,14 @@ * Look up the export entry. */ error = nfserr_stale; - exp = exp_get(rqstp->rq_client, xdev, xino); + if (fh->fh_version == 1 && fh->fh_fsid_type == 1) + exp = exp_get_fsid(rqstp->rq_client, fsid); + else + exp = exp_get(rqstp->rq_client, xdev, xino); - if (!exp) { + if (!exp) /* export entry revoked */ - nfsdstats.fh_stale++; goto out; - } /* Check if the request originated from a secure port. */ error = nfserr_perm; @@ -657,7 +674,7 @@ * write call). */ - /* When is type ever negative? */ + /* Type can be negative to e.g. exclude directories from linking */ if (type > 0 && (inode->i_mode & S_IFMT) != type) { error = (type == S_IFDIR)? nfserr_notdir : nfserr_isdir; goto out; @@ -690,13 +707,11 @@ && !(tdentry->d_inode->i_mode & S_IXOTH) ) { error = nfserr_stale; - nfsdstats.fh_stale++; dprintk("fh_verify: no root_squashed access.\n"); } } while ((tdentry != tdentry->d_parent)); if (exp->ex_dentry != tdentry) { error = nfserr_stale; - nfsdstats.fh_stale++; printk("nfsd Security: %s/%s bad export.\n", dentry->d_parent->d_name.name, dentry->d_name.name); @@ -716,6 +731,8 @@ } #endif out: + if (error == nfserr_stale) + nfsdstats.fh_stale++; return error; } @@ -820,12 +837,20 @@ } else { fhp->fh_handle.fh_version = 1; fhp->fh_handle.fh_auth_type = 0; - fhp->fh_handle.fh_fsid_type = 0; datap = fhp->fh_handle.fh_auth+0; - /* fsid_type 0 == 2byte major, 2byte minor, 4byte inode */ - *datap++ = htonl((MAJOR(exp->ex_dev)<<16)| MINOR(exp->ex_dev)); - *datap++ = ino_t_to_u32(exp->ex_ino); - fhp->fh_handle.fh_size = 3*4; + if ((exp->ex_flags & NFSEXP_FSID) && + (!ref_fh || ref_fh->fh_handle.fh_fsid_type == 1)) { + fhp->fh_handle.fh_fsid_type = 1; + /* fsid_type 1 == 4 bytes filesystem id */ + *datap++ = exp->ex_fsid; + fhp->fh_handle.fh_size = 2*4; + } else { + fhp->fh_handle.fh_fsid_type = 0; + /* fsid_type 0 == 2byte major, 2byte minor, 4byte inode */ + *datap++ = htonl((MAJOR(exp->ex_dev)<<16)| MINOR(exp->ex_dev)); + *datap++ = ino_t_to_u32(exp->ex_ino); + fhp->fh_handle.fh_size = 3*4; + } if (inode) { int size = fhp->fh_maxsize/4 - 3; fhp->fh_handle.fh_fileid_type = diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfsd/nfsproc.c linux.19pre5-ac1/fs/nfsd/nfsproc.c --- linux.19p5/fs/nfsd/nfsproc.c Thu Apr 4 13:18:10 2002 +++ linux.19pre5-ac1/fs/nfsd/nfsproc.c Thu Mar 21 00:48:42 2002 @@ -148,6 +148,7 @@ argp->count); argp->count = avail << 2; } + svc_reserve(rqstp, (19<<2) + argp->count + 4); resp->count = argp->count; nfserr = nfsd_read(rqstp, fh_copy(&resp->fh, &argp->fh), @@ -522,7 +523,7 @@ #define nfssvc_release_none NULL struct nfsd_void { int dummy; }; -#define PROC(name, argt, rest, relt, cache) \ +#define PROC(name, argt, rest, relt, cache, respsize) \ { (svc_procfunc) nfsd_proc_##name, \ (kxdrproc_t) nfssvc_decode_##argt, \ (kxdrproc_t) nfssvc_encode_##rest, \ @@ -530,27 +531,28 @@ sizeof(struct nfsd_##argt), \ sizeof(struct nfsd_##rest), \ 0, \ - cache \ + cache, \ + respsize, \ } struct svc_procedure nfsd_procedures2[18] = { - PROC(null, void, void, none, RC_NOCACHE), - PROC(getattr, fhandle, attrstat, fhandle, RC_NOCACHE), - PROC(setattr, sattrargs, attrstat, fhandle, RC_REPLBUFF), - PROC(none, void, void, none, RC_NOCACHE), - PROC(lookup, diropargs, diropres, fhandle, RC_NOCACHE), - PROC(readlink, fhandle, readlinkres, none, RC_NOCACHE), - PROC(read, readargs, readres, fhandle, RC_NOCACHE), - PROC(none, void, void, none, RC_NOCACHE), - PROC(write, writeargs, attrstat, fhandle, RC_REPLBUFF), - PROC(create, createargs, diropres, fhandle, RC_REPLBUFF), - PROC(remove, diropargs, void, none, RC_REPLSTAT), - PROC(rename, renameargs, void, none, RC_REPLSTAT), - PROC(link, linkargs, void, none, RC_REPLSTAT), - PROC(symlink, symlinkargs, void, none, RC_REPLSTAT), - PROC(mkdir, createargs, diropres, fhandle, RC_REPLBUFF), - PROC(rmdir, diropargs, void, none, RC_REPLSTAT), - PROC(readdir, readdirargs, readdirres, none, RC_REPLBUFF), - PROC(statfs, fhandle, statfsres, none, RC_NOCACHE), + PROC(null, void, void, none, RC_NOCACHE, 1), + PROC(getattr, fhandle, attrstat, fhandle, RC_NOCACHE, 1+18), + PROC(setattr, sattrargs, attrstat, fhandle, RC_REPLBUFF, 1+18), + PROC(none, void, void, none, RC_NOCACHE, 1), + PROC(lookup, diropargs, diropres, fhandle, RC_NOCACHE, 1+8+18), + PROC(readlink, fhandle, readlinkres, none, RC_NOCACHE, 1+1+256), + PROC(read, readargs, readres, fhandle, RC_NOCACHE, 1+18+1+NFSSVC_MAXBLKSIZE), + PROC(none, void, void, none, RC_NOCACHE, 1), + PROC(write, writeargs, attrstat, fhandle, RC_REPLBUFF, 1+18), + PROC(create, createargs, diropres, fhandle, RC_REPLBUFF, 1+8+18), + PROC(remove, diropargs, void, none, RC_REPLSTAT, 1), + PROC(rename, renameargs, void, none, RC_REPLSTAT, 1), + PROC(link, linkargs, void, none, RC_REPLSTAT, 1), + PROC(symlink, symlinkargs, void, none, RC_REPLSTAT, 1), + PROC(mkdir, createargs, diropres, fhandle, RC_REPLBUFF, 1+8+18), + PROC(rmdir, diropargs, void, none, RC_REPLSTAT, 1), + PROC(readdir, readdirargs, readdirres, none, RC_REPLBUFF, 0), + PROC(statfs, fhandle, statfsres, none, RC_NOCACHE, 1+5), }; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfsd/nfssvc.c linux.19pre5-ac1/fs/nfsd/nfssvc.c --- linux.19p5/fs/nfsd/nfssvc.c Thu Apr 4 13:18:10 2002 +++ linux.19pre5-ac1/fs/nfsd/nfssvc.c Thu Mar 21 00:48:42 2002 @@ -54,8 +54,9 @@ static void nfsd(struct svc_rqst *rqstp); struct timeval nfssvc_boot; static struct svc_serv *nfsd_serv; -static int nfsd_busy; +static atomic_t nfsd_busy; static unsigned long nfsd_last_call; +static spinlock_t nfsd_call_lock = SPIN_LOCK_UNLOCKED; struct nfsd_list { struct list_head list; @@ -74,7 +75,8 @@ int error; int none_left; struct list_head *victim; - + + lock_kernel(); dprintk("nfsd: creating service\n"); error = -EINVAL; if (nrservs <= 0) @@ -87,6 +89,7 @@ if (error<0) goto out; if (!nfsd_serv) { + atomic_set(&nfsd_busy, 0); nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE, NFSSVC_XDRSIZE); if (nfsd_serv == NULL) goto out; @@ -94,7 +97,7 @@ if (error < 0) goto failure; -#if 0 /* Don't even pretend that TCP works. It doesn't. */ +#if CONFIG_NFSD_TCP error = svc_makesock(nfsd_serv, IPPROTO_TCP, port); if (error < 0) goto failure; @@ -125,6 +128,7 @@ nfsd_racache_shutdown(); } out: + unlock_kernel(); return error; } @@ -135,6 +139,7 @@ unsigned long diff; int decile; + spin_lock(&nfsd_call_lock); prev_call = nfsd_last_call; nfsd_last_call = jiffies; decile = busy_threads*10/nfsdstats.th_cnt; @@ -145,6 +150,7 @@ if (decile == 10) nfsdstats.th_fullcnt++; } + spin_unlock(&nfsd_call_lock); } /* @@ -173,6 +179,7 @@ me.task = current; list_add(&me.list, &nfsd_list); + unlock_kernel(); /* * The main request loop */ @@ -188,12 +195,12 @@ * recvfrom routine. */ while ((err = svc_recv(serv, rqstp, - MAX_SCHEDULE_TIMEOUT)) == -EAGAIN) + 5*60*HZ)) == -EAGAIN) ; if (err < 0) break; - update_thread_usage(nfsd_busy); - nfsd_busy++; + update_thread_usage(atomic_read(&nfsd_busy)); + atomic_inc(&nfsd_busy); /* Lock the export hash tables for reading. */ exp_readlock(); @@ -211,9 +218,9 @@ svc_process(serv, rqstp); /* Unlock export hash tables */ - exp_unlock(); - update_thread_usage(nfsd_busy); - nfsd_busy--; + exp_readunlock(); + update_thread_usage(atomic_read(&nfsd_busy)); + atomic_dec(&nfsd_busy); } if (err != -EINTR) { @@ -228,6 +235,8 @@ err = signo; } + lock_kernel(); + /* Release lockd */ lockd_down(); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfsd/nfsxdr.c linux.19pre5-ac1/fs/nfsd/nfsxdr.c --- linux.19p5/fs/nfsd/nfsxdr.c Thu Apr 4 13:18:10 2002 +++ linux.19pre5-ac1/fs/nfsd/nfsxdr.c Thu Mar 21 00:48:42 2002 @@ -132,8 +132,9 @@ } static inline u32 * -encode_fattr(struct svc_rqst *rqstp, u32 *p, struct inode *inode) +encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) { + struct inode *inode = fhp->fh_dentry->d_inode; int type = (inode->i_mode & S_IFMT); *p++ = htonl(nfs_ftypes[type >> 12]); @@ -153,7 +154,12 @@ else *p++ = htonl(0xffffffff); *p++ = htonl((u32) inode->i_blocks); - *p++ = htonl((u32) inode->i_dev); + if (rqstp->rq_reffh->fh_version == 1 + && rqstp->rq_reffh->fh_fsid_type == 1 + && (fhp->fh_export->ex_flags & NFSEXP_FSID)) + *p++ = htonl((u32) fhp->fh_export->ex_fsid); + else + *p++ = htonl((u32) inode->i_dev); *p++ = htonl((u32) inode->i_ino); *p++ = htonl((u32) inode->i_atime); *p++ = 0; @@ -332,7 +338,7 @@ nfssvc_encode_attrstat(struct svc_rqst *rqstp, u32 *p, struct nfsd_attrstat *resp) { - p = encode_fattr(rqstp, p, resp->fh.fh_dentry->d_inode); + p = encode_fattr(rqstp, p, &resp->fh); return xdr_ressize_check(rqstp, p); } @@ -341,7 +347,7 @@ struct nfsd_diropres *resp) { p = encode_fh(p, &resp->fh); - p = encode_fattr(rqstp, p, resp->fh.fh_dentry->d_inode); + p = encode_fattr(rqstp, p, &resp->fh); return xdr_ressize_check(rqstp, p); } @@ -358,7 +364,7 @@ nfssvc_encode_readres(struct svc_rqst *rqstp, u32 *p, struct nfsd_readres *resp) { - p = encode_fattr(rqstp, p, resp->fh.fh_dentry->d_inode); + p = encode_fattr(rqstp, p, &resp->fh); *p++ = htonl(resp->count); p += XDR_QUADLEN(resp->count); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfsd/vfs.c linux.19pre5-ac1/fs/nfsd/vfs.c --- linux.19p5/fs/nfsd/vfs.c Thu Apr 4 13:18:10 2002 +++ linux.19pre5-ac1/fs/nfsd/vfs.c Thu Mar 21 00:48:42 2002 @@ -114,35 +114,31 @@ if (isdotent(name, len)) { if (len==1) dentry = dget(dparent); - else { /* must be ".." */ + else if (dparent != exp->ex_dentry) + dentry = dget(dparent->d_parent); + else if (!EX_CROSSMNT(exp)) + dentry = dget(dparent); /* .. == . just like at / */ + else { /* checking mountpoint crossing is very different when stepping up */ - if (dparent == exp->ex_dentry) { - if (!EX_CROSSMNT(exp)) - dentry = dget(dparent); /* .. == . just like at / */ - else - { - struct svc_export *exp2 = NULL; - struct dentry *dp; - struct vfsmount *mnt = mntget(exp->ex_mnt); - dentry = dget(dparent); - while(follow_up(&mnt, &dentry)) - ; - dp = dget(dentry->d_parent); - dput(dentry); - dentry = dp; - for ( ; exp2 == NULL && dp->d_parent != dp; - dp=dp->d_parent) - exp2 = exp_get(exp->ex_client, dp->d_inode->i_dev, dp->d_inode->i_ino); - if (exp2==NULL) { - dput(dentry); - dentry = dget(dparent); - } else { - exp = exp2; - } - mntput(mnt); - } - } else - dentry = dget(dparent->d_parent); + struct svc_export *exp2 = NULL; + struct dentry *dp; + struct vfsmount *mnt = mntget(exp->ex_mnt); + dentry = dget(dparent); + while(follow_up(&mnt, &dentry)) + ; + dp = dget(dentry->d_parent); + dput(dentry); + dentry = dp; + for ( ; exp2 == NULL && dp->d_parent != dp; + dp=dp->d_parent) + exp2 = exp_get(exp->ex_client, dp->d_inode->i_dev, dp->d_inode->i_ino); + if (exp2==NULL) { + dput(dentry); + dentry = dget(dparent); + } else { + exp = exp2; + } + mntput(mnt); } } else { fh_lock(fhp); @@ -216,36 +212,37 @@ dentry = fhp->fh_dentry; inode = dentry->d_inode; - err = inode_change_ok(inode, iap); - /* could be a "touch" (utimes) request where the user is not the owner but does - * have write permission. In this case the user should be allowed to set - * both times to the current time. We could just assume any such SETATTR - * is intended to set the times to "now", but we do a couple of simple tests - * to increase our confidence. + /* NFSv2 does not differentiate between "set-[ac]time-to-now" + * which only requires access, and "set-[ac]time-to-X" which + * requires ownership. + * So if it looks like it might be "set both to the same time which + * is close to now", and if inode_change_ok fails, then we + * convert to "set to now" instead of "set to explicit time" + * + * We only call inode_change_ok as the last test as technically + * it is not an interface that we should be using. It is only + * valid if the filesystem does not define it's own i_op->setattr. */ #define BOTH_TIME_SET (ATTR_ATIME_SET | ATTR_MTIME_SET) #define MAX_TOUCH_TIME_ERROR (30*60) - if (err - && (iap->ia_valid & BOTH_TIME_SET) == BOTH_TIME_SET + if ((iap->ia_valid & BOTH_TIME_SET) == BOTH_TIME_SET && iap->ia_mtime == iap->ia_atime ) { - /* looks good. now just make sure time is in the right ballpark. - * solaris, at least, doesn't seem to care what the time request is + /* Looks probable. Now just make sure time is in the right ballpark. + * Solaris, at least, doesn't seem to care what the time request is. + * We require it be within 30 minutes of now. */ time_t delta = iap->ia_atime - CURRENT_TIME; if (delta<0) delta = -delta; - if (delta < MAX_TOUCH_TIME_ERROR) { + if (delta < MAX_TOUCH_TIME_ERROR && + inode_change_ok(inode, iap) != 0) { /* turn off ATTR_[AM]TIME_SET but leave ATTR_[AM]TIME * this will cause notify_change to set these times to "now" */ iap->ia_valid &= ~BOTH_TIME_SET; - err = inode_change_ok(inode, iap); } } - if (err) - goto out_nfserr; - /* The size case is special. It changes the file as well as the attributes. */ if (iap->ia_valid & ATTR_SIZE) { if (iap->ia_size < inode->i_size) { @@ -518,36 +515,48 @@ * As this calls fsync (not fdatasync) there is no need for a write_inode * after it. */ +inline void nfsd_dosync(struct file *filp, struct dentry *dp, + struct file_operations *fop) +{ + struct inode *inode = dp->d_inode; + int (*fsync) (struct file *, struct dentry *, int); + + filemap_fdatasync(inode->i_mapping); + if (fop && (fsync = fop->fsync)) + fsync(filp, dp, 0); + filemap_fdatawait(inode->i_mapping); +} + + void nfsd_sync(struct file *filp) { + struct inode *inode = filp->f_dentry->d_inode; dprintk("nfsd: sync file %s\n", filp->f_dentry->d_name.name); - down(&filp->f_dentry->d_inode->i_sem); - filp->f_op->fsync(filp, filp->f_dentry, 0); - up(&filp->f_dentry->d_inode->i_sem); + down(&inode->i_sem); + nfsd_dosync(filp, filp->f_dentry, filp->f_op); + up(&inode->i_sem); } void nfsd_sync_dir(struct dentry *dp) { - struct inode *inode = dp->d_inode; - int (*fsync) (struct file *, struct dentry *, int); - - if (inode->i_fop && (fsync = inode->i_fop->fsync)) { - fsync(NULL, dp, 0); - } + nfsd_dosync(NULL, dp, dp->d_inode->i_fop); } /* * Obtain the readahead parameters for the file * specified by (dev, ino). */ +static spinlock_t ra_lock = SPIN_LOCK_UNLOCKED; + static inline struct raparms * nfsd_get_raparms(dev_t dev, ino_t ino) { struct raparms *ra, **rap, **frap = NULL; int depth = 0; - + + spin_lock(&ra_lock); for (rap = &raparm_cache; (ra = *rap); rap = &ra->p_next) { if (ra->p_ino == ino && ra->p_dev == dev) goto found; @@ -556,8 +565,10 @@ frap = rap; } depth = nfsdstats.ra_size*11/10; - if (!frap) + if (!frap) { + spin_unlock(&ra_lock); return NULL; + } rap = frap; ra = *frap; ra->p_dev = dev; @@ -575,6 +586,7 @@ } ra->p_count++; nfsdstats.ra_depth[depth*10/nfsdstats.ra_size]++; + spin_unlock(&ra_lock); return ra; } @@ -1278,6 +1290,7 @@ goto out_dput_old; + lock_kernel(); #ifdef MSNFS if ((ffhp->fh_export->ex_flags & NFSEXP_MSNFS) && ((atomic_read(&odentry->d_count) > 1) @@ -1286,6 +1299,7 @@ } else #endif err = vfs_rename(fdir, odentry, tdir, ndentry); + unlock_kernel(); if (!err && EX_ISSYNC(tfhp->fh_export)) { nfsd_sync_dir(tdentry); nfsd_sync_dir(fdentry); @@ -1380,7 +1394,6 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, encode_dent_fn func, u32 *buffer, int *countp, u32 *verf) { - struct inode *inode; u32 *p; int oldlen, eof, err; struct file file; @@ -1392,9 +1405,6 @@ if (offset > ~(u32) 0) goto out_close; - err = nfserr_notdir; - if (!file.f_op->readdir) - goto out_close; file.f_pos = offset; /* Set up the readdir context */ @@ -1409,25 +1419,16 @@ * readdir() is not guaranteed to fill up the entire buffer, but * may choose to do less. */ - inode = file.f_dentry->d_inode; - down(&inode->i_sem); - while (1) { + + do { oldlen = cd.buflen; - /* - dprintk("nfsd: f_op->readdir(%x/%ld @ %d) buflen = %d (%d)\n", - file.f_inode->i_dev, file.f_inode->i_ino, - (int) file.f_pos, (int) oldlen, (int) cd.buflen); - */ - err = file.f_op->readdir(&file, &cd, (filldir_t) func); + err = vfs_readdir(&file, (filldir_t) func, &cd); + if (err < 0) goto out_nfserr; - if (oldlen == cd.buflen) - break; - if (cd.eob) - break; - } - up(&inode->i_sem); + + } while (oldlen != cd.buflen && !cd.eob); /* If we didn't fill the buffer completely, we're at EOF */ eof = !cd.eob; @@ -1454,7 +1455,6 @@ return err; out_nfserr: - up(&inode->i_sem); err = nfserrno(err); goto out_close; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nls/Config.in linux.19pre5-ac1/fs/nls/Config.in --- linux.19p5/fs/nls/Config.in Thu Apr 4 13:18:10 2002 +++ linux.19pre5-ac1/fs/nls/Config.in Thu Feb 14 20:46:53 2002 @@ -12,7 +12,7 @@ # msdos and Joliet want NLS if [ "$CONFIG_JOLIET" = "y" -o "$CONFIG_FAT_FS" != "n" \ -o "$CONFIG_NTFS_FS" != "n" -o "$CONFIG_NCPFS_NLS" = "y" \ - -o "$CONFIG_SMB_NLS" = "y" ]; then + -o "$CONFIG_SMB_NLS" = "y" -o "$CONFIG_JFS_FS" != "n" ]; then define_bool CONFIG_NLS y else define_bool CONFIG_NLS n diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nls/nls_base.c linux.19pre5-ac1/fs/nls/nls_base.c --- linux.19p5/fs/nls/nls_base.c Thu Apr 4 13:18:10 2002 +++ linux.19pre5-ac1/fs/nls/nls_base.c Wed Apr 3 01:02:21 2002 @@ -1,5 +1,5 @@ /* - * linux/fs/nls.c + * linux/fs/nls_base.c * * Native language support--charsets and unicode translations. * By Gordon Chaffee 1996, 1997 @@ -93,7 +93,7 @@ ip++; n--; } else { - op += size; + op++; ip += size; n -= size; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/partitions/Makefile linux.19pre5-ac1/fs/partitions/Makefile --- linux.19p5/fs/partitions/Makefile Thu Apr 4 13:18:11 2002 +++ linux.19pre5-ac1/fs/partitions/Makefile Mon Jan 28 19:56:27 2002 @@ -9,7 +9,7 @@ O_TARGET := partitions.o -export-objs := check.o ibm.o +export-objs := check.o ibm.o msdos.o obj-y := check.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/partitions/ldm.c linux.19pre5-ac1/fs/partitions/ldm.c --- linux.19p5/fs/partitions/ldm.c Thu Apr 4 13:18:12 2002 +++ linux.19pre5-ac1/fs/partitions/ldm.c Mon Jan 28 19:56:27 2002 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/partitions/msdos.c linux.19pre5-ac1/fs/partitions/msdos.c --- linux.19p5/fs/partitions/msdos.c Thu Apr 4 13:21:14 2002 +++ linux.19pre5-ac1/fs/partitions/msdos.c Mon Mar 25 18:13:22 2002 @@ -29,7 +29,13 @@ #ifdef CONFIG_BLK_DEV_IDE #include /* IDE xlate */ -#endif /* CONFIG_BLK_DEV_IDE */ +#elif defined(CONFIG_BLK_DEV_IDE_MODULE) +#include + +int (*ide_xlate_1024_hook)(kdev_t, int, int, const char *); +EXPORT_SYMBOL(ide_xlate_1024_hook); +#define ide_xlate_1024 ide_xlate_1024_hook +#endif #include @@ -467,7 +473,7 @@ */ static int handle_ide_mess(struct block_device *bdev) { -#ifdef CONFIG_BLK_DEV_IDE +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) Sector sect; unsigned char *data; kdev_t dev = to_kdev_t(bdev->bd_dev); @@ -475,6 +481,10 @@ int heads = 0; struct partition *p; int i; +#ifdef CONFIG_BLK_DEV_IDE_MODULE + if (!ide_xlate_1024) + return 1; +#endif /* * The i386 partition handling programs very often * make partitions end on cylinder boundaries. @@ -536,7 +546,7 @@ /* Flush the cache */ invalidate_bdev(bdev, 1); truncate_inode_pages(bdev->bd_inode->i_mapping, 0); -#endif /* CONFIG_BLK_DEV_IDE */ +#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */ return 1; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/proc/array.c linux.19pre5-ac1/fs/proc/array.c --- linux.19p5/fs/proc/array.c Thu Apr 4 13:18:06 2002 +++ linux.19pre5-ac1/fs/proc/array.c Wed Feb 27 18:32:02 2002 @@ -335,9 +335,8 @@ /* scale priority and nice values from timeslices to -20..20 */ /* to make it look like a "normal" Unix priority/nice value */ - priority = task->counter; - priority = 20 - (priority * 10 + DEF_COUNTER / 2) / DEF_COUNTER; - nice = task->nice; + priority = task_prio(task); + nice = task_nice(task); read_lock(&tasklist_lock); ppid = task->pid ? task->p_opptr->pid : 0; @@ -387,7 +386,7 @@ task->nswap, task->cnswap, task->exit_signal, - task->processor); + task->cpu); if(mm) mmput(mm); return res; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/proc/proc_misc.c linux.19pre5-ac1/fs/proc/proc_misc.c --- linux.19p5/fs/proc/proc_misc.c Thu Apr 4 13:21:14 2002 +++ linux.19pre5-ac1/fs/proc/proc_misc.c Mon Mar 25 18:13:28 2002 @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -87,11 +88,11 @@ a = avenrun[0] + (FIXED_1/200); b = avenrun[1] + (FIXED_1/200); c = avenrun[2] + (FIXED_1/200); - len = sprintf(page,"%d.%02d %d.%02d %d.%02d %d/%d %d\n", + len = sprintf(page,"%d.%02d %d.%02d %d.%02d %ld/%d %d\n", LOAD_INT(a), LOAD_FRAC(a), LOAD_INT(b), LOAD_FRAC(b), LOAD_INT(c), LOAD_FRAC(c), - nr_running, nr_threads, last_pid); + nr_running(), nr_threads, last_pid); return proc_calc_metrics(page, start, off, count, eof, len); } @@ -103,7 +104,7 @@ int len; uptime = jiffies; - idle = init_tasks[0]->times.tms_utime + init_tasks[0]->times.tms_stime; + idle = init_task.times.tms_utime + init_task.times.tms_stime; /* The formula for the fraction parts really is ((t * 100) / HZ) % 100, but that would overflow about every five days at HZ == 100. @@ -136,7 +137,11 @@ struct sysinfo i; int len; int pg_size ; + int committed; + /* FIXME: needs to be in headers */ + extern atomic_t vm_committed_space; + /* * display in kilobytes. */ @@ -145,6 +150,7 @@ si_meminfo(&i); si_swapinfo(&i); pg_size = atomic_read(&page_cache_size) - i.bufferram ; + committed = atomic_read(&vm_committed_space); len = sprintf(page, " total: used: free: shared: buffers: cached:\n" "Mem: %8Lu %8Lu %8Lu %8Lu %8Lu %8Lu\n" @@ -166,13 +172,16 @@ "Cached: %8lu kB\n" "SwapCached: %8lu kB\n" "Active: %8u kB\n" - "Inactive: %8u kB\n" + "Inact_dirty: %8u kB\n" + "Inact_clean: %8u kB\n" + "Inact_target: %8u kB\n" "HighTotal: %8lu kB\n" "HighFree: %8lu kB\n" "LowTotal: %8lu kB\n" "LowFree: %8lu kB\n" "SwapTotal: %8lu kB\n" - "SwapFree: %8lu kB\n", + "SwapFree: %8lu kB\n" + "Committed_AS: %8u kB\n", K(i.totalram), K(i.freeram), K(i.sharedram), @@ -180,13 +189,16 @@ K(pg_size - swapper_space.nrpages), K(swapper_space.nrpages), K(nr_active_pages), - K(nr_inactive_pages), + K(nr_inactive_dirty_pages), + K(nr_inactive_clean_pages), + K(inactive_target()), K(i.totalhigh), K(i.freehigh), K(i.totalram-i.totalhigh), K(i.freeram-i.freehigh), K(i.totalswap), - K(i.freeswap)); + K(i.freeswap), + K(committed)); return proc_calc_metrics(page, start, off, count, eof, len); #undef B @@ -323,10 +335,10 @@ } len += sprintf(page + len, - "\nctxt %u\n" + "\nctxt %lu\n" "btime %lu\n" "processes %lu\n", - kstat.context_swtch, + nr_context_switches(), xtime.tv_sec - jif / HZ, total_forks); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/reiserfs/buffer2.c linux.19pre5-ac1/fs/reiserfs/buffer2.c --- linux.19p5/fs/reiserfs/buffer2.c Thu Apr 4 13:18:13 2002 +++ linux.19pre5-ac1/fs/reiserfs/buffer2.c Wed Feb 27 18:32:03 2002 @@ -33,8 +33,7 @@ buffer_journal_dirty(bh) ? ' ' : '!'); } run_task_queue(&tq_disk); - current->policy |= SCHED_YIELD; - schedule(); + yield(); } if (repeat_counter > 30000000) { reiserfs_warning("vs-3051: done waiting, ignore vs-3050 messages for (%b)\n", bh) ; @@ -52,11 +51,11 @@ struct buffer_head * reiserfs_bread (struct super_block *super, int n_block, int n_size) { struct buffer_head *result; - PROC_EXP( unsigned int ctx_switches = kstat.context_swtch ); + PROC_EXP( unsigned int ctx_switches = nr_context_switches(); ); result = bread (super -> s_dev, n_block, n_size); PROC_INFO_INC( super, breads ); - PROC_EXP( if( kstat.context_swtch != ctx_switches ) + PROC_EXP( if( nr_context_switches() != ctx_switches ) PROC_INFO_INC( super, bread_miss ) ); return result; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/reiserfs/journal.c linux.19pre5-ac1/fs/reiserfs/journal.c --- linux.19p5/fs/reiserfs/journal.c Thu Apr 4 13:21:14 2002 +++ linux.19pre5-ac1/fs/reiserfs/journal.c Sat Mar 2 19:32:24 2002 @@ -151,8 +151,7 @@ } bn = allocate_bitmap_node(p_s_sb) ; if (!bn) { - current->policy |= SCHED_YIELD ; - schedule() ; + yield(); goto repeat ; } return bn ; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/ufs/truncate.c linux.19pre5-ac1/fs/ufs/truncate.c --- linux.19p5/fs/ufs/truncate.c Thu Apr 4 13:18:08 2002 +++ linux.19pre5-ac1/fs/ufs/truncate.c Wed Feb 27 18:32:03 2002 @@ -448,10 +448,7 @@ if (IS_SYNC(inode) && (inode->i_state & I_DIRTY)) ufs_sync_inode (inode); run_task_queue(&tq_disk); - current->policy |= SCHED_YIELD; - schedule (); - - + yield(); } offset = inode->i_size & uspi->s_fshift; if (offset) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-alpha/ioctls.h linux.19pre5-ac1/include/asm-alpha/ioctls.h --- linux.19p5/include/asm-alpha/ioctls.h Thu Apr 4 13:18:23 2002 +++ linux.19pre5-ac1/include/asm-alpha/ioctls.h Mon Jan 28 19:57:08 2002 @@ -9,6 +9,7 @@ #define FIONBIO _IOW('f', 126, int) #define FIONREAD _IOR('f', 127, int) #define TIOCINQ FIONREAD +#define FIOQSIZE _IOR('f', 128, loff_t) #define TIOCGETP _IOR('t', 8, struct sgttyb) #define TIOCSETP _IOW('t', 9, struct sgttyb) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-alpha/pgtable.h linux.19pre5-ac1/include/asm-alpha/pgtable.h --- linux.19p5/include/asm-alpha/pgtable.h Thu Apr 4 13:21:14 2002 +++ linux.19pre5-ac1/include/asm-alpha/pgtable.h Mon Jan 28 19:33:28 2002 @@ -194,8 +194,8 @@ #define PAGE_TO_PA(page) ((page - mem_map) << PAGE_SHIFT) #else #define PAGE_TO_PA(page) \ - ((((page)-page_zone(page)->zone_mem_map) << PAGE_SHIFT) \ - + page_zone(page)->zone_start_paddr) + ((((page)-(page)->zone->zone_mem_map) << PAGE_SHIFT) \ + + (page)->zone->zone_start_paddr) #endif #ifndef CONFIG_DISCONTIGMEM @@ -213,8 +213,8 @@ pte_t pte; \ unsigned long pfn; \ \ - pfn = ((unsigned long)((page)-page_zone(page)->zone_mem_map)) << 32; \ - pfn += page_zone(page)->zone_start_paddr << (32-PAGE_SHIFT); \ + pfn = ((unsigned long)((page)-(page)->zone->zone_mem_map)) << 32; \ + pfn += (page)->zone->zone_start_paddr << (32-PAGE_SHIFT); \ pte_val(pte) = pfn | pgprot_val(pgprot); \ \ pte; \ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-alpha/rmap.h linux.19pre5-ac1/include/asm-alpha/rmap.h --- linux.19p5/include/asm-alpha/rmap.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/asm-alpha/rmap.h Mon Jan 28 19:33:28 2002 @@ -0,0 +1,7 @@ +#ifndef _ALPHA_RMAP_H +#define _ALPHA_RMAP_H + +/* nothing to see, move along */ +#include + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-arm/arch-cl7500/system.h linux.19pre5-ac1/include/asm-arm/arch-cl7500/system.h --- linux.19p5/include/asm-arm/arch-cl7500/system.h Thu Apr 4 13:18:29 2002 +++ linux.19pre5-ac1/include/asm-arm/arch-cl7500/system.h Wed Feb 13 00:25:36 2002 @@ -18,6 +18,6 @@ do { \ iomd_writeb(0, IOMD_ROMCR0); \ cpu_reset(0); \ - } while (0); + } while (0) #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-arm/arch-sa1100/keyboard.h linux.19pre5-ac1/include/asm-arm/arch-sa1100/keyboard.h --- linux.19p5/include/asm-arm/arch-sa1100/keyboard.h Thu Apr 4 13:21:14 2002 +++ linux.19pre5-ac1/include/asm-arm/arch-sa1100/keyboard.h Thu Apr 4 13:58:05 2002 @@ -10,8 +10,8 @@ #include #include -#define kbd_disable_irq() do { } while(0); -#define kbd_enable_irq() do { } while(0); +#define kbd_disable_irq() do { } while(0) +#define kbd_enable_irq() do { } while(0) extern int sa1111_kbd_init_hw(void); extern void gc_kbd_init_hw(void); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-arm/page.h linux.19pre5-ac1/include/asm-arm/page.h --- linux.19p5/include/asm-arm/page.h Thu Apr 4 13:21:14 2002 +++ linux.19pre5-ac1/include/asm-arm/page.h Thu Apr 4 13:58:17 2002 @@ -106,6 +106,9 @@ #define VALID_PAGE(page) ((page - mem_map) < max_mapnr) #endif +#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + #endif #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-cris/ioctls.h linux.19pre5-ac1/include/asm-cris/ioctls.h --- linux.19p5/include/asm-cris/ioctls.h Thu Apr 4 13:18:38 2002 +++ linux.19pre5-ac1/include/asm-cris/ioctls.h Mon Jan 28 19:57:45 2002 @@ -69,6 +69,7 @@ #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ #define TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ #define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ +#define FIOQSIZE 0x5460 /* Used for packet mode */ #define TIOCPKT_DATA 0 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-cris/rmap.h linux.19pre5-ac1/include/asm-cris/rmap.h --- linux.19p5/include/asm-cris/rmap.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/asm-cris/rmap.h Mon Jan 28 19:33:28 2002 @@ -0,0 +1,7 @@ +#ifndef _CRIS_RMAP_H +#define _CRIS_RMAP_H + +/* nothing to see, move along :) */ +#include + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-generic/rmap.h linux.19pre5-ac1/include/asm-generic/rmap.h --- linux.19p5/include/asm-generic/rmap.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/asm-generic/rmap.h Mon Jan 28 19:33:28 2002 @@ -0,0 +1,57 @@ +#ifndef _GENERIC_RMAP_H +#define _GENERIC_RMAP_H +/* + * linux/include/asm-generic/rmap.h + * + * Architecture dependant parts of the reverse mapping code, + * this version should work for most architectures with a + * 'normal' page table layout. + * + * We use the struct page of the page table page to find out + * the process and full address of a page table entry: + * - page->mapping points to the process' mm_struct + * - page->index has the high bits of the address + * - the lower bits of the address are calculated from the + * offset of the page table entry within the page table page + */ +#include + +static inline void pgtable_add_rmap(pte_t * ptep, struct mm_struct * mm, unsigned long address) +{ + struct page * page = virt_to_page(ptep); +#ifdef BROKEN_PPC_PTE_ALLOC_ONE + /* OK, so PPC calls pte_alloc() before mem_map[] is setup ... ;( */ + extern int mem_init_done; + + if (!mem_init_done) + return; +#endif + page->mapping = (void *)mm; + page->index = address & ~((PTRS_PER_PTE * PAGE_SIZE) - 1); +} + +static inline void pgtable_remove_rmap(pte_t * ptep) +{ + struct page * page = virt_to_page(ptep); + + page->mapping = NULL; + page->index = 0; +} + +static inline struct mm_struct * ptep_to_mm(pte_t * ptep) +{ + struct page * page = virt_to_page(ptep); + + return (struct mm_struct *) page->mapping; +} + +static inline unsigned long ptep_to_address(pte_t * ptep) +{ + struct page * page = virt_to_page(ptep); + unsigned long low_bits; + + low_bits = ((unsigned long)ptep & ~PAGE_MASK) * PTRS_PER_PTE; + return page->index + low_bits; +} + +#endif /* _GENERIC_RMAP_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/apic.h linux.19pre5-ac1/include/asm-i386/apic.h --- linux.19p5/include/asm-i386/apic.h Thu Apr 4 13:18:22 2002 +++ linux.19pre5-ac1/include/asm-i386/apic.h Thu Apr 4 15:46:31 2002 @@ -79,6 +79,8 @@ extern void setup_apic_nmi_watchdog (void); extern inline void nmi_watchdog_tick (struct pt_regs * regs); extern int APIC_init_uniprocessor (void); +extern void disable_APIC_timer(void); +extern void enable_APIC_timer(void); extern struct pm_dev *apic_pm_register(pm_dev_t, unsigned long, pm_callback); extern void apic_pm_unregister(struct pm_dev*); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/bitops.h linux.19pre5-ac1/include/asm-i386/bitops.h --- linux.19p5/include/asm-i386/bitops.h Thu Apr 4 13:18:21 2002 +++ linux.19pre5-ac1/include/asm-i386/bitops.h Tue Mar 26 20:11:14 2002 @@ -75,6 +75,14 @@ :"=m" (ADDR) :"Ir" (nr)); } + +static __inline__ void __clear_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( + "btrl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} #define smp_mb__before_clear_bit() barrier() #define smp_mb__after_clear_bit() barrier() @@ -284,6 +292,34 @@ } /** + * find_first_bit - find the first set bit in a memory region + * @addr: The address to start the search at + * @size: The maximum size to search + * + * Returns the bit-number of the first set bit, not the number of the byte + * containing a bit. + */ +static __inline__ int find_first_bit(void * addr, unsigned size) +{ + int d0, d1; + int res; + + /* This looks at memory. Mark it volatile to tell gcc not to move it around */ + __asm__ __volatile__( + "xorl %%eax,%%eax\n\t" + "repe; scasl\n\t" + "jz 1f\n\t" + "leal -4(%%edi),%%edi\n\t" + "bsfl (%%edi),%%eax\n" + "1:\tsubl %%ebx,%%edi\n\t" + "shll $3,%%edi\n\t" + "addl %%edi,%%eax" + :"=a" (res), "=&c" (d0), "=&D" (d1) + :"1" ((size + 31) >> 5), "2" (addr), "b" (addr)); + return res; +} + +/** * find_next_zero_bit - find the first zero bit in a memory region * @addr: The address to base the search on * @offset: The bitnumber to start searching at @@ -296,7 +332,7 @@ if (bit) { /* - * Look for zero in first byte + * Look for zero in the first 32 bits. */ __asm__("bsfl %1,%0\n\t" "jne 1f\n\t" @@ -317,6 +353,39 @@ } /** + * find_next_bit - find the first set bit in a memory region + * @addr: The address to base the search on + * @offset: The bitnumber to start searching at + * @size: The maximum size to search + */ +static __inline__ int find_next_bit (void * addr, int size, int offset) +{ + unsigned long * p = ((unsigned long *) addr) + (offset >> 5); + int set = 0, bit = offset & 31, res; + + if (bit) { + /* + * Look for nonzero in the first 32 bits: + */ + __asm__("bsfl %1,%0\n\t" + "jne 1f\n\t" + "movl $32, %0\n" + "1:" + : "=r" (set) + : "r" (*p >> bit)); + if (set < (32 - bit)) + return set + offset; + set = 32 - bit; + p++; + } + /* + * No set bit yet, search remaining full words for a bit + */ + res = find_first_bit (p, size - 32 * (p - (unsigned long *) addr)); + return (offset + set + res); +} + +/** * ffz - find first zero in word. * @word: The word to search * @@ -330,6 +399,20 @@ return word; } +/** + * __ffs - find first bit in word. + * @word: The word to search + * + * Undefined if no bit exists, so code should check against 0 first. + */ +static __inline__ unsigned long __ffs(unsigned long word) +{ + __asm__("bsfl %1,%0" + :"=r" (word) + :"rm" (word)); + return word; +} + #ifdef __KERNEL__ /** diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/desc.h linux.19pre5-ac1/include/asm-i386/desc.h --- linux.19p5/include/asm-i386/desc.h Thu Apr 4 13:18:22 2002 +++ linux.19pre5-ac1/include/asm-i386/desc.h Tue Jan 29 18:25:02 2002 @@ -18,23 +18,31 @@ * 9 - APM BIOS support * 10 - APM BIOS support * 11 - APM BIOS support + * 12 - PNPBIOS support + * 13 - PNPBIOS support + * 14 - PNPBIOS support + * 15 - PNPBIOS support + * 16 - PNPBIOS support + * 17 - not used + * 18 - not used + * 19 - not used * * The TSS+LDT descriptors are spread out a bit so that every CPU * has an exclusive cacheline for the per-CPU TSS and LDT: * - * 12 - CPU#0 TSS <-- new cacheline - * 13 - CPU#0 LDT - * 14 - not used - * 15 - not used - * 16 - CPU#1 TSS <-- new cacheline - * 17 - CPU#1 LDT - * 18 - not used - * 19 - not used + * 20 - CPU#0 TSS <-- new cacheline + * 21 - CPU#0 LDT + * 22 - not used + * 23 - not used + * 24 - CPU#1 TSS <-- new cacheline + * 25 - CPU#1 LDT + * 26 - not used + * 27 - not used * ... NR_CPUS per-CPU TSS+LDT's if on SMP * * Entry into gdt where to find first TSS. */ -#define __FIRST_TSS_ENTRY 12 +#define __FIRST_TSS_ENTRY 20 #define __FIRST_LDT_ENTRY (__FIRST_TSS_ENTRY+1) #define __TSS(n) (((n)<<2) + __FIRST_TSS_ENTRY) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/hw_irq.h linux.19pre5-ac1/include/asm-i386/hw_irq.h --- linux.19p5/include/asm-i386/hw_irq.h Thu Apr 4 13:18:22 2002 +++ linux.19pre5-ac1/include/asm-i386/hw_irq.h Tue Mar 26 20:11:14 2002 @@ -41,7 +41,8 @@ #define ERROR_APIC_VECTOR 0xfe #define INVALIDATE_TLB_VECTOR 0xfd #define RESCHEDULE_VECTOR 0xfc -#define CALL_FUNCTION_VECTOR 0xfb +#define TASK_MIGRATION_VECTOR 0xfb +#define CALL_FUNCTION_VECTOR 0xfa /* * Local APIC timer IRQ vector is on a different priority level, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/io_apic.h linux.19pre5-ac1/include/asm-i386/io_apic.h --- linux.19p5/include/asm-i386/io_apic.h Thu Apr 4 13:18:22 2002 +++ linux.19pre5-ac1/include/asm-i386/io_apic.h Thu Mar 21 00:36:42 2002 @@ -97,7 +97,7 @@ extern int mp_irq_entries; /* MP IRQ source entries */ -extern struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; +extern struct mpc_config_intsrc *mp_irqs; /* non-0 if default (table-less) MP configuration */ extern int mpc_default_type; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/ioctls.h linux.19pre5-ac1/include/asm-i386/ioctls.h --- linux.19p5/include/asm-i386/ioctls.h Thu Apr 4 13:18:22 2002 +++ linux.19pre5-ac1/include/asm-i386/ioctls.h Mon Jan 28 19:57:58 2002 @@ -67,6 +67,7 @@ #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ #define TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ #define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ +#define FIOQSIZE 0x5460 /* Used for packet mode */ #define TIOCPKT_DATA 0 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/mmu_context.h linux.19pre5-ac1/include/asm-i386/mmu_context.h --- linux.19p5/include/asm-i386/mmu_context.h Thu Apr 4 13:21:14 2002 +++ linux.19pre5-ac1/include/asm-i386/mmu_context.h Thu Apr 4 15:46:33 2002 @@ -7,6 +7,25 @@ #include /* + * Every architecture must define this function. It's the fastest + * way of searching a 140-bit bitmap where the first 100 bits are + * unlikely to be set. It's guaranteed that at least one of the 140 + * bits is cleared. + */ +static inline int sched_find_first_bit(unsigned long *b) +{ + if (unlikely(b[0])) + return __ffs(b[0]); + if (unlikely(b[1])) + return __ffs(b[1]) + 32; + if (unlikely(b[2])) + return __ffs(b[2]) + 64; + if (b[3]) + return __ffs(b[3]) + 96; + return __ffs(b[4]) + 128; +} + +/* * possibly do the LDT unload here? */ #define destroy_context(mm) do { } while(0) @@ -27,13 +46,13 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk, unsigned cpu) { - if (prev != next) { + if (likely(prev != next)) { /* stop flush ipis for the previous mm */ clear_bit(cpu, &prev->cpu_vm_mask); /* * Re-load LDT if necessary */ - if (prev->context.segments != next->context.segments) + if (unlikely(prev->context.segments != next->context.segments)) load_LDT(next); #ifdef CONFIG_SMP cpu_tlbstate[cpu].state = TLBSTATE_OK; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/mpspec.h linux.19pre5-ac1/include/asm-i386/mpspec.h --- linux.19p5/include/asm-i386/mpspec.h Thu Apr 4 13:21:14 2002 +++ linux.19pre5-ac1/include/asm-i386/mpspec.h Thu Mar 21 00:36:42 2002 @@ -184,11 +184,7 @@ * 7 2 CPU MCA+PCI */ -#ifdef CONFIG_MULTIQUAD -#define MAX_IRQ_SOURCES 512 -#else /* !CONFIG_MULTIQUAD */ #define MAX_IRQ_SOURCES 256 -#endif /* CONFIG_MULTIQUAD */ #define MAX_MP_BUSSES 32 enum mp_bustype { @@ -197,11 +193,11 @@ MP_BUS_PCI, MP_BUS_MCA }; -extern int mp_bus_id_to_type [MAX_MP_BUSSES]; -extern int mp_bus_id_to_node [MAX_MP_BUSSES]; -extern int mp_bus_id_to_local [MAX_MP_BUSSES]; +extern int *mp_bus_id_to_type; +extern int *mp_bus_id_to_node; +extern int *mp_bus_id_to_local; +extern int *mp_bus_id_to_pci_bus; extern int quad_local_to_mp_bus_id [NR_CPUS/4][4]; -extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES]; extern unsigned int boot_cpu_physical_apicid; extern unsigned long phys_cpu_present_map; @@ -210,11 +206,9 @@ extern void get_smp_config (void); extern int nr_ioapics; extern int apic_version [MAX_APICS]; -extern int mp_bus_id_to_type [MAX_MP_BUSSES]; extern int mp_irq_entries; -extern struct mpc_config_intsrc mp_irqs [MAX_IRQ_SOURCES]; +extern struct mpc_config_intsrc *mp_irqs; extern int mpc_default_type; -extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES]; extern int mp_current_pci_id; extern unsigned long mp_lapic_addr; extern int pic_mode; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/pgalloc.h linux.19pre5-ac1/include/asm-i386/pgalloc.h --- linux.19p5/include/asm-i386/pgalloc.h Thu Apr 4 13:18:22 2002 +++ linux.19pre5-ac1/include/asm-i386/pgalloc.h Thu Apr 4 15:46:31 2002 @@ -127,21 +127,25 @@ return (pte_t *)ret; } -static inline void pte_free_fast(pte_t *pte) +static __inline__ void pte_free_slow(pte_t *pte) { - *(unsigned long *)pte = (unsigned long) pte_quicklist; - pte_quicklist = (unsigned long *) pte; - pgtable_cache_size++; + free_page((unsigned long)pte); } -static __inline__ void pte_free_slow(pte_t *pte) +extern int pgt_cache_water[]; +static inline void pte_free_fast(pte_t *pte) { - free_page((unsigned long)pte); + if (pgtable_cache_size < pgt_cache_water[1]) { + *(unsigned long *)pte = (unsigned long) pte_quicklist; + pte_quicklist = (unsigned long *) pte; + pgtable_cache_size++; + } else + pte_free_slow(pte); } -#define pte_free(pte) pte_free_slow(pte) +#define pte_free(pte) pte_free_fast(pte) +#define pgd_alloc(mm) get_pgd_slow() #define pgd_free(pgd) free_pgd_slow(pgd) -#define pgd_alloc(mm) get_pgd_fast() /* * allocating and freeing a pmd is trivial: the 1-entry pmd is @@ -224,6 +228,7 @@ { struct mm_struct *active_mm; int state; + char __cacheline_padding[24]; }; extern struct tlb_state cpu_tlbstate[NR_CPUS]; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/rmap.h linux.19pre5-ac1/include/asm-i386/rmap.h --- linux.19p5/include/asm-i386/rmap.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/asm-i386/rmap.h Mon Jan 28 19:33:28 2002 @@ -0,0 +1,7 @@ +#ifndef _I386_RMAP_H +#define _I386_RMAP_H + +/* nothing to see, move along */ +#include + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/smp.h linux.19pre5-ac1/include/asm-i386/smp.h --- linux.19p5/include/asm-i386/smp.h Thu Apr 4 13:18:22 2002 +++ linux.19pre5-ac1/include/asm-i386/smp.h Thu Apr 4 15:46:31 2002 @@ -63,6 +63,7 @@ extern void smp_flush_tlb(void); extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); extern void smp_send_reschedule(int cpu); +extern void smp_send_reschedule_all(void); extern void smp_invalidate_rcv(void); /* Process an NMI */ extern void (*mtrr_hook) (void); extern void zap_low_mappings (void); @@ -104,7 +105,7 @@ * so this is correct in the x86 case. */ -#define smp_processor_id() (current->processor) +#define smp_processor_id() (current->cpu) static __inline int hard_smp_processor_id(void) { @@ -122,17 +123,5 @@ #define NO_PROC_ID 0xFF /* No processor magic marker */ -/* - * This magic constant controls our willingness to transfer - * a process across CPUs. Such a transfer incurs misses on the L1 - * cache, and on a P6 or P5 with multiple L2 caches L2 hits. My - * gut feeling is this will vary by board in value. For a board - * with separate L2 cache it probably depends also on the RSS, and - * for a board with shared L2 cache it ought to decay fast as other - * processes are run. - */ - -#define PROC_CHANGE_PENALTY 15 /* Schedule penalty */ - #endif #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-ia64/ioctls.h linux.19pre5-ac1/include/asm-ia64/ioctls.h --- linux.19p5/include/asm-ia64/ioctls.h Thu Apr 4 13:18:36 2002 +++ linux.19pre5-ac1/include/asm-ia64/ioctls.h Mon Jan 28 19:58:08 2002 @@ -72,6 +72,7 @@ #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ #define TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ #define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ +#define FIOQSIZE 0x5460 /* Used for packet mode */ #define TIOCPKT_DATA 0 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-ia64/rmap.h linux.19pre5-ac1/include/asm-ia64/rmap.h --- linux.19p5/include/asm-ia64/rmap.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/asm-ia64/rmap.h Mon Jan 28 19:33:28 2002 @@ -0,0 +1,7 @@ +#ifndef _IA64_RMAP_H +#define _IA64_RMAP_H + +/* nothing to see, move along */ +#include + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-m68k/ioctls.h linux.19pre5-ac1/include/asm-m68k/ioctls.h --- linux.19p5/include/asm-m68k/ioctls.h Thu Apr 4 13:18:23 2002 +++ linux.19pre5-ac1/include/asm-m68k/ioctls.h Mon Jan 28 19:58:17 2002 @@ -65,6 +65,7 @@ #define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ +#define FIOQSIZE 0x545E /* Used for packet mode */ #define TIOCPKT_DATA 0 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-m68k/rmap.h linux.19pre5-ac1/include/asm-m68k/rmap.h --- linux.19p5/include/asm-m68k/rmap.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/asm-m68k/rmap.h Mon Jan 28 19:33:28 2002 @@ -0,0 +1,7 @@ +#ifndef _M86K_RMAP_H +#define _M86K_RMAP_H + +/* nothing to see, move along */ +#include + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-mips/pgtable.h linux.19pre5-ac1/include/asm-mips/pgtable.h --- linux.19p5/include/asm-mips/pgtable.h Thu Apr 4 13:21:15 2002 +++ linux.19pre5-ac1/include/asm-mips/pgtable.h Thu Mar 14 22:23:04 2002 @@ -344,10 +344,16 @@ * setup: the pgd is never bad, and a pmd always exists (as it's folded * into the pgd entry) */ -static inline int pgd_none(pgd_t pgd) { return 0; } -static inline int pgd_bad(pgd_t pgd) { return 0; } -static inline int pgd_present(pgd_t pgd) { return 1; } -static inline void pgd_clear(pgd_t *pgdp) { } +extern inline int pgd_none(pgd_t pgd) { return 0; } +extern inline int pgd_bad(pgd_t pgd) { return 0; } +extern inline int pgd_present(pgd_t pgd) { return 1; } +extern inline void pgd_clear(pgd_t *pgdp) { } + +/* + * Permanent address of a page. On MIPS we never have highmem, so this + * is simple. + */ +#define page_address(page) ((page)->virtual) #ifdef CONFIG_CPU_VR41XX #define pte_page(x) (mem_map+(unsigned long)((pte_val(x) >> (PAGE_SHIFT + 2)))) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-mips/rmap.h linux.19pre5-ac1/include/asm-mips/rmap.h --- linux.19p5/include/asm-mips/rmap.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/asm-mips/rmap.h Mon Jan 28 19:33:28 2002 @@ -0,0 +1,7 @@ +#ifndef _MIPS_RMAP_H +#define _MIPS_RMAP_H + +/* nothing to see, move along */ +#include + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-mips/spinlock.h linux.19pre5-ac1/include/asm-mips/spinlock.h --- linux.19p5/include/asm-mips/spinlock.h Thu Apr 4 13:21:16 2002 +++ linux.19pre5-ac1/include/asm-mips/spinlock.h Fri Mar 1 19:24:53 2002 @@ -22,7 +22,7 @@ #define spin_lock_init(x) do { (x)->lock = 0; } while(0) #define spin_is_locked(x) ((x)->lock != 0) -#define spin_unlock_wait(x) do { barrier(); } while ((x)->lock); +#define spin_unlock_wait(x) do { barrier(); } while ((x)->lock) /* * Simple spin lock operations. There are two variants, one clears IRQ's diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-mips64/rmap.h linux.19pre5-ac1/include/asm-mips64/rmap.h --- linux.19p5/include/asm-mips64/rmap.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/asm-mips64/rmap.h Mon Jan 28 19:33:28 2002 @@ -0,0 +1,7 @@ +#ifndef _MIPS64_RMAP_H +#define _MIPS64_RMAP_H + +/* nothing to see, move along */ +#include + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-mips64/spinlock.h linux.19pre5-ac1/include/asm-mips64/spinlock.h --- linux.19p5/include/asm-mips64/spinlock.h Thu Apr 4 13:21:16 2002 +++ linux.19pre5-ac1/include/asm-mips64/spinlock.h Fri Mar 1 19:27:58 2002 @@ -22,7 +22,7 @@ #define spin_lock_init(x) do { (x)->lock = 0; } while(0) #define spin_is_locked(x) ((x)->lock != 0) -#define spin_unlock_wait(x) do { barrier(); } while ((x)->lock); +#define spin_unlock_wait(x) do { barrier(); } while ((x)->lock) /* * Simple spin lock operations. There are two variants, one clears IRQ's diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-parisc/ioctls.h linux.19pre5-ac1/include/asm-parisc/ioctls.h --- linux.19p5/include/asm-parisc/ioctls.h Thu Apr 4 13:18:38 2002 +++ linux.19pre5-ac1/include/asm-parisc/ioctls.h Mon Jan 28 19:58:45 2002 @@ -67,6 +67,7 @@ #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ #define TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ #define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ +#define FIOQSIZE 0x5460 /* Get exact space used by quota */ /* Used for packet mode */ #define TIOCPKT_DATA 0 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-parisc/page.h linux.19pre5-ac1/include/asm-parisc/page.h --- linux.19p5/include/asm-parisc/page.h Thu Apr 4 13:21:16 2002 +++ linux.19pre5-ac1/include/asm-parisc/page.h Mon Jan 28 17:51:48 2002 @@ -81,9 +81,6 @@ #define virt_to_page(kaddr) (mem_map + (__pa(kaddr) >> PAGE_SHIFT)) #define VALID_PAGE(page) ((page - mem_map) < max_mapnr) -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - #endif /* __KERNEL__ */ #endif /* _PARISC_PAGE_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-parisc/pgalloc.h linux.19pre5-ac1/include/asm-parisc/pgalloc.h --- linux.19p5/include/asm-parisc/pgalloc.h Thu Apr 4 13:21:16 2002 +++ linux.19pre5-ac1/include/asm-parisc/pgalloc.h Thu Mar 14 22:23:34 2002 @@ -123,7 +123,7 @@ #define flush_tlb() do { \ flush_data_tlb(); \ flush_instruction_tlb(); \ -} while(0); +} while(0) #define flush_tlb_all() flush_tlb() /* XXX p[id]tlb */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-parisc/rmap.h linux.19pre5-ac1/include/asm-parisc/rmap.h --- linux.19p5/include/asm-parisc/rmap.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/asm-parisc/rmap.h Mon Jan 28 19:33:28 2002 @@ -0,0 +1,7 @@ +#ifndef _PARISC_RMAP_H +#define _PARISC_RMAP_H + +/* nothing to see, move along */ +#include + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-ppc/rmap.h linux.19pre5-ac1/include/asm-ppc/rmap.h --- linux.19p5/include/asm-ppc/rmap.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/asm-ppc/rmap.h Mon Jan 28 19:33:28 2002 @@ -0,0 +1,9 @@ +#ifndef _PPC_RMAP_H +#define _PPC_RMAP_H + +/* PPC calls pte_alloc() before mem_map[] is setup ... */ +#define BROKEN_PPC_PTE_ALLOC_ONE + +#include + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-s390/rmap.h linux.19pre5-ac1/include/asm-s390/rmap.h --- linux.19p5/include/asm-s390/rmap.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/asm-s390/rmap.h Mon Jan 28 19:33:28 2002 @@ -0,0 +1,7 @@ +#ifndef _S390_RMAP_H +#define _S390_RMAP_H + +/* nothing to see, move along */ +#include + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-s390x/rmap.h linux.19pre5-ac1/include/asm-s390x/rmap.h --- linux.19p5/include/asm-s390x/rmap.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/asm-s390x/rmap.h Mon Jan 28 19:33:28 2002 @@ -0,0 +1,7 @@ +#ifndef _S390X_RMAP_H +#define _S390X_RMAP_H + +/* nothing to see, move along */ +#include + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-sh/ioctls.h linux.19pre5-ac1/include/asm-sh/ioctls.h --- linux.19p5/include/asm-sh/ioctls.h Thu Apr 4 13:18:35 2002 +++ linux.19pre5-ac1/include/asm-sh/ioctls.h Mon Jan 28 19:59:36 2002 @@ -9,6 +9,7 @@ #define FIONBIO _IOW('f', 126, int) #define FIONREAD _IOR('f', 127, int) #define TIOCINQ FIONREAD +#define FIOQSIZE _IOR('f', 128, loff_t) #define TCGETS 0x5401 #define TCSETS 0x5402 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-sh/rmap.h linux.19pre5-ac1/include/asm-sh/rmap.h --- linux.19p5/include/asm-sh/rmap.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/asm-sh/rmap.h Mon Jan 28 19:33:28 2002 @@ -0,0 +1,7 @@ +#ifndef _SH_RMAP_H +#define _SH_RMAP_H + +/* nothing to see, move along */ +#include + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-sparc/elf.h linux.19pre5-ac1/include/asm-sparc/elf.h --- linux.19p5/include/asm-sparc/elf.h Thu Apr 4 13:18:25 2002 +++ linux.19pre5-ac1/include/asm-sparc/elf.h Wed Feb 13 00:25:36 2002 @@ -41,7 +41,7 @@ dest[34] = src->npc; \ dest[35] = src->y; \ dest[36] = dest[37] = 0; /* XXX */ \ -} while(0); +} while(0) typedef struct { union { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-sparc/ioctls.h linux.19pre5-ac1/include/asm-sparc/ioctls.h --- linux.19p5/include/asm-sparc/ioctls.h Thu Apr 4 13:18:25 2002 +++ linux.19pre5-ac1/include/asm-sparc/ioctls.h Mon Jan 28 19:59:52 2002 @@ -86,6 +86,7 @@ #define FIONBIO _IOW('f', 126, int) #define FIONREAD _IOR('f', 127, int) #define TIOCINQ FIONREAD +#define FIOQSIZE _IOR('f', 128, loff_t) /* SCARY Rutgers local SunOS kernel hackery, perhaps I will support it * someday. This is completely bogus, I know... diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-sparc/pgtable.h linux.19pre5-ac1/include/asm-sparc/pgtable.h --- linux.19p5/include/asm-sparc/pgtable.h Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/include/asm-sparc/pgtable.h Thu Mar 14 22:26:15 2002 @@ -293,9 +293,6 @@ #define page_pte_prot(page, prot) mk_pte(page, prot) #define page_pte(page) page_pte_prot(page, __pgprot(0)) -/* Permanent address of a page. */ -#define page_address(page) ((page)->virtual) - BTFIXUPDEF_CALL(struct page *, pte_page, pte_t) #define pte_page(pte) BTFIXUP_CALL(pte_page)(pte) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-sparc/rmap.h linux.19pre5-ac1/include/asm-sparc/rmap.h --- linux.19p5/include/asm-sparc/rmap.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/asm-sparc/rmap.h Mon Jan 28 19:33:28 2002 @@ -0,0 +1,7 @@ +#ifndef _SPARC_RMAP_H +#define _SPARC_RMAP_H + +/* nothing to see, move along */ +#include + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-sparc64/ioctls.h linux.19pre5-ac1/include/asm-sparc64/ioctls.h --- linux.19p5/include/asm-sparc64/ioctls.h Thu Apr 4 13:18:27 2002 +++ linux.19pre5-ac1/include/asm-sparc64/ioctls.h Mon Jan 28 20:00:04 2002 @@ -87,6 +87,7 @@ #define FIONBIO _IOW('f', 126, int) #define FIONREAD _IOR('f', 127, int) #define TIOCINQ FIONREAD +#define FIOQSIZE _IOR('f', 128, loff_t) /* SCARY Rutgers local SunOS kernel hackery, perhaps I will support it * someday. This is completely bogus, I know... diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-sparc64/rmap.h linux.19pre5-ac1/include/asm-sparc64/rmap.h --- linux.19p5/include/asm-sparc64/rmap.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/asm-sparc64/rmap.h Mon Jan 28 19:33:28 2002 @@ -0,0 +1,7 @@ +#ifndef _SPARC64_RMAP_H +#define _SPARC64_RMAP_H + +/* nothing to see, move along */ +#include + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/atmbr2684.h linux.19pre5-ac1/include/linux/atmbr2684.h --- linux.19p5/include/linux/atmbr2684.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/linux/atmbr2684.h Thu Apr 4 16:05:53 2002 @@ -0,0 +1,101 @@ +#ifndef _LINUX_ATMBR2684_H +#define _LINUX_ATMBR2684_H + +#include +#include /* For IFNAMSIZ */ + +/* + * Type of media we're bridging (ethernet, token ring, etc) Currently only + * ethernet is supported + */ +#define BR2684_MEDIA_ETHERNET (0) /* 802.3 */ +#define BR2684_MEDIA_802_4 (1) /* 802.4 */ +#define BR2684_MEDIA_TR (2) /* 802.5 - token ring */ +#define BR2684_MEDIA_FDDI (3) +#define BR2684_MEDIA_802_6 (4) /* 802.6 */ + +/* + * Is there FCS inbound on this VC? This currently isn't supported. + */ +#define BR2684_FCSIN_NO (0) +#define BR2684_FCSIN_IGNORE (1) +#define BR2684_FCSIN_VERIFY (2) + +/* + * Is there FCS outbound on this VC? This currently isn't supported. + */ +#define BR2684_FCSOUT_NO (0) +#define BR2684_FCSOUT_SENDZERO (1) +#define BR2684_FCSOUT_GENERATE (2) + +/* + * Does this VC include LLC encapsulation? + */ +#define BR2684_ENCAPS_VC (0) /* VC-mux */ +#define BR2684_ENCAPS_LLC (1) +#define BR2684_ENCAPS_AUTODETECT (2) /* Unsuported */ + +/* + * This is for the ATM_NEWBACKENDIF call - these are like socket families: + * the first element of the structure is the backend number and the rest + * is per-backend specific + */ +struct atm_newif_br2684 { + atm_backend_t backend_num; /* ATM_BACKEND_BR2684 */ + int media; /* BR2684_MEDIA_* */ + char ifname[IFNAMSIZ]; + int mtu; +}; + +/* + * This structure is used to specify a br2684 interface - either by a + * positive integer (returned by ATM_NEWBACKENDIF) or the interfaces name + */ +#define BR2684_FIND_BYNOTHING (0) +#define BR2684_FIND_BYNUM (1) +#define BR2684_FIND_BYIFNAME (2) +struct br2684_if_spec { + int method; /* BR2684_FIND_* */ + union { + char ifname[IFNAMSIZ]; + int devnum; + } spec; +}; + +/* + * This is for the ATM_SETBACKEND call - these are like socket families: + * the first element of the structure is the backend number and the rest + * is per-backend specific + */ +struct atm_backend_br2684 { + atm_backend_t backend_num; /* ATM_BACKEND_BR2684 */ + struct br2684_if_spec ifspec; + int fcs_in; /* BR2684_FCSIN_* */ + int fcs_out; /* BR2684_FCSOUT_* */ + int fcs_auto; /* 1: fcs_{in,out} disabled if no FCS rx'ed */ + int encaps; /* BR2684_ENCAPS_* */ + int has_vpiid; /* 1: use vpn_id - Unsupported */ + __u8 vpn_id[7]; + int send_padding; /* unsupported */ + int min_size; /* we will pad smaller packets than this */ +}; + +/* + * The BR2684_SETFILT ioctl is an experimental mechanism for folks + * terminating a large number of IP-only vcc's. When netfilter allows + * efficient per-if in/out filters, this support will be removed + */ +struct br2684_filter { + __u32 prefix; /* network byte order */ + __u32 netmask; /* 0 = disable filter */ +}; + +struct br2684_filter_set { + struct br2684_if_spec ifspec; + struct br2684_filter filter; +}; + +#define BR2684_SETFILT _IOW( 'a', ATMIOC_BACKEND + 0, \ + struct br2684_filter_set) + +#endif /* _LINUX_ATMBR2684_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/atmdev.h linux.19pre5-ac1/include/linux/atmdev.h --- linux.19p5/include/linux/atmdev.h Thu Apr 4 13:18:20 2002 +++ linux.19pre5-ac1/include/linux/atmdev.h Thu Apr 4 15:48:38 2002 @@ -95,6 +95,8 @@ /* enable or disable single-copy */ #define ATM_SETBACKEND _IOW('a',ATMIOC_SPECIAL+2,atm_backend_t) /* set backend handler */ +#define ATM_NEWBACKENDIF _IOW('a',ATMIOC_SPECIAL+3,atm_backend_t) + /* use backend to make new if */ /* * These are backend handkers that can be set via the ATM_SETBACKEND call @@ -103,7 +105,7 @@ */ #define ATM_BACKEND_RAW 0 #define ATM_BACKEND_PPP 1 /* PPPoATM - RFC2364 */ -#define ATM_BACKEND_BR_2684 2 /* Bridged RFC1483/2684 */ +#define ATM_BACKEND_BR2684 2 /* Bridged RFC1483/2684 */ /* for ATM_GETTYPE */ #define ATM_ITFTYP_LEN 8 /* maximum length of interface type name */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/blkcdb.h linux.19pre5-ac1/include/linux/blkcdb.h --- linux.19p5/include/linux/blkcdb.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/linux/blkcdb.h Mon Jan 28 20:00:34 2002 @@ -0,0 +1,101 @@ +/* + * 2.5 Command Descriptor Block (CDB) Block Pre-Handler. + * + * Copyright (C) 2001 Andre Hedrick + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public Licens + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111- + */ + +#ifndef _LINUX_BLKCDB_H +#define _LINUX_BLKCDB_H + +typedef struct cdb_list { +#if 0 + unsigned char cdb_0; + unsigned char cdb_1; + unsigned char cdb_2; + unsigned char cdb_3; + unsigned char cdb_4; + unsigned char cdb_5; + unsigned char cdb_6; + unsigned char cdb_7; + unsigned char cdb_8; + unsigned char cdb_9; + unsigned char cdb_10; + unsigned char cdb_11; + unsigned char cdb_12; + unsigned char cdb_13; + unsigned char cdb_14; + unsigned char cdb_15; +#else + unsigned char cdb_regs[16]; +#endif +} cdb_list_t; + +#if 0 + +typedef cdb_list_t * (queue_proc) (kdev_t dev); + +request_queue_t *ide_get_queue (kdev_t dev) +{ + ide_hwif_t *hwif = (ide_hwif_t *)blk_dev[MAJOR(dev)].data; + + return &hwif->drives[DEVICE_NR(dev) & 1].queue; +} + +static request_queue_t *sd_find_queue(kdev_t dev) +{ + Scsi_Disk *dpnt; + int target; + target = DEVICE_NR(dev); + + dpnt = &rscsi_disks[target]; + if (!dpnt) + return NULL; /* No such device */ + return &dpnt->device->request_queue; +} + +prebuilder: NULL, +block_device_operations +struct block_device { + +void do_ide_request(request_queue_t *q) + +ide_do_request + +typedef cdb_list_t (request_cdb_proc) (request_queue_t *q); + +typedef cdb_list_t (request_cdb_proc) (request_queue_t *q); +typedef void (request_fn_proc) (request_queue_t *q); + +srb + +switch (SCpnt->request.cmd) +SCpnt->cmnd[0] = WRITE_6/READ_6; +SCpnt->cmnd[1] = (SCpnt->device->scsi_level <= SCSI_2) ? + ((SCpnt->lun << 5) & 0xe0) : 0; +SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff; +SCpnt->cmnd[3] = (unsigned char) (block >> 16) & 0xff; +SCpnt->cmnd[4] = (unsigned char) (block >> 8) & 0xff; +SCpnt->cmnd[5] = (unsigned char) block & 0xff; +SCpnt->cmnd[6] = 0; +SCpnt->cmnd[7] = (unsigned char) (this_count >> 8) & 0xff; +SCpnt->cmnd[8] = (unsigned char) this_count & 0xff; +SCpnt->cmnd[9] = 0; + +#endif + +#endif /* _LINUX_BLKCDB_H */ + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/blkdev.h linux.19pre5-ac1/include/linux/blkdev.h --- linux.19p5/include/linux/blkdev.h Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/include/linux/blkdev.h Thu Apr 4 15:46:31 2002 @@ -6,6 +6,7 @@ #include #include #include +/* #include */ struct request_queue; typedef struct request_queue request_queue_t; @@ -30,13 +31,16 @@ kdev_t rq_dev; int cmd; /* READ or WRITE */ int errors; + unsigned long start_time; unsigned long sector; unsigned long nr_sectors; unsigned long hard_sector, hard_nr_sectors; unsigned int nr_segments; unsigned int nr_hw_segments; unsigned long current_nr_sectors; + unsigned long hard_cur_sectors; void * special; +/* void * cdb; */ char * buffer; struct completion * waiting; struct buffer_head * bh; @@ -79,16 +83,6 @@ struct request_list rq[2]; /* - * The total number of requests on each queue - */ - int nr_requests; - - /* - * Batching threshold for sleep/wakeup decisions - */ - int batch_requests; - - /* * Together with queue_head for cacheline sharing */ struct list_head queue_head; @@ -167,7 +161,6 @@ /* * Access functions for manipulating queue properties */ -extern int blk_grow_request_list(request_queue_t *q, int nr_requests); extern void blk_init_queue(request_queue_t *, request_fn_proc *); extern void blk_cleanup_queue(request_queue_t *); extern void blk_queue_headactive(request_queue_t *, int); @@ -186,6 +179,8 @@ extern int * max_segments[MAX_BLKDEV]; +extern char * blkdev_varyio[MAX_BLKDEV]; + #define MAX_SEGMENTS 128 #define MAX_SECTORS 255 @@ -239,4 +234,12 @@ return retval; } +static inline int get_blkdev_varyio(int major, int minor) +{ + int retval = 0; + if (blkdev_varyio[major]) { + retval = blkdev_varyio[major][minor]; + } + return retval; +} #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/brlock.h linux.19pre5-ac1/include/linux/brlock.h --- linux.19p5/include/linux/brlock.h Thu Apr 4 13:18:21 2002 +++ linux.19pre5-ac1/include/linux/brlock.h Thu Apr 4 15:46:45 2002 @@ -28,13 +28,15 @@ * load-locked/store-conditional cpus (ALPHA/MIPS/PPC) and * compare-and-swap cpus (Sparc64). So we control which * implementation to use with a __BRLOCK_USE_ATOMICS define. -DaveM + * + * Added BR_LLC_LOCK for use in net/core/ext8022.c -acme */ /* Register bigreader lock indices here. */ enum brlock_indices { BR_GLOBALIRQ_LOCK, BR_NETPROTO_LOCK, - + BR_LLC_LOCK, __BR_END }; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/dcache.h linux.19pre5-ac1/include/linux/dcache.h --- linux.19p5/include/linux/dcache.h Thu Apr 4 13:18:18 2002 +++ linux.19pre5-ac1/include/linux/dcache.h Tue Mar 26 20:11:14 2002 @@ -242,11 +242,8 @@ static __inline__ struct dentry * dget(struct dentry *dentry) { - if (dentry) { - if (!atomic_read(&dentry->d_count)) - BUG(); + if (dentry) atomic_inc(&dentry->d_count); - } return dentry; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/elevator.h linux.19pre5-ac1/include/linux/elevator.h --- linux.19p5/include/linux/elevator.h Thu Apr 4 13:18:20 2002 +++ linux.19pre5-ac1/include/linux/elevator.h Mon Jan 28 19:33:28 2002 @@ -1,12 +1,9 @@ #ifndef _LINUX_ELEVATOR_H #define _LINUX_ELEVATOR_H -typedef void (elevator_fn) (struct request *, elevator_t *, - struct list_head *, - struct list_head *, int); - -typedef int (elevator_merge_fn) (request_queue_t *, struct request **, struct list_head *, - struct buffer_head *, int, int); +typedef int (elevator_merge_fn)(request_queue_t *, struct request **, + struct list_head *, struct buffer_head *bh, + int rw, int max_sectors); typedef void (elevator_merge_cleanup_fn) (request_queue_t *, struct request *, int); @@ -16,6 +13,7 @@ { int read_latency; int write_latency; + int max_bomb_segments; elevator_merge_fn *elevator_merge_fn; elevator_merge_cleanup_fn *elevator_merge_cleanup_fn; @@ -24,13 +22,13 @@ unsigned int queue_ID; }; -int elevator_noop_merge(request_queue_t *, struct request **, struct list_head *, struct buffer_head *, int, int); -void elevator_noop_merge_cleanup(request_queue_t *, struct request *, int); -void elevator_noop_merge_req(struct request *, struct request *); - -int elevator_linus_merge(request_queue_t *, struct request **, struct list_head *, struct buffer_head *, int, int); -void elevator_linus_merge_cleanup(request_queue_t *, struct request *, int); -void elevator_linus_merge_req(struct request *, struct request *); +elevator_merge_fn elevator_noop_merge; +elevator_merge_cleanup_fn elevator_noop_merge_cleanup; +elevator_merge_req_fn elevator_noop_merge_req; + +elevator_merge_fn elevator_linus_merge; +elevator_merge_cleanup_fn elevator_linus_merge_cleanup; +elevator_merge_req_fn elevator_linus_merge_req; typedef struct blkelv_ioctl_arg_s { int queue_ID; @@ -54,22 +52,6 @@ #define ELEVATOR_FRONT_MERGE 1 #define ELEVATOR_BACK_MERGE 2 -/* - * This is used in the elevator algorithm. We don't prioritise reads - * over writes any more --- although reads are more time-critical than - * writes, by treating them equally we increase filesystem throughput. - * This turns out to give better overall performance. -- sct - */ -#define IN_ORDER(s1,s2) \ - ((((s1)->rq_dev == (s2)->rq_dev && \ - (s1)->sector < (s2)->sector)) || \ - (s1)->rq_dev < (s2)->rq_dev) - -#define BHRQ_IN_ORDER(bh, rq) \ - ((((bh)->b_rdev == (rq)->rq_dev && \ - (bh)->b_rsector < (rq)->sector)) || \ - (bh)->b_rdev < (rq)->rq_dev) - static inline int elevator_request_latency(elevator_t * elevator, int rw) { int latency; @@ -85,7 +67,7 @@ ((elevator_t) { \ 0, /* read_latency */ \ 0, /* write_latency */ \ - \ + 0, /* max_bomb_segments */ \ elevator_noop_merge, /* elevator_merge_fn */ \ elevator_noop_merge_cleanup, /* elevator_merge_cleanup_fn */ \ elevator_noop_merge_req, /* elevator_merge_req_fn */ \ @@ -95,7 +77,7 @@ ((elevator_t) { \ 8192, /* read passovers */ \ 16384, /* write passovers */ \ - \ + 6, /* max_bomb_segments */ \ elevator_linus_merge, /* elevator_merge_fn */ \ elevator_linus_merge_cleanup, /* elevator_merge_cleanup_fn */ \ elevator_linus_merge_req, /* elevator_merge_req_fn */ \ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/fb.h linux.19pre5-ac1/include/linux/fb.h --- linux.19p5/include/linux/fb.h Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/include/linux/fb.h Thu Apr 4 15:47:47 2002 @@ -95,6 +95,18 @@ #define FB_ACCEL_SIS_GLAMOUR 36 /* SiS 300/630/540 */ #define FB_ACCEL_3DLABS_PERMEDIA3 37 /* 3Dlabs Permedia 3 */ + +#define FB_ACCEL_NEOMAGIC_NM2070 90 /* NeoMagic NM2070 */ +#define FB_ACCEL_NEOMAGIC_NM2090 91 /* NeoMagic NM2090 */ +#define FB_ACCEL_NEOMAGIC_NM2093 92 /* NeoMagic NM2093 */ +#define FB_ACCEL_NEOMAGIC_NM2097 93 /* NeoMagic NM2097 */ +#define FB_ACCEL_NEOMAGIC_NM2160 94 /* NeoMagic NM2160 */ +#define FB_ACCEL_NEOMAGIC_NM2200 95 /* NeoMagic NM2200 */ +#define FB_ACCEL_NEOMAGIC_NM2230 96 /* NeoMagic NM2230 */ +#define FB_ACCEL_NEOMAGIC_NM2360 97 /* NeoMagic NM2360 */ +#define FB_ACCEL_NEOMAGIC_NM2380 98 /* NeoMagic NM2380 */ + + struct fb_fix_screeninfo { char id[16]; /* identification string eg "TT Builtin" */ unsigned long smem_start; /* Start of frame buffer mem */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/fs.h linux.19pre5-ac1/include/linux/fs.h --- linux.19p5/include/linux/fs.h Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/include/linux/fs.h Thu Apr 4 15:46:31 2002 @@ -206,6 +206,7 @@ extern void buffer_init(unsigned long); extern void inode_init(unsigned long); extern void mnt_init(unsigned long); +extern void files_init(unsigned long); /* bh state bits */ enum bh_state_bits { @@ -217,7 +218,7 @@ BH_New, /* 1 if the buffer is new and not yet written out */ BH_Async, /* 1 if the buffer is under end_buffer_io_async I/O */ BH_Wait_IO, /* 1 if we should write out this buffer */ - BH_Launder, /* 1 if we can throttle on this buffer */ + BH_launder, /* 1 if we should throttle on this buffer */ BH_JBD, /* 1 if it has an attached journal_head */ BH_PrivateStart,/* not a state bit, but the first bit available @@ -279,13 +280,12 @@ #define buffer_mapped(bh) __buffer_state(bh,Mapped) #define buffer_new(bh) __buffer_state(bh,New) #define buffer_async(bh) __buffer_state(bh,Async) -#define buffer_launder(bh) __buffer_state(bh,Launder) #define bh_offset(bh) ((unsigned long)(bh)->b_data & ~PAGE_MASK) extern void set_bh_page(struct buffer_head *bh, struct page *page, unsigned long offset); -#define touch_buffer(bh) mark_page_accessed(bh->b_page) +#define touch_buffer(bh) touch_page(bh->b_page) #include @@ -451,6 +451,7 @@ unsigned long i_blksize; unsigned long i_blocks; unsigned long i_version; + unsigned short i_bytes; struct semaphore i_sem; struct semaphore i_zombie; struct inode_operations *i_op; @@ -511,6 +512,39 @@ } u; }; +static inline void inode_add_bytes(struct inode *inode, loff_t bytes) +{ + inode->i_blocks += bytes >> 9; + bytes &= 511; + inode->i_bytes += bytes; + if (inode->i_bytes >= 512) { + inode->i_blocks++; + inode->i_bytes -= 512; + } +} + +static inline void inode_sub_bytes(struct inode *inode, loff_t bytes) +{ + inode->i_blocks -= bytes >> 9; + bytes &= 511; + if (inode->i_bytes < bytes) { + inode->i_blocks--; + inode->i_bytes += 512; + } + inode->i_bytes -= bytes; +} + +static inline loff_t inode_get_bytes(struct inode *inode) +{ + return (((loff_t)inode->i_blocks) << 9) + inode->i_bytes; +} + +static inline void inode_set_bytes(struct inode *inode, loff_t bytes) +{ + inode->i_blocks = bytes >> 9; + inode->i_bytes = bytes & 511; +} + struct fown_struct { int pid; /* pid or -pgrp where SIGIO should be sent */ uid_t uid, euid; /* uid/euid of process setting the owner */ @@ -658,15 +692,13 @@ #define DQUOT_USR_ENABLED 0x01 /* User diskquotas enabled */ #define DQUOT_GRP_ENABLED 0x02 /* Group diskquotas enabled */ -struct quota_mount_options +struct quota_info { unsigned int flags; /* Flags for diskquotas on this device */ struct semaphore dqio_sem; /* lock device while I/O in progress */ struct semaphore dqoff_sem; /* serialize quota_off() and quota_on() on device */ struct file *files[MAXQUOTAS]; /* fp's to quotafiles */ - time_t inode_expire[MAXQUOTAS]; /* expiretime for inode-quota */ - time_t block_expire[MAXQUOTAS]; /* expiretime for block-quota */ - char rsquash[MAXQUOTAS]; /* for quotas threat root as any other user */ + struct mem_dqinfo info[MAXQUOTAS]; /* Information for each quota type */ }; /* @@ -730,7 +762,7 @@ struct block_device *s_bdev; struct list_head s_instances; - struct quota_mount_options s_dquot; /* Diskquota specific options */ + struct quota_info s_dquot; /* Diskquota specific options */ union { struct minix_sb_info minix_sb; @@ -949,9 +981,9 @@ struct dquot_operations { void (*initialize) (struct inode *, short); void (*drop) (struct inode *); - int (*alloc_block) (struct inode *, unsigned long, char); + int (*alloc_space) (struct inode *, qsize_t, char); int (*alloc_inode) (const struct inode *, unsigned long); - void (*free_block) (struct inode *, unsigned long); + void (*free_space) (struct inode *, qsize_t); void (*free_inode) (const struct inode *, unsigned long); int (*transfer) (struct inode *, struct iattr *); }; @@ -1111,7 +1143,7 @@ extern int fs_may_remount_ro(struct super_block *); -extern int FASTCALL(try_to_free_buffers(struct page *, unsigned int)); +extern int try_to_free_buffers(struct page *, unsigned int); extern void refile_buffer(struct buffer_head * buf); extern void create_empty_buffers(struct page *, kdev_t, unsigned long); extern void end_buffer_io_sync(struct buffer_head *bh, int uptodate); @@ -1360,6 +1392,7 @@ extern struct buffer_head * getblk(kdev_t, int, int); extern void ll_rw_block(int, int, struct buffer_head * bh[]); extern void submit_bh(int, struct buffer_head *); +extern void submit_bh_blknr(int, struct buffer_head *); extern int is_read_only(kdev_t); extern void __brelse(struct buffer_head *); static inline void brelse(struct buffer_head *buf) @@ -1450,8 +1483,6 @@ } return 0; } -unsigned long generate_cluster(kdev_t, int b[], int); -unsigned long generate_cluster_swab32(kdev_t, int b[], int); extern kdev_t ROOT_DEV; extern char root_device_name[]; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/genhd.h linux.19pre5-ac1/include/linux/genhd.h --- linux.19p5/include/linux/genhd.h Thu Apr 4 13:18:17 2002 +++ linux.19pre5-ac1/include/linux/genhd.h Thu Apr 4 15:46:31 2002 @@ -63,6 +63,22 @@ unsigned long nr_sects; devfs_handle_t de; /* primary (master) devfs entry */ int number; /* stupid old code wastes space */ + + /* Performance stats: */ + unsigned int ios_in_flight; + unsigned int io_ticks; + unsigned int last_idle_time; + unsigned int last_queue_change; + unsigned int aveq; + + unsigned int rd_ios; + unsigned int rd_merges; + unsigned int rd_ticks; + unsigned int rd_sectors; + unsigned int wr_ios; + unsigned int wr_merges; + unsigned int wr_ticks; + unsigned int wr_sectors; }; #define GENHD_FL_REMOVABLE 1 @@ -242,6 +258,19 @@ char *disk_name (struct gendisk *hd, int minor, char *buf); +/* + * disk_round_stats is used to round off the IO statistics for a disk + * for a complete clock tick. + */ +void disk_round_stats(struct hd_struct *hd); + +/* + * Account for the completion of an IO request (used by drivers which + * bypass the normal end_request processing) + */ +struct request; +void req_finished_io(struct request *); + extern void devfs_register_partitions (struct gendisk *dev, int minor, int unregister); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/highmem.h linux.19pre5-ac1/include/linux/highmem.h --- linux.19p5/include/linux/highmem.h Thu Apr 4 13:18:21 2002 +++ linux.19pre5-ac1/include/linux/highmem.h Thu Apr 4 15:46:31 2002 @@ -63,8 +63,6 @@ { char *kaddr; - if (offset + size > PAGE_SIZE) - BUG(); kaddr = kmap(page); memset(kaddr + offset, 0, size); flush_dcache_page(page); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/i2o.h linux.19pre5-ac1/include/linux/i2o.h --- linux.19p5/include/linux/i2o.h Thu Apr 4 13:18:18 2002 +++ linux.19pre5-ac1/include/linux/i2o.h Thu Apr 4 15:47:17 2002 @@ -112,9 +112,9 @@ atomic_t users; struct i2o_device *devices; /* I2O device chain */ struct i2o_controller *next; /* Controller chain */ - volatile u32 *post_port; /* Inbout port */ - volatile u32 *reply_port; /* Outbound port */ - volatile u32 *irq_mask; /* Interrupt register */ + unsigned long post_port; /* Inbout port address */ + unsigned long reply_port; /* Outbound port address */ + unsigned long irq_mask; /* Interrupt register address */ /* Dynamic LCT related data */ struct semaphore lct_sem; @@ -126,8 +126,8 @@ i2o_lct *dlct; /* Temp LCT */ i2o_hrt *hrt; /* HW Resource Table */ - u32 mem_offset; /* MFA offset */ - u32 mem_phys; /* MFA physical */ + unsigned long mem_offset; /* MFA offset */ + unsigned long mem_phys; /* MFA physical */ int battery:1; /* Has a battery backup */ int io_alloc:1; /* An I/O resource was allocated */ @@ -295,6 +295,13 @@ I2O_REPLY_WRITE32(c, m); } +/* + * Endian handling wrapped into the macro - keeps the core code + * cleaner. + */ + +#define i2o_raw_writel(val, mem) __raw_writel(cpu_to_le32(val), mem) + extern struct i2o_controller *i2o_find_controller(int); extern void i2o_unlock_controller(struct i2o_controller *); extern struct i2o_controller *i2o_controller_chain; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/ide.h linux.19pre5-ac1/include/linux/ide.h --- linux.19p5/include/linux/ide.h Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/include/linux/ide.h Thu Apr 4 15:46:59 2002 @@ -16,6 +16,13 @@ #include #include + +#ifdef CONFIG_BLK_DEV_IDEDMA_TIMEOUT +# define __IDEDMA_TIMEOUT +#else /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */ +# undef __IDEDMA_TIMEOUT +#endif /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */ + /* * This is the multiple IDE interface driver, as evolved from hd.c. * It supports up to four IDE interfaces, on one or more IRQs (usually 14 & 15). @@ -347,6 +354,9 @@ } b; } special_t; +struct ide_driver_s; +struct ide_settings_s; + typedef struct ide_drive_s { request_queue_t queue; /* request queue */ struct ide_drive_s *next; /* circular list of hwgroup drives */ @@ -404,16 +414,16 @@ unsigned long capacity; /* total number of sectors */ unsigned long long capacity48; /* total number of sectors */ unsigned int drive_data; /* for use by tuneproc/selectproc as needed */ - void *hwif; /* actually (ide_hwif_t *) */ + struct hwif_s *hwif; /* actually (ide_hwif_t *) */ wait_queue_head_t wqueue; /* used to wait for drive in open() */ struct hd_driveid *id; /* drive model identification info */ struct hd_struct *part; /* drive partition table */ char name[4]; /* drive name, such as "hda" */ - void *driver; /* (ide_driver_t *) */ + struct ide_driver_s *driver; /* (ide_driver_t *) */ void *driver_data; /* extra driver data */ devfs_handle_t de; /* directory for device */ struct proc_dir_entry *proc; /* /proc/ide/ directory entry */ - void *settings; /* /proc/ide/ drive settings */ + struct ide_settings_s *settings; /* /proc/ide/ drive settings */ char driver_req[10]; /* requests specific driver */ int last_lun; /* last logical unit */ int forced_lun; /* if hdxlun was given at boot */ @@ -469,6 +479,24 @@ typedef void (ide_ideproc_t)(ide_ide_action_t, ide_drive_t *, void *, unsigned int); /* + * mapping stuff, prepare for highmem... + * + * temporarily mapping a (possible) highmem bio for PIO transfer + */ +#define ide_rq_offset(rq) \ + (((rq)->hard_cur_sectors - (rq)->current_nr_sectors) << 9) + +extern inline void *ide_map_buffer(struct request *rq, unsigned long *flags) +{ + return rq->buffer + ide_rq_offset(rq); +} + +extern inline void ide_unmap_buffer(char *buffer, unsigned long *flags) +{ + do { } while (0); +} + +/* * An ide_tuneproc_t() is used to set the speed of an IDE interface * to a particular PIO mode. The "byte" parameter is used * to select the PIO mode by number (0,1,2,3,4,5), and a value of 255 @@ -513,8 +541,14 @@ typedef struct hwif_s { struct hwif_s *next; /* for linked-list in ide_hwgroup_t */ - void *hwgroup; /* actually (ide_hwgroup_t *) */ + struct hwgroup_s *hwgroup; /* actually (ide_hwgroup_t *) */ ide_ioreg_t io_ports[IDE_NR_PORTS]; /* task file registers */ +/* + * FIXME!! need a generic register set :-/ PPC guys ideas?? + * + * ide_mmioreg_t mm_ports[IDE_NR_PORTS]; "task file registers" + * + */ hw_regs_t hw; /* Hardware info */ ide_drive_t drives[MAX_DRIVES]; /* drive info */ struct gendisk *gd; /* gendisk structure */ @@ -552,6 +586,7 @@ unsigned reset : 1; /* reset after probe */ unsigned autodma : 1; /* automatically try to enable DMA at boot */ unsigned udma_four : 1; /* 1=ATA-66 capable, 0=default */ + unsigned highmem : 1; /* can do full 32-bit dma */ byte channel; /* for dual-port chips: 0=primary, 1=secondary */ #ifdef CONFIG_BLK_DEV_IDEPCI struct pci_dev *pci_dev; /* for pci chipsets */ @@ -598,6 +633,7 @@ struct request wrq; /* local copy of current write rq */ unsigned long poll_timeout; /* timeout value during long polls */ ide_expiry_t *expiry; /* queried upon timeouts */ + int pio_clock; /* ide_system_bus_speed */ } ide_hwgroup_t; /* structure attached to the request for IDE_TASK_CMDS */ @@ -685,24 +721,6 @@ */ #define IDE_SUBDRIVER_VERSION 1 -typedef int (ide_cleanup_proc)(ide_drive_t *); -typedef int (ide_standby_proc)(ide_drive_t *); -typedef int (ide_flushcache_proc)(ide_drive_t *); -typedef ide_startstop_t (ide_do_request_proc)(ide_drive_t *, struct request *, unsigned long); -typedef void (ide_end_request_proc)(byte, ide_hwgroup_t *); -typedef int (ide_ioctl_proc)(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long); -typedef int (ide_open_proc)(struct inode *, struct file *, ide_drive_t *); -typedef void (ide_release_proc)(struct inode *, struct file *, ide_drive_t *); -typedef int (ide_check_media_change_proc)(ide_drive_t *); -typedef void (ide_revalidate_proc)(ide_drive_t *); -typedef void (ide_pre_reset_proc)(ide_drive_t *); -typedef unsigned long (ide_capacity_proc)(ide_drive_t *); -typedef ide_startstop_t (ide_special_proc)(ide_drive_t *); -typedef void (ide_setting_proc)(ide_drive_t *); -typedef int (ide_reinit_proc)(ide_drive_t *); -typedef void (ata_prebuilder_proc)(ide_drive_t *); -typedef void (atapi_prebuilder_proc)(ide_drive_t *); - typedef struct ide_driver_s { const char *name; const char *version; @@ -710,26 +728,28 @@ unsigned busy : 1; unsigned supports_dma : 1; unsigned supports_dsc_overlap : 1; - ide_cleanup_proc *cleanup; - ide_standby_proc *standby; - ide_flushcache_proc *flushcache; - ide_do_request_proc *do_request; - ide_end_request_proc *end_request; - ide_ioctl_proc *ioctl; - ide_open_proc *open; - ide_release_proc *release; - ide_check_media_change_proc *media_change; - ide_revalidate_proc *revalidate; - ide_pre_reset_proc *pre_reset; - ide_capacity_proc *capacity; - ide_special_proc *special; - ide_proc_entry_t *proc; - ide_reinit_proc *reinit; - ata_prebuilder_proc *ata_prebuilder; - atapi_prebuilder_proc *atapi_prebuilder; + int (*cleanup)(ide_drive_t *); + int (*standby)(ide_drive_t *); + int (*flushcache)(ide_drive_t *); + ide_startstop_t (*do_request)(ide_drive_t *, struct request *, unsigned long); + int (*end_request)(ide_drive_t *, int); + int (*ioctl)(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long); + int (*open)(struct inode *, struct file *, ide_drive_t *); + void (*release)(struct inode *, struct file *, ide_drive_t *); + int (*media_change)(ide_drive_t *); + void (*revalidate)(ide_drive_t *); + void (*pre_reset)(ide_drive_t *); + unsigned long (*capacity)(ide_drive_t *); + ide_startstop_t (*special)(ide_drive_t *); + ide_proc_entry_t *proc; +// void (*setting)(ide_drive_t *); + int (*init)(void); + int (*reinit)(ide_drive_t *); + void (*ata_prebuilder)(ide_drive_t *); + void (*atapi_prebuilder)(ide_drive_t *); } ide_driver_t; -#define DRIVER(drive) ((ide_driver_t *)((drive)->driver)) +#define DRIVER(drive) ((drive)->driver) /* * IDE modules. @@ -769,23 +789,7 @@ #define LOCAL_END_REQUEST /* Don't generate end_request in blk.h */ #include -void ide_end_request(byte uptodate, ide_hwgroup_t *hwgroup); - -/* - * This is used for (nearly) all data transfers from/to the IDE interface - * FIXME for 2.5, to a pointer pass verses memcpy........ - */ -void ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount); -void ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount); - -/* - * This is used for (nearly) all ATAPI data transfers from/to the IDE interface - * FIXME for 2.5, to a pointer pass verses memcpy........ - */ -void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount); -void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount); - -int drive_is_ready (ide_drive_t *drive); +int ide_end_request (ide_drive_t *drive, int uptodate); /* * This is used on exit from the driver, to designate the next irq handler @@ -856,7 +860,7 @@ * Re-Start an operation for an IDE interface. * The caller should return immediately after invoking this. */ -ide_startstop_t restart_request (ide_drive_t *); +int restart_request (ide_drive_t *, struct request *); /* * This function is intended to be used prior to invoking ide_do_drive_cmd(). @@ -924,9 +928,8 @@ ide_pre_handler_t *prehandler; ide_handler_t *handler; ide_post_handler_t *posthandler; - void *special; /* valid_t generally */ struct request *rq; /* copy of request */ - unsigned long block; /* copy of block */ + void *special; /* valid_t generally */ } ide_task_t; typedef struct pkt_task_s { @@ -934,11 +937,20 @@ int data_phase; int command_type; ide_handler_t *handler; - void *special; struct request *rq; /* copy of request */ - unsigned long block; /* copy of block */ + void *special; } pkt_task_t; +void ata_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount); +void ata_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount); +void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount); +void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount); +void taskfile_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount); +void taskfile_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount); + +int drive_is_ready (ide_drive_t *drive); +int wait_for_ready (ide_drive_t *drive, int timeout); + /* * taskfile io for disks for now... */ @@ -962,6 +974,7 @@ ide_startstop_t task_mulin_intr (ide_drive_t *drive); ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq); ide_startstop_t task_out_intr (ide_drive_t *drive); +ide_startstop_t pre_task_mulout_intr (ide_drive_t *drive, struct request *rq); ide_startstop_t task_mulout_intr (ide_drive_t *drive); void ide_init_drive_taskfile (struct request *rq); @@ -971,10 +984,13 @@ ide_pre_handler_t * ide_pre_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile); ide_handler_t * ide_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile); +ide_post_handler_t * ide_post_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile); /* Expects args is a full set of TF registers and parses the command type */ int ide_cmd_type_parser (ide_task_t *args); int ide_taskfile_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); +int ide_cmd_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); +int ide_task_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); #ifdef CONFIG_PKT_TASK_IOCTL int pkt_taskfile_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); @@ -999,12 +1015,6 @@ int ide_system_bus_speed (void); /* - * ide_multwrite() transfers a block of up to mcount sectors of data - * to a drive as part of a disk multwrite operation. - */ -int ide_multwrite (ide_drive_t *drive, unsigned int mcount); - -/* * ide_stall_queue() can be used by a drive to give excess bandwidth back * to the hwgroup by sleeping for timeout jiffies. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/iobuf.h linux.19pre5-ac1/include/linux/iobuf.h --- linux.19p5/include/linux/iobuf.h Thu Apr 4 13:18:18 2002 +++ linux.19pre5-ac1/include/linux/iobuf.h Thu Apr 4 15:46:31 2002 @@ -28,6 +28,8 @@ #define KIO_STATIC_PAGES (KIO_MAX_ATOMIC_IO / (PAGE_SIZE >> 10) + 1) #define KIO_MAX_SECTORS (KIO_MAX_ATOMIC_IO * 2) +#define RAWIO_BLOCKSIZE 4096 + /* The main kiobuf struct used for all our IO! */ struct kiobuf @@ -44,7 +46,8 @@ struct page ** maplist; - unsigned int locked : 1; /* If set, pages has been locked */ + unsigned int locked : 1, /* If set, pages has been locked */ + dovary : 1; /* If set, do variable size IO */ /* Always embed enough struct pages for atomic IO */ struct page * map_array[KIO_STATIC_PAGES]; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/jbd.h linux.19pre5-ac1/include/linux/jbd.h --- linux.19p5/include/linux/jbd.h Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/include/linux/jbd.h Thu Apr 4 15:48:06 2002 @@ -352,7 +352,7 @@ */ struct journal_head * t_async_datalist; - /* Doubly-linked circular list of all forget buffers (superseded + /* Doubly-linked circular list of all forget buffers (superceded buffers which we can un-checkpoint once this transaction commits) */ struct journal_head * t_forget; @@ -793,7 +793,7 @@ #define BJ_SyncData 1 /* Normal data: flush before commit */ #define BJ_AsyncData 2 /* writepage data: wait on it before commit */ #define BJ_Metadata 3 /* Normal journaled metadata */ -#define BJ_Forget 4 /* Buffer superseded by this transaction */ +#define BJ_Forget 4 /* Buffer superceded by this transaction */ #define BJ_IO 5 /* Buffer is for temporary IO use */ #define BJ_Shadow 6 /* Buffer contents being shadowed to the log */ #define BJ_LogCtl 7 /* Buffer contains log descriptors */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/kernel.h linux.19pre5-ac1/include/linux/kernel.h --- linux.19p5/include/linux/kernel.h Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/include/linux/kernel.h Thu Apr 4 14:01:05 2002 @@ -11,7 +11,6 @@ #include #include #include -#include /* Optimization barrier */ /* The "volatile" is due to gcc bugs */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/kernel_stat.h linux.19pre5-ac1/include/linux/kernel_stat.h --- linux.19p5/include/linux/kernel_stat.h Thu Apr 4 13:18:17 2002 +++ linux.19pre5-ac1/include/linux/kernel_stat.h Thu Apr 4 15:46:33 2002 @@ -32,11 +32,12 @@ unsigned int ipackets, opackets; unsigned int ierrors, oerrors; unsigned int collisions; - unsigned int context_swtch; }; extern struct kernel_stat kstat; +extern unsigned long nr_context_switches(void); + #if !defined(CONFIG_ARCH_S390) /* * Number of interrupts per specific IRQ source, since bootup diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/list.h linux.19pre5-ac1/include/linux/list.h --- linux.19p5/include/linux/list.h Thu Apr 4 13:18:17 2002 +++ linux.19pre5-ac1/include/linux/list.h Tue Mar 26 20:11:14 2002 @@ -19,6 +19,8 @@ struct list_head *next, *prev; }; +typedef struct list_head list_t; + #define LIST_HEAD_INIT(name) { &(name), &(name) } #define LIST_HEAD(name) \ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/llc.h linux.19pre5-ac1/include/linux/llc.h --- linux.19p5/include/linux/llc.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/linux/llc.h Tue Mar 26 20:36:20 2002 @@ -0,0 +1,102 @@ +#ifndef __LINUX_LLC_H +#define __LINUX_LLC_H +/* + * IEEE 802.2 User Interface SAPs for Linux, data structures and indicators. + * + * Copyright (c) 2001 by Jay Schulist + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +#define __LLC_SOCK_SIZE__ 28 /* sizeof(sockaddr_llc), word align. */ +struct sockaddr_llc { + sa_family_t sllc_family; /* AF_LLC */ + sa_family_t sllc_arphrd; /* ARPHRD_ETHER */ + unsigned char sllc_test; + unsigned char sllc_xid; + unsigned char sllc_ua; /* UA data, only for SOCK_STREAM. */ + unsigned char sllc_dsap; + unsigned char sllc_ssap; + unsigned char sllc_dmac[IFHWADDRLEN]; + unsigned char sllc_smac[IFHWADDRLEN]; + unsigned char sllc_mmac[IFHWADDRLEN]; + unsigned char __pad[__LLC_SOCK_SIZE__ - sizeof(sa_family_t) * 2 - + sizeof(unsigned char) * 5 - IFHWADDRLEN * 3]; +}; + +/* sockopt definitions. */ +enum llc_sockopts { + LLC_OPT_UNKNOWN = 0, + LLC_OPT_RETRY, /* max retrans attempts. */ + LLC_OPT_SIZE, /* max PDU size (octets). */ + LLC_OPT_ACK_TMR_EXP, /* ack expire time (secs). */ + LLC_OPT_P_TMR_EXP, /* pf cycle expire time (secs). */ + LLC_OPT_REJ_TMR_EXP, /* rej sent expire time (secs). */ + LLC_OPT_BUSY_TMR_EXP, /* busy state expire time (secs). */ + LLC_OPT_TX_WIN, /* tx window size. */ + LLC_OPT_RX_WIN, /* rx window size. */ + LLC_OPT_MAX +}; + +#define LLC_OPT_MAX_RETRY 100 +#define LLC_OPT_MAX_SIZE 4196 +#define LLC_OPT_MAX_WIN 127 +#define LLC_OPT_MAX_ACK_TMR_EXP 60 +#define LLC_OPT_MAX_P_TMR_EXP 60 +#define LLC_OPT_MAX_REJ_TMR_EXP 60 +#define LLC_OPT_MAX_BUSY_TMR_EXP 60 + +/* LLC SAP types. */ +#define LLC_SAP_NULL 0x00 /* NULL SAP. */ +#define LLC_SAP_LLC 0x02 /* LLC Sublayer Managment. */ +#define LLC_SAP_SNA 0x04 /* SNA Path Control. */ +#define LLC_SAP_PNM 0x0E /* Proway Network Managment. */ +#define LLC_SAP_IP 0x06 /* TCP/IP. */ +#define LLC_SAP_BSPAN 0x42 /* Bridge Spanning Tree Proto */ +#define LLC_SAP_MMS 0x4E /* Manufacturing Message Srv. */ +#define LLC_SAP_8208 0x7E /* ISO 8208 */ +#define LLC_SAP_3COM 0x80 /* 3COM. */ +#define LLC_SAP_PRO 0x8E /* Proway Active Station List */ +#define LLC_SAP_SNAP 0xAA /* SNAP. */ +#define LLC_SAP_BANYAN 0xBC /* Banyan. */ +#define LLC_SAP_IPX 0xE0 /* IPX/SPX. */ +#define LLC_SAP_NETBEUI 0xF0 /* NetBEUI. */ +#define LLC_SAP_LANMGR 0xF4 /* LanManager. */ +#define LLC_SAP_IMPL 0xF8 /* IMPL */ +#define LLC_SAP_DISC 0xFC /* Discovery */ +#define LLC_SAP_OSI 0xFE /* OSI Network Layers. */ +#define LLC_SAP_LAR 0xDC /* LAN Address Resolution */ +#define LLC_SAP_RM 0xD4 /* Resource Management */ +#define LLC_SAP_GLOBAL 0xFF /* Global SAP. */ + +#ifdef __KERNEL__ +#define LLC_SAP_DYN_START 0xC0 +#define LLC_SAP_DYN_STOP 0xDE +#define LLC_SAP_DYN_TRIES 4 + +struct sock; + +struct llc_ui_opt { + u16 link; /* network layer link number */ + struct llc_sap *sap; /* pointer to parent SAP */ + struct sock *core_sk; + struct net_device *dev; /* device to send to remote */ + struct sockaddr_llc addr; /* address sock is bound to */ +}; + +#define llc_ui_sk(__sk) ((struct llc_ui_opt *)(__sk)->protinfo.destruct_hook) +#define llc_ui_skb_cb(__skb) ((struct sockaddr_llc *)&((__skb)->cb[0])) + +#ifdef CONFIG_LLC_UI +extern int llc_ui_init(void); +extern void llc_ui_exit(void); +#else +#define llc_ui_init() +#define llc_ui_exit() +#endif +#endif /* __KERNEL__ */ +#endif /* __LINUX_LLC_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/malloc.h linux.19pre5-ac1/include/linux/malloc.h --- linux.19p5/include/linux/malloc.h Thu Apr 4 13:18:17 2002 +++ linux.19pre5-ac1/include/linux/malloc.h Thu Apr 4 16:00:37 2002 @@ -1,7 +1,7 @@ #ifndef _LINUX_MALLOC_H #define _LINUX_MALLOC_H -#warning linux/malloc.h is deprecated, use linux/slab.h instead. +#error linux/malloc.h is deprecated, use linux/slab.h instead. #include #endif /* _LINUX_MALLOC_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/mm.h linux.19pre5-ac1/include/linux/mm.h --- linux.19p5/include/linux/mm.h Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/include/linux/mm.h Thu Apr 4 15:46:31 2002 @@ -18,9 +18,6 @@ extern unsigned long num_mappedpages; extern void * high_memory; extern int page_cluster; -/* The inactive_clean lists are per zone. */ -extern struct list_head active_list; -extern struct list_head inactive_list; #include #include @@ -104,7 +101,9 @@ #define VM_DONTEXPAND 0x00040000 /* Cannot expand with mremap() */ #define VM_RESERVED 0x00080000 /* Don't unmap it from swap_out */ -#define VM_STACK_FLAGS 0x00000177 +#define VM_ACCOUNT 0x00100000 /* Memory is a vm accounted object */ + +#define VM_STACK_FLAGS (0x00000177|VM_ACCOUNT) #define VM_READHINTMASK (VM_SEQ_READ | VM_RAND_READ) #define VM_ClearReadHint(v) (v)->vm_flags &= ~VM_READHINTMASK @@ -122,7 +121,6 @@ */ extern pgprot_t protection_map[16]; - /* * These are the virtual MM functions - opening of an area, closing and * unmapping it (needed to keep files on disk up-to-date etc), pointer @@ -134,6 +132,9 @@ struct page * (*nopage)(struct vm_area_struct * area, unsigned long address, int unused); }; +/* forward declaration; pte_chain is meant to be internal to rmap.c */ +struct pte_chain; + /* * Each physical page in the system has a struct page associated with * it to keep track of whatever it is we are using the page for at the @@ -160,6 +161,9 @@ updated asynchronously */ struct list_head lru; /* Pageout list, eg. active_list; protected by pagemap_lru_lock !! */ + unsigned char age; /* Page aging counter. */ + unsigned char zone; /* Memory zone the page belongs to. */ + struct pte_chain * pte_chain; /* Reverse pte mapping pointer. */ struct page **pprev_hash; /* Complement to *next_hash. */ struct buffer_head * buffers; /* Buffer maps us to a disk block. */ @@ -169,14 +173,11 @@ * highmem some memory is mapped into kernel virtual memory * dynamically, so we need a place to store that address. * Note that this field could be 16 bits on x86 ... ;) - * - * Architectures with slow multiplication can define - * WANT_PAGE_VIRTUAL in asm/page.h */ -#if defined(CONFIG_HIGHMEM) || defined(WANT_PAGE_VIRTUAL) +#if defined(CONFIG_HIGHMEM) || defined(CONFIG_SPARC64) void *virtual; /* Kernel virtual address (NULL if not kmapped, ie. highmem) */ -#endif /* CONFIG_HIGMEM || WANT_PAGE_VIRTUAL */ +#endif /* CONFIG_HIGMEM || CONFIG_SPARC64 */ } mem_map_t; /* @@ -197,6 +198,11 @@ #define page_count(p) atomic_read(&(p)->count) #define set_page_count(p,v) atomic_set(&(p)->count, v) +static inline void init_page_count(struct page *page) +{ + page->count.counter = 0; +} + /* * Various page->flags bits: * @@ -287,9 +293,9 @@ #define PG_referenced 2 #define PG_uptodate 3 #define PG_dirty 4 -#define PG_unused 5 -#define PG_lru 6 -#define PG_active 7 +#define PG_inactive_clean 5 +#define PG_active 6 +#define PG_inactive_dirty 7 #define PG_slab 8 #define PG_skip 10 #define PG_highmem 11 @@ -314,6 +320,53 @@ #define PageLaunder(page) test_bit(PG_launder, &(page)->flags) #define SetPageLaunder(page) set_bit(PG_launder, &(page)->flags) +extern void FASTCALL(set_page_dirty(struct page *)); + +/* + * The first mb is necessary to safely close the critical section opened by the + * TryLockPage(), the second mb is necessary to enforce ordering between + * the clear_bit and the read of the waitqueue (to avoid SMP races with a + * parallel wait_on_page). + */ +#define PageError(page) test_bit(PG_error, &(page)->flags) +#define SetPageError(page) set_bit(PG_error, &(page)->flags) +#define ClearPageError(page) clear_bit(PG_error, &(page)->flags) +#define PageReferenced(page) test_bit(PG_referenced, &(page)->flags) +#define SetPageReferenced(page) set_bit(PG_referenced, &(page)->flags) +#define ClearPageReferenced(page) clear_bit(PG_referenced, &(page)->flags) +#define PageTestandClearReferenced(page) test_and_clear_bit(PG_referenced, &(page)->flags) +#define PageSlab(page) test_bit(PG_slab, &(page)->flags) +#define PageSetSlab(page) set_bit(PG_slab, &(page)->flags) +#define PageClearSlab(page) clear_bit(PG_slab, &(page)->flags) +#define PageReserved(page) test_bit(PG_reserved, &(page)->flags) + +#define PageActive(page) test_bit(PG_active, &(page)->flags) +#define SetPageActive(page) set_bit(PG_active, &(page)->flags) +#define ClearPageActive(page) clear_bit(PG_active, &(page)->flags) +#define TestandSetPageActive(page) test_and_set_bit(PG_active, &(page)->flags) +#define TestandClearPageActive(page) test_and_clear_bit(PG_active, &(page)->flags) + +#define PageInactiveDirty(page) test_bit(PG_inactive_dirty, &(page)->flags) +#define SetPageInactiveDirty(page) set_bit(PG_inactive_dirty, &(page)->flags) +#define ClearPageInactiveDirty(page) clear_bit(PG_inactive_dirty, &(page)->flags) + +#define PageInactiveClean(page) test_bit(PG_inactive_clean, &(page)->flags) +#define SetPageInactiveClean(page) set_bit(PG_inactive_clean, &(page)->flags) +#define ClearPageInactiveClean(page) clear_bit(PG_inactive_clean, &(page)->flags) + +#ifdef CONFIG_HIGHMEM +#define PageHighMem(page) test_bit(PG_highmem, &(page)->flags) +#else +#define PageHighMem(page) 0 /* needed to optimize away at compile time */ +#endif + +#define SetPageReserved(page) set_bit(PG_reserved, &(page)->flags) +#define ClearPageReserved(page) clear_bit(PG_reserved, &(page)->flags) +#define __SetPageReserved(page) __set_bit(PG_reserved, &(page)->flags) + +#define PageLRU(pp) \ + (PageActive(pp) | PageInactiveDirty(pp) | PageInactiveClean(pp)) + /* * The zone field is never updated after free_area_init_core() * sets it, so none of the operations on it need to be atomic. @@ -342,7 +395,6 @@ * The same is true for page_address() in arch-dependent code. */ #if defined(CONFIG_HIGHMEM) || defined(WANT_PAGE_VIRTUAL) - #define set_page_address(page, address) \ do { \ (page)->virtual = (address); \ @@ -356,6 +408,7 @@ * Permanent address of a page. Obviously must never be * called on a highmem page. */ + #if defined(CONFIG_HIGHMEM) || defined(WANT_PAGE_VIRTUAL) #define page_address(page) ((page)->virtual) @@ -367,44 +420,7 @@ + page_zone(page)->zone_start_paddr) #endif /* CONFIG_HIGHMEM || WANT_PAGE_VIRTUAL */ - -extern void FASTCALL(set_page_dirty(struct page *)); - -/* - * The first mb is necessary to safely close the critical section opened by the - * TryLockPage(), the second mb is necessary to enforce ordering between - * the clear_bit and the read of the waitqueue (to avoid SMP races with a - * parallel wait_on_page). - */ -#define PageError(page) test_bit(PG_error, &(page)->flags) -#define SetPageError(page) set_bit(PG_error, &(page)->flags) -#define ClearPageError(page) clear_bit(PG_error, &(page)->flags) -#define PageReferenced(page) test_bit(PG_referenced, &(page)->flags) -#define SetPageReferenced(page) set_bit(PG_referenced, &(page)->flags) -#define ClearPageReferenced(page) clear_bit(PG_referenced, &(page)->flags) -#define PageTestandClearReferenced(page) test_and_clear_bit(PG_referenced, &(page)->flags) -#define PageSlab(page) test_bit(PG_slab, &(page)->flags) -#define PageSetSlab(page) set_bit(PG_slab, &(page)->flags) -#define PageClearSlab(page) clear_bit(PG_slab, &(page)->flags) -#define PageReserved(page) test_bit(PG_reserved, &(page)->flags) - -#define PageActive(page) test_bit(PG_active, &(page)->flags) -#define SetPageActive(page) set_bit(PG_active, &(page)->flags) -#define ClearPageActive(page) clear_bit(PG_active, &(page)->flags) - -#define PageLRU(page) test_bit(PG_lru, &(page)->flags) -#define TestSetPageLRU(page) test_and_set_bit(PG_lru, &(page)->flags) -#define TestClearPageLRU(page) test_and_clear_bit(PG_lru, &(page)->flags) - -#ifdef CONFIG_HIGHMEM -#define PageHighMem(page) test_bit(PG_highmem, &(page)->flags) -#else -#define PageHighMem(page) 0 /* needed to optimize away at compile time */ -#endif - -#define SetPageReserved(page) set_bit(PG_reserved, &(page)->flags) -#define ClearPageReserved(page) clear_bit(PG_reserved, &(page)->flags) - + /* * Error return values for the *_nopage functions */ @@ -459,6 +475,7 @@ #define __free_page(page) __free_pages((page), 0) #define free_page(addr) free_pages((addr),0) +extern void FASTCALL(fixup_freespace(struct zone_struct *, int)); extern void show_free_areas(void); extern void show_free_areas_node(pg_data_t *pgdat); @@ -515,6 +532,9 @@ extern void si_meminfo(struct sysinfo * val); extern void swapin_readahead(swp_entry_t); +struct zone_struct; +extern struct zone_struct *zone_table[]; + extern struct address_space swapper_space; #define PageSwapCache(page) ((page)->mapping == &swapper_space) @@ -555,7 +575,7 @@ return ret; } -extern int do_munmap(struct mm_struct *, unsigned long, size_t); +extern int do_munmap(struct mm_struct *, unsigned long, size_t, int acct); extern unsigned long do_brk(unsigned long, unsigned long); @@ -622,34 +642,9 @@ return gfp_mask; } - -/* vma is the first one with address < vma->vm_end, - * and even address < vma->vm_start. Have to extend vma. */ -static inline int expand_stack(struct vm_area_struct * vma, unsigned long address) -{ - unsigned long grow; - /* - * vma->vm_start/vm_end cannot change under us because the caller is required - * to hold the mmap_sem in write mode. We need to get the spinlock only - * before relocating the vma range ourself. - */ - address &= PAGE_MASK; - spin_lock(&vma->vm_mm->page_table_lock); - grow = (vma->vm_start - address) >> PAGE_SHIFT; - if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur || - ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur) { - spin_unlock(&vma->vm_mm->page_table_lock); - return -ENOMEM; - } - vma->vm_start = address; - vma->vm_pgoff -= grow; - vma->vm_mm->total_vm += grow; - if (vma->vm_flags & VM_LOCKED) - vma->vm_mm->locked_vm += grow; - spin_unlock(&vma->vm_mm->page_table_lock); - return 0; -} +/* Do stack extension */ +extern int expand_stack(struct vm_area_struct * vma, unsigned long address); /* Look up the first VMA which satisfies addr < vm_end, NULL if none. */ extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/mm_inline.h linux.19pre5-ac1/include/linux/mm_inline.h --- linux.19p5/include/linux/mm_inline.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/linux/mm_inline.h Thu Apr 4 15:47:52 2002 @@ -0,0 +1,311 @@ +#ifndef _LINUX_VM_INLINE_H +#define _LINUX_VM_INLINE_H + +#include + +/* + * Knuth recommends primes in approximately golden ratio to the maximum + * integer representable by a machine word for multiplicative hashing. + * Chuck Lever verified the effectiveness of this technique for several + * hash tables in his paper documenting the benchmark results: + * http://www.citi.umich.edu/techreports/reports/citi-tr-00-1.pdf + */ +#if BITS_PER_LONG == 32 +#define GOLDEN_RATIO_PRIME 2654435761UL + +#elif BITS_PER_LONG == 64 +#define GOLDEN_RATIO_PRIME 11400714819323198549UL + +#else +#error Define GOLDEN_RATIO_PRIME in mm_inline.h for your wordsize. +#endif + +/* + * These inline functions tend to need bits and pieces of all the + * other VM include files, meaning they cannot be defined inside + * one of the other VM include files. + * + * The include file mess really needs to be cleaned up... + */ + +static inline void add_page_to_active_list(struct page * page) +{ + struct zone_struct * zone = page_zone(page); + DEBUG_LRU_PAGE(page); + SetPageActive(page); + list_add(&page->lru, &zone->active_list); + zone->active_pages++; + nr_active_pages++; +} + +static inline void add_page_to_inactive_dirty_list(struct page * page) +{ + struct zone_struct * zone = page_zone(page); + DEBUG_LRU_PAGE(page); + SetPageInactiveDirty(page); + list_add(&page->lru, &zone->inactive_dirty_list); + zone->inactive_dirty_pages++; + nr_inactive_dirty_pages++; +} + +static inline void add_page_to_inactive_clean_list(struct page * page) +{ + struct zone_struct * zone = page_zone(page); + DEBUG_LRU_PAGE(page); + SetPageInactiveClean(page); + list_add(&page->lru, &zone->inactive_clean_list); + zone->inactive_clean_pages++; + nr_inactive_clean_pages++; +} + +static inline void del_page_from_active_list(struct page * page) +{ + struct zone_struct * zone = page_zone(page); + list_del(&page->lru); + ClearPageActive(page); + nr_active_pages--; + zone->active_pages--; + DEBUG_LRU_PAGE(page); +} + +static inline void del_page_from_inactive_dirty_list(struct page * page) +{ + struct zone_struct * zone = page_zone(page); + list_del(&page->lru); + ClearPageInactiveDirty(page); + nr_inactive_dirty_pages--; + zone->inactive_dirty_pages--; + DEBUG_LRU_PAGE(page); +} + +static inline void del_page_from_inactive_clean_list(struct page * page) +{ + struct zone_struct * zone = page_zone(page); + list_del(&page->lru); + ClearPageInactiveClean(page); + zone->inactive_clean_pages--; + nr_inactive_clean_pages--; + DEBUG_LRU_PAGE(page); +} + +/* + * Inline functions to control some balancing in the VM. + * + * Note that we do both global and per-zone balancing, with + * most of the balancing done globally. + */ +#define PLENTY_FACTOR 2 +#define ALL_ZONES NULL +#define ANY_ZONE (struct zone_struct *)(~0UL) +#define INACTIVE_FACTOR 5 + +#define VM_MIN 0 +#define VM_LOW 1 +#define VM_HIGH 2 +#define VM_PLENTY 3 +static inline int zone_free_limit(struct zone_struct * zone, int limit) +{ + int free, target, delta; + + /* This is really nasty, but GCC should completely optimise it away. */ + if (limit == VM_MIN) + target = zone->pages_min; + else if (limit == VM_LOW) + target = zone->pages_low; + else if (limit == VM_HIGH) + target = zone->pages_high; + else + target = zone->pages_high * PLENTY_FACTOR; + + free = zone->free_pages + zone->inactive_clean_pages; + delta = target - free; + + return delta; +} + +static inline int free_limit(struct zone_struct * zone, int limit) +{ + int shortage = 0, local; + + if (zone == ALL_ZONES) { + for_each_zone(zone) + shortage += zone_free_limit(zone, limit); + } else if (zone == ANY_ZONE) { + for_each_zone(zone) { + local = zone_free_limit(zone, limit); + shortage += max(local, 0); + } + } else { + shortage = zone_free_limit(zone, limit); + } + + return shortage; +} + +/** + * free_min - test for critically low amount of free pages + * @zone: zone to test, ALL_ZONES to test memory globally + * + * Returns a positive value if we have a serious shortage of free and + * clean pages, zero or negative if there is no serious shortage. + */ +static inline int free_min(struct zone_struct * zone) +{ + return free_limit(zone, VM_MIN); +} + +/** + * free_low - test for low amount of free pages + * @zone: zone to test, ALL_ZONES to test memory globally + * + * Returns a positive value if we have a shortage of free and + * clean pages, zero or negative if there is no shortage. + */ +static inline int free_low(struct zone_struct * zone) +{ + return free_limit(zone, VM_LOW); +} + +/** + * free_high - test if amount of free pages is less than ideal + * @zone: zone to test, ALL_ZONES to test memory globally + * + * Returns a positive value if the number of free and clean + * pages is below kswapd's target, zero or negative if we + * have more than enough free and clean pages. + */ +static inline int free_high(struct zone_struct * zone) +{ + return free_limit(zone, VM_HIGH); +} + +/** + * free_plenty - test if enough pages are freed + * @zone: zone to test, ALL_ZONES to test memory globally + * + * Returns a positive value if the number of free + clean pages + * in a zone is not yet excessive and kswapd is still allowed to + * free pages here, a negative value if kswapd should leave the + * zone alone. + */ +static inline int free_plenty(struct zone_struct * zone) +{ + return free_limit(zone, VM_PLENTY); +} + +/* + * The inactive page target is the free target + 20% of (active + inactive) + * pages. + */ +static inline int zone_inactive_limit(struct zone_struct * zone, int limit) +{ + int inactive, target, inactive_base; + + inactive_base = zone->active_pages + zone->inactive_dirty_pages; + inactive_base /= INACTIVE_FACTOR; + + /* GCC should optimise this away completely. */ + if (limit == VM_MIN) + target = zone->pages_high + inactive_base / 2; + else if (limit == VM_LOW) + target = zone->pages_high + inactive_base; + else + target = zone->pages_high + inactive_base * 2; + + inactive = zone->free_pages + zone->inactive_clean_pages; + inactive += zone->inactive_dirty_pages; + + return target - inactive; +} + +static inline int inactive_limit(struct zone_struct * zone, int limit) +{ + int shortage = 0, local; + + if (zone == ALL_ZONES) { + for_each_zone(zone) + shortage += zone_inactive_limit(zone, limit); + } else if (zone == ANY_ZONE) { + for_each_zone(zone) { + local = zone_inactive_limit(zone, limit); + shortage += max(local, 0); + } + } else { + shortage = zone_inactive_limit(zone, limit); + } + + return shortage; +} + +/** + * inactive_min - test for serious shortage of (free + inactive clean) pages + * @zone: zone to test, ALL_ZONES for global testing + * + * Returns the shortage as a positive number, a negative number + * if we have no serious shortage of (free + inactive clean) pages + */ +static inline int inactive_min(struct zone_struct * zone) +{ + return inactive_limit(zone, VM_MIN); +} + +/** + * inactive_low - test for shortage of (free + inactive clean) pages + * @zone: zone to test, ALL_ZONES for global testing + * + * Returns the shortage as a positive number, a negative number + * if we have no shortage of (free + inactive clean) pages + */ +static inline int inactive_low(struct zone_struct * zone) +{ + return inactive_limit(zone, VM_LOW); +} + +/** + * inactive_high - less than ideal amount of (free + inactive) pages + * @zone: zone to test, ALL_ZONES for global testing + * + * Returns the shortage as a positive number, a negative number + * if we have more than enough (free + inactive) pages + */ +static inline int inactive_high(struct zone_struct * zone) +{ + return inactive_limit(zone, VM_HIGH); +} + +/* + * inactive_target - number of inactive pages we ought to have. + */ +static inline int inactive_target(void) +{ + int target; + + target = nr_active_pages + nr_inactive_dirty_pages + + nr_inactive_clean_pages; + + target /= INACTIVE_FACTOR; + + return target; +} + +/* + * Called whenever the VM references a page. We immediately reclaim + * the inactive clean pages because those are counted as freeable. + * We don't modify the inactive dirty ones because we're never sure + * if those are freeable anyway. + */ +static inline void touch_page(struct page * page) +{ + if (PageInactiveClean(page)) { + struct zone_struct * zone = page_zone(page); + int free = zone->free_pages + zone->inactive_clean_pages; + activate_page(page); + if (free < zone->pages_low) + wakeup_kswapd(GFP_NOIO); + if (zone->free_pages < zone->pages_min) + fixup_freespace(zone, 1); + } else + SetPageReferenced(page); +} + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/mman.h linux.19pre5-ac1/include/linux/mman.h --- linux.19p5/include/linux/mman.h Thu Apr 4 13:18:17 2002 +++ linux.19pre5-ac1/include/linux/mman.h Mon Feb 18 09:35:41 2002 @@ -6,4 +6,8 @@ #define MREMAP_MAYMOVE 1 #define MREMAP_FIXED 2 +extern int vm_enough_memory(long pages, int charge); +extern void vm_unacct_memory(long pages); +extern void vm_unacct_vma(struct vm_area_struct *vma); + #endif /* _LINUX_MMAN_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/mmzone.h linux.19pre5-ac1/include/linux/mmzone.h --- linux.19p5/include/linux/mmzone.h Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/include/linux/mmzone.h Thu Apr 4 15:46:31 2002 @@ -40,19 +40,25 @@ */ spinlock_t lock; unsigned long free_pages; - unsigned long pages_min, pages_low, pages_high; + unsigned long active_pages; + unsigned long inactive_dirty_pages; + unsigned long inactive_clean_pages; + unsigned long pages_min, pages_low, pages_high, pages_plenty; int need_balance; /* * free areas of different sizes */ + struct list_head active_list; + struct list_head inactive_dirty_list; + struct list_head inactive_clean_list; free_area_t free_area[MAX_ORDER]; /* - * wait_table -- the array holding the hash table - * wait_table_size -- the size of the hash table array - * wait_table_shift -- wait_table_size - * == BITS_PER_LONG (1 << wait_table_bits) + * wait_table -- the array holding the hash table + * wait_table_size -- the size of the hash table array + * wait_table_shift -- wait_table_size + * == BITS_PER_LONG (1 << wait_table_bits) * * The purpose of all these is to keep track of the people * waiting for a page to become available and make them @@ -69,13 +75,13 @@ * table, they should be so rare as to be outweighed by the * benefits from the saved space. * - * __wait_on_page() and unlock_page() in mm/filemap.c, are the + *__wait_on_page() and unlock_page() in mm/filemap.c, are the * primary users of these fields, and in mm/page_alloc.c * free_area_init_core() performs the initialization of them. */ - wait_queue_head_t * wait_table; - unsigned long wait_table_size; - unsigned long wait_table_shift; + wait_queue_head_t *wait_table; + unsigned long wait_table_size; + unsigned long wait_table_shift; /* * Discontig memory support fields. @@ -143,9 +149,6 @@ extern int numnodes; extern pg_data_t *pgdat_list; -#define memclass(pgzone, classzone) (((pgzone)->zone_pgdat == (classzone)->zone_pgdat) \ - && ((pgzone) <= (classzone))) - /* * The following two are not meant for general usage. They are here as * prototypes for the discontig memory code. @@ -158,6 +161,60 @@ extern pg_data_t contig_page_data; +/** + * for_each_pgdat - helper macro to iterate over all nodes + * @pgdat - pg_data_t * variable + * + * Meant to help with common loops of the form + * pgdat = pgdat_list; + * while(pgdat) { + * ... + * pgdat = pgdat->node_next; + * } + */ +#define for_each_pgdat(pgdat) \ + for (pgdat = pgdat_list; pgdat; pgdat = pgdat->node_next) + + +/* + * next_zone - helper magic for for_each_zone() + * Thanks to William Lee Irwin III for this piece of ingenuity. + */ +static inline zone_t *next_zone(zone_t *zone) +{ + pg_data_t *pgdat = zone->zone_pgdat; + + if (zone - pgdat->node_zones < MAX_NR_ZONES - 1) + zone++; + + else if (pgdat->node_next) { + pgdat = pgdat->node_next; + zone = pgdat->node_zones; + } else + zone = NULL; + + return zone; +} + +/** + * for_each_zone - helper macro to iterate over all memory zones + * @zone - zone_t * variable + * + * The user only needs to declare the zone variable, for_each_zone + * fills it in. This basically means for_each_zone() is an + * easier to read version of this piece of code: + * + * for(pgdat = pgdat_list; pgdat; pgdat = pgdat->node_next) + * for(i = 0; i < MAX_NR_ZONES; ++i) { + * zone_t * z = pgdat->node_zones + i; + * ... + * } + * } + */ +#define for_each_zone(zone) \ + for(zone = pgdat_list->node_zones; zone; zone = next_zone(zone)) + + #ifndef CONFIG_DISCONTIGMEM #define NODE_DATA(nid) (&contig_page_data) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/nfsd/export.h linux.19pre5-ac1/include/linux/nfsd/export.h --- linux.19p5/include/linux/nfsd/export.h Thu Apr 4 13:18:18 2002 +++ linux.19pre5-ac1/include/linux/nfsd/export.h Tue Mar 26 20:32:34 2002 @@ -39,7 +39,8 @@ #define NFSEXP_NOSUBTREECHECK 0x0400 #define NFSEXP_NOAUTHNLM 0x0800 /* Don't authenticate NLM requests - just trust */ #define NFSEXP_MSNFS 0x1000 /* do silly things that MS clients expect */ -#define NFSEXP_ALLFLAGS 0x1FFF +#define NFSEXP_FSID 0x2000 +#define NFSEXP_ALLFLAGS 0x3FFF #ifdef __KERNEL__ @@ -54,11 +55,15 @@ int cl_naddr; struct in_addr cl_addr[NFSCLNT_ADDRMAX]; struct svc_uidmap * cl_umap; - struct svc_export * cl_export[NFSCLNT_EXPMAX]; + struct list_head cl_export[NFSCLNT_EXPMAX]; + struct list_head cl_expfsid[NFSCLNT_EXPMAX]; + struct list_head cl_list; }; struct svc_export { - struct svc_export * ex_next; + struct list_head ex_hash; + struct list_head ex_fsid_hash; + struct list_head ex_list; char ex_path[NFS_MAXPATHLEN+1]; struct svc_export * ex_parent; struct svc_client * ex_client; @@ -69,6 +74,7 @@ ino_t ex_ino; uid_t ex_anon_uid; gid_t ex_anon_gid; + int ex_fsid; }; #define EX_SECURE(exp) (!((exp)->ex_flags & NFSEXP_INSECURE_PORT)) @@ -85,11 +91,11 @@ void nfsd_export_init(void); void nfsd_export_shutdown(void); void exp_readlock(void); -int exp_writelock(void); -void exp_unlock(void); +void exp_readunlock(void); struct svc_client * exp_getclient(struct sockaddr_in *sin); void exp_putclient(struct svc_client *clp); struct svc_export * exp_get(struct svc_client *clp, kdev_t dev, ino_t ino); +struct svc_export * exp_get_fsid(struct svc_client *clp, int fsid); int exp_rootfh(struct svc_client *, kdev_t, ino_t, char *path, struct knfsd_fh *, int maxsize); int nfserrno(int errno); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/nfsd/interface.h linux.19pre5-ac1/include/linux/nfsd/interface.h --- linux.19p5/include/linux/nfsd/interface.h Thu Apr 4 13:18:18 2002 +++ linux.19pre5-ac1/include/linux/nfsd/interface.h Tue Mar 26 20:13:11 2002 @@ -12,12 +12,15 @@ #include -#ifdef CONFIG_NFSD_MODULE +#ifndef CONFIG_NFSD +# ifdef CONFIG_MODULES extern struct nfsd_linkage { long (*do_nfsservctl)(int cmd, void *argp, void *resp); + struct module *owner; } * nfsd_linkage; +# endif #endif #endif /* LINUX_NFSD_INTERFACE_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/nls.h linux.19pre5-ac1/include/linux/nls.h --- linux.19p5/include/linux/nls.h Thu Apr 4 13:18:18 2002 +++ linux.19pre5-ac1/include/linux/nls.h Wed Apr 3 01:02:21 2002 @@ -18,7 +18,7 @@ }; /* this value hold the maximum octet of charset */ -#define NLS_MAX_CHARSET_SIZE 3 +#define NLS_MAX_CHARSET_SIZE 6 /* for UTF-8 */ /* nls.c */ extern int register_nls(struct nls_table *); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/pagemap.h linux.19pre5-ac1/include/linux/pagemap.h --- linux.19p5/include/linux/pagemap.h Thu Apr 4 13:18:18 2002 +++ linux.19pre5-ac1/include/linux/pagemap.h Thu Apr 4 15:46:31 2002 @@ -97,6 +97,8 @@ ___wait_on_page(page); } +extern void wake_up_page(struct page *); + extern struct page * grab_cache_page (struct address_space *, unsigned long); extern struct page * grab_cache_page_nowait (struct address_space *, unsigned long); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/pci_ids.h linux.19pre5-ac1/include/linux/pci_ids.h --- linux.19p5/include/linux/pci_ids.h Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/include/linux/pci_ids.h Thu Apr 4 14:42:07 2002 @@ -603,6 +603,7 @@ #define PCI_DEVICE_ID_PROMISE_20268 0x4d68 #define PCI_DEVICE_ID_PROMISE_20268R 0x6268 #define PCI_DEVICE_ID_PROMISE_20269 0x4d69 +#define PCI_DEVICE_ID_PROMISE_20271 0x6269 #define PCI_DEVICE_ID_PROMISE_20275 0x1275 #define PCI_DEVICE_ID_PROMISE_20276 0x5275 #define PCI_DEVICE_ID_PROMISE_5300 0x5300 @@ -922,6 +923,8 @@ #define PCI_VENDOR_ID_TTI 0x1103 #define PCI_DEVICE_ID_TTI_HPT343 0x0003 #define PCI_DEVICE_ID_TTI_HPT366 0x0004 +#define PCI_DEVICE_ID_TTI_HPT372 0x0005 +#define PCI_DEVICE_ID_TTI_HPT374 0x0008 #define PCI_VENDOR_ID_VIA 0x1106 #define PCI_DEVICE_ID_VIA_8363_0 0x0305 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/pnpbios.h linux.19pre5-ac1/include/linux/pnpbios.h --- linux.19p5/include/linux/pnpbios.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/linux/pnpbios.h Thu Apr 4 15:46:31 2002 @@ -0,0 +1,212 @@ +/* + * Include file for the interface to a PnP BIOS + * + * Original BIOS code (C) 1998 Christian Schmidt (chr.schmidt@tu-bs.de) + * PnP handler parts (c) 1998 Tom Lees + * Minor reorganizations by David Hinds + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _LINUX_PNPBIOS_H +#define _LINUX_PNPBIOS_H + +#ifdef __KERNEL__ + +#include +#include + +/* + * Status codes (warnings and errors) + */ +#define PNP_SUCCESS 0x00 +#define PNP_NOT_SET_STATICALLY 0x7f +#define PNP_UNKNOWN_FUNCTION 0x81 +#define PNP_FUNCTION_NOT_SUPPORTED 0x82 +#define PNP_INVALID_HANDLE 0x83 +#define PNP_BAD_PARAMETER 0x84 +#define PNP_SET_FAILED 0x85 +#define PNP_EVENTS_NOT_PENDING 0x86 +#define PNP_SYSTEM_NOT_DOCKED 0x87 +#define PNP_NO_ISA_PNP_CARDS 0x88 +#define PNP_UNABLE_TO_DETERMINE_DOCK_CAPABILITIES 0x89 +#define PNP_CONFIG_CHANGE_FAILED_NO_BATTERY 0x8a +#define PNP_CONFIG_CHANGE_FAILED_RESOURCE_CONFLICT 0x8b +#define PNP_BUFFER_TOO_SMALL 0x8c +#define PNP_USE_ESCD_SUPPORT 0x8d +#define PNP_MESSAGE_NOT_SUPPORTED 0x8e +#define PNP_HARDWARE_ERROR 0x8f + +#define ESCD_SUCCESS 0x00 +#define ESCD_IO_ERROR_READING 0x55 +#define ESCD_INVALID 0x56 +#define ESCD_BUFFER_TOO_SMALL 0x59 +#define ESCD_NVRAM_TOO_SMALL 0x5a +#define ESCD_FUNCTION_NOT_SUPPORTED 0x81 + +/* + * Events that can be received by "get event" + */ +#define PNPEV_ABOUT_TO_CHANGE_CONFIG 0x0001 +#define PNPEV_DOCK_CHANGED 0x0002 +#define PNPEV_SYSTEM_DEVICE_CHANGED 0x0003 +#define PNPEV_CONFIG_CHANGED_FAILED 0x0004 +#define PNPEV_UNKNOWN_SYSTEM_EVENT 0xffff +/* 0x8000 through 0xfffe are OEM defined */ + +/* + * Messages that should be sent through "send message" + */ +#define PNPMSG_OK 0x00 +#define PNPMSG_ABORT 0x01 +#define PNPMSG_UNDOCK_DEFAULT_ACTION 0x40 +#define PNPMSG_POWER_OFF 0x41 +#define PNPMSG_PNP_OS_ACTIVE 0x42 +#define PNPMSG_PNP_OS_INACTIVE 0x43 +/* 0x8000 through 0xffff are OEM defined */ + +#pragma pack(1) +struct pnp_dev_node_info { + __u16 no_nodes; + __u16 max_node_size; +}; +struct pnp_docking_station_info { + __u32 location_id; + __u32 serial; + __u16 capabilities; +}; +struct pnp_isa_config_struc { + __u8 revision; + __u8 no_csns; + __u16 isa_rd_data_port; + __u16 reserved; +}; +struct escd_info_struc { + __u16 min_escd_write_size; + __u16 escd_size; + __u32 nv_storage_base; +}; +struct pnp_bios_node { + __u16 size; + __u8 handle; + __u32 eisa_id; + __u8 type_code[3]; + __u16 flags; + __u8 data[0]; +}; +#pragma pack() + +struct pnpbios_device_id +{ + char id[8]; + unsigned long driver_data; +}; + +struct pnpbios_driver { + struct list_head node; + char *name; + const struct pnpbios_device_id *id_table; /* NULL if wants all devices */ + int (*probe) (struct pci_dev *dev, const struct pnpbios_device_id *id); /* New device inserted */ + void (*remove) (struct pci_dev *dev); /* Device removed, either due to hotplug remove or module remove */ +}; + +#ifdef CONFIG_PNPBIOS + +/* exported */ +extern int pnpbios_register_driver(struct pnpbios_driver *drv); +extern void pnpbios_unregister_driver(struct pnpbios_driver *drv); + +/* non-exported */ +#define pnpbios_for_each_dev(dev) \ + for(dev = pnpbios_dev_g(pnpbios_devices.next); dev != pnpbios_dev_g(&pnpbios_devices); dev = pnpbios_dev_g(dev->global_list.next)) + + +#define pnpbios_dev_g(n) list_entry(n, struct pci_dev, global_list) + +static __inline struct pnpbios_driver *pnpbios_dev_driver(const struct pci_dev *dev) +{ + return (struct pnpbios_driver *)dev->driver; +} + +extern int pnpbios_dont_use_current_config; +extern void *pnpbios_kmalloc(size_t size, int f); +extern int pnpbios_init (void); +extern int pnpbios_proc_init (void); +extern void pnpbios_proc_exit (void); + +extern int pnp_bios_dev_node_info (struct pnp_dev_node_info *data); +extern int pnp_bios_get_dev_node (u8 *nodenum, char config, struct pnp_bios_node *data); +extern int pnp_bios_set_dev_node (u8 nodenum, char config, struct pnp_bios_node *data); +extern int pnp_bios_get_stat_res (char *info); +extern int pnp_bios_isapnp_config (struct pnp_isa_config_struc *data); +extern int pnp_bios_escd_info (struct escd_info_struc *data); +extern int pnp_bios_read_escd (char *data, u32 nvram_base); +#if needed +extern int pnp_bios_get_event (u16 *message); +extern int pnp_bios_send_message (u16 message); +extern int pnp_bios_set_stat_res (char *info); +extern int pnp_bios_apm_id_table (char *table, u16 *size); +extern int pnp_bios_write_escd (char *data, u32 nvram_base); +#endif + +/* + * a helper function which helps ensure correct pnpbios_driver + * setup and cleanup for commonly-encountered hotplug/modular cases + * + * This MUST stay in a header, as it checks for -DMODULE + */ + +static inline int pnpbios_module_init(struct pnpbios_driver *drv) +{ + int rc = pnpbios_register_driver (drv); + + if (rc > 0) + return 0; + + /* iff CONFIG_HOTPLUG and built into kernel, we should + * leave the driver around for future hotplug events. + * For the module case, a hotplug daemon of some sort + * should load a module in response to an insert event. */ +#if defined(CONFIG_HOTPLUG) && !defined(MODULE) + if (rc == 0) + return 0; +#else + if (rc == 0) + rc = -ENODEV; +#endif + + /* if we get here, we need to clean up pci driver instance + * and return some sort of error */ + pnpbios_unregister_driver (drv); + + return rc; +} + +#else /* CONFIG_PNPBIOS */ + +static __inline__ int pnpbios_register_driver(struct pnpbios_driver *drv) +{ + return 0; +} + +static __inline__ void pnpbios_unregister_driver(struct pnpbios_driver *drv) +{ + return; +} + +#endif /* CONFIG_PNPBIOS */ +#endif /* __KERNEL__ */ + +#endif /* _LINUX_PNPBIOS_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/quota.h linux.19pre5-ac1/include/linux/quota.h --- linux.19p5/include/linux/quota.h Thu Apr 4 13:18:18 2002 +++ linux.19pre5-ac1/include/linux/quota.h Tue Mar 26 20:11:14 2002 @@ -40,30 +40,10 @@ #define _LINUX_QUOTA_ #include +#include -/* - * Convert diskblocks to blocks and the other way around. - */ -#define dbtob(num) (num << BLOCK_SIZE_BITS) -#define btodb(num) (num >> BLOCK_SIZE_BITS) - -/* - * Convert count of filesystem blocks to diskquota blocks, meant - * for filesystems where i_blksize != BLOCK_SIZE - */ -#define fs_to_dq_blocks(num, blksize) (((num) * (blksize)) / BLOCK_SIZE) - -/* - * Definitions for disk quotas imposed on the average user - * (big brother finally hits Linux). - * - * The following constants define the amount of time given a user - * before the soft limits are treated as hard limits (usually resulting - * in an allocation failure). The timer is started when the user crosses - * their soft limit, it is reset when they go below their soft limit. - */ -#define MAX_IQ_TIME 604800 /* (7*24*60*60) 1 week */ -#define MAX_DQ_TIME 604800 /* (7*24*60*60) 1 week */ +typedef __kernel_uid32_t qid_t; /* Type in which we store ids in memory */ +typedef __u64 qsize_t; /* Type in which we store size limitations */ #define MAXQUOTAS 2 #define USRQUOTA 0 /* element used for user quotas */ @@ -76,11 +56,33 @@ "user", /* USRQUOTA */ \ "group", /* GRPQUOTA */ \ "undefined", \ -}; +} + +/* + * Definitions of magics and versions of current quota files + */ +#define INITQMAGICS {\ + 0xd9c01f11, /* USRQUOTA */\ + 0xd9c01927 /* GRPQUOTA */\ +} -#define QUOTAFILENAME "quota" +#define INITQVERSIONS {\ + 0, /* USRQUOTA */\ + 0 /* GRPQUOTA */\ +} + +#define QUOTAFILENAME "aquota" #define QUOTAGROUP "staff" +/* Size of blocks in which are counted size limits */ +#define QUOTABLOCK_BITS 10 +#define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS) + +/* Conversion routines from and to quota blocks */ +#define qb2kb(x) ((x) << (QUOTABLOCK_BITS-10)) +#define kb2qb(x) ((x) >> (QUOTABLOCK_BITS-10)) +#define toqb(x) (((x) + QUOTABLOCK_SIZE - 1) >> QUOTABLOCK_BITS) + /* * Command definitions for the 'quotactl' system call. * The commands are broken into a main command defined below @@ -93,43 +95,107 @@ #define Q_QUOTAON 0x0100 /* enable quotas */ #define Q_QUOTAOFF 0x0200 /* disable quotas */ -#define Q_GETQUOTA 0x0300 /* get limits and usage */ -#define Q_SETQUOTA 0x0400 /* set limits and usage */ -#define Q_SETUSE 0x0500 /* set usage */ +/* GETQUOTA, SETQUOTA and SETUSE which were at 0x0300-0x0500 has now other parameteres */ #define Q_SYNC 0x0600 /* sync disk copy of a filesystems quotas */ #define Q_SETQLIM 0x0700 /* set limits */ -#define Q_GETSTATS 0x0800 /* get collected stats */ -#define Q_RSQUASH 0x1000 /* set root_squash option */ +/* GETSTATS at 0x0800 is now longer... */ +#define Q_GETINFO 0x0900 /* get info about quotas - graces, flags... */ +#define Q_SETINFO 0x0A00 /* set info about quotas */ +#define Q_SETGRACE 0x0B00 /* set inode and block grace */ +#define Q_SETFLAGS 0x0C00 /* set flags for quota */ +#define Q_GETQUOTA 0x0D00 /* get limits and usage */ +#define Q_SETQUOTA 0x0E00 /* set limits and usage */ +#define Q_SETUSE 0x0F00 /* set usage */ +/* 0x1000 used by old RSQUASH */ +#define Q_GETSTATS 0x1100 /* get collected stats */ /* * The following structure defines the format of the disk quota file - * (as it appears on disk) - the file is an array of these structures - * indexed by user or group number. + * (as it appears on disk) - the file is a hash table whose entries points + * to blocks of these structures. */ -struct dqblk { - __u32 dqb_bhardlimit; /* absolute limit on disk blks alloc */ - __u32 dqb_bsoftlimit; /* preferred limit on disk blks */ - __u32 dqb_curblocks; /* current block count */ +struct disk_dqblk { + __u32 dqb_id; /* id this quota applies to */ __u32 dqb_ihardlimit; /* absolute limit on allocated inodes */ __u32 dqb_isoftlimit; /* preferred inode limit */ __u32 dqb_curinodes; /* current # allocated inodes */ - time_t dqb_btime; /* time limit for excessive disk use */ - time_t dqb_itime; /* time limit for excessive inode use */ + __u32 dqb_bhardlimit; /* absolute limit on disk space (in QUOTABLOCK_SIZE) */ + __u32 dqb_bsoftlimit; /* preferred limit on disk space (in QUOTABLOCK_SIZE) */ + __u64 dqb_curspace; /* current space occupied (in bytes) */ + __u64 dqb_btime; /* time limit for excessive disk use */ + __u64 dqb_itime; /* time limit for excessive inode use */ +}; + +/* This is in-memory copy of quota block. See meaning of entries above */ +struct mem_dqblk { + unsigned int dqb_ihardlimit; + unsigned int dqb_isoftlimit; + unsigned int dqb_curinodes; + unsigned int dqb_bhardlimit; + unsigned int dqb_bsoftlimit; + qsize_t dqb_curspace; + __kernel_time_t dqb_btime; + __kernel_time_t dqb_itime; }; /* - * Shorthand notation. + * Here are header structures as written on disk and their in-memory copies */ -#define dq_bhardlimit dq_dqb.dqb_bhardlimit -#define dq_bsoftlimit dq_dqb.dqb_bsoftlimit -#define dq_curblocks dq_dqb.dqb_curblocks -#define dq_ihardlimit dq_dqb.dqb_ihardlimit -#define dq_isoftlimit dq_dqb.dqb_isoftlimit -#define dq_curinodes dq_dqb.dqb_curinodes -#define dq_btime dq_dqb.dqb_btime -#define dq_itime dq_dqb.dqb_itime +/* First generic header */ +struct disk_dqheader { + __u32 dqh_magic; /* Magic number identifying file */ + __u32 dqh_version; /* File version */ +}; + +/* Header with type and version specific information */ +struct disk_dqinfo { + __u32 dqi_bgrace; /* Time before block soft limit becomes hard limit */ + __u32 dqi_igrace; /* Time before inode soft limit becomes hard limit */ + __u32 dqi_flags; /* Flags for quotafile (DQF_*) */ + __u32 dqi_blocks; /* Number of blocks in file */ + __u32 dqi_free_blk; /* Number of first free block in the list */ + __u32 dqi_free_entry; /* Number of block with at least one free entry */ +}; -#define dqoff(UID) ((loff_t)((UID) * sizeof (struct dqblk))) +/* Inmemory copy of version specific information */ +struct mem_dqinfo { + unsigned int dqi_bgrace; + unsigned int dqi_igrace; + unsigned int dqi_flags; + unsigned int dqi_blocks; + unsigned int dqi_free_blk; + unsigned int dqi_free_entry; +}; + +/* Flags for version specific files */ +#define DQF_MASK 0x0000 /* Mask for all valid ondisk flags */ + +#ifdef __KERNEL__ +#define DQF_DIRTY 0x0010 /* Is info dirty? */ +extern inline void mark_info_dirty(struct mem_dqinfo *info) +{ + info->dqi_flags |= DQF_DIRTY; +} +#define info_dirty(info) ((info)->dqi_flags & DQF_DIRTY) +#endif +/* + * Structure of header of block with quota structures. It is padded to 16 bytes so + * there will be space for exactly 18 quota-entries in a block + */ +struct disk_dqdbheader { + __u32 dqdh_next_free; /* Number of next block with free entry */ + __u32 dqdh_prev_free; /* Number of previous block with free entry */ + __u16 dqdh_entries; /* Number of valid entries in block */ + __u16 dqdh_pad1; + __u32 dqdh_pad2; +}; + +#define DQINFOOFF sizeof(struct disk_dqheader) /* Offset of info header in file */ +#define DQBLKSIZE_BITS 10 +#define DQBLKSIZE (1 << DQBLKSIZE_BITS) /* Size of block with quota structures */ +#define DQTREEOFF 1 /* Offset of tree in file in blocks */ +#define DQTREEDEPTH 4 /* Depth of quota tree */ +#define DQSTRINBLK ((DQBLKSIZE - sizeof(struct disk_dqdbheader)) / sizeof(struct disk_dqblk)) /* Number of entries in one blocks */ struct dqstats { __u32 lookups; @@ -140,12 +206,12 @@ __u32 allocated_dquots; __u32 free_dquots; __u32 syncs; + __u32 version; }; #ifdef __KERNEL__ extern int nr_dquots, nr_free_dquots; -extern int dquot_root_squash; #define NR_DQHASH 43 /* Just an arbitrary number */ @@ -162,37 +228,57 @@ struct list_head dq_free; /* Free list element */ wait_queue_head_t dq_wait_lock; /* Pointer to waitqueue on dquot lock */ wait_queue_head_t dq_wait_free; /* Pointer to waitqueue for quota to be unused */ - int dq_count; /* Reference count */ + int dq_count; /* Use count */ + int dq_dup_ref; /* Number of duplicated refences */ /* fields after this point are cleared when invalidating */ struct super_block *dq_sb; /* superblock this applies to */ - unsigned int dq_id; /* ID this applies to (uid, gid) */ + qid_t dq_id; /* ID this applies to (uid, gid) */ kdev_t dq_dev; /* Device this applies to */ short dq_type; /* Type of quota */ short dq_flags; /* See DQ_* */ + loff_t dq_off; /* Offset of structure in file (0 for not allocated) */ unsigned long dq_referenced; /* Number of times this dquot was referenced during its lifetime */ - struct dqblk dq_dqb; /* Diskquota usage */ + struct mem_dqblk dq_dqb; /* Diskquota usage */ }; #define NODQUOT (struct dquot *)NULL +#define dq_curspace dq_dqb.dqb_curspace +#define dq_curinodes dq_dqb.dqb_curinodes +#define dq_isoftlimit dq_dqb.dqb_isoftlimit +#define dq_ihardlimit dq_dqb.dqb_ihardlimit +#define dq_bsoftlimit dq_dqb.dqb_bsoftlimit +#define dq_bhardlimit dq_dqb.dqb_bhardlimit +#define dq_itime dq_dqb.dqb_itime +#define dq_btime dq_dqb.dqb_btime + /* * Flags used for set_dqblk. */ -#define SET_QUOTA 0x02 -#define SET_USE 0x04 -#define SET_QLIMIT 0x08 +#define SET_QUOTA 0x01 +#define SET_USE 0x02 +#define SET_QLIMIT 0x04 + +/* + * Flags used for set_info + */ +#define ISET_GRACE 0x01 +#define ISET_FLAGS 0x02 +#define ISET_ALL 0x03 #define QUOTA_OK 0 #define NO_QUOTA 1 +typedef char *dqbuf_t; + #else # /* nodep */ include __BEGIN_DECLS -long quotactl __P ((int, const char *, int, caddr_t)); +long quotactl __P ((int, const char *, qid_t, __kernel_caddr_t)); __END_DECLS #endif /* __KERNEL__ */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/quotaops.h linux.19pre5-ac1/include/linux/quotaops.h --- linux.19p5/include/linux/quotaops.h Thu Apr 4 13:18:20 2002 +++ linux.19pre5-ac1/include/linux/quotaops.h Thu Apr 4 15:46:58 2002 @@ -25,10 +25,10 @@ extern int quota_off(struct super_block *sb, short type); extern int sync_dquots(kdev_t dev, short type); -extern int dquot_alloc_block(struct inode *inode, unsigned long number, char prealloc); +extern int dquot_alloc_space(struct inode *inode, qsize_t number, char prealloc); extern int dquot_alloc_inode(const struct inode *inode, unsigned long number); -extern void dquot_free_block(struct inode *inode, unsigned long number); +extern void dquot_free_space(struct inode *inode, qsize_t number); extern void dquot_free_inode(const struct inode *inode, unsigned long number); extern int dquot_transfer(struct inode *inode, struct iattr *iattr); @@ -40,8 +40,6 @@ static __inline__ void DQUOT_INIT(struct inode *inode) { - if (!inode->i_sb) - BUG(); lock_kernel(); if (sb_any_quota_enabled(inode->i_sb) && !IS_NOQUOTA(inode)) inode->i_sb->dq_op->initialize(inode, -1); @@ -51,58 +49,55 @@ static __inline__ void DQUOT_DROP(struct inode *inode) { lock_kernel(); - if (IS_QUOTAINIT(inode)) { - if (!inode->i_sb) - BUG(); + if (IS_QUOTAINIT(inode)) inode->i_sb->dq_op->drop(inode); /* Ops must be set when there's any quota... */ - } unlock_kernel(); } -static __inline__ int DQUOT_PREALLOC_BLOCK_NODIRTY(struct inode *inode, int nr) +static __inline__ int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr) { lock_kernel(); if (sb_any_quota_enabled(inode->i_sb)) { /* Number of used blocks is updated in alloc_block() */ - if (inode->i_sb->dq_op->alloc_block(inode, fs_to_dq_blocks(nr, inode->i_sb->s_blocksize), 1) == NO_QUOTA) { + if (inode->i_sb->dq_op->alloc_space(inode, nr, 1) == NO_QUOTA) { unlock_kernel(); return 1; } } else - inode->i_blocks += nr << (inode->i_sb->s_blocksize_bits - 9); + inode_add_bytes(inode, nr); unlock_kernel(); return 0; } -static __inline__ int DQUOT_PREALLOC_BLOCK(struct inode *inode, int nr) +static __inline__ int DQUOT_PREALLOC_SPACE(struct inode *inode, qsize_t nr) { int ret; - if (!(ret = DQUOT_PREALLOC_BLOCK_NODIRTY(inode, nr))) + if (!(ret = DQUOT_PREALLOC_SPACE_NODIRTY(inode, nr))) mark_inode_dirty(inode); return ret; } -static __inline__ int DQUOT_ALLOC_BLOCK_NODIRTY(struct inode *inode, int nr) +static __inline__ int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr) { lock_kernel(); if (sb_any_quota_enabled(inode->i_sb)) { /* Number of used blocks is updated in alloc_block() */ - if (inode->i_sb->dq_op->alloc_block(inode, fs_to_dq_blocks(nr, inode->i_sb->s_blocksize), 0) == NO_QUOTA) { + if (inode->i_sb->dq_op->alloc_space(inode, nr, 0) == NO_QUOTA) { unlock_kernel(); return 1; } } else - inode->i_blocks += nr << (inode->i_sb->s_blocksize_bits - 9); + inode_add_bytes(inode, nr); unlock_kernel(); return 0; } -static __inline__ int DQUOT_ALLOC_BLOCK(struct inode *inode, int nr) +static __inline__ int DQUOT_ALLOC_SPACE(struct inode *inode, qsize_t nr) { int ret; - if (!(ret = DQUOT_ALLOC_BLOCK_NODIRTY(inode, nr))) + if (!(ret = DQUOT_ALLOC_SPACE_NODIRTY(inode, nr))) mark_inode_dirty(inode); return ret; } @@ -121,22 +116,22 @@ return 0; } -static __inline__ void DQUOT_FREE_BLOCK_NODIRTY(struct inode *inode, int nr) +static __inline__ void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr) { lock_kernel(); if (sb_any_quota_enabled(inode->i_sb)) - inode->i_sb->dq_op->free_block(inode, fs_to_dq_blocks(nr, inode->i_sb->s_blocksize)); + inode->i_sb->dq_op->free_space(inode, nr); else - inode->i_blocks -= nr << (inode->i_sb->s_blocksize_bits - 9); + inode_sub_bytes(inode, nr); unlock_kernel(); } -static __inline__ void DQUOT_FREE_BLOCK(struct inode *inode, int nr) +static __inline__ void DQUOT_FREE_SPACE(struct inode *inode, qsize_t nr) { - DQUOT_FREE_BLOCK_NODIRTY(inode, nr); + DQUOT_FREE_SPACE_NODIRTY(inode, nr); mark_inode_dirty(inode); } - + static __inline__ void DQUOT_FREE_INODE(struct inode *inode) { lock_kernel(); @@ -174,48 +169,56 @@ #define DQUOT_SYNC(dev) do { } while(0) #define DQUOT_OFF(sb) do { } while(0) #define DQUOT_TRANSFER(inode, iattr) (0) -extern __inline__ int DQUOT_PREALLOC_BLOCK_NODIRTY(struct inode *inode, int nr) +extern __inline__ int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr) { lock_kernel(); - inode->i_blocks += nr << (inode->i_sb->s_blocksize_bits - 9); + inode_add_bytes(inode, nr); unlock_kernel(); return 0; } -extern __inline__ int DQUOT_PREALLOC_BLOCK(struct inode *inode, int nr) +extern __inline__ int DQUOT_PREALLOC_SPACE(struct inode *inode, qsize_t nr) { - DQUOT_PREALLOC_BLOCK_NODIRTY(inode, nr); + DQUOT_PREALLOC_SPACE_NODIRTY(inode, nr); mark_inode_dirty(inode); return 0; } -extern __inline__ int DQUOT_ALLOC_BLOCK_NODIRTY(struct inode *inode, int nr) +extern __inline__ int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr) { lock_kernel(); - inode->i_blocks += nr << (inode->i_sb->s_blocksize_bits - 9); + inode_add_bytes(inode, nr); unlock_kernel(); return 0; } -extern __inline__ int DQUOT_ALLOC_BLOCK(struct inode *inode, int nr) +extern __inline__ int DQUOT_ALLOC_SPACE(struct inode *inode, qsize_t nr) { - DQUOT_ALLOC_BLOCK_NODIRTY(inode, nr); + DQUOT_ALLOC_SPACE_NODIRTY(inode, nr); mark_inode_dirty(inode); return 0; } -extern __inline__ void DQUOT_FREE_BLOCK_NODIRTY(struct inode *inode, int nr) +extern __inline__ void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr) { lock_kernel(); - inode->i_blocks -= nr << (inode->i_sb->s_blocksize_bits - 9); + inode_sub_bytes(inode, nr); unlock_kernel(); } -extern __inline__ void DQUOT_FREE_BLOCK(struct inode *inode, int nr) +extern __inline__ void DQUOT_FREE_SPACE(struct inode *inode, qsize_t nr) { - DQUOT_FREE_BLOCK_NODIRTY(inode, nr); + DQUOT_FREE_SPACE_NODIRTY(inode, nr); mark_inode_dirty(inode); -} +} #endif /* CONFIG_QUOTA */ + +#define DQUOT_ALLOC_BLOCK_NODIRTY(inode, nr) DQUOT_ALLOC_SPACE_NODIRTY((inode), ((qsize_t)(nr)) << (inode)->i_sb->s_blocksize_bits) +#define DQUOT_ALLOC_BLOCK(inode, nr) DQUOT_ALLOC_SPACE((inode), ((qsize_t)(nr)) << (inode)->i_sb->s_blocksize_bits) +#define DQUOT_PREALLOC_BLOCK_NODIRTY(inode, nr) DQUOT_PREALLOC_SPACE_NODIRTY((inode), ((qsize_t)(nr)) << (inode)->i_sb->s_blocksize_bits) +#define DQUOT_PREALLOC_BLOCK(inode, nr) DQUOT_PREALLOC_SPACE((inode), ((qsize_t)(nr)) << (inode)->i_sb->s_blocksize_bits) +#define DQUOT_FREE_BLOCK_NODIRTY(inode, nr) DQUOT_FREE_SPACE_NODIRTY((inode), ((qsize_t)(nr)) << (inode)->i_sb->s_blocksize_bits) +#define DQUOT_FREE_BLOCK(inode, nr) DQUOT_FREE_SPACE((inode), ((qsize_t)(nr)) << (inode)->i_sb->s_blocksize_bits) + #endif /* _LINUX_QUOTAOPS_ */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/sched.h linux.19pre5-ac1/include/linux/sched.h --- linux.19p5/include/linux/sched.h Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/include/linux/sched.h Thu Apr 4 15:46:31 2002 @@ -6,6 +6,7 @@ extern unsigned long event; #include +#include #include #include #include @@ -42,6 +43,7 @@ #define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */ #define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */ #define CLONE_THREAD 0x00010000 /* Same thread group? */ +#define CLONE_NEWNS 0x00020000 /* New namespace group? */ #define CLONE_SIGNAL (CLONE_SIGHAND | CLONE_THREAD) @@ -72,8 +74,9 @@ #define CT_TO_SECS(x) ((x) / HZ) #define CT_TO_USECS(x) (((x) % HZ) * 1000000/HZ) -extern int nr_running, nr_threads; +extern int nr_threads; extern int last_pid; +extern unsigned long nr_running(void); #include #include @@ -116,12 +119,6 @@ #define SCHED_FIFO 1 #define SCHED_RR 2 -/* - * This is an additional bit set when we want to - * yield the CPU for one re-schedule.. - */ -#define SCHED_YIELD 0x10 - struct sched_param { int sched_priority; }; @@ -139,17 +136,23 @@ * a separate lock). */ extern rwlock_t tasklist_lock; -extern spinlock_t runqueue_lock; extern spinlock_t mmlist_lock; +typedef struct task_struct task_t; + extern void sched_init(void); -extern void init_idle(void); +extern void init_idle(task_t *idle, int cpu); extern void show_state(void); extern void cpu_init (void); extern void trap_init(void); extern void update_process_times(int user); -extern void update_one_process(struct task_struct *p, unsigned long user, +extern void update_one_process(task_t *p, unsigned long user, unsigned long system, int cpu); +extern void scheduler_tick(int user_tick, int system); +extern void sched_task_migrated(task_t *p); +extern void smp_migrate_task(int cpu, task_t *task); +extern unsigned long cache_decay_ticks; +extern int set_user(uid_t new_ruid, int dumpclear); #define MAX_SCHEDULE_TIMEOUT LONG_MAX extern signed long FASTCALL(schedule_timeout(signed long timeout)); @@ -166,6 +169,7 @@ */ #define NR_OPEN_DEFAULT BITS_PER_LONG +struct namespace; /* * Open file table structure */ @@ -225,7 +229,7 @@ unsigned long rss, total_vm, locked_vm; unsigned long def_flags; unsigned long cpu_vm_mask; - unsigned long swap_address; + unsigned long rlimit_rss; unsigned dumpable:1; @@ -244,6 +248,7 @@ mmap_sem: __RWSEM_INITIALIZER(name.mmap_sem), \ page_table_lock: SPIN_LOCK_UNLOCKED, \ mmlist: LIST_HEAD_INIT(name.mmlist), \ + rlimit_rss: RLIM_INFINITY, \ } struct signal_struct { @@ -280,6 +285,8 @@ extern struct user_struct root_user; #define INIT_USER (&root_user) +typedef struct prio_array prio_array_t; + struct task_struct { /* * offsets of these are hardcoded elsewhere - touch with care @@ -297,36 +304,25 @@ int lock_depth; /* Lock depth */ -/* - * offset 32 begins here on 32-bit platforms. We keep - * all fields in a single cacheline that are needed for - * the goodness() loop in schedule(). - */ - long counter; - long nice; - unsigned long policy; - struct mm_struct *mm; - int processor; /* - * cpus_runnable is ~0 if the process is not running on any - * CPU. It's (1 << cpu) if it's running on a CPU. This mask - * is updated under the runqueue lock. - * - * To determine whether a process might run on a CPU, this - * mask is AND-ed with cpus_allowed. + * offset 32 begins here on 32-bit platforms. */ - unsigned long cpus_runnable, cpus_allowed; - /* - * (only the 'next' pointer fits into the cacheline, but - * that's just fine.) - */ - struct list_head run_list; - unsigned long sleep_time; + unsigned int cpu; + int prio, static_prio; + list_t run_list; + prio_array_t *array; + + unsigned long sleep_avg; + unsigned long sleep_timestamp; + + unsigned long policy; + unsigned long cpus_allowed; + unsigned int time_slice; + + task_t *next_task, *prev_task; + + struct mm_struct *mm, *active_mm; - struct task_struct *next_task, *prev_task; - struct mm_struct *active_mm; - struct list_head local_pages; - unsigned int allocation_order, nr_local_pages; /* task state */ struct linux_binfmt *binfmt; @@ -347,12 +343,12 @@ * older sibling, respectively. (p->father can be replaced with * p->p_pptr->pid) */ - struct task_struct *p_opptr, *p_pptr, *p_cptr, *p_ysptr, *p_osptr; + task_t *p_opptr, *p_pptr, *p_cptr, *p_ysptr, *p_osptr; struct list_head thread_group; /* PID hash table linkage. */ - struct task_struct *pidhash_next; - struct task_struct **pidhash_pprev; + task_t *pidhash_next; + task_t **pidhash_pprev; wait_queue_head_t wait_chldexit; /* for wait4() */ struct completion *vfork_done; /* for vfork() */ @@ -391,6 +387,8 @@ struct fs_struct *fs; /* open file information */ struct files_struct *files; +/* namespace */ + struct namespace *namespace; /* signal handlers */ spinlock_t sigmask_lock; /* Protects signal and blocked */ struct signal_struct *sig; @@ -448,10 +446,13 @@ */ #define _STK_LIM (8*1024*1024) -#define DEF_COUNTER (10*HZ/100) /* 100 ms time slice */ -#define MAX_COUNTER (20*HZ/100) -#define DEF_NICE (0) +extern void set_cpus_allowed(task_t *p, unsigned long new_mask); +extern void set_user_nice(task_t *p, long nice); +extern int task_prio(task_t *p); +extern int task_nice(task_t *p); +asmlinkage long sys_sched_yield(void); +#define yield() sys_sched_yield() /* * The default (Linux) execution domain. @@ -470,14 +471,14 @@ addr_limit: KERNEL_DS, \ exec_domain: &default_exec_domain, \ lock_depth: -1, \ - counter: DEF_COUNTER, \ - nice: DEF_NICE, \ + prio: 120, \ + static_prio: 120, \ policy: SCHED_OTHER, \ + cpus_allowed: -1, \ mm: NULL, \ active_mm: &init_mm, \ - cpus_runnable: -1, \ - cpus_allowed: -1, \ run_list: LIST_HEAD_INIT(tsk.run_list), \ + time_slice: HZ, \ next_task: &tsk, \ prev_task: &tsk, \ p_opptr: &tsk, \ @@ -511,24 +512,24 @@ #endif union task_union { - struct task_struct task; + task_t task; unsigned long stack[INIT_TASK_SIZE/sizeof(long)]; }; extern union task_union init_task_union; extern struct mm_struct init_mm; -extern struct task_struct *init_tasks[NR_CPUS]; +extern task_t *init_tasks[NR_CPUS]; /* PID hashing. (shouldnt this be dynamic?) */ #define PIDHASH_SZ (4096 >> 2) -extern struct task_struct *pidhash[PIDHASH_SZ]; +extern task_t *pidhash[PIDHASH_SZ]; #define pid_hashfn(x) ((((x) >> 8) ^ (x)) & (PIDHASH_SZ - 1)) -static inline void hash_pid(struct task_struct *p) +static inline void hash_pid(task_t *p) { - struct task_struct **htable = &pidhash[pid_hashfn(p->pid)]; + task_t **htable = &pidhash[pid_hashfn(p->pid)]; if((p->pidhash_next = *htable) != NULL) (*htable)->pidhash_pprev = &p->pidhash_next; @@ -536,16 +537,16 @@ p->pidhash_pprev = htable; } -static inline void unhash_pid(struct task_struct *p) +static inline void unhash_pid(task_t *p) { if(p->pidhash_next) p->pidhash_next->pidhash_pprev = p->pidhash_pprev; *p->pidhash_pprev = p->pidhash_next; } -static inline struct task_struct *find_task_by_pid(int pid) +static inline task_t *find_task_by_pid(int pid) { - struct task_struct *p, **htable = &pidhash[pid_hashfn(pid)]; + task_t *p, **htable = &pidhash[pid_hashfn(pid)]; for(p = *htable; p && p->pid != pid; p = p->pidhash_next) ; @@ -553,19 +554,6 @@ return p; } -#define task_has_cpu(tsk) ((tsk)->cpus_runnable != ~0UL) - -static inline void task_set_cpu(struct task_struct *tsk, unsigned int cpu) -{ - tsk->processor = cpu; - tsk->cpus_runnable = 1UL << cpu; -} - -static inline void task_release_cpu(struct task_struct *tsk) -{ - tsk->cpus_runnable = ~0UL; -} - /* per-UID process charging. */ extern struct user_struct * alloc_uid(uid_t); extern void free_uid(struct user_struct *); @@ -592,7 +580,9 @@ extern void FASTCALL(interruptible_sleep_on(wait_queue_head_t *q)); extern long FASTCALL(interruptible_sleep_on_timeout(wait_queue_head_t *q, signed long timeout)); -extern int FASTCALL(wake_up_process(struct task_struct * tsk)); +extern int FASTCALL(wake_up_process(task_t * tsk)); +extern void FASTCALL(wake_up_forked_process(task_t * tsk)); +extern void FASTCALL(sched_exit(task_t * p)); #define wake_up(x) __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1) #define wake_up_nr(x, nr) __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, nr) @@ -610,29 +600,29 @@ extern int in_egroup_p(gid_t); extern void proc_caches_init(void); -extern void flush_signals(struct task_struct *); -extern void flush_signal_handlers(struct task_struct *); +extern void flush_signals(task_t *); +extern void flush_signal_handlers(task_t *); extern void sig_exit(int, int, struct siginfo *); extern int dequeue_signal(sigset_t *, siginfo_t *); extern void block_all_signals(int (*notifier)(void *priv), void *priv, sigset_t *mask); extern void unblock_all_signals(void); -extern int send_sig_info(int, struct siginfo *, struct task_struct *); -extern int force_sig_info(int, struct siginfo *, struct task_struct *); +extern int send_sig_info(int, struct siginfo *, task_t *); +extern int force_sig_info(int, struct siginfo *, task_t *); extern int kill_pg_info(int, struct siginfo *, pid_t); extern int kill_sl_info(int, struct siginfo *, pid_t); extern int kill_proc_info(int, struct siginfo *, pid_t); -extern void notify_parent(struct task_struct *, int); -extern void do_notify_parent(struct task_struct *, int); -extern void force_sig(int, struct task_struct *); -extern int send_sig(int, struct task_struct *, int); +extern void notify_parent(task_t *, int); +extern void do_notify_parent(task_t *, int); +extern void force_sig(int, task_t *); +extern int send_sig(int, task_t *, int); extern int kill_pg(pid_t, int, int); extern int kill_sl(pid_t, int, int); extern int kill_proc(pid_t, int, int); extern int do_sigaction(int, const struct k_sigaction *, struct k_sigaction *); extern int do_sigaltstack(const stack_t *, stack_t *, unsigned long); -static inline int signal_pending(struct task_struct *p) +static inline int signal_pending(task_t *p) { return (p->sigpending != 0); } @@ -671,7 +661,7 @@ This is required every time the blocked sigset_t changes. All callers should have t->sigmask_lock. */ -static inline void recalc_sigpending(struct task_struct *t) +static inline void recalc_sigpending(task_t *t) { t->sigpending = has_pending_signals(&t->pending.signal, &t->blocked); } @@ -778,16 +768,17 @@ extern int expand_fdset(struct files_struct *, int nr); extern void free_fdset(fd_set *, int); -extern int copy_thread(int, unsigned long, unsigned long, unsigned long, struct task_struct *, struct pt_regs *); +extern int copy_thread(int, unsigned long, unsigned long, unsigned long, task_t *, struct pt_regs *); extern void flush_thread(void); extern void exit_thread(void); -extern void exit_mm(struct task_struct *); -extern void exit_files(struct task_struct *); -extern void exit_sighand(struct task_struct *); +extern void exit_mm(task_t *); +extern void exit_files(task_t *); +extern void exit_sighand(task_t *); extern void reparent_to_init(void); extern void daemonize(void); +extern task_t *child_reaper; extern int do_execve(char *, char **, char **, struct pt_regs *); extern int do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long); @@ -796,6 +787,9 @@ extern void FASTCALL(add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait)); extern void FASTCALL(remove_wait_queue(wait_queue_head_t *q, wait_queue_t * wait)); +extern void wait_task_inactive(task_t * p); +extern void kick_if_running(task_t * p); + #define __wait_event(wq, condition) \ do { \ wait_queue_t __wait; \ @@ -877,26 +871,12 @@ for (task = next_thread(current) ; task != current ; task = next_thread(task)) #define next_thread(p) \ - list_entry((p)->thread_group.next, struct task_struct, thread_group) + list_entry((p)->thread_group.next, task_t, thread_group) #define thread_group_leader(p) (p->pid == p->tgid) -static inline void del_from_runqueue(struct task_struct * p) -{ - nr_running--; - p->sleep_time = jiffies; - list_del(&p->run_list); - p->run_list.next = NULL; -} - -static inline int task_on_runqueue(struct task_struct *p) -{ - return (p->run_list.next != NULL); -} - -static inline void unhash_process(struct task_struct *p) +static inline void unhash_process(task_t *p) { - if (task_on_runqueue(p)) BUG(); write_lock_irq(&tasklist_lock); nr_threads--; unhash_pid(p); @@ -906,12 +886,12 @@ } /* Protects ->fs, ->files, ->mm, and synchronises with wait4(). Nests inside tasklist_lock */ -static inline void task_lock(struct task_struct *p) +static inline void task_lock(task_t *p) { spin_lock(&p->alloc_lock); } -static inline void task_unlock(struct task_struct *p) +static inline void task_unlock(task_t *p) { spin_unlock(&p->alloc_lock); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/serialP.h linux.19pre5-ac1/include/linux/serialP.h --- linux.19p5/include/linux/serialP.h Thu Apr 4 13:18:19 2002 +++ linux.19pre5-ac1/include/linux/serialP.h Thu Apr 4 15:51:04 2002 @@ -83,6 +83,7 @@ long pgrp; /* pgrp of opening process */ struct circ_buf xmit; spinlock_t xmit_lock; + spinlock_t irq_spinlock; u8 *iomem_base; u16 iomem_reg_shift; int io_type; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/skbuff.h linux.19pre5-ac1/include/linux/skbuff.h --- linux.19p5/include/linux/skbuff.h Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/include/linux/skbuff.h Thu Apr 4 15:46:45 2002 @@ -825,8 +825,6 @@ static inline char *__skb_pull(struct sk_buff *skb, unsigned int len) { skb->len-=len; - if (skb->len < skb->data_len) - BUG(); return skb->data+=len; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/slab.h linux.19pre5-ac1/include/linux/slab.h --- linux.19p5/include/linux/slab.h Thu Apr 4 13:18:18 2002 +++ linux.19pre5-ac1/include/linux/slab.h Thu Apr 4 15:46:31 2002 @@ -55,6 +55,7 @@ void (*)(void *, kmem_cache_t *, unsigned long)); extern int kmem_cache_destroy(kmem_cache_t *); extern int kmem_cache_shrink(kmem_cache_t *); +extern int kmem_cache_shrink_nr(kmem_cache_t *); extern void *kmem_cache_alloc(kmem_cache_t *, int); extern void kmem_cache_free(kmem_cache_t *, void *); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/smp.h linux.19pre5-ac1/include/linux/smp.h --- linux.19p5/include/linux/smp.h Thu Apr 4 13:18:18 2002 +++ linux.19pre5-ac1/include/linux/smp.h Thu Apr 4 15:46:31 2002 @@ -86,6 +86,14 @@ #define cpu_number_map(cpu) 0 #define smp_call_function(func,info,retry,wait) ({ 0; }) #define cpu_online_map 1 +static inline void smp_send_reschedule(int cpu) { } +static inline void smp_send_reschedule_all(void) { } #endif + +/* + * Common definitions: + */ +#define cpu() smp_processor_id() + #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/sunrpc/sched.h linux.19pre5-ac1/include/linux/sunrpc/sched.h --- linux.19p5/include/linux/sunrpc/sched.h Thu Apr 4 13:18:18 2002 +++ linux.19pre5-ac1/include/linux/sunrpc/sched.h Thu Apr 4 15:46:33 2002 @@ -34,13 +34,11 @@ * This is the RPC task struct */ struct rpc_task { - struct rpc_task * tk_prev; /* wait queue links */ - struct rpc_task * tk_next; + struct list_head tk_list; /* wait queue links */ #ifdef RPC_DEBUG unsigned long tk_magic; /* 0xf00baa */ #endif - struct rpc_task * tk_next_task; /* global list of tasks */ - struct rpc_task * tk_prev_task; /* global list of tasks */ + struct list_head tk_task; /* global list of tasks */ struct rpc_clnt * tk_client; /* RPC client */ struct rpc_rqst * tk_rqstp; /* RPC request */ int tk_status; /* result of last operation */ @@ -88,6 +86,20 @@ #define tk_auth tk_client->cl_auth #define tk_xprt tk_client->cl_xprt +/* support walking a list of tasks on a wait queue */ +#define task_for_each(task, pos, head) \ + list_for_each(pos, head) \ + if ((task=list_entry(pos, struct rpc_task, tk_list)),1) + +#define task_for_first(task, head) \ + if (!list_empty(head) && \ + ((task=list_entry((head)->next, struct rpc_task, tk_list)),1)) + +/* .. and walking list of all tasks */ +#define alltask_for_each(task, pos, head) \ + list_for_each(pos, head) \ + if ((task=list_entry(pos, struct rpc_task, tk_task)),1) + typedef void (*rpc_action)(struct rpc_task *); /* @@ -133,16 +145,24 @@ * RPC synchronization objects */ struct rpc_wait_queue { - struct rpc_task * task; + struct list_head tasks; #ifdef RPC_DEBUG char * name; #endif }; #ifndef RPC_DEBUG -# define RPC_INIT_WAITQ(name) ((struct rpc_wait_queue) { NULL }) +# define RPC_WAITQ_INIT(var,qname) ((struct rpc_wait_queue) {LIST_HEAD_INIT(var)}) +# define RPC_WAITQ(var,qname) struct rpc_wait_queue var = RPC_WAITQ_INIT(var.tasks,qname) +# define INIT_RPC_WAITQ(ptr,qname) do { \ + INIT_LIST_HEAD(&(ptr)->tasks); \ + } while(0) #else -# define RPC_INIT_WAITQ(name) ((struct rpc_wait_queue) { NULL, name }) +# define RPC_WAITQ_INIT(var,qname) ((struct rpc_wait_queue) {LIST_HEAD_INIT(var.tasks), qname}) +# define RPC_WAITQ(var,qname) struct rpc_wait_queue var = RPC_WAITQ_INIT(var,qname) +# define INIT_RPC_WAITQ(ptr,qname) do { \ + INIT_LIST_HEAD(&(ptr)->tasks); (ptr)->name = qname; \ + } while(0) #endif /* diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/sunrpc/svc.h linux.19pre5-ac1/include/linux/sunrpc/svc.h --- linux.19p5/include/linux/sunrpc/svc.h Thu Apr 4 13:18:18 2002 +++ linux.19pre5-ac1/include/linux/sunrpc/svc.h Thu Apr 4 16:04:25 2002 @@ -26,8 +26,8 @@ * We currently do not support more than one RPC program per daemon. */ struct svc_serv { - struct svc_rqst * sv_threads; /* idle server threads */ - struct svc_sock * sv_sockets; /* pending sockets */ + struct list_head sv_threads; /* idle server threads */ + struct list_head sv_sockets; /* pending sockets */ struct svc_program * sv_program; /* RPC program */ struct svc_stat * sv_stats; /* RPC statistics */ spinlock_t sv_lock; @@ -35,7 +35,9 @@ unsigned int sv_bufsz; /* datagram buffer size */ unsigned int sv_xdrsize; /* XDR buffer size */ - struct svc_sock * sv_allsocks; /* all sockets */ + struct list_head sv_permsocks; /* all permanent sockets */ + struct list_head sv_tempsocks; /* all temporary sockets */ + int sv_tmpcnt; /* count of temporary sockets */ char * sv_name; /* service name */ }; @@ -88,8 +90,7 @@ * NOTE: First two items must be prev/next. */ struct svc_rqst { - struct svc_rqst * rq_prev; /* idle list */ - struct svc_rqst * rq_next; + struct list_head rq_list; /* idle list */ struct svc_sock * rq_sock; /* socket */ struct sockaddr_in rq_addr; /* peer address */ int rq_addrlen; @@ -114,9 +115,17 @@ void * rq_argp; /* decoded arguments */ void * rq_resp; /* xdr'd results */ + int rq_reserved; /* space on socket outq + * reserved for this request + */ + /* Catering to nfsd */ struct svc_client * rq_client; /* RPC peer info */ struct svc_cacherep * rq_cacherep; /* cache info */ + struct knfsd_fh * rq_reffh; /* Referrence filehandle, used to + * determine what device number + * to report (real or virtual) + */ wait_queue_head_t rq_wait; /* synchronozation */ }; @@ -162,6 +171,7 @@ unsigned int pc_ressize; /* result struct size */ unsigned int pc_count; /* call count */ unsigned int pc_cachetype; /* cache info (NFS) */ + unsigned int pc_xdrressize; /* maximum size of XDR reply */ }; /* @@ -179,5 +189,6 @@ int svc_process(struct svc_serv *, struct svc_rqst *); int svc_register(struct svc_serv *, int, unsigned short); void svc_wake_up(struct svc_serv *); +void svc_reserve(struct svc_rqst *rqstp, int space); #endif /* SUNRPC_SVC_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/sunrpc/svcsock.h linux.19pre5-ac1/include/linux/sunrpc/svcsock.h --- linux.19p5/include/linux/sunrpc/svcsock.h Thu Apr 4 13:18:18 2002 +++ linux.19pre5-ac1/include/linux/sunrpc/svcsock.h Thu Apr 4 16:04:27 2002 @@ -13,38 +13,38 @@ /* * RPC server socket. - * NOTE: First two items must be prev/next. */ struct svc_sock { - struct svc_sock * sk_prev; /* list of ready sockets */ - struct svc_sock * sk_next; - struct svc_sock * sk_list; /* list of all sockets */ + struct list_head sk_ready; /* list of ready sockets */ + struct list_head sk_list; /* list of all sockets */ struct socket * sk_sock; /* berkeley socket layer */ struct sock * sk_sk; /* INET layer */ - spinlock_t sk_lock; struct svc_serv * sk_server; /* service for this socket */ unsigned char sk_inuse; /* use count */ - unsigned char sk_busy; /* enqueued/receiving */ - unsigned char sk_conn; /* conn pending */ - unsigned char sk_close; /* dead or dying */ - int sk_data; /* data pending */ - unsigned int sk_temp : 1, /* temp socket */ - sk_qued : 1, /* on serv->sk_sockets */ - sk_dead : 1; /* socket closed */ + unsigned int sk_flags; +#define SK_BUSY 0 /* enqueued/receiving */ +#define SK_CONN 1 /* conn pending */ +#define SK_CLOSE 2 /* dead or dying */ +#define SK_DATA 3 /* data pending */ +#define SK_TEMP 4 /* temp (TCP) socket */ +#define SK_QUED 5 /* on serv->sk_sockets */ +#define SK_DEAD 6 /* socket closed */ + + int sk_reserved; /* space on outq that is reserved */ + int (*sk_recvfrom)(struct svc_rqst *rqstp); int (*sk_sendto)(struct svc_rqst *rqstp); /* We keep the old state_change and data_ready CB's here */ void (*sk_ostate)(struct sock *); void (*sk_odata)(struct sock *, int bytes); + void (*sk_owspace)(struct sock *); /* private TCP part */ int sk_reclen; /* length of record */ int sk_tcplen; /* current read length */ - - /* Debugging */ - struct svc_rqst * sk_rqstp; + time_t sk_lastrecv; /* time of last received request */ }; /* @@ -55,5 +55,6 @@ int svc_recv(struct svc_serv *, struct svc_rqst *, long); int svc_send(struct svc_rqst *); void svc_drop(struct svc_rqst *); +void svc_sock_update_bufs(struct svc_serv *serv); #endif /* SUNRPC_SVCSOCK_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/sunrpc/types.h linux.19pre5-ac1/include/linux/sunrpc/types.h --- linux.19p5/include/linux/sunrpc/types.h Thu Apr 4 13:18:18 2002 +++ linux.19pre5-ac1/include/linux/sunrpc/types.h Thu Apr 4 15:46:33 2002 @@ -12,60 +12,7 @@ #include #include #include - -/* - * These are the RPC list manipulation primitives used everywhere. - */ -struct rpc_listitem { - struct rpc_listitem * prev; - struct rpc_listitem * next; -}; - -static __inline__ void -__rpc_append_list(struct rpc_listitem **q, struct rpc_listitem *item) -{ - struct rpc_listitem *next, *prev; - - if (!(next = *q)) { - *q = item->next = item->prev = item; - } else { - prev = next->prev; - prev->next = item; - next->prev = item; - item->next = next; - item->prev = prev; - } -} - -static __inline__ void -__rpc_insert_list(struct rpc_listitem **q, struct rpc_listitem *item) -{ - __rpc_append_list(q, item); - *q = item; -} - -static __inline__ void -__rpc_remove_list(struct rpc_listitem **q, struct rpc_listitem *item) -{ - struct rpc_listitem *prev = item->prev, - *next = item->next; - - if (item != prev) { - next->prev = prev; - prev->next = next; - } else { - next = NULL; - } - if (*q == item) - *q = next; -} - -#define rpc_insert_list(q, i) \ - __rpc_insert_list((struct rpc_listitem **) q, (struct rpc_listitem *) i) -#define rpc_append_list(q, i) \ - __rpc_append_list((struct rpc_listitem **) q, (struct rpc_listitem *) i) -#define rpc_remove_list(q, i) \ - __rpc_remove_list((struct rpc_listitem **) q, (struct rpc_listitem *) i) +#include /* * Shorthands diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/swap.h linux.19pre5-ac1/include/linux/swap.h --- linux.19p5/include/linux/swap.h Thu Apr 4 13:18:17 2002 +++ linux.19pre5-ac1/include/linux/swap.h Thu Apr 4 15:46:31 2002 @@ -86,8 +86,8 @@ extern unsigned int nr_free_pages(void); extern unsigned int nr_free_buffer_pages(void); extern int nr_active_pages; -extern int nr_inactive_pages; -extern atomic_t nr_async_pages; +extern int nr_inactive_dirty_pages; +extern int nr_inactive_clean_pages; extern atomic_t page_cache_size; extern atomic_t buffermem_pages; extern spinlock_t pagecache_lock; @@ -100,18 +100,39 @@ struct zone_t; +/* linux/mm/rmap.c */ +extern int FASTCALL(page_referenced(struct page *)); +extern void FASTCALL(page_add_rmap(struct page *, pte_t *)); +extern void FASTCALL(page_remove_rmap(struct page *, pte_t *)); +extern int FASTCALL(try_to_unmap(struct page *)); +extern int FASTCALL(page_over_rsslimit(struct page *)); + +/* return values of try_to_unmap */ +#define SWAP_SUCCESS 0 +#define SWAP_AGAIN 1 +#define SWAP_FAIL 2 +#define SWAP_ERROR 3 + /* linux/mm/swap.c */ +extern int total_swap_pages; extern void FASTCALL(lru_cache_add(struct page *)); extern void FASTCALL(__lru_cache_del(struct page *)); extern void FASTCALL(lru_cache_del(struct page *)); extern void FASTCALL(activate_page(struct page *)); +extern void FASTCALL(activate_page_nolock(struct page *)); +extern void FASTCALL(deactivate_page(struct page *)); +extern void FASTCALL(deactivate_page_nolock(struct page *)); +extern void FASTCALL(drop_page(struct page *)); extern void swap_setup(void); /* linux/mm/vmscan.c */ +extern struct page * FASTCALL(reclaim_page(zone_t *)); extern wait_queue_head_t kswapd_wait; -extern int FASTCALL(try_to_free_pages(zone_t *, unsigned int, unsigned int)); +extern int FASTCALL(try_to_free_pages(unsigned int gfp_mask)); +extern void wakeup_kswapd(unsigned int); +extern void rss_free_pages(unsigned int); /* linux/mm/page_io.c */ extern void rw_swap_page(int, struct page *); @@ -125,6 +146,7 @@ extern void show_swap_cache_info(void); #endif extern int add_to_swap_cache(struct page *, swp_entry_t); +extern int add_to_swap(struct page *); extern void __delete_from_swap_cache(struct page *page); extern void delete_from_swap_cache(struct page *page); extern void free_page_and_swap_cache(struct page *page); @@ -158,7 +180,14 @@ extern spinlock_t pagemap_lru_lock; -extern void FASTCALL(mark_page_accessed(struct page *)); +/* + * Page aging defines. These seem to work great in FreeBSD, + * no need to reinvent the wheel. + */ +#define PAGE_AGE_START 5 +#define PAGE_AGE_ADV 3 +#define PAGE_AGE_DECL 1 +#define PAGE_AGE_MAX 64 /* * List add/del helper macros. These must be called @@ -166,38 +195,12 @@ */ #define DEBUG_LRU_PAGE(page) \ do { \ - if (!PageLRU(page)) \ - BUG(); \ if (PageActive(page)) \ BUG(); \ -} while (0) - -#define add_page_to_active_list(page) \ -do { \ - DEBUG_LRU_PAGE(page); \ - SetPageActive(page); \ - list_add(&(page)->lru, &active_list); \ - nr_active_pages++; \ -} while (0) - -#define add_page_to_inactive_list(page) \ -do { \ - DEBUG_LRU_PAGE(page); \ - list_add(&(page)->lru, &inactive_list); \ - nr_inactive_pages++; \ -} while (0) - -#define del_page_from_active_list(page) \ -do { \ - list_del(&(page)->lru); \ - ClearPageActive(page); \ - nr_active_pages--; \ -} while (0) - -#define del_page_from_inactive_list(page) \ -do { \ - list_del(&(page)->lru); \ - nr_inactive_pages--; \ + if (PageInactiveDirty(page)) \ + BUG(); \ + if (PageInactiveClean(page)) \ + BUG(); \ } while (0) extern spinlock_t swaplock; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/swapctl.h linux.19pre5-ac1/include/linux/swapctl.h --- linux.19p5/include/linux/swapctl.h Thu Apr 4 13:18:18 2002 +++ linux.19pre5-ac1/include/linux/swapctl.h Mon Jan 28 19:33:28 2002 @@ -10,4 +10,13 @@ typedef pager_daemon_v1 pager_daemon_t; extern pager_daemon_t pager_daemon; +typedef struct freepages_v1 +{ + unsigned int min; + unsigned int low; + unsigned int high; +} freepages_v1; +typedef freepages_v1 freepages_t; +extern freepages_t freepages; + #endif /* _LINUX_SWAPCTL_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/trdevice.h linux.19pre5-ac1/include/linux/trdevice.h --- linux.19p5/include/linux/trdevice.h Thu Apr 4 13:18:18 2002 +++ linux.19pre5-ac1/include/linux/trdevice.h Tue Mar 19 19:15:34 2002 @@ -31,6 +31,9 @@ extern int tr_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len); +extern void tr_source_route(struct sk_buff *skb, + struct trh_hdr *trh, + struct net_device *dev); extern int tr_rebuild_header(struct sk_buff *skb); extern unsigned short tr_type_trans(struct sk_buff *skb, struct net_device *dev); extern struct net_device *init_trdev(struct net_device *dev, int sizeof_priv); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/wait.h linux.19pre5-ac1/include/linux/wait.h --- linux.19p5/include/linux/wait.h Thu Apr 4 13:18:17 2002 +++ linux.19pre5-ac1/include/linux/wait.h Thu Apr 4 15:46:31 2002 @@ -58,6 +58,7 @@ # define wq_read_unlock read_unlock # define wq_write_lock_irq write_lock_irq # define wq_write_lock_irqsave write_lock_irqsave +# define wq_write_unlock_irq write_unlock_irq # define wq_write_unlock_irqrestore write_unlock_irqrestore # define wq_write_unlock write_unlock #else @@ -70,6 +71,7 @@ # define wq_read_unlock_irqrestore spin_unlock_irqrestore # define wq_write_lock_irq spin_lock_irq # define wq_write_lock_irqsave spin_lock_irqsave +# define wq_write_unlock_irq spin_unlock_irq # define wq_write_unlock_irqrestore spin_unlock_irqrestore # define wq_write_unlock spin_unlock #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/zconf.h linux.19pre5-ac1/include/linux/zconf.h --- linux.19p5/include/linux/zconf.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/linux/zconf.h Tue Mar 26 20:37:12 2002 @@ -0,0 +1,90 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-1998 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef _ZCONF_H +#define _ZCONF_H + +#if defined(__GNUC__) || defined(__386__) || defined(i386) +# ifndef __32BIT__ +# define __32BIT__ +# endif +#endif + +#if defined(__STDC__) || defined(__cplusplus) +# ifndef STDC +# define STDC +# endif +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# define MAX_MEM_LEVEL 9 +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef FAR +# define FAR +#endif + +typedef unsigned char Byte; /* 8 bits */ +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +typedef Byte FAR Bytef; +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +typedef void FAR *voidpf; +typedef void *voidp; + +#include /* for off_t */ +#include /* for SEEK_* and off_t */ +#define z_off_t off_t + +#endif /* _ZCONF_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/zlib.h linux.19pre5-ac1/include/linux/zlib.h --- linux.19p5/include/linux/zlib.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/linux/zlib.h Sat Mar 9 20:41:06 2002 @@ -0,0 +1,654 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.1.3, July 9th, 1998 + + Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef _ZLIB_H +#define _ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.1.3" + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + void *workspace; /* memory allocated for this stream */ + + int data_type; /* best guess about the data type: ascii or binary */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_PACKET_FLUSH 2 +#define Z_SYNC_FLUSH 3 +#define Z_FULL_FLUSH 4 +#define Z_FINISH 5 +/* Allowed flush values; see deflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_ASCII 1 +#define Z_UNKNOWN 2 +/* Possible values of the data_type field */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlib_zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +ZEXTERN int ZEXPORT zlib_deflate_workspacesize OF((void)); +/* + Returns the number of bytes that needs to be allocated for a per- + stream workspace. A pointer to this number of bytes should be + returned in stream->workspace before calling zlib_deflateInit(). +*/ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT zlib_deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + the compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + 0.1% larger than avail_in plus 12 bytes. If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update data_type if it can make a good guess about + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). +*/ + + +ZEXTERN int ZEXPORT zlib_deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +ZEXTERN int ZEXPORT zlib_inflate_workspacesize OF((void)); +/* + Returns the number of bytes that needs to be allocated for a per- + stream workspace. A pointer to this number of bytes should be + returned in stream->workspace before calling zlib_inflateInit(). +*/ + +/* +ZEXTERN int ZEXPORT zlib_inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, and workspace must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN int ZEXPORT zlib_inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may some + introduce some output latency (reading input without producing any output) + except when forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much + output as possible to the output buffer. The flushing behavior of inflate is + not specified for values of the flush parameter other than Z_SYNC_FLUSH + and Z_FINISH, but the current implementation actually flushes as much output + as possible anyway. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster routine + may be used for the single inflate() call. + + If a preset dictionary is needed at this point (see inflateSetDictionary + below), inflate sets strm-adler to the adler32 checksum of the + dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise + it sets strm->adler to the adler32 checksum of all output produced + so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or + an error code as described below. At the end of the stream, inflate() + checks that its computed adler32 checksum is equal to that saved by the + compressor and returns Z_STREAM_END only if the checksum is correct. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect + adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent + (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if no progress is possible or if there was not + enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR + case, the application may then call inflateSync to look for a good + compression block. +*/ + + +ZEXTERN int ZEXPORT zlib_inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match). Filtered data consists mostly of small values with a + somewhat random distribution. In this case, the compression algorithm is + tuned to compress them better. The effect of Z_FILTERED is to force more + Huffman coding and less string matching; it is somewhat intermediate + between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects + the compression ratio but not the correctness of the compressed output even + if it is not set appropriately. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT zlib_deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. + + Upon return of this function, strm->adler is set to the Adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT zlib_deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT zlib_deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT zlib_deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. If a compressed stream with a larger window size is given as + input, inflate() will return with the error code Z_DATA_ERROR instead of + trying to allocate a larger window. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative + memLevel). msg is set to null if there is no error message. inflateInit2 + does not perform any decompression apart from reading the zlib header if + present: this will be done by inflate(). (So next_in and avail_in may be + modified, but next_out and avail_out are unchanged.) +*/ + +ZEXTERN int ZEXPORT zlib_inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate + if this call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler32 value returned by this call of + inflate. The compressor and decompressor must use exactly the same + dictionary (see deflateSetDictionary). + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT zlib_inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT zlib_inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +extern int ZEXPORT zlib_inflateIncomp OF((z_stream *strm)); +/* + This function adds the data at next_in (avail_in bytes) to the output + history without performing any output. There must be no pending output, + and the decompressor must be expecting to see the start of a block. + Calling this function is equivalent to decompressing a stored block + containing the data at next_in (except that the data is not output). +*/ + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT zlib_deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT zlib_inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT zlib_deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT zlib_inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +#define zlib_deflateInit(strm, level) \ + zlib_deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define zlib_inflateInit(strm) \ + zlib_inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define zlib_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + zlib_deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define zlib_inflateInit2(strm, windowBits) \ + zlib_inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) + + +#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +ZEXTERN const char * ZEXPORT zlib_zError OF((int err)); +ZEXTERN int ZEXPORT zlib_inflateSyncPoint OF((z_streamp z)); +ZEXTERN const uLongf * ZEXPORT zlib_get_crc_table OF((void)); + +#ifdef __cplusplus +} +#endif + +#endif /* _ZLIB_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/zlib_fs.h linux.19pre5-ac1/include/linux/zlib_fs.h --- linux.19p5/include/linux/zlib_fs.h Thu Apr 4 13:18:21 2002 +++ linux.19pre5-ac1/include/linux/zlib_fs.h Thu Jan 1 01:00:00 1970 @@ -1,679 +0,0 @@ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.1.3, July 9th, 1998 - - Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt - (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). -*/ - -#ifndef _ZLIB_H -#define _ZLIB_H - -#include "zconf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ZLIB_VERSION "1.1.3" - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed - data. This version of the library supports only one compression method - (deflation) but other algorithms will be added later and will have the same - stream interface. - - Compression can be done in a single step if the buffers are large - enough (for example if an input file is mmap'ed), or can be done by - repeated calls of the compression function. In the latter case, the - application must provide more input and/or consume the output - (providing more output space) before each call. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never - crash even in case of corrupted input. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); - -struct internal_state; - -typedef struct z_stream_s { - Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total nb of input bytes read so far */ - - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total nb of bytes output so far */ - - char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - void *workspace; /* memory allocated for this stream */ - - int data_type; /* best guess about the data type: ascii or binary */ - uLong adler; /* adler32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - The application must update next_in and avail_in when avail_in has - dropped to zero. It must update next_out and avail_out when avail_out - has dropped to zero. The application must initialize zalloc, zfree and - opaque before calling the init function. All other fields are set by the - compression library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. - - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this - if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, - pointers returned by zalloc for objects of exactly 65536 bytes *must* - have their offset normalized to zero. The default allocation function - provided by this library ensures this (see zutil.c). To reduce memory - requirements and avoid any allocation of 64K objects, at the expense of - compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or - progress reports. After compression, total_in holds the total size of - the uncompressed data and may be saved for use in the decompressor - (particularly if the decompressor wants to decompress everything in - a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -/* Allowed flush values; see deflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative - * values are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_ASCII 1 -#define Z_UNKNOWN 2 -/* Possible values of the data_type field */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - - /* basic functions */ - -ZEXTERN const char * ZEXPORT zlib_fs_zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is - not compatible with the zlib.h header file used by the application. - This check is automatically made by deflateInit and inflateInit. - */ - -/* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. - If zalloc and zfree are set to Z_NULL, deflateInit updates them to - use default allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at - all (the input data is simply copied a block at a time). - Z_DEFAULT_COMPRESSION requests a default compromise between speed and - compression (currently equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if level is not a valid compression level, - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). - msg is set to null if there is no error message. deflateInit does not - perform any compression: this will be done by deflate(). -*/ - - -ZEXTERN int ZEXPORT zlib_fs_deflate OF((z_streamp strm, int flush)); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce some - output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). - Some output may be provided even if flush is not set. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating avail_in or avail_out accordingly; avail_out - should never be zero before the call. The application can consume the - compressed output when it wants, for example when the output buffer is full - (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK - and with zero avail_out, it must be called again after making room in the - output buffer because there might be more output pending. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In particular - avail_in is zero after the call if enough output space has been provided - before the call.) Flushing may degrade compression for some compression - algorithms and so it should be used only when necessary. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - the compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there - was enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the - stream are deflateReset or deflateEnd. - - Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least - 0.1% larger than avail_in plus 12 bytes. If deflate does not return - Z_STREAM_END, then it must be called again as described above. - - deflate() sets strm->adler to the adler32 checksum of all input read - so far (that is, total_in bytes). - - deflate() may update data_type if it can make a good guess about - the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered - binary. This field is only for information purposes and does not affect - the compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible - (for example avail_in or avail_out was zero). -*/ - - -ZEXTERN int ZEXPORT zlib_fs_deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, - msg may be set but then points to a static string (which must not be - deallocated). -*/ - - -ZEXTERN int ZEXPORT zlib_fs_inflate_workspacesize OF((void)); -/* - Returns the number of bytes that needs to be allocated for a per- - stream workspace. A pointer to this number of bytes should be - returned in stream->workspace before calling zlib_fs_inflateInit(). -*/ - -/* -ZEXTERN int ZEXPORT zlib_fs_inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, and workspace must be initialized before by - the caller. If next_in is not Z_NULL and avail_in is large enough (the exact - value depends on the compression method), inflateInit determines the - compression method from the zlib header and allocates all data structures - accordingly; otherwise the allocation will be deferred to the first call of - inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to - use default allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller. msg is set to null if there is no error - message. inflateInit does not perform any decompression apart from reading - the zlib header if present: this will be done by inflate(). (So next_in and - avail_in may be modified, but next_out and avail_out are unchanged.) -*/ - - -ZEXTERN int ZEXPORT zlib_fs_inflate OF((z_streamp strm, int flush)); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may some - introduce some output latency (reading input without producing any output) - except when forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing - will resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there - is no more input data or no more space in the output buffer (see below - about the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating the next_* and avail_* values accordingly. - The application can consume the uncompressed output when it wants, for - example when the output buffer is full (avail_out == 0), or after each - call of inflate(). If inflate returns Z_OK and with zero avail_out, it - must be called again after making room in the output buffer because there - might be more output pending. - - If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much - output as possible to the output buffer. The flushing behavior of inflate is - not specified for values of the flush parameter other than Z_SYNC_FLUSH - and Z_FINISH, but the current implementation actually flushes as much output - as possible anyway. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step - (a single call of inflate), the parameter flush should be set to - Z_FINISH. In this case all pending input is processed and all pending - output is flushed; avail_out must be large enough to hold all the - uncompressed data. (The size of the uncompressed data may have been saved - by the compressor for this purpose.) The next operation on this stream must - be inflateEnd to deallocate the decompression state. The use of Z_FINISH - is never required, but can be used to inform inflate that a faster routine - may be used for the single inflate() call. - - If a preset dictionary is needed at this point (see inflateSetDictionary - below), inflate sets strm-adler to the adler32 checksum of the - dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise - it sets strm->adler to the adler32 checksum of all output produced - so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or - an error code as described below. At the end of the stream, inflate() - checks that its computed adler32 checksum is equal to that saved by the - compressor and returns Z_STREAM_END only if the checksum is correct. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect - adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent - (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if no progress is possible or if there was not - enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR - case, the application may then call inflateSync to look for a good - compression block. -*/ - - -ZEXTERN int ZEXPORT zlib_fs_inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by - the caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but - is slow and reduces compression ratio; memLevel=9 uses maximum memory - for optimal speed. The default value is 8. See zconf.h for total memory - usage as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match). Filtered data consists mostly of small values with a - somewhat random distribution. In this case, the compression algorithm is - tuned to compress them better. The effect of Z_FILTERED is to force more - Huffman coding and less string matching; it is somewhat intermediate - between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects - the compression ratio but not the correctness of the compressed output even - if it is not set appropriately. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid - method). msg is set to null if there is no error message. deflateInit2 does - not perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT zlib_fs_deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. This function must be called - immediately after deflateInit, deflateInit2 or deflateReset, before any - call of deflate. The compressor and decompressor must use exactly the same - dictionary (see inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size in - deflate or deflate2. Thus the strings most likely to be useful should be - put at the end of the dictionary, not at the front. - - Upon return of this function, strm->adler is set to the Adler32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The Adler32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if the compression method is bsort). deflateSetDictionary does not - perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT zlib_fs_deflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and - can consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT zlib_fs_deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, - but does not free and reallocate all the internal compression state. - The stream will keep the same compression level and any other attributes - that may have been set by deflateInit2. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - -ZEXTERN int ZEXPORT zlib_fs_deflateParams OF((z_streamp strm, - int level, - int strategy)); -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2. This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different - strategy. If the compression level is changed, the input available so far - is compressed with the old level (and may be flushed); the new level will - take effect only at the next call of deflate(). - - Before the call of deflateParams, the stream state must be set as for - a call of deflate(), since the currently available input may have to - be compressed and flushed. In particular, strm->avail_out must be non-zero. - - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR - if strm->avail_out was zero. -*/ - -/* -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. If a compressed stream with a larger window size is given as - input, inflate() will return with the error code Z_DATA_ERROR instead of - trying to allocate a larger window. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative - memLevel). msg is set to null if there is no error message. inflateInit2 - does not perform any decompression apart from reading the zlib header if - present: this will be done by inflate(). (So next_in and avail_in may be - modified, but next_out and avail_out are unchanged.) -*/ - -ZEXTERN int ZEXPORT zlib_fs_inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate - if this call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the Adler32 value returned by this call of - inflate. The compressor and decompressor must use exactly the same - dictionary (see deflateSetDictionary). - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect Adler32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int ZEXPORT zlib_fs_inflateSync OF((z_streamp strm)); -/* - Skips invalid compressed data until a full flush point (see above the - description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR - if no more input was provided, Z_DATA_ERROR if no flush point has been found, - or Z_STREAM_ERROR if the stream structure was inconsistent. In the success - case, the application may save the current current value of total_in which - indicates where valid compressed data was found. In the error case, the - application may repeatedly call inflateSync, providing more input each time, - until success or end of the input data. -*/ - -ZEXTERN int ZEXPORT zlib_fs_inflateReset OF((z_streamp strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. - The stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the - compression library. -*/ - -ZEXTERN uLong ZEXPORT zlib_fs_adler32 OF((uLong adler, const Bytef *buf, uInt len)); - -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is NULL, this function returns - the required initial value for the checksum. - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed - much faster. Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -ZEXTERN uLong ZEXPORT zlib_fs_crc32 OF((uLong crc, const Bytef *buf, uInt len)); -/* - Update a running crc with the bytes buf[0..len-1] and return the updated - crc. If buf is NULL, this function returns the required initial value - for the crc. Pre- and post-conditioning (one's complement) is performed - within this function so it shouldn't be done by the application. - Usage example: - - uLong crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ - - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -ZEXTERN int ZEXPORT zlib_fs_deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT zlib_fs_inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT zlib_fs_deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int ZEXPORT zlib_fs_inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -#define zlib_fs_deflateInit(strm, level) \ - zlib_fs_deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) -#define zlib_fs_inflateInit(strm) \ - zlib_fs_inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) -#define zlib_fs_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - zlib_fs_deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, sizeof(z_stream)) -#define zlib_fs_inflateInit2(strm, windowBits) \ - zlib_fs_inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) - - -#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL) - struct internal_state {int dummy;}; /* hack for buggy compilers */ -#endif - -ZEXTERN const char * ZEXPORT zlib_fs_zError OF((int err)); -ZEXTERN int ZEXPORT zlib_fs_inflateSyncPoint OF((z_streamp z)); -ZEXTERN const uLongf * ZEXPORT zlib_fs_get_crc_table OF((void)); - -#ifdef __cplusplus -} -#endif - -#endif /* _ZLIB_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/zutil.h linux.19pre5-ac1/include/linux/zutil.h --- linux.19p5/include/linux/zutil.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/linux/zutil.h Thu Apr 4 16:09:01 2002 @@ -0,0 +1,126 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-1998 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id: zutil.h,v 1.1 2000/01/01 03:32:23 davem Exp $ */ + +#ifndef _Z_UTIL_H +#define _Z_UTIL_H + +#include +#include +#include +#include + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + + /* Common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + + /* functions */ + +typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf, + uInt len)); + + + /* checksum functions */ + +#define BASE 65521L /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* ========================================================================= */ +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ +static inline uLong zlib_adler32(uLong adler, + const Bytef *buf, + uInt len) +{ + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int k; + + if (buf == Z_NULL) return 1L; + + while (len > 0) { + k = len < NMAX ? len : NMAX; + len -= k; + while (k >= 16) { + DO16(buf); + buf += 16; + k -= 16; + } + if (k != 0) do { + s1 += *buf++; + s2 += s1; + } while (--k); + s1 %= BASE; + s2 %= BASE; + } + return (s2 << 16) | s1; +} + +#endif /* _Z_UTIL_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/datalink.h linux.19pre5-ac1/include/net/datalink.h --- linux.19p5/include/net/datalink.h Thu Apr 4 13:18:26 2002 +++ linux.19pre5-ac1/include/net/datalink.h Tue Mar 19 19:15:34 2002 @@ -2,15 +2,24 @@ #define _NET_INET_DATALINK_H_ struct datalink_proto { - unsigned short type_len; - unsigned char type[8]; - const char *string_name; - unsigned short header_length; - int (*rcvfunc)(struct sk_buff *, struct net_device *, - struct packet_type *); - void (*datalink_header)(struct datalink_proto *, struct sk_buff *, - unsigned char *); - struct datalink_proto *next; + unsigned short type_len; + unsigned char type[8]; + const char *string_name; + + union { + struct llc_pinfo *llc; + } ll_pinfo; + + struct llc_sc_info *llc_sc; + struct sock *sock; + + unsigned short header_length; + + int (*rcvfunc)(struct sk_buff *, struct net_device *, + struct packet_type *); + void (*datalink_header)(struct datalink_proto *, struct sk_buff *, + unsigned char *); + struct datalink_proto *next; }; #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_actn.h linux.19pre5-ac1/include/net/llc_actn.h --- linux.19p5/include/net/llc_actn.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/net/llc_actn.h Tue Mar 19 19:15:34 2002 @@ -0,0 +1,48 @@ +#ifndef LLC_ACTN_H +#define LLC_ACTN_H +/* + * Copyright (c) 1997 by Procom Technology,Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +/* Station component state transition actions */ +#define LLC_STATION_AC_START_ACK_TMR 1 +#define LLC_STATION_AC_SET_RETRY_CNT_0 2 +#define LLC_STATION_AC_INC_RETRY_CNT_BY_1 3 +#define LLC_STATION_AC_SET_XID_R_CNT_0 4 +#define LLC_STATION_AC_INC_XID_R_CNT_BY_1 5 +#define LLC_STATION_AC_SEND_NULL_DSAP_XID_C 6 +#define LLC_STATION_AC_SEND_XID_R 7 +#define LLC_STATION_AC_SEND_TEST_R 8 +#define LLC_STATION_AC_REPORT_STATUS 9 + +/* All station state event action functions look like this */ +typedef int (*llc_station_action_t)(struct llc_station *station, + struct llc_station_state_ev *ev); +extern int llc_station_ac_start_ack_timer(struct llc_station *station, + struct llc_station_state_ev *ev); +extern int llc_station_ac_set_retry_cnt_0(struct llc_station *station, + struct llc_station_state_ev *ev); +extern int llc_station_ac_inc_retry_cnt_by_1(struct llc_station *station, + struct llc_station_state_ev *ev); +extern int llc_station_ac_set_xid_r_cnt_0(struct llc_station *station, + struct llc_station_state_ev *ev); +extern int llc_station_ac_inc_xid_r_cnt_by_1(struct llc_station *station, + struct llc_station_state_ev *ev); +extern int llc_station_ac_send_null_dsap_xid_c(struct llc_station *station, + struct llc_station_state_ev *ev); +extern int llc_station_ac_send_xid_r(struct llc_station *station, + struct llc_station_state_ev *ev); +extern int llc_station_ac_send_test_r(struct llc_station *station, + struct llc_station_state_ev *ev); +extern int llc_station_ac_report_status(struct llc_station *station, + struct llc_station_state_ev *ev); +extern int llc_station_ac_report_status(struct llc_station *station, + struct llc_station_state_ev *ev); +#endif /* LLC_ACTN_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_c_ac.h linux.19pre5-ac1/include/net/llc_c_ac.h --- linux.19p5/include/net/llc_c_ac.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/net/llc_c_ac.h Tue Mar 19 19:15:34 2002 @@ -0,0 +1,254 @@ +#ifndef LLC_C_AC_H +#define LLC_C_AC_H +/* + * Copyright (c) 1997 by Procom Technology,Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +/* Connection component state transition actions */ +/* + * Connection state transition actions + * (Fb = F bit; Pb = P bit; Xb = X bit) + */ +#define LLC_CONN_AC_CLR_REMOTE_BUSY 1 +#define LLC_CONN_AC_CONN_IND 2 +#define LLC_CONN_AC_CONN_CONFIRM 3 +#define LLC_CONN_AC_DATA_IND 4 +#define LLC_CONN_AC_DISC_IND 5 +#define LLC_CONN_AC_RESET_IND 6 +#define LLC_CONN_AC_RESET_CONFIRM 7 +#define LLC_CONN_AC_REPORT_STATUS 8 +#define LLC_CONN_AC_CLR_REMOTE_BUSY_IF_Fb_EQ_1 9 +#define LLC_CONN_AC_STOP_REJ_TMR_IF_DATA_FLAG_EQ_2 10 +#define LLC_CONN_AC_SEND_DISC_CMD_Pb_SET_X 11 +#define LLC_CONN_AC_SEND_DM_RSP_Fb_SET_Pb 12 +#define LLC_CONN_AC_SEND_DM_RSP_Fb_SET_1 13 +#define LLC_CONN_AC_SEND_DM_RSP_Fb_SET_F_FLAG 14 +#define LLC_CONN_AC_SEND_FRMR_RSP_Fb_SET_X 15 +#define LLC_CONN_AC_RESEND_FRMR_RSP_Fb_SET_0 16 +#define LLC_CONN_AC_RESEND_FRMR_RSP_Fb_SET_Pb 17 +#define LLC_CONN_AC_SEND_I_CMD_Pb_SET_1 18 +#define LLC_CONN_AC_RESEND_I_CMD_Pb_SET_1 19 +#define LLC_CONN_AC_RESEND_I_CMD_Pb_SET_1_OR_SEND_RR 20 +#define LLC_CONN_AC_SEND_I_XXX_Xb_SET_0 21 +#define LLC_CONN_AC_RESEND_I_XXX_Xb_SET_0 22 +#define LLC_CONN_AC_RESEND_I_XXX_Xb_SET_0_OR_SEND_RR 23 +#define LLC_CONN_AC_RESEND_I_RSP_Fb_SET_1 24 +#define LLC_CONN_AC_SEND_REJ_CMD_Pb_SET_1 25 +#define LLC_CONN_AC_SEND_REJ_RSP_Fb_SET_1 26 +#define LLC_CONN_AC_SEND_REJ_XXX_Xb_SET_0 27 +#define LLC_CONN_AC_SEND_RNR_CMD_Pb_SET_1 28 +#define LLC_CONN_AC_SEND_RNR_RSP_Fb_SET_1 29 +#define LLC_CONN_AC_SEND_RNR_XXX_Xb_SET_0 30 +#define LLC_CONN_AC_SET_REMOTE_BUSY 31 +#define LLC_CONN_AC_OPTIONAL_SEND_RNR_XXX_Xb_SET_0 32 +#define LLC_CONN_AC_SEND_RR_CMD_Pb_SET_1 33 +#define LLC_CONN_AC_SEND_ACK_CMD_Pb_SET_1 34 +#define LLC_CONN_AC_SEND_RR_RSP_Fb_SET_1 35 +#define LLC_CONN_AC_SEND_ACK_RSP_Fb_SET_1 36 +#define LLC_CONN_AC_SEND_RR_XXX_Xb_SET_0 37 +#define LLC_CONN_AC_SEND_ACK_XXX_Xb_SET_0 38 +#define LLC_CONN_AC_SEND_SABME_CMD_Pb_SET_X 39 +#define LLC_CONN_AC_SEND_UA_RSP_Fb_SET_Pb 40 +#define LLC_CONN_AC_SEND_UA_RSP_Fb_SET_F_FLAG 41 +#define LLC_CONN_AC_S_FLAG_SET_0 42 +#define LLC_CONN_AC_S_FLAG_SET_1 43 +#define LLC_CONN_AC_START_P_TMR 44 +#define LLC_CONN_AC_START_ACK_TMR 45 +#define LLC_CONN_AC_START_REJ_TMR 46 +#define LLC_CONN_AC_START_ACK_TMR_IF_NOT_RUNNING 47 +#define LLC_CONN_AC_STOP_ACK_TMR 48 +#define LLC_CONN_AC_STOP_P_TMR 49 +#define LLC_CONN_AC_STOP_REJ_TMR 50 +#define LLC_CONN_AC_STOP_ALL_TMRS 51 +#define LLC_CONN_AC_STOP_OTHER_TMRS 52 +#define LLC_CONN_AC_UPDATE_Nr_RECEIVED 53 +#define LLC_CONN_AC_UPDATE_P_FLAG 54 +#define LLC_CONN_AC_DATA_FLAG_SET_2 55 +#define LLC_CONN_AC_DATA_FLAG_SET_0 56 +#define LLC_CONN_AC_DATA_FLAG_SET_1 57 +#define LLC_CONN_AC_DATA_FLAG_SET_1_IF_DATA_FLAG_EQ_0 58 +#define LLC_CONN_AC_P_FLAG_SET_0 59 +#define LLC_CONN_AC_P_FLAG_SET_P 60 +#define LLC_CONN_AC_REMOTE_BUSY_SET_0 61 +#define LLC_CONN_AC_RETRY_CNT_SET_0 62 +#define LLC_CONN_AC_RETRY_CNT_INC_BY_1 63 +#define LLC_CONN_AC_Vr_SET_0 64 +#define LLC_CONN_AC_Vr_INC_BY_1 65 +#define LLC_CONN_AC_Vs_SET_0 66 +#define LLC_CONN_AC_Vs_SET_Nr 67 +#define LLC_CONN_AC_F_FLAG_SET_P 68 +#define LLC_CONN_AC_STOP_SENDACK_TMR 70 +#define LLC_CONN_AC_START_SENDACK_TMR_IF_NOT_RUNNING 71 + +typedef int (*llc_conn_action_t)(struct sock *sk, struct llc_conn_state_ev *ev); + +extern int llc_conn_ac_clear_remote_busy(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_conn_ind(struct sock *sk, struct llc_conn_state_ev *ev); +extern int llc_conn_ac_conn_confirm(struct sock* sk, struct llc_conn_state_ev *ev); +extern int llc_conn_ac_data_ind(struct sock* sk, struct llc_conn_state_ev *ev); +extern int llc_conn_ac_disc_ind(struct sock* sk, struct llc_conn_state_ev *ev); +extern int llc_conn_ac_rst_ind(struct sock* sk, struct llc_conn_state_ev *ev); +extern int llc_conn_ac_rst_confirm(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_report_status(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_clear_remote_busy_if_f_eq_1(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_disc_cmd_p_set_x(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_dm_rsp_f_set_p(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_dm_rsp_f_set_1(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_dm_rsp_f_set_f_flag(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_i_cmd_p_set_1(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_i_cmd_p_set_0(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_resend_i_cmd_p_set_1(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_resend_i_cmd_p_set_1_or_send_rr(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_i_xxx_x_set_0(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_resend_i_xxx_x_set_0(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_resend_i_rsp_f_set_1(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_rej_cmd_p_set_1(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_rej_rsp_f_set_1(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_rej_xxx_x_set_0(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_set_remote_busy(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_rr_cmd_p_set_1(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_ack_cmd_p_set_1(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_rr_rsp_f_set_1(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_ack_rsp_f_set_1(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_rr_xxx_x_set_0(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_ack_xxx_x_set_0(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_ua_rsp_f_set_f_flag(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_ua_rsp_f_set_p(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_set_s_flag_0(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_set_s_flag_1(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_start_p_timer(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_start_ack_timer(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_start_rej_timer(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_start_ack_tmr_if_not_running(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_stop_ack_timer(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_stop_p_timer(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_stop_rej_timer(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_stop_all_timers(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_stop_other_timers(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_upd_nr_received(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_inc_tx_win_size(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_dec_tx_win_size(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_upd_p_flag(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_set_data_flag_2(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_set_data_flag_0(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_set_data_flag_1(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_set_data_flag_1_if_data_flag_eq_0(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_set_p_flag_0(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_set_p_flag_1(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_set_remote_busy_0(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_set_retry_cnt_0(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_set_cause_flag_0(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_set_cause_flag_1(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_inc_retry_cnt_by_1(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_set_vr_0(struct sock* sk, struct llc_conn_state_ev *ev); +extern int llc_conn_ac_inc_vr_by_1(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_set_vs_0(struct sock* sk, struct llc_conn_state_ev *ev); +extern int llc_conn_ac_set_vs_nr(struct sock* sk, struct llc_conn_state_ev *ev); +extern int llc_conn_ac_rst_vs(struct sock* sk, struct llc_conn_state_ev *ev); +extern int llc_conn_ac_upd_vs(struct sock* sk, struct llc_conn_state_ev *ev); +extern int llc_conn_ac_set_f_flag_p(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_disc(struct sock* sk, struct llc_conn_state_ev *ev); +extern int llc_conn_reset(struct sock* sk, struct llc_conn_state_ev *ev); +extern int llc_conn_ac_disc_confirm(struct sock* sk, struct llc_conn_state_ev *ev); +extern u8 llc_circular_between(u8 a, u8 b, u8 c); +extern int llc_conn_ac_send_ack_if_needed(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_inc_npta_value(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_adjust_npta_by_rr(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_adjust_npta_by_rnr(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_rst_sendack_flag(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_i_rsp_as_ack(struct sock* sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ac_send_i_as_ack(struct sock* sk, + struct llc_conn_state_ev *ev); +#endif /* LLC_C_AC_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_c_ev.h linux.19pre5-ac1/include/net/llc_c_ev.h --- linux.19p5/include/net/llc_c_ev.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/net/llc_c_ev.h Tue Mar 19 19:15:34 2002 @@ -0,0 +1,323 @@ +#ifndef LLC_C_EV_H +#define LLC_C_EV_H +/* + * Copyright (c) 1997 by Procom Technology,Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +/* Connection component state transition event qualifiers */ +/* Types of events (possible values in 'ev->type') */ +#define LLC_CONN_EV_TYPE_SIMPLE 1 +#define LLC_CONN_EV_TYPE_CONDITION 2 +#define LLC_CONN_EV_TYPE_PRIM 3 +#define LLC_CONN_EV_TYPE_PDU 4 /* command/response PDU */ +#define LLC_CONN_EV_TYPE_ACK_TMR 5 +#define LLC_CONN_EV_TYPE_P_TMR 6 +#define LLC_CONN_EV_TYPE_REJ_TMR 7 +#define LLC_CONN_EV_TYPE_BUSY_TMR 8 +#define LLC_CONN_EV_TYPE_RPT_STATUS 9 +#define LLC_CONN_EV_TYPE_SENDACK_TMR 10 + +#define NBR_CONN_EV 5 +/* Connection events which cause state transitions when fully qualified */ + +#define LLC_CONN_EV_CONN_REQ 1 +#define LLC_CONN_EV_CONN_RESP 2 +#define LLC_CONN_EV_DATA_REQ 3 +#define LLC_CONN_EV_DISC_REQ 4 +#define LLC_CONN_EV_RESET_REQ 5 +#define LLC_CONN_EV_RESET_RESP 6 +#define LLC_CONN_EV_LOCAL_BUSY_DETECTED 7 +#define LLC_CONN_EV_LOCAL_BUSY_CLEARED 8 +#define LLC_CONN_EV_RX_BAD_PDU 9 +#define LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X 10 +#define LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X 11 +#define LLC_CONN_EV_RX_FRMR_RSP_Fbit_SET_X 12 +#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_X 13 +#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_X_UNEXPD_Ns 14 +#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_X_INVAL_Ns 15 +#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_X 16 +#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_X_UNEXPD_Ns 17 +#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_X_INVAL_Ns 18 +#define LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_X 19 +#define LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_X 20 +#define LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_X 21 +#define LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_X 22 +#define LLC_CONN_EV_RX_RR_CMD_Pbit_SET_X 23 +#define LLC_CONN_EV_RX_RR_RSP_Fbit_SET_X 24 +#define LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X 25 +#define LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X 26 +#define LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_X 27 +#define LLC_CONN_EV_RX_XXX_RSP_Fbit_SET_X 28 +#define LLC_CONN_EV_RX_XXX_YYY 29 +#define LLC_CONN_EV_RX_ZZZ_CMD_Pbit_SET_X_INVAL_Nr 30 +#define LLC_CONN_EV_RX_ZZZ_RSP_Fbit_SET_X_INVAL_Nr 31 +#define LLC_CONN_EV_P_TMR_EXP 32 +#define LLC_CONN_EV_ACK_TMR_EXP 33 +#define LLC_CONN_EV_REJ_TMR_EXP 34 +#define LLC_CONN_EV_BUSY_TMR_EXP 35 +#define LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_1 36 +#define LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_0 37 +#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns 38 +#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns 39 +#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_1_UNEXPD_Ns 40 +#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns 41 +#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 42 +#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_0 43 +#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_1 44 +#define LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0 45 +#define LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0 46 +#define LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1 47 +#define LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1 48 +#define LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0 49 +#define LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0 50 +#define LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1 51 +#define LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1 52 +#define LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 53 +#define LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0 54 +#define LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1 55 +#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_1 56 +#define LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_1 57 +#define LLC_CONN_EV_RX_XXX_RSP_Fbit_SET_1 58 +#define LLC_CONN_EV_TX_BUFF_FULL 59 + +#define LLC_CONN_EV_INIT_P_F_CYCLE 100 +/* + * Connection event qualifiers; for some events a certain combination of + * these qualifiers must be TRUE before event recognized valid for state; + * these constants act as indexes into the Event Qualifier function + * table + */ +#define LLC_CONN_EV_QFY_DATA_FLAG_EQ_1 1 +#define LLC_CONN_EV_QFY_DATA_FLAG_EQ_0 2 +#define LLC_CONN_EV_QFY_DATA_FLAG_EQ_2 3 +#define LLC_CONN_EV_QFY_P_FLAG_EQ_1 4 +#define LLC_CONN_EV_QFY_P_FLAG_EQ_0 5 +#define LLC_CONN_EV_QFY_P_FLAG_EQ_Fbit 6 +#define LLC_CONN_EV_QFY_REMOTE_BUSY_EQ_0 7 +#define LLC_CONN_EV_QFY_RETRY_CNT_LT_N2 8 +#define LLC_CONN_EV_QFY_RETRY_CNT_GTE_N2 9 +#define LLC_CONN_EV_QFY_S_FLAG_EQ_1 10 +#define LLC_CONN_EV_QFY_S_FLAG_EQ_0 11 +#define LLC_CONN_EV_QFY_INIT_P_F_CYCLE 12 + +/* Event data interface; what is sent in an event package */ +/* Event LLC_CONN_EV_TYPE_SIMPLE interface */ +struct llc_conn_ev_simple_if { + u8 ev; +}; + +/* Event LLC_CONN_EV_TYPE_PRIM interface */ +struct llc_conn_ev_prim_if { + u8 prim; /* connect, disconnect, reset, ... */ + u8 type; /* request, indicate, response, conf */ + struct llc_prim_if_block *data; +}; + +/* Event LLC_CONN_EV_TYPE_PDU interface */ +struct llc_conn_ev_pdu_if { + u8 ev; + u8 reason; + struct sk_buff *skb; +}; + +/* Event interface for timer-generated events */ +struct llc_conn_ev_tmr_if { + struct sock *sk; + u32 component_handle; + void *timer_specific; +}; + +struct llc_conn_ev_rpt_sts_if { + u8 status; +}; + +union llc_conn_ev_if { + struct llc_conn_ev_simple_if a; /* 'a' for simple, easy ... */ + struct llc_conn_ev_prim_if prim; + struct llc_conn_ev_pdu_if pdu; + struct llc_conn_ev_tmr_if tmr; + struct llc_conn_ev_rpt_sts_if rsts; /* report status */ +}; + +struct llc_conn_state_ev { + u8 type; + u8 status; + u8 flag; + struct llc_prim_if_block *ind_prim; + struct llc_prim_if_block *cfm_prim; + union llc_conn_ev_if data; +}; + +typedef int (*llc_conn_ev_t)(struct sock *sk, struct llc_conn_state_ev *ev); +typedef int (*llc_conn_ev_qfyr_t)(struct sock *sk, + struct llc_conn_state_ev *ev); + +extern int llc_conn_ev_conn_req(struct sock *sk, struct llc_conn_state_ev *ev); +extern int llc_conn_ev_conn_resp(struct sock *sk, struct llc_conn_state_ev *ev); +extern int llc_conn_ev_data_req(struct sock *sk, struct llc_conn_state_ev *ev); +extern int llc_conn_ev_disc_req(struct sock *sk, struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rst_req(struct sock *sk, struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rst_resp(struct sock *sk, struct llc_conn_state_ev *ev); +extern int llc_conn_ev_local_busy_detected(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_local_busy_cleared(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_bad_pdu(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_ua_rsp_fbit_set_x(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_xxx_yyy(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_p_tmr_exp(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_ack_tmr_exp(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rej_tmr_exp(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_busy_tmr_exp(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_any_tmr_exp(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_sendack_tmr_exp(struct sock *sk, + struct llc_conn_state_ev *ev); +/* NOT_USED functions and their variations */ +extern int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_xxx_cmd_pbit_set_0(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_xxx_rsp_fbit_set_1(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_rx_any_frame(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_tx_buffer_full(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_init_p_f_cycle(struct sock *sk, + struct llc_conn_state_ev *ev); + +/* Available connection action qualifiers */ +extern int llc_conn_ev_qlfy_data_flag_eq_1(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_data_flag_eq_0(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_data_flag_eq_2(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_p_flag_eq_1(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_last_frame_eq_1(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_last_frame_eq_0(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_p_flag_eq_0(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_p_flag_eq_f(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_remote_busy_eq_0(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_remote_busy_eq_1(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_retry_cnt_lt_n2(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_retry_cnt_gte_n2(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_s_flag_eq_1(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_s_flag_eq_0(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_cause_flag_eq_1(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_cause_flag_eq_0(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_init_p_f_cycle(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_set_status_conn(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_set_status_disc(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_set_status_failed(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_set_status_impossible(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_set_status_remote_busy(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_set_status_received(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_set_status_refuse(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_set_status_conflict(struct sock *sk, + struct llc_conn_state_ev *ev); +extern int llc_conn_ev_qlfy_set_status_rst_done(struct sock *sk, + struct llc_conn_state_ev *ev); +#endif /* LLC_C_EV_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_c_st.h linux.19pre5-ac1/include/net/llc_c_st.h --- linux.19p5/include/net/llc_c_st.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/net/llc_c_st.h Tue Mar 19 19:15:34 2002 @@ -0,0 +1,48 @@ +#ifndef LLC_C_ST_H +#define LLC_C_ST_H +/* + * Copyright (c) 1997 by Procom Technology,Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +/* Connection component state management */ +/* connection states */ +#define LLC_CONN_OUT_OF_SVC 0 /* prior to allocation */ + +#define LLC_CONN_STATE_ADM 1 /* disc, initial state */ +#define LLC_CONN_STATE_SETUP 2 /* disconnected state */ +#define LLC_CONN_STATE_NORMAL 3 /* connected state */ +#define LLC_CONN_STATE_BUSY 4 /* connected state */ +#define LLC_CONN_STATE_REJ 5 /* connected state */ +#define LLC_CONN_STATE_AWAIT 6 /* connected state */ +#define LLC_CONN_STATE_AWAIT_BUSY 7 /* connected state */ +#define LLC_CONN_STATE_AWAIT_REJ 8 /* connected state */ +#define LLC_CONN_STATE_D_CONN 9 /* disconnected state */ +#define LLC_CONN_STATE_RESET 10 /* disconnected state */ +#define LLC_CONN_STATE_ERROR 11 /* disconnected state */ +#define LLC_CONN_STATE_TEMP 12 /* disconnected state */ + +#define NBR_CONN_STATES 12 /* size of state table */ +#define NO_STATE_CHANGE 100 + +/* Connection state table structure */ +struct llc_conn_state_trans { + llc_conn_ev_t ev; + u8 next_state; + llc_conn_ev_qfyr_t *ev_qualifiers; + llc_conn_action_t *ev_actions; +}; + +struct llc_conn_state { + u8 current_state; + struct llc_conn_state_trans **transitions; +}; + +extern struct llc_conn_state llc_conn_state_table[]; +#endif /* LLC_C_ST_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_conn.h linux.19pre5-ac1/include/net/llc_conn.h --- linux.19p5/include/net/llc_conn.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/net/llc_conn.h Tue Mar 26 20:36:16 2002 @@ -0,0 +1,155 @@ +#ifndef LLC_CONN_H +#define LLC_CONN_H +/* + * Copyright (c) 1997 by Procom Technology, Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +#include +#include + +#undef DEBUG_LLC_CONN_ALLOC + +struct llc_timer { + struct timer_list timer; + u8 running; /* timer is running or no */ + u16 expire; /* timer expire time */ +}; + +struct llc_opt { + struct list_head node; /* entry in sap->sk_list.list */ + struct sock *sk; /* sock that has this llc_opt */ + void *handler; /* for upper layers usage */ + u8 state; /* state of connection */ + struct llc_sap *sap; /* pointer to parent SAP */ + struct llc_addr laddr; /* lsap/mac pair */ + struct llc_addr daddr; /* dsap/mac pair */ + struct net_device *dev; /* device to send to remote */ + u8 retry_count; /* number of retries */ + u8 ack_must_be_send; + u8 first_pdu_Ns; + u8 npta; + struct llc_timer ack_timer; + struct llc_timer pf_cycle_timer; + struct llc_timer rej_sent_timer; + struct llc_timer busy_state_timer; /* ind busy clr at remote LLC */ + u8 vS; /* seq# next in-seq I-PDU tx'd*/ + u8 vR; /* seq# next in-seq I-PDU rx'd*/ + u32 n2; /* max nbr re-tx's for timeout*/ + u32 n1; /* max nbr octets in I PDU */ + u8 k; /* tx window size; max = 127 */ + u8 rw; /* rx window size; max = 127 */ + u8 p_flag; /* state flags */ + u8 f_flag; + u8 s_flag; + u8 data_flag; + u8 remote_busy_flag; + u8 cause_flag; + struct sk_buff_head pdu_unack_q; /* PUDs sent/waiting ack */ + u16 link; /* network layer link number */ + u8 X; /* a temporary variable */ + u8 ack_pf; /* this flag indicates what is + the P-bit of acknowledge */ + u8 failed_data_req; /* recognize that already exist a + failed llc_data_req_handler + (tx_buffer_full or unacceptable + state */ + u8 dec_step; + u8 inc_cntr; + u8 dec_cntr; + u8 connect_step; + u8 last_nr; /* NR of last pdu recieved */ + u32 rx_pdu_hdr; /* used for saving header of last pdu + received and caused sending FRMR. + Used for resending FRMR */ +#ifdef DEBUG_LLC_CONN_ALLOC + char *f_alloc, /* function that allocated this connection */ + *f_free; /* function that freed this connection */ + int l_alloc, /* line that allocated this connection */ + l_free; /* line that freed this connection */ +#endif +}; + +#define llc_sk(__sk) ((struct llc_opt *)(__sk)->protinfo.destruct_hook) + +struct llc_conn_state_ev; + +extern struct sock *__llc_sock_alloc(void); +extern void __llc_sock_free(struct sock *sk, u8 free); + +#ifdef DEBUG_LLC_CONN_ALLOC +#define dump_stack() printk(KERN_INFO "call trace: %p, %p, %p\n", \ + __builtin_return_address(0), \ + __builtin_return_address(1), \ + __builtin_return_address(2)); +#define llc_sock_alloc() ({ \ + struct sock *__sk = __llc_sock_alloc(); \ + if (__sk) { \ + llc_sk(__sk)->f_alloc = __FUNCTION__; \ + llc_sk(__sk)->l_alloc = __LINE__; \ + } \ + __sk;}) +#define __llc_sock_assert(__sk) \ + if (llc_sk(__sk)->f_free) { \ + printk(KERN_ERR \ + "%p conn (alloc'd @ %s(%d)) " \ + "already freed @ %s(%d) " \ + "being used again @ %s(%d)\n", \ + llc_sk(__sk), \ + llc_sk(__sk)->f_alloc, llc_sk(__sk)->l_alloc, \ + llc_sk(__sk)->f_free, llc_sk(__sk)->l_free, \ + __FUNCTION__, __LINE__); \ + dump_stack(); +#define llc_sock_free(__sk) \ +{ \ + __llc_sock_assert(__sk) \ + } else { \ + __llc_sock_free(__sk, 0); \ + llc_sk(__sk)->f_free = __FUNCTION__; \ + llc_sk(__sk)->l_free = __LINE__; \ + } \ +} +#define llc_sock_assert(__sk) \ +{ \ + __llc_sock_assert(__sk); \ + return; } \ +} +#define llc_sock_assert_ret(__sk, __ret) \ +{ \ + __llc_sock_assert(__sk); \ + return __ret; } \ +} +#else /* DEBUG_LLC_CONN_ALLOC */ +#define llc_sock_alloc() __llc_sock_alloc() +#define llc_sock_free(__sk) __llc_sock_free(__sk, 1) +#define llc_sock_assert(__sk) +#define llc_sock_assert_ret(__sk) +#endif /* DEBUG_LLC_CONN_ALLOC */ + +extern void llc_sock_reset(struct sock *sk); +extern int llc_sock_init(struct sock *sk); + +/* Access to a connection */ +extern struct llc_conn_state_ev *llc_conn_alloc_ev(struct sock *sk); +extern int llc_conn_send_ev(struct sock *sk, struct llc_conn_state_ev *ev); +extern void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb); +extern void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb, + struct llc_conn_state_ev *ev); +extern void llc_conn_free_ev(struct llc_conn_state_ev *ev); +extern void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr, + u8 first_p_bit); +extern void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, + u8 first_f_bit); +extern int llc_conn_remove_acked_pdus(struct sock *conn, u8 nr, + u16 *how_many_unacked); +extern struct sock *llc_find_sock(struct llc_sap *sap, struct llc_addr *daddr, + struct llc_addr *laddr); +extern u8 llc_data_accept_state(u8 state); +extern void llc_build_offset_table(void); +#endif /* LLC_CONN_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_evnt.h linux.19pre5-ac1/include/net/llc_evnt.h --- linux.19p5/include/net/llc_evnt.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/net/llc_evnt.h Tue Mar 19 19:15:34 2002 @@ -0,0 +1,93 @@ +#ifndef LLC_EVNT_H +#define LLC_EVNT_H +/* + * Copyright (c) 1997 by Procom Technology,Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +/* Station component state transition events */ +/* Types of events (possible values in 'ev->type') */ +#define LLC_STATION_EV_TYPE_SIMPLE 1 +#define LLC_STATION_EV_TYPE_CONDITION 2 +#define LLC_STATION_EV_TYPE_PRIM 3 +#define LLC_STATION_EV_TYPE_PDU 4 /* command/response PDU */ +#define LLC_STATION_EV_TYPE_ACK_TMR 5 +#define LLC_STATION_EV_TYPE_RPT_STATUS 6 + +/* Events */ +#define LLC_STATION_EV_ENABLE_WITH_DUP_ADDR_CHECK 1 +#define LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK 2 +#define LLC_STATION_EV_ACK_TMR_EXP_LT_RETRY_CNT_MAX_RETRY 3 +#define LLC_STATION_EV_ACK_TMR_EXP_EQ_RETRY_CNT_MAX_RETRY 4 +#define LLC_STATION_EV_RX_NULL_DSAP_XID_C 5 +#define LLC_STATION_EV_RX_NULL_DSAP_0_XID_R_XID_R_CNT_EQ 6 +#define LLC_STATION_EV_RX_NULL_DSAP_1_XID_R_XID_R_CNT_EQ 7 +#define LLC_STATION_EV_RX_NULL_DSAP_TEST_C 8 +#define LLC_STATION_EV_DISABLE_REQ 9 + +/* Interfaces for various types of supported events */ +struct llc_stat_ev_simple_if { + u8 ev; +}; + +struct llc_stat_ev_prim_if { + u8 prim; /* connect, disconnect, reset, ... */ + u8 type; /* request, indicate, response, confirm */ +}; + +struct llc_stat_ev_pdu_if { + u8 reason; + struct sk_buff *skb; +}; + +struct llc_stat_ev_tmr_if { + void *timer_specific; +}; + +struct llc_stat_ev_rpt_sts_if { + u8 status; +}; + +union llc_stat_ev_if { + struct llc_stat_ev_simple_if a; /* 'a' for simple, easy ... */ + struct llc_stat_ev_prim_if prim; + struct llc_stat_ev_pdu_if pdu; + struct llc_stat_ev_tmr_if tmr; + struct llc_stat_ev_rpt_sts_if rsts; /* report status */ +}; + +struct llc_station_state_ev { + u8 type; + union llc_stat_ev_if data; + struct list_head node; /* node in station->ev_q.list */ +}; + +typedef int (*llc_station_ev_t)(struct llc_station *station, + struct llc_station_state_ev *ev); + +extern int llc_stat_ev_enable_with_dup_addr_check(struct llc_station *station, + struct llc_station_state_ev *ev); +extern int llc_stat_ev_enable_without_dup_addr_check(struct llc_station *station, + struct llc_station_state_ev *ev); +extern int llc_stat_ev_ack_tmr_exp_lt_retry_cnt_max_retry(struct llc_station * + station, + struct llc_station_state_ev *ev); +extern int llc_stat_ev_ack_tmr_exp_eq_retry_cnt_max_retry(struct llc_station *station, + struct llc_station_state_ev *ev); +extern int llc_stat_ev_rx_null_dsap_xid_c(struct llc_station *station, + struct llc_station_state_ev *ev); +extern int llc_stat_ev_rx_null_dsap_0_xid_r_xid_r_cnt_eq(struct llc_station *station, + struct llc_station_state_ev *ev); +extern int llc_stat_ev_rx_null_dsap_1_xid_r_xid_r_cnt_eq(struct llc_station *station, + struct llc_station_state_ev *ev); +extern int llc_stat_ev_rx_null_dsap_test_c(struct llc_station *station, + struct llc_station_state_ev *ev); +extern int llc_stat_ev_disable_req(struct llc_station *station, + struct llc_station_state_ev *ev); +#endif /* LLC_EVNT_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_if.h linux.19pre5-ac1/include/net/llc_if.h --- linux.19p5/include/net/llc_if.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/net/llc_if.h Tue Mar 26 20:36:16 2002 @@ -0,0 +1,155 @@ +#ifndef LLC_IF_H +#define LLC_IF_H +/* + * Copyright (c) 1997 by Procom Technology,Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +/* Defines LLC interface to network layer */ +/* Available primitives */ +#include + +#define LLC_DATAUNIT_PRIM 0 +#define LLC_CONN_PRIM 1 +#define LLC_DATA_PRIM 2 +#define LLC_DISC_PRIM 3 +#define LLC_RESET_PRIM 4 +#define LLC_FLOWCONTROL_PRIM 5 +#define LLC_DISABLE_PRIM 6 +#define LLC_XID_PRIM 7 +#define LLC_TEST_PRIM 8 +#define LLC_SAP_ACTIVATION 9 +#define LLC_SAP_DEACTIVATION 10 + +#define LLC_NBR_PRIMITIVES 11 + +#define LLC_IND 1 +#define LLC_CONFIRM 2 + +/* Primitive type */ +#define LLC_PRIM_TYPE_REQ 1 +#define LLC_PRIM_TYPE_IND 2 +#define LLC_PRIM_TYPE_RESP 3 +#define LLC_PRIM_TYPE_CONFIRM 4 + +/* Reset reasons, remote entity or local LLC */ +#define LLC_RESET_REASON_REMOTE 1 +#define LLC_RESET_REASON_LOCAL 2 + +/* Disconnect reasons */ +#define LLC_DISC_REASON_RX_DM_RSP_PDU 0 +#define LLC_DISC_REASON_RX_DISC_CMD_PDU 1 +#define LLC_DISC_REASON_ACK_TMR_EXP 2 + +/* Confirm reasons */ +#define LLC_STATUS_CONN 0 /* connect confirm & reset confirm */ +#define LLC_STATUS_DISC 1 /* connect confirm & reset confirm */ +#define LLC_STATUS_FAILED 2 /* connect confirm & reset confirm */ +#define LLC_STATUS_IMPOSSIBLE 3 /* connect confirm */ +#define LLC_STATUS_RECEIVED 4 /* data conn */ +#define LLC_STATUS_REMOTE_BUSY 5 /* data conn */ +#define LLC_STATUS_REFUSE 6 /* data conn */ +#define LLC_STATUS_CONFLICT 7 /* disconnect conn */ +#define LLC_STATUS_RESET_DONE 8 /* */ + +/* Structures and types */ +/* SAP/MAC Address pair */ +struct llc_addr { + u8 lsap; + u8 mac[IFHWADDRLEN]; +}; + +/* Primitive-specific data */ +struct llc_prim_conn { + struct llc_addr saddr; /* used by request only */ + struct llc_addr daddr; /* used by request only */ + u8 status; /* reason for failure */ + u8 pri; /* service_class */ + struct net_device *dev; + struct sock *sk; /* returned from REQUEST */ + void *handler; /* upper layer use, + stored in llc_opt->handler */ + u16 link; + struct sk_buff *skb; /* received SABME */ +}; + +struct llc_prim_disc { + struct sock *sk; + u16 link; + u8 reason; /* not used by request */ +}; + +struct llc_prim_reset { + struct sock *sk; + u16 link; + u8 reason; /* used only by indicate */ +}; + +struct llc_prim_flow_ctrl { + struct sock *sk; + u16 link; + u32 amount; +}; + +struct llc_prim_data { + struct sock *sk; + u16 link; + u8 pri; + struct sk_buff *skb; /* pointer to frame */ + u8 status; /* reason */ +}; + + /* Sending data in conection-less mode */ +struct llc_prim_unit_data { + struct llc_addr saddr; + struct llc_addr daddr; + u8 pri; + struct sk_buff *skb; /* pointer to frame */ + u8 lfb; /* largest frame bit (TR) */ +}; + +struct llc_prim_xid { + struct llc_addr saddr; + struct llc_addr daddr; + u8 pri; + struct sk_buff *skb; +}; + +struct llc_prim_test { + struct llc_addr saddr; + struct llc_addr daddr; + u8 pri; + struct sk_buff *skb; /* pointer to frame */ +}; + +union llc_u_prim_data { + struct llc_prim_conn conn; + struct llc_prim_disc disc; + struct llc_prim_reset res; + struct llc_prim_flow_ctrl fc; + struct llc_prim_data data; /* data */ + struct llc_prim_unit_data udata; /* unit data */ + struct llc_prim_xid xid; + struct llc_prim_test test; +}; + +struct llc_sap; + +/* Information block passed with all called primitives */ +struct llc_prim_if_block { + struct llc_sap *sap; + u8 prim; + union llc_u_prim_data *data; +}; +typedef int (*llc_prim_call_t)(struct llc_prim_if_block *prim_if); + +extern struct llc_sap *llc_sap_open(llc_prim_call_t network_indicate, + llc_prim_call_t network_confirm, u8 lsap); +extern void llc_sap_close(struct llc_sap *sap); +#endif /* LLC_IF_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_mac.h linux.19pre5-ac1/include/net/llc_mac.h --- linux.19p5/include/net/llc_mac.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/net/llc_mac.h Tue Mar 19 19:15:34 2002 @@ -0,0 +1,23 @@ +#ifndef LLC_MAC_H +#define LLC_MAC_H +/* + * Copyright (c) 1997 by Procom Technology, Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +/* Defines MAC-layer interface to LLC layer */ +extern int mac_send_pdu(struct sk_buff *skb); +extern int mac_indicate(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt); +extern struct net_device *mac_dev_peer(struct net_device *current_dev, + int type, u8 *mac); +extern int llc_pdu_router(struct llc_sap *sap, struct sock *sk, + struct sk_buff *skb, u8 type); +extern u16 lan_hdrs_init(struct sk_buff *skb, u8 *sa, u8 *da); +#endif /* LLC_MAC_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_main.h linux.19pre5-ac1/include/net/llc_main.h --- linux.19p5/include/net/llc_main.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/net/llc_main.h Tue Mar 19 19:15:34 2002 @@ -0,0 +1,68 @@ +#ifndef LLC_MAIN_H +#define LLC_MAIN_H +/* + * Copyright (c) 1997 by Procom Technology, Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +#define LLC_EVENT 1 +#define LLC_PACKET 2 +#define LLC_TYPE_1 1 +#define LLC_TYPE_2 2 +#define LLC_P_TIME 2 +#define LLC_ACK_TIME 3 +#define LLC_REJ_TIME 3 +#define LLC_BUSY_TIME 3 +#define LLC_SENDACK_TIME 50 +#define LLC_DEST_INVALID 0 /* Invalid LLC PDU type */ +#define LLC_DEST_SAP 1 /* Type 1 goes here */ +#define LLC_DEST_CONN 2 /* Type 2 goes here */ + +/* LLC Layer global default parameters */ + +#define LLC_GLOBAL_DEFAULT_MAX_NBR_SAPS 4 +#define LLC_GLOBAL_DEFAULT_MAX_NBR_CONNS 64 + +extern struct llc_prim_if_block llc_ind_prim, llc_cfm_prim; + +/* LLC station component (SAP and connection resource manager) */ +/* Station component; one per adapter */ +struct llc_station { + u8 state; /* state of station */ + u8 xid_r_count; /* XID response PDU counter */ + struct timer_list ack_timer; + u8 ack_tmr_running; /* 1 or 0 */ + u8 retry_count; + u8 maximum_retry; + u8 mac_sa[6]; /* MAC source address */ + struct { + spinlock_t lock; + struct list_head list; + } sap_list; /* list of related SAPs */ + struct { + spinlock_t lock; + struct list_head list; + } ev_q; /* events entering state mach. */ + struct sk_buff_head mac_pdu_q; /* PDUs ready to send to MAC */ +}; +struct llc_station_state_ev; + +extern struct llc_sap *llc_sap_alloc(void); +extern void llc_sap_save(struct llc_sap *sap); +extern void llc_free_sap(struct llc_sap *sap); +extern struct llc_sap *llc_sap_find(u8 lsap); +extern struct llc_station *llc_station_get(void); +extern struct llc_station_state_ev * + llc_station_alloc_ev(struct llc_station *station); +extern void llc_station_send_ev(struct llc_station *station, + struct llc_station_state_ev *ev); +extern void llc_station_send_pdu(struct llc_station *station, + struct sk_buff *skb); +extern struct sk_buff *llc_alloc_frame(void); +#endif /* LLC_MAIN_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_pdu.h linux.19pre5-ac1/include/net/llc_pdu.h --- linux.19p5/include/net/llc_pdu.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/net/llc_pdu.h Tue Mar 19 19:15:34 2002 @@ -0,0 +1,255 @@ +#ifndef LLC_PDU_H +#define LLC_PDU_H +/* + * Copyright (c) 1997 by Procom Technology,Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +/* LLC PDU structure */ +/* Lengths of frame formats */ +#define LLC_PDU_LEN_I 4 /* header and 2 control bytes */ +#define LLC_PDU_LEN_S 4 +#define LLC_PDU_LEN_U 3 /* header and 1 control byte */ +/* Known SAP addresses */ +#define LLC_GLOBAL_SAP 0xFF +#define LLC_NULL_SAP 0x00 /* not network-layer visible */ +#define LLC_MGMT_INDIV 0x02 /* station LLC mgmt indiv addr */ +#define LLC_MGMT_GRP 0x03 /* station LLC mgmt group addr */ +#define LLC_RDE_SAP 0xA6 /* route ... */ + +/* SAP field bit masks */ +#define LLC_ISO_RESERVED_SAP 0x02 +#define LLC_SAP_GROUP_DSAP 0x01 +#define LLC_SAP_RESP_SSAP 0x01 + +/* Group/individual DSAP indicator is DSAP field */ +#define LLC_PDU_GROUP_DSAP_MASK 0x01 +#define LLC_PDU_IS_GROUP_DSAP(pdu) \ + ((pdu->dsap & LLC_PDU_GROUP_DSAP_MASK) ? 0 : 1) +#define LLC_PDU_IS_INDIV_DSAP(pdu) \ + (!(pdu->dsap & LLC_PDU_GROUP_DSAP_MASK) ? 0 : 1) + +/* Command/response PDU indicator in SSAP field */ +#define LLC_PDU_CMD_RSP_MASK 0x01 +#define LLC_PDU_CMD 0 +#define LLC_PDU_RSP 1 +#define LLC_PDU_IS_CMD(pdu) ((pdu->ssap & LLC_PDU_RSP) ? 1 : 0) +#define LLC_PDU_IS_RSP(pdu) ((pdu->ssap & LLC_PDU_RSP) ? 0 : 1) + +/* Get PDU type from 2 lowest-order bits of control field first byte */ +#define LLC_PDU_TYPE_I_MASK 0x01 /* 16-bit control field */ +#define LLC_PDU_TYPE_S_MASK 0x03 +#define LLC_PDU_TYPE_U_MASK 0x03 /* 8-bit control field */ +#define LLC_PDU_TYPE_MASK 0x03 + +#define LLC_PDU_TYPE_I 0 /* first bit */ +#define LLC_PDU_TYPE_S 1 /* first two bits */ +#define LLC_PDU_TYPE_U 3 /* first two bits */ + +#define LLC_PDU_TYPE_IS_I(pdu) \ + ((!(pdu->ctrl_1 & LLC_PDU_TYPE_I_MASK)) ? 0 : 1) + +#define LLC_PDU_TYPE_IS_U(pdu) \ + (((pdu->ctrl_1 & LLC_PDU_TYPE_U_MASK) == LLC_PDU_TYPE_U) ? 0 : 1) + +#define LLC_PDU_TYPE_IS_S(pdu) \ + (((pdu->ctrl_1 & LLC_PDU_TYPE_S_MASK) == LLC_PDU_TYPE_S) ? 0 : 1) + +/* U-format PDU control field masks */ +#define LLC_U_PF_BIT_MASK 0x10 /* P/F bit mask */ +#define LLC_U_PF_IS_1(pdu) ((pdu->ctrl_1 & LLC_U_PF_BIT_MASK) ? 0 : 1) +#define LLC_U_PF_IS_0(pdu) ((!(pdu->ctrl_1 & LLC_U_PF_BIT_MASK)) ? 0 : 1) + +#define LLC_U_PDU_CMD_MASK 0xEC /* cmd/rsp mask */ +#define LLC_U_PDU_CMD(pdu) (pdu->ctrl_1 & LLC_U_PDU_CMD_MASK) +#define LLC_U_PDU_RSP(pdu) (pdu->ctrl_1 & LLC_U_PDU_CMD_MASK) + +#define LLC_1_PDU_CMD_UI 0x00 /* Type 1 cmds/rsps */ +#define LLC_1_PDU_CMD_XID 0xAC +#define LLC_1_PDU_CMD_TEST 0xE0 + +#define LLC_2_PDU_CMD_SABME 0x6C /* Type 2 cmds/rsps */ +#define LLC_2_PDU_CMD_DISC 0x40 +#define LLC_2_PDU_RSP_UA 0x60 +#define LLC_2_PDU_RSP_DM 0x0C +#define LLC_2_PDU_RSP_FRMR 0x84 + +/* Type 1 operations */ + +/* XID information field bit masks */ + +/* LLC format identifier (byte 1) */ +#define LLC_XID_FMT_ID 0x81 /* first byte must be this */ + +/* LLC types/classes identifier (byte 2) */ +#define LLC_XID_CLASS_ZEROS_MASK 0xE0 /* these must be zeros */ +#define LLC_XID_CLASS_MASK 0x1F /* AND with byte to get below */ + +#define LLC_XID_NULL_CLASS_1 0x01 /* if NULL LSAP...use these */ +#define LLC_XID_NULL_CLASS_2 0x03 +#define LLC_XID_NULL_CLASS_3 0x05 +#define LLC_XID_NULL_CLASS_4 0x07 + +#define LLC_XID_NNULL_TYPE_1 0x01 /* if non-NULL LSAP...use these */ +#define LLC_XID_NNULL_TYPE_2 0x02 +#define LLC_XID_NNULL_TYPE_3 0x04 +#define LLC_XID_NNULL_TYPE_1_2 0x03 +#define LLC_XID_NNULL_TYPE_1_3 0x05 +#define LLC_XID_NNULL_TYPE_2_3 0x06 +#define LLC_XID_NNULL_ALL 0x07 + +/* Sender Receive Window (byte 3) */ +#define LLC_XID_RW_MASK 0xFE /* AND with value to get below */ + +#define LLC_XID_MIN_RW 0x02 /* lowest-order bit always zero */ + +/* Type 2 operations */ + +#define LLC_2_SEQ_NBR_MODULO ((u8) 128) + +/* I-PDU masks ('ctrl' is I-PDU control word) */ +#define LLC_I_GET_NS(pdu) (u8)((pdu->ctrl_1 & 0xFE) >> 1) +#define LLC_I_GET_NR(pdu) (u8)((pdu->ctrl_2 & 0xFE) >> 1) + +#define LLC_I_PF_BIT_MASK 0x01 + +#define LLC_I_PF_IS_0(pdu) ((!(pdu->ctrl_2 & LLC_I_PF_BIT_MASK)) ? 0 : 1) +#define LLC_I_PF_IS_1(pdu) ((pdu->ctrl_2 & LLC_I_PF_BIT_MASK) ? 0 : 1) + +/* S-PDU supervisory commands and responses */ + +#define LLC_S_PDU_CMD_MASK 0x0C +#define LLC_S_PDU_CMD(pdu) (pdu->ctrl_1 & LLC_S_PDU_CMD_MASK) +#define LLC_S_PDU_RSP(pdu) (pdu->ctrl_1 & LLC_S_PDU_CMD_MASK) + +#define LLC_2_PDU_CMD_RR 0x00 /* rx ready cmd */ +#define LLC_2_PDU_RSP_RR 0x00 /* rx ready rsp */ +#define LLC_2_PDU_CMD_REJ 0x08 /* reject PDU cmd */ +#define LLC_2_PDU_RSP_REJ 0x08 /* reject PDU rsp */ +#define LLC_2_PDU_CMD_RNR 0x04 /* rx not ready cmd */ +#define LLC_2_PDU_RSP_RNR 0x04 /* rx not ready rsp */ + +#define LLC_S_PF_BIT_MASK 0x01 +#define LLC_S_PF_IS_0(pdu) ((!(pdu->ctrl_2 & LLC_S_PF_BIT_MASK)) ? 0 : 1) +#define LLC_S_PF_IS_1(pdu) ((pdu->ctrl_2 & LLC_S_PF_BIT_MASK) ? 0 : 1) + +#define PDU_SUPV_GET_Nr(pdu) ((pdu->ctrl_2 & 0xFE) >> 1) +#define PDU_GET_NEXT_Vr(sn) (++sn & ~LLC_2_SEQ_NBR_MODULO) + +/* FRMR information field macros */ + +#define FRMR_INFO_LENGTH 5 /* 5 bytes of information */ + +/* + * info is pointer to FRMR info field structure; 'rej_ctrl' is byte pointer + * (if U-PDU) or word pointer to rejected PDU control field + */ +#define FRMR_INFO_SET_REJ_CNTRL(info,rej_ctrl) \ + info->rej_pdu_ctrl = ((*((u8 *) rej_ctrl) & \ + LLC_PDU_TYPE_U) != LLC_PDU_TYPE_U ? \ + (u16)*((u16 *) rej_ctrl) : \ + (((u16) *((u8 *) rej_ctrl)) & 0x00FF)) + +/* + * Info is pointer to FRMR info field structure; 'vs' is a byte containing + * send state variable value in low-order 7 bits (insure the lowest-order + * bit remains zero (0)) + */ +#define FRMR_INFO_SET_Vs(info,vs) (info->curr_ssv = (((u8) vs) << 1)) +#define FRMR_INFO_SET_Vr(info,vr) (info->curr_rsv = (((u8) vr) << 1)) + +/* + * Info is pointer to FRMR info field structure; 'cr' is a byte containing + * the C/R bit value in the low-order bit + */ +#define FRMR_INFO_SET_C_R_BIT(info, cr) (info->curr_rsv |= (((u8) cr) & 0x01)) + +/* + * In the remaining five macros, 'info' is pointer to FRMR info field + * structure; 'ind' is a byte containing the bit value to set in the + * lowest-order bit) + */ +#define FRMR_INFO_SET_INVALID_PDU_CTRL_IND(info, ind) \ + (info->ind_bits = ((info->ind_bits & 0xFE) | (((u8) ind) & 0x01))) + +#define FRMR_INFO_SET_INVALID_PDU_INFO_IND(info, ind) \ + (info->ind_bits = ( (info->ind_bits & 0xFD) | (((u8) ind) & 0x02))) + +#define FRMR_INFO_SET_PDU_INFO_2LONG_IND(info, ind) \ + (info->ind_bits = ( (info->ind_bits & 0xFB) | (((u8) ind) & 0x04))) + +#define FRMR_INFO_SET_PDU_INVALID_Nr_IND(info, ind) \ + (info->ind_bits = ( (info->ind_bits & 0xF7) | (((u8) ind) & 0x08))) + +#define FRMR_INFO_SET_PDU_INVALID_Ns_IND(info, ind) \ + (info->ind_bits = ( (info->ind_bits & 0xEF) | (((u8) ind) & 0x10))) + +/* Sequence-numbered PDU format (4 bytes in length) */ +typedef struct llc_pdu_sn { + u8 dsap; + u8 ssap; + u8 ctrl_1; + u8 ctrl_2; +} llc_pdu_sn_t; + +/* Un-numbered PDU format (3 bytes in length) */ +typedef struct llc_pdu_un { + u8 dsap; + u8 ssap; + u8 ctrl_1; +} llc_pdu_un_t; + +/* LLC Type 1 XID command/response information fields format */ +typedef struct llc_xid_info { + u8 fmt_id; /* always 0x18 for LLC */ + u8 type; /* different if NULL/non-NULL LSAP */ + u8 rw; /* sender receive window */ +} llc_xid_info_t; + +/* LLC Type 2 FRMR response information field format */ +typedef struct llc_frmr_info { + u16 rej_pdu_ctrl; /* bits 1-8 if U-PDU */ + u8 curr_ssv; /* current send state variable val */ + u8 curr_rsv; /* current receive state variable */ + u8 ind_bits; /* indicator bits set with macro */ +} llc_frmr_info_t; + +extern void llc_pdu_set_cmd_rsp(struct sk_buff *skb, u8 type); +extern void llc_pdu_set_pf_bit(struct sk_buff *skb, u8 bit_value); +extern int llc_pdu_decode_pf_bit(struct sk_buff *skb, u8 *pf_bit); +extern int llc_pdu_decode_cr_bit(struct sk_buff *skb, u8 *cr_bit); +extern int llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa); +extern int llc_pdu_decode_da(struct sk_buff *skb, u8 *ds); +extern int llc_pdu_decode_dsap(struct sk_buff *skb, u8 *dsap); +extern int llc_pdu_decode_ssap(struct sk_buff *skb, u8 *ssap); +extern int llc_decode_pdu_type(struct sk_buff *skb, u8 *destination); +extern void llc_pdu_header_init(struct sk_buff *skb, u8 pdu_type, u8 ssap, + u8 dsap, u8 cr); +extern int llc_pdu_init_as_ui_cmd(struct sk_buff *skb); +extern int llc_pdu_init_as_xid_cmd(struct sk_buff *skb, u8 svcs_supported, + u8 rx_window); +extern int llc_pdu_init_as_test_cmd(struct sk_buff *skb); +extern int llc_pdu_init_as_disc_cmd(struct sk_buff *skb, u8 p_bit); +extern int llc_pdu_init_as_i_cmd(struct sk_buff *skb, u8 p_bit, u8 ns, u8 nr); +extern int llc_pdu_init_as_rej_cmd(struct sk_buff *skb, u8 p_bit, u8 nr); +extern int llc_pdu_init_as_rnr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr); +extern int llc_pdu_init_as_rr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr); +extern int llc_pdu_init_as_sabme_cmd(struct sk_buff *skb, u8 p_bit); +extern int llc_pdu_init_as_dm_rsp(struct sk_buff *skb, u8 f_bit); +extern int llc_pdu_init_as_xid_rsp(struct sk_buff *skb, u8 svcs_supported, + u8 rx_window); +extern int llc_pdu_init_as_test_rsp(struct sk_buff *skb, + struct sk_buff *ev_skb); +extern int llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, llc_pdu_sn_t *prev_pdu, + u8 f_bit, u8 vs, u8 vr, u8 vzyxw); +extern int llc_pdu_init_as_rr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr); +extern int llc_pdu_init_as_rej_rsp(struct sk_buff *skb, u8 f_bit, u8 nr); +extern int llc_pdu_init_as_rnr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr); +extern int llc_pdu_init_as_ua_rsp(struct sk_buff *skb, u8 f_bit); +#endif /* LLC_PDU_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_s_ac.h linux.19pre5-ac1/include/net/llc_s_ac.h --- linux.19p5/include/net/llc_s_ac.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/net/llc_s_ac.h Tue Mar 19 19:15:34 2002 @@ -0,0 +1,47 @@ +#ifndef LLC_S_AC_H +#define LLC_S_AC_H +/* + * Copyright (c) 1997 by Procom Technology,Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +/* SAP component actions */ +#define SAP_ACT_UNITDATA_IND 1 +#define SAP_ACT_SEND_UI 2 +#define SAP_ACT_SEND_XID_C 3 +#define SAP_ACT_SEND_XID_R 4 +#define SAP_ACT_SEND_TEST_C 5 +#define SAP_ACT_SEND_TEST_R 6 +#define SAP_ACT_REPORT_STATUS 7 +#define SAP_ACT_XID_IND 8 +#define SAP_ACT_TEST_IND 9 + +/* All action functions must look like this */ +typedef int (*llc_sap_action_t)(struct llc_sap *sap, + struct llc_sap_state_ev *ev); + +extern int llc_sap_action_unitdata_ind(struct llc_sap *sap, + struct llc_sap_state_ev *ev); +extern int llc_sap_action_send_ui(struct llc_sap *sap, + struct llc_sap_state_ev *ev); +extern int llc_sap_action_send_xid_c(struct llc_sap *sap, + struct llc_sap_state_ev *ev); +extern int llc_sap_action_send_xid_r(struct llc_sap *sap, + struct llc_sap_state_ev *ev); +extern int llc_sap_action_send_test_c(struct llc_sap *sap, + struct llc_sap_state_ev *ev); +extern int llc_sap_action_send_test_r(struct llc_sap *sap, + struct llc_sap_state_ev *ev); +extern int llc_sap_action_report_status(struct llc_sap *sap, + struct llc_sap_state_ev *ev); +extern int llc_sap_action_xid_ind(struct llc_sap *sap, + struct llc_sap_state_ev *ev); +extern int llc_sap_action_test_ind(struct llc_sap *sap, + struct llc_sap_state_ev *ev); +#endif /* LLC_S_AC_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_s_ev.h linux.19pre5-ac1/include/net/llc_s_ev.h --- linux.19p5/include/net/llc_s_ev.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/net/llc_s_ev.h Tue Mar 19 19:15:34 2002 @@ -0,0 +1,101 @@ +#ifndef LLC_S_EV_H +#define LLC_S_EV_H +/* + * Copyright (c) 1997 by Procom Technology,Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +/* Defines SAP component events */ +/* Types of events (possible values in 'ev->type') */ +#define LLC_SAP_EV_TYPE_SIMPLE 1 +#define LLC_SAP_EV_TYPE_CONDITION 2 +#define LLC_SAP_EV_TYPE_PRIM 3 +#define LLC_SAP_EV_TYPE_PDU 4 /* command/response PDU */ +#define LLC_SAP_EV_TYPE_ACK_TMR 5 +#define LLC_SAP_EV_TYPE_RPT_STATUS 6 + +#define LLC_SAP_EV_ACTIVATION_REQ 1 +#define LLC_SAP_EV_RX_UI 2 +#define LLC_SAP_EV_UNITDATA_REQ 3 +#define LLC_SAP_EV_XID_REQ 4 +#define LLC_SAP_EV_RX_XID_C 5 +#define LLC_SAP_EV_RX_XID_R 6 +#define LLC_SAP_EV_TEST_REQ 7 +#define LLC_SAP_EV_RX_TEST_C 8 +#define LLC_SAP_EV_RX_TEST_R 9 +#define LLC_SAP_EV_DEACTIVATION_REQ 10 + +/* Interfaces for various types of supported events */ +struct llc_sap_ev_simple_if { + u8 ev; +}; + +struct llc_prim_if_block; + +struct llc_sap_ev_prim_if { + u8 prim; /* connect, disconnect, reset, ... */ + u8 type; /* request, indicate, response, conf */ + struct llc_prim_if_block *data; +}; + +struct llc_sap_ev_pdu_if { + u8 ev; + u8 reason; + struct sk_buff *skb; +}; + +struct llc_sap_ev_tmr_if { + void *timer_specific; +}; + +struct llc_sap_ev_rpt_sts_if { + u8 status; +}; + +union llc_sap_ev_if { + struct llc_sap_ev_simple_if a; /* 'a' for simple, easy ... */ + struct llc_sap_ev_prim_if prim; + struct llc_sap_ev_pdu_if pdu; + struct llc_sap_ev_tmr_if tmr; + struct llc_sap_ev_rpt_sts_if rsts; /* report status */ +}; + +struct llc_prim_if_block; + +struct llc_sap_state_ev { + u8 type; + u8 ind_cfm_flag; + struct llc_prim_if_block *prim; + union llc_sap_ev_if data; +}; + +struct llc_sap; + +typedef int (*llc_sap_ev_t)(struct llc_sap *sap, struct llc_sap_state_ev *ev); + +extern int llc_sap_ev_activation_req(struct llc_sap *sap, + struct llc_sap_state_ev *ev); +extern int llc_sap_ev_rx_ui(struct llc_sap *sap, struct llc_sap_state_ev *ev); +extern int llc_sap_ev_unitdata_req(struct llc_sap *sap, + struct llc_sap_state_ev *ev); +extern int llc_sap_ev_xid_req(struct llc_sap *sap, + struct llc_sap_state_ev *ev); +extern int llc_sap_ev_rx_xid_c(struct llc_sap *sap, + struct llc_sap_state_ev *ev); +extern int llc_sap_ev_rx_xid_r(struct llc_sap *sap, + struct llc_sap_state_ev *ev); +extern int llc_sap_ev_test_req(struct llc_sap *sap, + struct llc_sap_state_ev *ev); +extern int llc_sap_ev_rx_test_c(struct llc_sap *sap, + struct llc_sap_state_ev *ev); +extern int llc_sap_ev_rx_test_r(struct llc_sap *sap, + struct llc_sap_state_ev *ev); +extern int llc_sap_ev_deactivation_req(struct llc_sap *sap, + struct llc_sap_state_ev *ev); +#endif /* LLC_S_EV_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_s_st.h linux.19pre5-ac1/include/net/llc_s_st.h --- linux.19p5/include/net/llc_s_st.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/net/llc_s_st.h Tue Mar 19 19:15:34 2002 @@ -0,0 +1,34 @@ +#ifndef LLC_S_ST_H +#define LLC_S_ST_H +/* + * Copyright (c) 1997 by Procom Technology,Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +/* Defines SAP component states */ + +#define LLC_SAP_STATE_INACTIVE 1 +#define LLC_SAP_STATE_ACTIVE 2 +#define LLC_NBR_SAP_STATES 2 /* size of state table */ +/* structures and types */ +/* SAP state table structure */ +struct llc_sap_state_trans { + llc_sap_ev_t ev; + u8 next_state; + llc_sap_action_t *ev_actions; +}; + +struct llc_sap_state { + u8 curr_state; + struct llc_sap_state_trans **transitions; +}; + +/* only access to SAP state table */ +extern struct llc_sap_state llc_sap_state_table[LLC_NBR_SAP_STATES]; +#endif /* LLC_S_ST_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_sap.h linux.19pre5-ac1/include/net/llc_sap.h --- linux.19p5/include/net/llc_sap.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/net/llc_sap.h Thu Apr 4 16:08:06 2002 @@ -0,0 +1,42 @@ +#ifndef LLC_SAP_H +#define LLC_SAP_H +/* + * Copyright (c) 1997 by Procom Technology,Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +#include +/* Defines the SAP component */ +struct llc_sap { + u8 state; + struct llc_station *parent_station; + u8 p_bit; /* only lowest-order bit used */ + u8 f_bit; /* only lowest-order bit used */ + llc_prim_call_t req; /* provided by LLC layer */ + llc_prim_call_t resp; /* provided by LLC layer */ + llc_prim_call_t ind; /* provided by network layer */ + llc_prim_call_t conf; /* provided by network layer */ + struct llc_addr laddr; /* SAP value in this 'lsap' */ + struct list_head node; /* entry in station sap_list */ + struct { + spinlock_t lock; + struct list_head list; + } sk_list; /* LLC sockets this one manages */ + struct sk_buff_head mac_pdu_q; /* PDUs ready to send to MAC */ +}; +struct llc_sap_state_ev; + +extern void llc_sap_assign_sock(struct llc_sap *sap, struct sock *sk); +extern void llc_sap_unassign_sock(struct llc_sap *sap, struct sock *sk); +extern void llc_sap_send_ev(struct llc_sap *sap, struct llc_sap_state_ev *ev); +extern void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb, + struct llc_sap_state_ev *ev); +extern void llc_sap_send_pdu(struct llc_sap *sap, struct sk_buff *skb); +extern struct llc_sap_state_ev *llc_sap_alloc_ev(struct llc_sap *sap); +#endif /* LLC_SAP_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_stat.h linux.19pre5-ac1/include/net/llc_stat.h --- linux.19p5/include/net/llc_stat.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/include/net/llc_stat.h Tue Mar 19 19:15:34 2002 @@ -0,0 +1,35 @@ +#ifndef LLC_STAT_H +#define LLC_STAT_H +/* + * Copyright (c) 1997 by Procom Technology,Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +/* Station component state table */ +/* Station component states */ +#define LLC_STATION_STATE_DOWN 1 /* initial state */ +#define LLC_STATION_STATE_DUP_ADDR_CHK 2 +#define LLC_STATION_STATE_UP 3 + +#define LLC_NBR_STATION_STATES 3 /* size of state table */ + +/* Station component state table structure */ +struct llc_station_state_trans { + llc_station_ev_t ev; + u8 next_state; + llc_station_action_t *ev_actions; +}; + +struct llc_station_state { + u8 curr_state; + struct llc_station_state_trans **transitions; +}; + +extern struct llc_station_state llc_station_state_table[LLC_NBR_STATION_STATES]; +#endif /* LLC_STAT_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/p8022.h linux.19pre5-ac1/include/net/p8022.h --- linux.19p5/include/net/p8022.h Thu Apr 4 13:18:26 2002 +++ linux.19pre5-ac1/include/net/p8022.h Tue Mar 19 19:15:34 2002 @@ -1,7 +1,9 @@ #ifndef _NET_P8022_H #define _NET_P8022_H - -extern struct datalink_proto *register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct net_device *, struct packet_type *)); +extern struct datalink_proto *register_8022_client(unsigned char type, + int (*rcvfunc) + (struct sk_buff *, + struct net_device *, + struct packet_type *)); extern void unregister_8022_client(unsigned char type); - #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/tcp.h linux.19pre5-ac1/include/net/tcp.h --- linux.19p5/include/net/tcp.h Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/include/net/tcp.h Thu Apr 4 15:48:47 2002 @@ -1327,8 +1327,6 @@ if (tp->ucopy.memory > sk->rcvbuf) { struct sk_buff *skb1; - if (sk->lock.users) BUG(); - while ((skb1 = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) { sk->backlog_rcv(sk, skb1); NET_INC_STATS_BH(TCPPrequeueDropped); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/scsi/scsi.h linux.19pre5-ac1/include/scsi/scsi.h --- linux.19p5/include/scsi/scsi.h Thu Apr 4 13:18:27 2002 +++ linux.19pre5-ac1/include/scsi/scsi.h Tue Mar 26 18:33:06 2002 @@ -89,6 +89,8 @@ #define SEND_VOLUME_TAG 0xb6 #define WRITE_LONG_2 0xea +#define SCSI_RETRY_10(c) ((c) == READ_6 || (c) == WRITE_6 || (c) == SEEK_6) + /* * Status codes */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/init/main.c linux.19pre5-ac1/init/main.c --- linux.19p5/init/main.c Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/init/main.c Fri Mar 15 22:52:15 2002 @@ -60,6 +60,10 @@ #include #endif +#ifdef CONFIG_PNPBIOS +#include +#endif + #ifdef CONFIG_IRDA extern int irda_proto_init(void); extern int irda_device_init(void); @@ -288,8 +292,6 @@ extern void setup_arch(char **); extern void cpu_idle(void); -unsigned long wait_init_idle; - #ifndef CONFIG_SMP #ifdef CONFIG_X86_LOCAL_APIC @@ -298,34 +300,24 @@ APIC_init_uniprocessor(); } #else -#define smp_init() do { } while (0) +#define smp_init() do { } while (0) #endif #else - /* Called by boot processor to activate the rest. */ static void __init smp_init(void) { /* Get other processors into their bootup holding patterns. */ smp_boot_cpus(); - wait_init_idle = cpu_online_map; - clear_bit(current->processor, &wait_init_idle); /* Don't wait on me! */ smp_threads_ready=1; smp_commence(); - - /* Wait for the other cpus to set up their idle processes */ - printk("Waiting on wait_init_idle (map = 0x%lx)\n", wait_init_idle); - while (wait_init_idle) { - cpu_relax(); - barrier(); - } - printk("All processors have done init_idle\n"); } #endif + /* * We need to finalize in a non-__init function or else race conditions * between the root thread and the init thread may cause start_kernel to @@ -337,9 +329,8 @@ { kernel_thread(init, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL); unlock_kernel(); - current->need_resched = 1; - cpu_idle(); -} + cpu_idle(); +} /* * Activate the first processor. @@ -424,14 +415,18 @@ ipc_init(); #endif check_bugs(); + printk("POSIX conformance testing by UNIFIX\n"); - /* - * We count on the initial thread going ok - * Like idlers init is an unlocked kernel thread, which will - * make syscalls (and thus be locked). + init_idle(current, smp_processor_id()); + /* + * We count on the initial thread going ok + * Like idlers init is an unlocked kernel thread, which will + * make syscalls (and thus be locked). */ smp_init(); + + /* Do the rest non-__init'ed, we're now alive */ rest_init(); } @@ -519,6 +514,9 @@ #ifdef CONFIG_ISAPNP isapnp_init(); #endif +#ifdef CONFIG_PNPBIOS + pnpbios_init(); +#endif #ifdef CONFIG_TC tc_init(); #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/ipc/shm.c linux.19pre5-ac1/ipc/shm.c --- linux.19p5/ipc/shm.c Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/ipc/shm.c Mon Mar 25 18:15:25 2002 @@ -679,7 +679,7 @@ shmdnext = shmd->vm_next; if (shmd->vm_ops == &shm_vm_ops && shmd->vm_start - (shmd->vm_pgoff << PAGE_SHIFT) == (ulong) shmaddr) { - do_munmap(mm, shmd->vm_start, shmd->vm_end - shmd->vm_start); + do_munmap(mm, shmd->vm_start, shmd->vm_end - shmd->vm_start, 1); retval = 0; } } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/Makefile linux.19pre5-ac1/kernel/Makefile --- linux.19p5/kernel/Makefile Thu Apr 4 13:18:16 2002 +++ linux.19pre5-ac1/kernel/Makefile Thu Apr 4 14:44:43 2002 @@ -19,6 +19,7 @@ obj-$(CONFIG_UID16) += uid16.o obj-$(CONFIG_MODULES) += ksyms.o obj-$(CONFIG_PM) += pm.o +obj-$(CONFIG_IKCONFIG) += configs.o ifneq ($(CONFIG_IA64),y) # According to Alan Modra , the -fno-omit-frame-pointer is @@ -26,7 +27,23 @@ # me. I suspect most platforms don't need this, but until we know that for sure # I turn this off for IA-64 only. Andreas Schwab says it's also needed on m68k # to get a correct value for the wait-channel (WCHAN in ps). --davidm -CFLAGS_sched.o := $(PROFILING) -fno-omit-frame-pointer +# +# Some gcc's are building so that O(1) scheduler is triple faulting if we +# build -O2. Nobody yet knows why, but for the moment let's keep O1 +# (Turns out to be a CPU issue. Update your microcode if you hit it) +# +CFLAGS_sched.o := $(PROFILING) -fno-omit-frame-pointer -O2 endif include $(TOPDIR)/Rules.make + +configs.o: $(TOPDIR)/scripts/mkconfigs configs.c + echo obj-y == $(obj-y) + $(CC) $(CFLAGS) $(CFLAGS_KERNEL) -DEXPORT_SYMTAB -c -o configs.o configs.c + +$(TOPDIR)/scripts/mkconfigs: $(TOPDIR)/scripts/mkconfigs.c + $(HOSTCC) $(HOSTCFLAGS) -o $(TOPDIR)/scripts/mkconfigs $(TOPDIR)/scripts/mkconfigs.c + +configs.c: $(TOPDIR)/.config $(TOPDIR)/scripts/mkconfigs + $(TOPDIR)/scripts/mkconfigs $(TOPDIR)/.config configs.c + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/capability.c linux.19pre5-ac1/kernel/capability.c --- linux.19p5/kernel/capability.c Thu Apr 4 13:18:17 2002 +++ linux.19pre5-ac1/kernel/capability.c Wed Feb 27 18:32:03 2002 @@ -8,6 +8,8 @@ #include #include +unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */ + kernel_cap_t cap_bset = CAP_INIT_EFF_SET; /* Note: never hold tasklist_lock while spinning for this one */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/exit.c linux.19pre5-ac1/kernel/exit.c --- linux.19p5/kernel/exit.c Thu Apr 4 13:18:16 2002 +++ linux.19pre5-ac1/kernel/exit.c Wed Feb 27 18:32:03 2002 @@ -27,49 +27,22 @@ static void release_task(struct task_struct * p) { - if (p != current) { + if (p == current) + BUG(); #ifdef CONFIG_SMP - /* - * Wait to make sure the process isn't on the - * runqueue (active on some other CPU still) - */ - for (;;) { - task_lock(p); - if (!task_has_cpu(p)) - break; - task_unlock(p); - do { - cpu_relax(); - barrier(); - } while (task_has_cpu(p)); - } - task_unlock(p); + wait_task_inactive(p); #endif - atomic_dec(&p->user->processes); - free_uid(p->user); - unhash_process(p); - - release_thread(p); - current->cmin_flt += p->min_flt + p->cmin_flt; - current->cmaj_flt += p->maj_flt + p->cmaj_flt; - current->cnswap += p->nswap + p->cnswap; - /* - * Potentially available timeslices are retrieved - * here - this way the parent does not get penalized - * for creating too many processes. - * - * (this cannot be used to artificially 'generate' - * timeslices, because any timeslice recovered here - * was given away by the parent in the first place.) - */ - current->counter += p->counter; - if (current->counter >= MAX_COUNTER) - current->counter = MAX_COUNTER; - p->pid = 0; - free_task_struct(p); - } else { - printk("task releasing itself\n"); - } + atomic_dec(&p->user->processes); + free_uid(p->user); + unhash_process(p); + + release_thread(p); + current->cmin_flt += p->min_flt + p->cmin_flt; + current->cmaj_flt += p->maj_flt + p->cmaj_flt; + current->cnswap += p->nswap + p->cnswap; + sched_exit(p); + p->pid = 0; + free_task_struct(p); } /* @@ -149,6 +122,79 @@ return retval; } +/** + * reparent_to_init() - Reparent the calling kernel thread to the init task. + * + * If a kernel thread is launched as a result of a system call, or if + * it ever exits, it should generally reparent itself to init so that + * it is correctly cleaned up on exit. + * + * The various task state such as scheduling policy and priority may have + * been inherited from a user process, so we reset them to sane values here. + * + * NOTE that reparent_to_init() gives the caller full capabilities. + */ +void reparent_to_init(void) +{ + write_lock_irq(&tasklist_lock); + + /* Reparent to init */ + REMOVE_LINKS(current); + current->p_pptr = child_reaper; + current->p_opptr = child_reaper; + SET_LINKS(current); + + /* Set the exit signal to SIGCHLD so we signal init on exit */ + current->exit_signal = SIGCHLD; + + current->ptrace = 0; + if ((current->policy == SCHED_OTHER) && (task_nice(current) < 0)) + set_user_nice(current, 0); + /* cpus_allowed? */ + /* rt_priority? */ + /* signals? */ + current->cap_effective = CAP_INIT_EFF_SET; + current->cap_inheritable = CAP_INIT_INH_SET; + current->cap_permitted = CAP_FULL_SET; + current->keep_capabilities = 0; + memcpy(current->rlim, init_task.rlim, sizeof(*(current->rlim))); + current->user = INIT_USER; + + write_unlock_irq(&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; + current->tty = NULL; + + /* Become as one with the init task */ + + exit_fs(current); /* current->fs->count--; */ + fs = init_task.fs; + current->fs = fs; + atomic_inc(&fs->count); + exit_files(current); + current->files = init_task.files; + atomic_inc(¤t->files->count); +} + /* * When we die, we re-parent all our children. * Try to give them to another thread in our process diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/fork.c linux.19pre5-ac1/kernel/fork.c --- linux.19p5/kernel/fork.c Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/kernel/fork.c Sat Mar 9 20:52:21 2002 @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include @@ -28,7 +30,6 @@ /* The idle threads do not count.. */ int nr_threads; -int nr_running; int max_threads; unsigned long total_forks; /* Handle normal Linux uptimes. */ @@ -36,6 +37,8 @@ struct task_struct *pidhash[PIDHASH_SZ]; +rwlock_t tasklist_lock __cacheline_aligned = RW_LOCK_UNLOCKED; /* outer */ + void add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait) { unsigned long flags; @@ -85,12 +88,13 @@ { static int next_safe = PID_MAX; struct task_struct *p; - int pid; + int pid, beginpid; if (flags & CLONE_PID) return current->pid; spin_lock(&lastpid_lock); + beginpid = last_pid; if((++last_pid) & 0xffff8000) { last_pid = 300; /* Skip daemons etc. */ goto inside; @@ -110,12 +114,16 @@ last_pid = 300; next_safe = PID_MAX; } + if(unlikely(last_pid == beginpid)) + goto nomorepids; goto repeat; } if(p->pid > last_pid && next_safe > p->pid) next_safe = p->pid; if(p->pgrp > last_pid && next_safe > p->pgrp) next_safe = p->pgrp; + if(p->tgid > last_pid && next_safe > p->tgid) + next_safe = p->tgid; if(p->session > last_pid && next_safe > p->session) next_safe = p->session; } @@ -125,12 +133,18 @@ spin_unlock(&lastpid_lock); return pid; + +nomorepids: + read_unlock(&tasklist_lock); + spin_unlock(&lastpid_lock); + return 0; } static inline int dup_mmap(struct mm_struct * mm) { struct vm_area_struct * mpnt, *tmp, **pprev; int retval; + unsigned long charge = 0; flush_cache_mm(current->mm); mm->locked_vm = 0; @@ -139,7 +153,6 @@ mm->map_count = 0; mm->rss = 0; mm->cpu_vm_mask = 0; - mm->swap_address = 0; pprev = &mm->mmap; /* @@ -159,6 +172,15 @@ retval = -ENOMEM; if(mpnt->vm_flags & VM_DONTCOPY) continue; + + /* FIXME: shared writable map accounting should be one off */ + if(mpnt->vm_flags & VM_ACCOUNT) + { + unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; + if(!vm_enough_memory(len, 1)) + goto fail_nomem; + charge += len; + } tmp = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (!tmp) goto fail_nomem; @@ -202,10 +224,12 @@ } retval = 0; build_mmap_rb(mm); - -fail_nomem: +out: flush_tlb_mm(current->mm); return retval; +fail_nomem: + vm_unacct_memory(charge); + goto out; } spinlock_t mmlist_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED; @@ -263,9 +287,6 @@ void mmput(struct mm_struct *mm) { if (atomic_dec_and_lock(&mm->mm_users, &mmlist_lock)) { - extern struct mm_struct *swap_mm; - if (swap_mm == mm) - swap_mm = list_entry(mm->mmlist.next, struct mm_struct, mmlist); list_del(&mm->mmlist); mmlist_nr--; spin_unlock(&mmlist_lock); @@ -566,6 +587,7 @@ struct pt_regs *regs, unsigned long stack_size) { int retval; + unsigned long flags; struct task_struct *p; struct completion vfork; @@ -620,9 +642,10 @@ copy_flags(clone_flags, p); p->pid = get_pid(clone_flags); + if (p->pid == 0 && current->pid != 0) + goto bad_fork_cleanup; - p->run_list.next = NULL; - p->run_list.prev = NULL; + INIT_LIST_HEAD(&p->run_list); p->p_cptr = NULL; init_waitqueue_head(&p->wait_chldexit); @@ -648,19 +671,18 @@ #ifdef CONFIG_SMP { int i; - p->cpus_runnable = ~0UL; - p->processor = current->processor; + /* ?? should we just memset this ?? */ for(i = 0; i < smp_num_cpus; i++) - p->per_cpu_utime[i] = p->per_cpu_stime[i] = 0; + p->per_cpu_utime[cpu_logical_map(i)] = + p->per_cpu_stime[cpu_logical_map(i)] = 0; spin_lock_init(&p->sigmask_lock); } #endif + p->array = NULL; p->lock_depth = -1; /* -1 = no lock */ p->start_time = jiffies; - INIT_LIST_HEAD(&p->local_pages); - retval = -ENOMEM; /* copy all the process information */ if (copy_files(clone_flags, p)) @@ -687,15 +709,27 @@ p->pdeath_signal = 0; /* - * "share" dynamic priority between parent and child, thus the - * total amount of dynamic priorities in the system doesnt change, - * more scheduling fairness. This is only important in the first - * timeslice, on the long run the scheduling behaviour is unchanged. - */ - p->counter = (current->counter + 1) >> 1; - current->counter >>= 1; - if (!current->counter) - current->need_resched = 1; + * Share the timeslice between parent and child, thus the + * total amount of pending timeslices in the system doesnt change, + * resulting in more scheduling fairness. + */ + __save_flags(flags); + __cli(); + if (!current->time_slice) + BUG(); + p->time_slice = (current->time_slice + 1) >> 1; + current->time_slice >>= 1; + if (!current->time_slice) { + /* + * This case is rare, it happens when the parent has only + * a single jiffy left from its timeslice. Taking the + * runqueue lock is not a problem. + */ + current->time_slice = 1; + scheduler_tick(0,0); + } + p->sleep_timestamp = jiffies; + __restore_flags(flags); /* * Ok, add it to the run-queues and make it @@ -732,10 +766,23 @@ if (p->ptrace & PT_PTRACED) send_sig(SIGSTOP, p, 1); +#define RUN_CHILD_FIRST 1 +#if RUN_CHILD_FIRST + wake_up_forked_process(p); /* do this last */ +#else wake_up_process(p); /* do this last */ +#endif ++total_forks; if (clone_flags & CLONE_VFORK) wait_for_completion(&vfork); +#if RUN_CHILD_FIRST + else + /* + * Let the child process run first, to avoid most of the + * COW overhead when the child exec()s afterwards. + */ + current->need_resched = 1; +#endif fork_out: return retval; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/kmod.c linux.19pre5-ac1/kernel/kmod.c --- linux.19p5/kernel/kmod.c Thu Apr 4 13:18:17 2002 +++ linux.19pre5-ac1/kernel/kmod.c Fri Mar 15 22:20:42 2002 @@ -111,15 +111,8 @@ if (curtask->files->fd[i]) close(i); } - /* Drop the "current user" thing */ - { - struct user_struct *user = curtask->user; - curtask->user = INIT_USER; - atomic_inc(&INIT_USER->__count); - atomic_inc(&INIT_USER->processes); - atomic_dec(&user->processes); - free_uid(user); - } + /* Become root */ + set_user(0, 0); /* Give kmod all effective privileges.. */ curtask->euid = curtask->fsuid = 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/ksyms.c linux.19pre5-ac1/kernel/ksyms.c --- linux.19p5/kernel/ksyms.c Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/kernel/ksyms.c Wed Mar 20 16:02:25 2002 @@ -201,6 +201,7 @@ EXPORT_SYMBOL(unlock_buffer); EXPORT_SYMBOL(__wait_on_buffer); EXPORT_SYMBOL(___wait_on_page); +EXPORT_SYMBOL(wake_up_page); EXPORT_SYMBOL(generic_direct_IO); EXPORT_SYMBOL(discard_bh_page); EXPORT_SYMBOL(block_write_full_page); @@ -313,6 +314,7 @@ EXPORT_SYMBOL(refile_buffer); EXPORT_SYMBOL(max_sectors); EXPORT_SYMBOL(max_readahead); +EXPORT_SYMBOL(blkdev_varyio); /* tty routines */ EXPORT_SYMBOL(tty_hangup); @@ -440,6 +442,9 @@ EXPORT_SYMBOL(interruptible_sleep_on_timeout); EXPORT_SYMBOL(schedule); EXPORT_SYMBOL(schedule_timeout); +EXPORT_SYMBOL(sys_sched_yield); +EXPORT_SYMBOL(set_user_nice); +EXPORT_SYMBOL(set_cpus_allowed); EXPORT_SYMBOL(jiffies); EXPORT_SYMBOL(xtime); EXPORT_SYMBOL(do_gettimeofday); @@ -451,6 +456,7 @@ EXPORT_SYMBOL(kstat); EXPORT_SYMBOL(nr_running); +EXPORT_SYMBOL(nr_context_switches); /* misc */ EXPORT_SYMBOL(panic); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/printk.c linux.19pre5-ac1/kernel/printk.c --- linux.19p5/kernel/printk.c Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/kernel/printk.c Fri Mar 1 19:38:32 2002 @@ -26,6 +26,7 @@ #include #include /* For in_interrupt() */ #include +#include #include @@ -529,6 +530,7 @@ if (must_wake_klogd && !oops_in_progress) wake_up_interruptible(&log_wait); } +EXPORT_SYMBOL(release_console_sem); /** console_conditional_schedule - yield the CPU if required * diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/ptrace.c linux.19pre5-ac1/kernel/ptrace.c --- linux.19p5/kernel/ptrace.c Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/kernel/ptrace.c Thu Mar 14 22:28:52 2002 @@ -31,20 +31,7 @@ if (child->state != TASK_STOPPED) return -ESRCH; #ifdef CONFIG_SMP - /* Make sure the child gets off its CPU.. */ - for (;;) { - task_lock(child); - if (!task_has_cpu(child)) - break; - task_unlock(child); - do { - if (child->state != TASK_STOPPED) - return -ESRCH; - barrier(); - cpu_relax(); - } while (task_has_cpu(child)); - } - task_unlock(child); + wait_task_inactive(child); #endif } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/sched.c linux.19pre5-ac1/kernel/sched.c --- linux.19p5/kernel/sched.c Thu Apr 4 13:18:16 2002 +++ linux.19pre5-ac1/kernel/sched.c Sat Mar 9 20:37:41 2002 @@ -12,333 +12,306 @@ * 1998-12-28 Implemented better SMP scheduling by Ingo Molnar */ -/* - * 'sched.c' is the main kernel file. It contains scheduling primitives - * (sleep_on, wakeup, schedule etc) as well as a number of simple system - * call functions (type getpid()), which just extract a field from - * current-task - */ - -#include #include +#include #include +#include #include -#include #include -#include -#include -#include -#include - -#include #include - -extern void timer_bh(void); -extern void tqueue_bh(void); -extern void immediate_bh(void); +#include /* - * scheduler variables + * Priority of a process goes from 0 to 139. The 0-99 + * priority range is allocated to RT tasks, the 100-139 + * range is for SCHED_OTHER tasks. Priority values are + * inverted: lower p->prio value means higher priority. */ - -unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */ - -extern void mem_use(void); +#define MAX_RT_PRIO 100 +#define MAX_PRIO (MAX_RT_PRIO + 40) /* - * Scheduling quanta. - * - * NOTE! The unix "nice" value influences how long a process - * gets. The nice value ranges from -20 to +19, where a -20 - * is a "high-priority" task, and a "+10" is a low-priority - * task. - * - * We want the time-slice to be around 50ms or so, so this - * calculation depends on the value of HZ. + * Convert user-nice values [ -20 ... 0 ... 19 ] + * to static priority [ 100 ... 139 (MAX_PRIO-1) ], + * and back. */ -#if HZ < 200 -#define TICK_SCALE(x) ((x) >> 2) -#elif HZ < 400 -#define TICK_SCALE(x) ((x) >> 1) -#elif HZ < 800 -#define TICK_SCALE(x) (x) -#elif HZ < 1600 -#define TICK_SCALE(x) ((x) << 1) -#else -#define TICK_SCALE(x) ((x) << 2) -#endif - -#define NICE_TO_TICKS(nice) (TICK_SCALE(20-(nice))+1) +#define NICE_TO_PRIO(nice) (MAX_RT_PRIO + (nice) + 20) +#define PRIO_TO_NICE(prio) ((prio) - MAX_RT_PRIO - 20) +#define TASK_NICE(p) PRIO_TO_NICE((p)->static_prio) +/* + * 'User priority' is the nice value converted to something we + * can work with better when scaling various scheduler parameters, + * it's a [ 0 ... 39 ] range. + */ +#define USER_PRIO(p) ((p)-MAX_RT_PRIO) +#define TASK_USER_PRIO(p) USER_PRIO((p)->static_prio) +#define MAX_USER_PRIO (USER_PRIO(MAX_PRIO)) /* - * Init task must be ok at boot for the ix86 as we will check its signals - * via the SMP irq return path. + * These are the 'tuning knobs' of the scheduler: + * + * Minimum timeslice is 10 msecs, default timeslice is 150 msecs, + * maximum timeslice is 300 msecs. Timeslices get refilled after + * they expire. */ - -struct task_struct * init_tasks[NR_CPUS] = {&init_task, }; +#define MIN_TIMESLICE ( 10 * HZ / 1000) +#define MAX_TIMESLICE (300 * HZ / 1000) +#define CHILD_PENALTY 95 +#define PARENT_PENALTY 100 +#define EXIT_WEIGHT 3 +#define PRIO_BONUS_RATIO 25 +#define INTERACTIVE_DELTA 2 +#define MAX_SLEEP_AVG (2*HZ) +#define STARVATION_LIMIT (2*HZ) /* - * The tasklist_lock protects the linked list of processes. + * If a task is 'interactive' then we reinsert it in the active + * array after it has expired its current timeslice. (it will not + * continue to run immediately, it will still roundrobin with + * other interactive tasks.) * - * The runqueue_lock locks the parts that actually access - * and change the run-queues, and have to be interrupt-safe. + * This part scales the interactivity limit depending on niceness. * - * If both locks are to be concurrently held, the runqueue_lock - * nests inside the tasklist_lock. + * We scale it linearly, offset by the INTERACTIVE_DELTA delta. + * Here are a few examples of different nice levels: * - * task->alloc_lock nests inside tasklist_lock. + * TASK_INTERACTIVE(-20): [1,1,1,1,1,1,1,1,1,0,0] + * TASK_INTERACTIVE(-10): [1,1,1,1,1,1,1,0,0,0,0] + * TASK_INTERACTIVE( 0): [1,1,1,1,0,0,0,0,0,0,0] + * TASK_INTERACTIVE( 10): [1,1,0,0,0,0,0,0,0,0,0] + * TASK_INTERACTIVE( 19): [0,0,0,0,0,0,0,0,0,0,0] + * + * (the X axis represents the possible -5 ... 0 ... +5 dynamic + * priority range a task can explore, a value of '1' means the + * task is rated interactive.) + * + * Ie. nice +19 tasks can never get 'interactive' enough to be + * reinserted into the active array. And only heavily CPU-hog nice -20 + * tasks will be expired. Default nice 0 tasks are somewhere between, + * it takes some effort for them to get interactive, but it's not + * too hard. */ -spinlock_t runqueue_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED; /* inner */ -rwlock_t tasklist_lock __cacheline_aligned = RW_LOCK_UNLOCKED; /* outer */ -static LIST_HEAD(runqueue_head); +#define SCALE(v1,v1_max,v2_max) \ + (v1) * (v2_max) / (v1_max) -/* - * We align per-CPU scheduling data on cacheline boundaries, - * to prevent cacheline ping-pong. - */ -static union { - struct schedule_data { - struct task_struct * curr; - cycles_t last_schedule; - } schedule_data; - char __pad [SMP_CACHE_BYTES]; -} aligned_data [NR_CPUS] __cacheline_aligned = { {{&init_task,0}}}; +#define DELTA(p) \ + (SCALE(TASK_NICE(p), 40, MAX_USER_PRIO*PRIO_BONUS_RATIO/100) + \ + INTERACTIVE_DELTA) -#define cpu_curr(cpu) aligned_data[(cpu)].schedule_data.curr -#define last_schedule(cpu) aligned_data[(cpu)].schedule_data.last_schedule +#define TASK_INTERACTIVE(p) \ + ((p)->prio <= (p)->static_prio - DELTA(p)) -struct kernel_stat kstat; -extern struct task_struct *child_reaper; +/* + * TASK_TIMESLICE scales user-nice values [ -20 ... 19 ] + * to time slice values. + * + * The higher a process's priority, the bigger timeslices + * it gets during one round of execution. But even the lowest + * priority process gets MIN_TIMESLICE worth of execution time. + */ -#ifdef CONFIG_SMP +#define TASK_TIMESLICE(p) (MIN_TIMESLICE + \ + ((MAX_TIMESLICE - MIN_TIMESLICE) * (MAX_PRIO-1-(p)->static_prio)/39)) -#define idle_task(cpu) (init_tasks[cpu_number_map(cpu)]) -#define can_schedule(p,cpu) \ - ((p)->cpus_runnable & (p)->cpus_allowed & (1 << cpu)) +/* + * These are the runqueue data structures: + */ -#else +#define BITMAP_SIZE ((((MAX_PRIO+1+7)/8)+sizeof(long)-1)/sizeof(long)) -#define idle_task(cpu) (&init_task) -#define can_schedule(p,cpu) (1) +typedef struct runqueue runqueue_t; -#endif - -void scheduling_functions_start_here(void) { } +struct prio_array { + int nr_active; + spinlock_t *lock; + runqueue_t *rq; + unsigned long bitmap[BITMAP_SIZE]; + list_t queue[MAX_PRIO]; +}; /* - * This is the function that decides how desirable a process is.. - * You can weigh different processes against each other depending - * on what CPU they've run on lately etc to try to handle cache - * and TLB miss penalties. + * This is the main, per-CPU runqueue data structure. * - * Return values: - * -1000: never select this - * 0: out of time, recalculate counters (but it might still be - * selected) - * +ve: "goodness" value (the larger, the better) - * +1000: realtime process, select this. + * Locking rule: those places that want to lock multiple runqueues + * (such as the load balancing or the process migration code), lock + * acquire operations must be ordered by ascending &runqueue. */ +struct runqueue { + spinlock_t lock; + unsigned long nr_running, nr_switches, expired_timestamp; + task_t *curr, *idle; + prio_array_t *active, *expired, arrays[2]; + int prev_nr_running[NR_CPUS]; +} ____cacheline_aligned; -static inline int goodness(struct task_struct * p, int this_cpu, struct mm_struct *this_mm) -{ - int weight; +static struct runqueue runqueues[NR_CPUS] __cacheline_aligned; - /* - * select the current process after every other - * runnable process, but before the idle thread. - * Also, dont trigger a counter recalculation. - */ - weight = -1; - if (p->policy & SCHED_YIELD) - goto out; +#define cpu_rq(cpu) (runqueues + (cpu)) +#define this_rq() cpu_rq(smp_processor_id()) +#define task_rq(p) cpu_rq((p)->cpu) +#define cpu_curr(cpu) (cpu_rq(cpu)->curr) +#define rt_task(p) ((p)->prio < MAX_RT_PRIO) - /* - * Non-RT process - normal case first. - */ - if (p->policy == SCHED_OTHER) { - /* - * Give the process a first-approximation goodness value - * according to the number of clock-ticks it has left. - * - * Don't do any other calculations if the time slice is - * over.. - */ - weight = p->counter; - if (!weight) - goto out; - -#ifdef CONFIG_SMP - /* Give a largish advantage to the same processor... */ - /* (this is equivalent to penalizing other processors) */ - if (p->processor == this_cpu) - weight += PROC_CHANGE_PENALTY; -#endif +static inline runqueue_t *lock_task_rq(task_t *p, unsigned long *flags) +{ + struct runqueue *__rq; - /* .. and a slight advantage to the current MM */ - if (p->mm == this_mm || !p->mm) - weight += 1; - weight += 20 - p->nice; - goto out; +repeat_lock_task: + __rq = task_rq(p); + spin_lock_irqsave(&__rq->lock, *flags); + if (unlikely(__rq != task_rq(p))) { + spin_unlock_irqrestore(&__rq->lock, *flags); + goto repeat_lock_task; } + return __rq; +} - /* - * Realtime process, select the first one on the - * runqueue (taking priorities within processes - * into account). - */ - weight = 1000 + p->rt_priority; -out: - return weight; +static inline void unlock_task_rq(runqueue_t *rq, unsigned long *flags) +{ + spin_unlock_irqrestore(&rq->lock, *flags); } /* - * the 'goodness value' of replacing a process on a given CPU. - * positive value means 'replace', zero or negative means 'dont'. + * Adding/removing a task to/from a priority array: */ -static inline int preemption_goodness(struct task_struct * prev, struct task_struct * p, int cpu) +static inline void dequeue_task(struct task_struct *p, prio_array_t *array) { - return goodness(p, cpu, prev->active_mm) - goodness(prev, cpu, prev->active_mm); + array->nr_active--; + list_del_init(&p->run_list); + if (list_empty(array->queue + p->prio)) + __clear_bit(p->prio, array->bitmap); } -/* - * This is ugly, but reschedule_idle() is very timing-critical. - * We are called with the runqueue spinlock held and we must - * not claim the tasklist_lock. - */ -static FASTCALL(void reschedule_idle(struct task_struct * p)); +static inline void enqueue_task(struct task_struct *p, prio_array_t *array) +{ + list_add_tail(&p->run_list, array->queue + p->prio); + __set_bit(p->prio, array->bitmap); + array->nr_active++; + p->array = array; +} -static void reschedule_idle(struct task_struct * p) +static inline int effective_prio(task_t *p) { -#ifdef CONFIG_SMP - int this_cpu = smp_processor_id(); - struct task_struct *tsk, *target_tsk; - int cpu, best_cpu, i, max_prio; - cycles_t oldest_idle; - - /* - * shortcut if the woken up task's last CPU is - * idle now. - */ - best_cpu = p->processor; - if (can_schedule(p, best_cpu)) { - tsk = idle_task(best_cpu); - if (cpu_curr(best_cpu) == tsk) { - int need_resched; -send_now_idle: - /* - * If need_resched == -1 then we can skip sending - * the IPI altogether, tsk->need_resched is - * actively watched by the idle thread. - */ - need_resched = tsk->need_resched; - tsk->need_resched = 1; - if ((best_cpu != this_cpu) && !need_resched) - smp_send_reschedule(best_cpu); - return; - } - } + int bonus, prio; /* - * We know that the preferred CPU has a cache-affine current - * process, lets try to find a new idle CPU for the woken-up - * process. Select the least recently active idle CPU. (that - * one will have the least active cache context.) Also find - * the executing process which has the least priority. - */ - oldest_idle = (cycles_t) -1; - target_tsk = NULL; - max_prio = 0; + * Here we scale the actual sleep average [0 .... MAX_SLEEP_AVG] + * into the -5 ... 0 ... +5 bonus/penalty range. + * + * We use 25% of the full 0...39 priority range so that: + * + * 1) nice +19 interactive tasks do not preempt nice 0 CPU hogs. + * 2) nice -20 CPU hogs do not get preempted by nice 0 tasks. + * + * Both properties are important to certain workloads. + */ + bonus = MAX_USER_PRIO*PRIO_BONUS_RATIO*p->sleep_avg/MAX_SLEEP_AVG/100 - + MAX_USER_PRIO*PRIO_BONUS_RATIO/100/2; - for (i = 0; i < smp_num_cpus; i++) { - cpu = cpu_logical_map(i); - if (!can_schedule(p, cpu)) - continue; - tsk = cpu_curr(cpu); + prio = p->static_prio - bonus; + if (prio < MAX_RT_PRIO) + prio = MAX_RT_PRIO; + if (prio > MAX_PRIO-1) + prio = MAX_PRIO-1; + return prio; +} + +static inline void activate_task(task_t *p, runqueue_t *rq) +{ + unsigned long sleep_time = jiffies - p->sleep_timestamp; + prio_array_t *array = rq->active; + + if (!rt_task(p) && sleep_time) { /* - * We use the first available idle CPU. This creates - * a priority list between idle CPUs, but this is not - * a problem. + * This code gives a bonus to interactive tasks. We update + * an 'average sleep time' value here, based on + * sleep_timestamp. The more time a task spends sleeping, + * the higher the average gets - and the higher the priority + * boost gets as well. */ - if (tsk == idle_task(cpu)) { -#if defined(__i386__) && defined(CONFIG_SMP) - /* - * Check if two siblings are idle in the same - * physical package. Use them if found. - */ - if (smp_num_siblings == 2) { - if (cpu_curr(cpu_sibling_map[cpu]) == - idle_task(cpu_sibling_map[cpu])) { - oldest_idle = last_schedule(cpu); - target_tsk = tsk; - break; - } - - } -#endif - if (last_schedule(cpu) < oldest_idle) { - oldest_idle = last_schedule(cpu); - target_tsk = tsk; - } - } else { - if (oldest_idle == -1ULL) { - int prio = preemption_goodness(tsk, p, cpu); - - if (prio > max_prio) { - max_prio = prio; - target_tsk = tsk; - } - } - } - } - tsk = target_tsk; - if (tsk) { - if (oldest_idle != -1ULL) { - best_cpu = tsk->processor; - goto send_now_idle; - } - tsk->need_resched = 1; - if (tsk->processor != this_cpu) - smp_send_reschedule(tsk->processor); + p->sleep_avg += sleep_time; + if (p->sleep_avg > MAX_SLEEP_AVG) + p->sleep_avg = MAX_SLEEP_AVG; + p->prio = effective_prio(p); } - return; - + enqueue_task(p, array); + rq->nr_running++; +} -#else /* UP */ - int this_cpu = smp_processor_id(); - struct task_struct *tsk; - - tsk = cpu_curr(this_cpu); - if (preemption_goodness(tsk, p, this_cpu) > 0) - tsk->need_resched = 1; -#endif +static inline void deactivate_task(struct task_struct *p, runqueue_t *rq) +{ + rq->nr_running--; + dequeue_task(p, p->array); + p->array = NULL; } +static inline void resched_task(task_t *p) +{ + int need_resched; + + need_resched = p->need_resched; + wmb(); + p->need_resched = 1; + if (!need_resched && (p->cpu != smp_processor_id())) + smp_send_reschedule(p->cpu); +} + +#ifdef CONFIG_SMP + /* - * Careful! - * - * This has to add the process to the _beginning_ of the - * run-queue, not the end. See the comment about "This is - * subtle" in the scheduler proper.. + * Wait for a process to unschedule. This is used by the exit() and + * ptrace() code. */ -static inline void add_to_runqueue(struct task_struct * p) +void wait_task_inactive(task_t * p) { - list_add(&p->run_list, &runqueue_head); - nr_running++; + unsigned long flags; + runqueue_t *rq; + +repeat: + rq = task_rq(p); + while (unlikely(rq->curr == p)) { + cpu_relax(); + barrier(); + } + rq = lock_task_rq(p, &flags); + if (unlikely(rq->curr == p)) { + unlock_task_rq(rq, &flags); + goto repeat; + } + unlock_task_rq(rq, &flags); } -static inline void move_last_runqueue(struct task_struct * p) +/* + * The SMP message passing code calls this function whenever + * the new task has arrived at the target CPU. We move the + * new task into the local runqueue. + * + * This function must be called with interrupts disabled. + */ +void sched_task_migrated(task_t *new_task) { - list_del(&p->run_list); - list_add_tail(&p->run_list, &runqueue_head); + wait_task_inactive(new_task); + new_task->cpu = smp_processor_id(); + wake_up_process(new_task); } -static inline void move_first_runqueue(struct task_struct * p) +/* + * Kick the remote CPU if the task is running currently, + * this code is used by the signal code to signal tasks + * which are in user-mode as quickly as possible. + * + * (Note that we do this lockless - if the task does anything + * while the message is in flight then it will notice the + * sigpending condition anyway.) + */ +void kick_if_running(task_t * p) { - list_del(&p->run_list); - list_add(&p->run_list, &runqueue_head); + if (p == task_rq(p)->curr) + resched_task(p); } +#endif /* * Wake up a process. Put it on the run-queue if it's not @@ -348,392 +321,528 @@ * "current->state = TASK_RUNNING" to mark yourself runnable * without the overhead of this. */ -static inline int try_to_wake_up(struct task_struct * p, int synchronous) +static int try_to_wake_up(task_t * p, int synchronous) { unsigned long flags; int success = 0; + runqueue_t *rq; - /* - * We want the common case fall through straight, thus the goto. - */ - spin_lock_irqsave(&runqueue_lock, flags); + rq = lock_task_rq(p, &flags); p->state = TASK_RUNNING; - if (task_on_runqueue(p)) - goto out; - add_to_runqueue(p); - if (!synchronous || !(p->cpus_allowed & (1 << smp_processor_id()))) - reschedule_idle(p); - success = 1; -out: - spin_unlock_irqrestore(&runqueue_lock, flags); + if (!p->array) { + activate_task(p, rq); + if ((rq->curr == rq->idle) || (p->prio < rq->curr->prio)) + resched_task(rq->curr); + success = 1; + } + unlock_task_rq(rq, &flags); return success; } -inline int wake_up_process(struct task_struct * p) +int wake_up_process(task_t * p) { return try_to_wake_up(p, 0); } -static void process_timeout(unsigned long __data) +void wake_up_forked_process(task_t * p) { - struct task_struct * p = (struct task_struct *) __data; + runqueue_t *rq = this_rq(); - wake_up_process(p); + p->state = TASK_RUNNING; + if (!rt_task(p)) { + /* + * We decrease the sleep average of forking parents + * and children as well, to keep max-interactive tasks + * from forking tasks that are max-interactive. + */ + current->sleep_avg = current->sleep_avg * PARENT_PENALTY / 100; + p->sleep_avg = p->sleep_avg * CHILD_PENALTY / 100; + p->prio = effective_prio(p); + } + spin_lock_irq(&rq->lock); + p->cpu = smp_processor_id(); + activate_task(p, rq); + spin_unlock_irq(&rq->lock); } -/** - * schedule_timeout - sleep until timeout - * @timeout: timeout value in jiffies - * - * Make the current task sleep until @timeout jiffies have - * elapsed. The routine will return immediately unless - * the current task state has been set (see set_current_state()). - * - * You can set the task state as follows - - * - * %TASK_UNINTERRUPTIBLE - at least @timeout jiffies are guaranteed to - * pass before the routine returns. The routine will return 0 - * - * %TASK_INTERRUPTIBLE - the routine may return early if a signal is - * delivered to the current task. In this case the remaining time - * in jiffies will be returned, or 0 if the timer expired in time - * - * The current task state is guaranteed to be TASK_RUNNING when this - * routine returns. - * - * Specifying a @timeout value of %MAX_SCHEDULE_TIMEOUT will schedule - * the CPU away without a bound on the timeout. In this case the return - * value will be %MAX_SCHEDULE_TIMEOUT. +/* + * Potentially available exiting-child timeslices are + * retrieved here - this way the parent does not get + * penalized for creating too many processes. * - * In all cases the return value is guaranteed to be non-negative. + * (this cannot be used to 'generate' timeslices + * artificially, because any timeslice recovered here + * was given away by the parent in the first place.) */ -signed long schedule_timeout(signed long timeout) +void sched_exit(task_t * p) { - struct timer_list timer; - unsigned long expire; + __cli(); + current->time_slice += p->time_slice; + if (unlikely(current->time_slice > MAX_TIMESLICE)) + current->time_slice = MAX_TIMESLICE; + __sti(); + /* + * If the child was a (relative-) CPU hog then decrease + * the sleep_avg of the parent as well. + */ + if (p->sleep_avg < current->sleep_avg) + current->sleep_avg = (current->sleep_avg * EXIT_WEIGHT + + p->sleep_avg) / (EXIT_WEIGHT + 1); +} - switch (timeout) - { - case MAX_SCHEDULE_TIMEOUT: - /* - * These two special cases are useful to be comfortable - * in the caller. Nothing more. We could take - * MAX_SCHEDULE_TIMEOUT from one of the negative value - * but I' d like to return a valid offset (>=0) to allow - * the caller to do everything it want with the retval. - */ - schedule(); - goto out; - default: - /* - * Another bit of PARANOID. Note that the retval will be - * 0 since no piece of kernel is supposed to do a check - * for a negative retval of schedule_timeout() (since it - * should never happens anyway). You just have the printk() - * that will tell you if something is gone wrong and where. - */ - if (timeout < 0) - { - printk(KERN_ERR "schedule_timeout: wrong timeout " - "value %lx from %p\n", timeout, - __builtin_return_address(0)); - current->state = TASK_RUNNING; - goto out; - } - } +#if CONFIG_SMP +asmlinkage void schedule_tail(task_t *prev) +{ + spin_unlock_irq(&this_rq()->lock); +} +#endif - expire = timeout + jiffies; +static inline void context_switch(task_t *prev, task_t *next) +{ + struct mm_struct *mm = next->mm; + struct mm_struct *oldmm = prev->active_mm; - init_timer(&timer); - timer.expires = expire; - timer.data = (unsigned long) current; - timer.function = process_timeout; + prepare_to_switch(); - add_timer(&timer); - schedule(); - del_timer_sync(&timer); + if (unlikely(!mm)) { + next->active_mm = oldmm; + atomic_inc(&oldmm->mm_count); + enter_lazy_tlb(oldmm, next, smp_processor_id()); + } else + switch_mm(oldmm, mm, next, smp_processor_id()); - timeout = expire - jiffies; + if (unlikely(!prev->mm)) { + prev->active_mm = NULL; + mmdrop(oldmm); + } - out: - return timeout < 0 ? 0 : timeout; + /* + * Here we just switch the register state and the stack. There are + * 3 processes affected by a context switch: + * + * prev ==> .... ==> (last => next) + * + * It's the 'much more previous' 'prev' that is on next's stack, + * but prev is set to (the just run) 'last' process by switch_to(). + * This might sound slightly confusing but makes tons of sense. + */ + switch_to(prev, next, prev); } -/* - * schedule_tail() is getting called from the fork return path. This - * cleans up all remaining scheduler things, without impacting the - * common case. - */ -static inline void __schedule_tail(struct task_struct *prev) +unsigned long nr_running(void) { -#ifdef CONFIG_SMP - int policy; - - /* - * prev->policy can be written from here only before `prev' - * can be scheduled (before setting prev->cpus_runnable to ~0UL). - * Of course it must also be read before allowing prev - * to be rescheduled, but since the write depends on the read - * to complete, wmb() is enough. (the spin_lock() acquired - * before setting cpus_runnable is not enough because the spin_lock() - * common code semantics allows code outside the critical section - * to enter inside the critical section) - */ - policy = prev->policy; - prev->policy = policy & ~SCHED_YIELD; - wmb(); + unsigned long i, sum = 0; - /* - * fast path falls through. We have to clear cpus_runnable before - * checking prev->state to avoid a wakeup race. Protect against - * the task exiting early. - */ - task_lock(prev); - task_release_cpu(prev); - mb(); - if (prev->state == TASK_RUNNING) - goto needs_resched; + for (i = 0; i < smp_num_cpus; i++) + sum += cpu_rq(cpu_logical_map(i))->nr_running; -out_unlock: - task_unlock(prev); /* Synchronise here with release_task() if prev is TASK_ZOMBIE */ - return; + return sum; +} - /* - * Slow path - we 'push' the previous process and - * reschedule_idle() will attempt to find a new - * processor for it. (but it might preempt the - * current process as well.) We must take the runqueue - * lock and re-check prev->state to be correct. It might - * still happen that this process has a preemption - * 'in progress' already - but this is not a problem and - * might happen in other circumstances as well. - */ -needs_resched: - { - unsigned long flags; +unsigned long nr_context_switches(void) +{ + unsigned long i, sum = 0; - /* - * Avoid taking the runqueue lock in cases where - * no preemption-check is necessery: - */ - if ((prev == idle_task(smp_processor_id())) || - (policy & SCHED_YIELD)) - goto out_unlock; + for (i = 0; i < smp_num_cpus; i++) + sum += cpu_rq(cpu_logical_map(i))->nr_switches; - spin_lock_irqsave(&runqueue_lock, flags); - if ((prev->state == TASK_RUNNING) && !task_has_cpu(prev)) - reschedule_idle(prev); - spin_unlock_irqrestore(&runqueue_lock, flags); - goto out_unlock; - } -#else - prev->policy &= ~SCHED_YIELD; -#endif /* CONFIG_SMP */ + return sum; } -asmlinkage void schedule_tail(struct task_struct *prev) +#if CONFIG_SMP +/* + * Lock the busiest runqueue as well, this_rq is locked already. + * Recalculate nr_running if we have to drop the runqueue lock. + */ +static inline unsigned int double_lock_balance(runqueue_t *this_rq, + runqueue_t *busiest, int this_cpu, int idle, unsigned int nr_running) { - __schedule_tail(prev); + if (unlikely(!spin_trylock(&busiest->lock))) { + if (busiest < this_rq) { + spin_unlock(&this_rq->lock); + spin_lock(&busiest->lock); + spin_lock(&this_rq->lock); + /* Need to recalculate nr_running */ + if (idle || (this_rq->nr_running > this_rq->prev_nr_running[this_cpu])) + nr_running = this_rq->nr_running; + else + nr_running = this_rq->prev_nr_running[this_cpu]; + } else + spin_lock(&busiest->lock); + } + return nr_running; } /* - * 'schedule()' is the scheduler function. It's a very simple and nice - * scheduler: it's not perfect, but certainly works for most things. - * - * The goto is "interesting". + * Current runqueue is empty, or rebalance tick: if there is an + * inbalance (current runqueue is too short) then pull from + * busiest runqueue(s). * - * NOTE!! Task 0 is the 'idle' task, which gets called when no other - * tasks can run. It can not be killed, and it cannot sleep. The 'state' - * information in task[0] is never used. + * We call this with the current runqueue locked, + * irqs disabled. */ -asmlinkage void schedule(void) +static void load_balance(runqueue_t *this_rq, int idle) { - struct schedule_data * sched_data; - struct task_struct *prev, *next, *p; - struct list_head *tmp; - int this_cpu, c; + int imbalance, nr_running, load, max_load, + idx, i, this_cpu = smp_processor_id(); + task_t *next = this_rq->idle, *tmp; + runqueue_t *busiest, *rq_src; + prio_array_t *array; + list_t *head, *curr; + /* + * We search all runqueues to find the most busy one. + * We do this lockless to reduce cache-bouncing overhead, + * we re-check the 'best' source CPU later on again, with + * the lock held. + * + * We fend off statistical fluctuations in runqueue lengths by + * saving the runqueue length during the previous load-balancing + * operation and using the smaller one the current and saved lengths. + * If a runqueue is long enough for a longer amount of time then + * we recognize it and pull tasks from it. + * + * The 'current runqueue length' is a statistical maximum variable, + * for that one we take the longer one - to avoid fluctuations in + * the other direction. So for a load-balance to happen it needs + * stable long runqueue on the target CPU and stable short runqueue + * on the local runqueue. + * + * We make an exception if this CPU is about to become idle - in + * that case we are less picky about moving a task across CPUs and + * take what can be taken. + */ + if (idle || (this_rq->nr_running > this_rq->prev_nr_running[this_cpu])) + nr_running = this_rq->nr_running; + else + nr_running = this_rq->prev_nr_running[this_cpu]; - spin_lock_prefetch(&runqueue_lock); + busiest = NULL; + max_load = 1; + for (i = 0; i < smp_num_cpus; i++) { + rq_src = cpu_rq(cpu_logical_map(i)); + if (idle || (rq_src->nr_running < this_rq->prev_nr_running[i])) + load = rq_src->nr_running; + else + load = this_rq->prev_nr_running[i]; + this_rq->prev_nr_running[i] = rq_src->nr_running; + + if ((load > max_load) && (rq_src != this_rq)) { + busiest = rq_src; + max_load = load; + } + } - if (!current->active_mm) BUG(); -need_resched_back: - prev = current; - this_cpu = prev->processor; + if (likely(!busiest)) + return; - if (unlikely(in_interrupt())) { - printk("Scheduling in interrupt\n"); - BUG(); - } + imbalance = (max_load - nr_running) / 2; - release_kernel_lock(prev, this_cpu); + /* It needs an at least ~25% imbalance to trigger balancing. */ + if (!idle && (imbalance < (max_load + 3)/4)) + return; + nr_running = double_lock_balance(this_rq, busiest, this_cpu, idle, nr_running); /* - * 'sched_data' is protected by the fact that we can run - * only one process per CPU. + * Make sure nothing changed since we checked the + * runqueue length. */ - sched_data = & aligned_data[this_cpu].schedule_data; + if (busiest->nr_running <= this_rq->nr_running + 1) + goto out_unlock; - spin_lock_irq(&runqueue_lock); + /* + * We first consider expired tasks. Those will likely not be + * executed in the near future, and they are most likely to + * be cache-cold, thus switching CPUs has the least effect + * on them. + */ + if (busiest->expired->nr_active) + array = busiest->expired; + else + array = busiest->active; - /* move an exhausted RR process to be last.. */ - if (unlikely(prev->policy == SCHED_RR)) - if (!prev->counter) { - prev->counter = NICE_TO_TICKS(prev->nice); - move_last_runqueue(prev); +new_array: + /* Start searching at priority 0: */ + idx = 0; +skip_bitmap: + if (!idx) + idx = sched_find_first_bit(array->bitmap); + else + idx = find_next_bit(array->bitmap, MAX_PRIO, idx); + if (idx == MAX_PRIO) { + if (array == busiest->expired) { + array = busiest->active; + goto new_array; } - - switch (prev->state) { - case TASK_INTERRUPTIBLE: - if (signal_pending(prev)) { - prev->state = TASK_RUNNING; - break; - } - default: - del_from_runqueue(prev); - case TASK_RUNNING:; + goto out_unlock; } - prev->need_resched = 0; - - /* - * this is the scheduler proper: - */ -repeat_schedule: - /* - * Default process to select.. - */ - next = idle_task(this_cpu); - c = -1000; - list_for_each(tmp, &runqueue_head) { - p = list_entry(tmp, struct task_struct, run_list); - if (can_schedule(p, this_cpu)) { - int weight = goodness(p, this_cpu, prev->active_mm); - if (weight > c) - c = weight, next = p; + head = array->queue + idx; + curr = head->prev; +skip_queue: + tmp = list_entry(curr, task_t, run_list); + + /* + * We do not migrate tasks that are: + * 1) running (obviously), or + * 2) cannot be migrated to this CPU due to cpus_allowed, or + * 3) are cache-hot on their current CPU. + */ + +#define CAN_MIGRATE_TASK(p,rq,this_cpu) \ + ((jiffies - (p)->sleep_timestamp > cache_decay_ticks) && \ + ((p) != (rq)->curr) && \ + (tmp->cpus_allowed & (1 << (this_cpu)))) + + if (!CAN_MIGRATE_TASK(tmp, busiest, this_cpu)) { + curr = curr->next; + if (curr != head) + goto skip_queue; + idx++; + goto skip_bitmap; + } + next = tmp; + /* + * take the task out of the other runqueue and + * put it into this one: + */ + dequeue_task(next, array); + busiest->nr_running--; + next->cpu = this_cpu; + this_rq->nr_running++; + enqueue_task(next, this_rq->active); + if (next->prio < current->prio) + current->need_resched = 1; + if (!idle && --imbalance) { + if (array == busiest->expired) { + array = busiest->active; + goto new_array; } } +out_unlock: + spin_unlock(&busiest->lock); +} + +/* + * One of the idle_cpu_tick() or the busy_cpu_tick() function will + * gets called every timer tick, on every CPU. Our balancing action + * frequency and balancing agressivity depends on whether the CPU is + * idle or not. + * + * busy-rebalance every 250 msecs. idle-rebalance every 1 msec. (or on + * systems with HZ=100, every 10 msecs.) + */ +#define BUSY_REBALANCE_TICK (HZ/4 ?: 1) +#define IDLE_REBALANCE_TICK (HZ/1000 ?: 1) + +static inline void idle_tick(void) +{ + if (jiffies % IDLE_REBALANCE_TICK) + return; + spin_lock(&this_rq()->lock); + load_balance(this_rq(), 1); + spin_unlock(&this_rq()->lock); +} + +#endif - /* Do we need to re-calculate counters? */ - if (unlikely(!c)) { - struct task_struct *p; - - spin_unlock_irq(&runqueue_lock); - read_lock(&tasklist_lock); - for_each_task(p) - p->counter = (p->counter >> 1) + NICE_TO_TICKS(p->nice); - read_unlock(&tasklist_lock); - spin_lock_irq(&runqueue_lock); - goto repeat_schedule; +/* + * We place interactive tasks back into the active array, if possible. + * + * To guarantee that this does not starve expired tasks we ignore the + * interactivity of a task if the first expired task had to wait more + * than a 'reasonable' amount of time. This deadline timeout is + * load-dependent, as the frequency of array switched decreases with + * increasing number of running tasks: + */ +#define EXPIRED_STARVING(rq) \ + ((rq)->expired_timestamp && \ + (jiffies - (rq)->expired_timestamp >= \ + STARVATION_LIMIT * ((rq)->nr_running) + 1)) + +/* + * This function gets called by the timer code, with HZ frequency. + * We call it with interrupts disabled. + */ +void scheduler_tick(int user_tick, int system) +{ + int cpu = smp_processor_id(); + runqueue_t *rq = this_rq(); + task_t *p = current; + + if (p == rq->idle) { + if (local_bh_count(cpu) || local_irq_count(cpu) > 1) + kstat.per_cpu_system[cpu] += system; +#if CONFIG_SMP + idle_tick(); +#endif + return; } + if (TASK_NICE(p) > 0) + kstat.per_cpu_nice[cpu] += user_tick; + else + kstat.per_cpu_user[cpu] += user_tick; + kstat.per_cpu_system[cpu] += system; + /* Task might have expired already, but not scheduled off yet */ + if (p->array != rq->active) { + p->need_resched = 1; + return; + } + spin_lock(&rq->lock); + if (unlikely(rt_task(p))) { + /* + * RR tasks need a special form of timeslice management. + * FIFO tasks have no timeslices. + */ + if ((p->policy == SCHED_RR) && !--p->time_slice) { + p->time_slice = TASK_TIMESLICE(p); + p->need_resched = 1; + + /* put it at the end of the queue: */ + dequeue_task(p, rq->active); + enqueue_task(p, rq->active); + } + goto out; + } /* - * from this point on nothing can prevent us from - * switching to the next task, save this fact in - * sched_data. - */ - sched_data->curr = next; - task_set_cpu(next, this_cpu); - spin_unlock_irq(&runqueue_lock); - - if (unlikely(prev == next)) { - /* We won't go through the normal tail, so do this by hand */ - prev->policy &= ~SCHED_YIELD; - goto same_process; + * The task was running during this tick - update the + * time slice counter and the sleep average. Note: we + * do not update a process's priority until it either + * goes to sleep or uses up its timeslice. This makes + * it possible for interactive tasks to use up their + * timeslices at their highest priority levels. + */ + if (p->sleep_avg) + p->sleep_avg--; + if (!--p->time_slice) { + dequeue_task(p, rq->active); + p->need_resched = 1; + p->prio = effective_prio(p); + p->time_slice = TASK_TIMESLICE(p); + + if (!TASK_INTERACTIVE(p) || EXPIRED_STARVING(rq)) { + if (!rq->expired_timestamp) + rq->expired_timestamp = jiffies; + enqueue_task(p, rq->expired); + } else + enqueue_task(p, rq->active); } +out: +#if CONFIG_SMP + if (!(jiffies % BUSY_REBALANCE_TICK)) + load_balance(rq, 0); +#endif + spin_unlock(&rq->lock); +} -#ifdef CONFIG_SMP - /* - * maintain the per-process 'last schedule' value. - * (this has to be recalculated even if we reschedule to - * the same process) Currently this is only used on SMP, - * and it's approximate, so we do not have to maintain - * it while holding the runqueue spinlock. - */ - sched_data->last_schedule = get_cycles(); +void scheduling_functions_start_here(void) { } - /* - * We drop the scheduler lock early (it's a global spinlock), - * thus we have to lock the previous process from getting - * rescheduled during switch_to(). - */ +/* + * 'schedule()' is the main scheduler function. + */ +asmlinkage void schedule(void) +{ + task_t *prev = current, *next; + runqueue_t *rq = this_rq(); + prio_array_t *array; + list_t *queue; + int idx; -#endif /* CONFIG_SMP */ + if (unlikely(in_interrupt())) + BUG(); + release_kernel_lock(prev, smp_processor_id()); + prev->sleep_timestamp = jiffies; + spin_lock_irq(&rq->lock); - kstat.context_swtch++; - /* - * there are 3 processes which are affected by a context switch: - * - * prev == .... ==> (last => next) - * - * It's the 'much more previous' 'prev' that is on next's stack, - * but prev is set to (the just run) 'last' process by switch_to(). - * This might sound slightly confusing but makes tons of sense. - */ - prepare_to_switch(); - { - struct mm_struct *mm = next->mm; - struct mm_struct *oldmm = prev->active_mm; - if (!mm) { - if (next->active_mm) BUG(); - next->active_mm = oldmm; - atomic_inc(&oldmm->mm_count); - enter_lazy_tlb(oldmm, next, this_cpu); - } else { - if (next->active_mm != mm) BUG(); - switch_mm(oldmm, mm, next, this_cpu); + switch (prev->state) { + case TASK_INTERRUPTIBLE: + if (unlikely(signal_pending(prev))) { + prev->state = TASK_RUNNING; + break; } + default: + deactivate_task(prev, rq); + case TASK_RUNNING: + ; + } +#if CONFIG_SMP +pick_next_task: +#endif + if (unlikely(!rq->nr_running)) { +#if CONFIG_SMP + load_balance(rq, 1); + if (rq->nr_running) + goto pick_next_task; +#endif + next = rq->idle; + rq->expired_timestamp = 0; + goto switch_tasks; + } - if (!prev->mm) { - prev->active_mm = NULL; - mmdrop(oldmm); - } + array = rq->active; + if (unlikely(!array->nr_active)) { + /* + * Switch the active and expired arrays. + */ + rq->active = rq->expired; + rq->expired = array; + array = rq->active; + rq->expired_timestamp = 0; } - /* - * This just switches the register state and the - * stack. - */ - switch_to(prev, next, prev); - __schedule_tail(prev); + idx = sched_find_first_bit(array->bitmap); + queue = array->queue + idx; + next = list_entry(queue->next, task_t, run_list); + +switch_tasks: + prefetch(next); + prev->need_resched = 0; + + if (likely(prev != next)) { + rq->nr_switches++; + rq->curr = next; + context_switch(prev, next); + /* + * The runqueue pointer might be from another CPU + * if the new task was last running on a different + * CPU - thus re-load it. + */ + barrier(); + rq = this_rq(); + } + spin_unlock_irq(&rq->lock); -same_process: reacquire_kernel_lock(current); - if (current->need_resched) - goto need_resched_back; return; } /* - * The core wakeup function. Non-exclusive wakeups (nr_exclusive == 0) just wake everything - * up. If it's an exclusive wakeup (nr_exclusive == small +ve number) then we wake all the - * non-exclusive tasks and one exclusive task. + * The core wakeup function. Non-exclusive wakeups (nr_exclusive == 0) just + * wake everything up. If it's an exclusive wakeup (nr_exclusive == small +ve + * number) then we wake all the non-exclusive tasks and one exclusive task. * * There are circumstances in which we can try to wake a task which has already - * started to run but is not in state TASK_RUNNING. try_to_wake_up() returns zero - * in this (rare) case, and we handle it by contonuing to scan the queue. + * started to run but is not in state TASK_RUNNING. try_to_wake_up() returns + * zero in this (rare) case, and we handle it by continuing to scan the queue. */ static inline void __wake_up_common (wait_queue_head_t *q, unsigned int mode, int nr_exclusive, const int sync) { struct list_head *tmp; - struct task_struct *p; + task_t *p; - CHECK_MAGIC_WQHEAD(q); - WQ_CHECK_LIST_HEAD(&q->task_list); - list_for_each(tmp,&q->task_list) { unsigned int state; - wait_queue_t *curr = list_entry(tmp, wait_queue_t, task_list); + wait_queue_t *curr = list_entry(tmp, wait_queue_t, task_list); - CHECK_MAGIC(curr->__magic); p = curr->task; state = p->state; - if (state & mode) { - WQ_NOTE_WAKER(curr); - if (try_to_wake_up(p, sync) && (curr->flags&WQ_FLAG_EXCLUSIVE) && !--nr_exclusive) - break; - } + if ((state & mode) && + try_to_wake_up(p, sync) && + ((curr->flags & WQ_FLAG_EXCLUSIVE) && + !--nr_exclusive)) + break; } } @@ -761,15 +870,15 @@ { unsigned long flags; - spin_lock_irqsave(&x->wait.lock, flags); + wq_write_lock_irqsave(&x->wait.lock, flags); x->done++; __wake_up_common(&x->wait, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1, 0); - spin_unlock_irqrestore(&x->wait.lock, flags); + wq_write_unlock_irqrestore(&x->wait.lock, flags); } void wait_for_completion(struct completion *x) { - spin_lock_irq(&x->wait.lock); + wq_write_lock_irq(&x->wait.lock); if (!x->done) { DECLARE_WAITQUEUE(wait, current); @@ -777,14 +886,14 @@ __add_wait_queue_tail(&x->wait, &wait); do { __set_current_state(TASK_UNINTERRUPTIBLE); - spin_unlock_irq(&x->wait.lock); + wq_write_unlock_irq(&x->wait.lock); schedule(); - spin_lock_irq(&x->wait.lock); + wq_write_lock_irq(&x->wait.lock); } while (!x->done); __remove_wait_queue(&x->wait, &wait); } x->done--; - spin_unlock_irq(&x->wait.lock); + wq_write_unlock_irq(&x->wait.lock); } #define SLEEP_ON_VAR \ @@ -850,8 +959,71 @@ return timeout; } +/* + * Change the current task's CPU affinity. Migrate the process to a + * proper CPU and schedule away if the current CPU is removed from + * the allowed bitmask. + */ +void set_cpus_allowed(task_t *p, unsigned long new_mask) +{ + new_mask &= cpu_online_map; + if (!new_mask) + BUG(); + if (p != current) + BUG(); + + p->cpus_allowed = new_mask; + /* + * Can the task run on the current CPU? If not then + * migrate the process off to a proper CPU. + */ + if (new_mask & (1UL << smp_processor_id())) + return; +#if CONFIG_SMP + current->state = TASK_UNINTERRUPTIBLE; + smp_migrate_task(__ffs(new_mask), current); + + schedule(); +#endif +} + void scheduling_functions_end_here(void) { } +void set_user_nice(task_t *p, long nice) +{ + unsigned long flags; + prio_array_t *array; + runqueue_t *rq; + + if (TASK_NICE(p) == nice || nice < -20 || nice > 19) + return; + /* + * We have to be careful, if called from sys_setpriority(), + * the task might be in the middle of scheduling on another CPU. + */ + rq = lock_task_rq(p, &flags); + if (rt_task(p)) { + p->static_prio = NICE_TO_PRIO(nice); + goto out_unlock; + } + array = p->array; + if (array) + dequeue_task(p, array); + p->static_prio = NICE_TO_PRIO(nice); + p->prio = NICE_TO_PRIO(nice); + if (array) { + enqueue_task(p, array); + /* + * If the task is running and lowered its priority, + * or increased its priority then reschedule its CPU: + */ + if ((NICE_TO_PRIO(nice) < p->static_prio) || (p == rq->curr)) + resched_task(rq->curr); + } +out_unlock: + unlock_task_rq(rq, &flags); +} + #ifndef __alpha__ /* @@ -862,7 +1034,7 @@ asmlinkage long sys_nice(int increment) { - long newprio; + long nice; /* * Setpriority might change our priority at the same moment. @@ -878,32 +1050,46 @@ if (increment > 40) increment = 40; - newprio = current->nice + increment; - if (newprio < -20) - newprio = -20; - if (newprio > 19) - newprio = 19; - current->nice = newprio; + nice = PRIO_TO_NICE(current->static_prio) + increment; + if (nice < -20) + nice = -20; + if (nice > 19) + nice = 19; + set_user_nice(current, nice); return 0; } #endif -static inline struct task_struct *find_process_by_pid(pid_t pid) +/* + * This is the priority value as seen by users in /proc + * + * RT tasks are offset by -200. Normal tasks are centered + * around 0, value goes from -16 to +15. + */ +int task_prio(task_t *p) { - struct task_struct *tsk = current; + return p->prio - 100; +} - if (pid) - tsk = find_task_by_pid(pid); - return tsk; +int task_nice(task_t *p) +{ + return TASK_NICE(p); +} + +static inline task_t *find_process_by_pid(pid_t pid) +{ + return pid ? find_task_by_pid(pid) : current; } -static int setscheduler(pid_t pid, int policy, - struct sched_param *param) +static int setscheduler(pid_t pid, int policy, struct sched_param *param) { struct sched_param lp; - struct task_struct *p; + prio_array_t *array; + unsigned long flags; + runqueue_t *rq; int retval; + task_t *p; retval = -EINVAL; if (!param || pid < 0) @@ -917,14 +1103,19 @@ * We play safe to avoid deadlocks. */ read_lock_irq(&tasklist_lock); - spin_lock(&runqueue_lock); p = find_process_by_pid(pid); retval = -ESRCH; if (!p) - goto out_unlock; - + goto out_unlock_tasklist; + + /* + * To be able to change p->policy safely, the apropriate + * runqueue lock must be held. + */ + rq = lock_task_rq(p, &flags); + if (policy < 0) policy = p->policy; else { @@ -945,30 +1136,36 @@ goto out_unlock; retval = -EPERM; - if ((policy == SCHED_FIFO || policy == SCHED_RR) && + if ((policy == SCHED_FIFO || policy == SCHED_RR) && !capable(CAP_SYS_NICE)) goto out_unlock; if ((current->euid != p->euid) && (current->euid != p->uid) && !capable(CAP_SYS_NICE)) goto out_unlock; + array = p->array; + if (array) + deactivate_task(p, task_rq(p)); retval = 0; p->policy = policy; p->rt_priority = lp.sched_priority; - if (task_on_runqueue(p)) - move_first_runqueue(p); - - current->need_resched = 1; + if (rt_task(p)) + p->prio = 99 - p->rt_priority; + else + p->prio = p->static_prio; + if (array) + activate_task(p, task_rq(p)); out_unlock: - spin_unlock(&runqueue_lock); + unlock_task_rq(rq, &flags); +out_unlock_tasklist: read_unlock_irq(&tasklist_lock); out_nounlock: return retval; } -asmlinkage long sys_sched_setscheduler(pid_t pid, int policy, +asmlinkage long sys_sched_setscheduler(pid_t pid, int policy, struct sched_param *param) { return setscheduler(pid, policy, param); @@ -981,7 +1178,7 @@ asmlinkage long sys_sched_getscheduler(pid_t pid) { - struct task_struct *p; + task_t *p; int retval; retval = -EINVAL; @@ -992,7 +1189,7 @@ read_lock(&tasklist_lock); p = find_process_by_pid(pid); if (p) - retval = p->policy & ~SCHED_YIELD; + retval = p->policy; read_unlock(&tasklist_lock); out_nounlock: @@ -1001,7 +1198,7 @@ asmlinkage long sys_sched_getparam(pid_t pid, struct sched_param *param) { - struct task_struct *p; + task_t *p; struct sched_param lp; int retval; @@ -1032,42 +1229,64 @@ asmlinkage long sys_sched_yield(void) { + task_t *prev = current, *next; + runqueue_t *rq = this_rq(); + prio_array_t *array; + list_t *queue; + + if (unlikely(prev->state != TASK_RUNNING)) { + schedule(); + return 0; + } + release_kernel_lock(prev, smp_processor_id()); + prev->sleep_timestamp = jiffies; /* - * Trick. sched_yield() first counts the number of truly - * 'pending' runnable processes, then returns if it's - * only the current processes. (This test does not have - * to be atomic.) In threaded applications this optimization - * gets triggered quite often. + * Decrease the yielding task's priority by one, to avoid + * livelocks. This priority loss is temporary, it's recovered + * once the current timeslice expires. + * + * If priority is already MAX_PRIO-1 then we still + * roundrobin the task within the runlist. */ + spin_lock_irq(&rq->lock); + array = current->array; + /* + * If the task has reached maximum priority (or is a RT task) + * then just requeue the task to the end of the runqueue: + */ + if (likely(current->prio == MAX_PRIO-1 || rt_task(current))) { + list_del(¤t->run_list); + list_add_tail(¤t->run_list, array->queue + current->prio); + } else { + list_del(¤t->run_list); + if (list_empty(array->queue + current->prio)) + __clear_bit(current->prio, array->bitmap); + current->prio++; + list_add_tail(¤t->run_list, array->queue + current->prio); + __set_bit(current->prio, array->bitmap); + } + /* + * Context-switch manually. This is equivalent to + * calling schedule(), but faster, because yield() + * knows lots of things that can be optimized away + * from the generic scheduler path: + */ + queue = array->queue + sched_find_first_bit(array->bitmap); + next = list_entry(queue->next, task_t, run_list); + prefetch(next); - int nr_pending = nr_running; - -#if CONFIG_SMP - int i; - - // Subtract non-idle processes running on other CPUs. - for (i = 0; i < smp_num_cpus; i++) { - int cpu = cpu_logical_map(i); - if (aligned_data[cpu].schedule_data.curr != idle_task(cpu)) - nr_pending--; + prev->need_resched = 0; + if (likely(prev != next)) { + rq->nr_switches++; + rq->curr = next; + context_switch(prev, next); + barrier(); + rq = this_rq(); } -#else - // on UP this process is on the runqueue as well - nr_pending--; -#endif - if (nr_pending) { - /* - * This process can only be rescheduled by us, - * so this is safe without any locking. - */ - if (current->policy == SCHED_OTHER) - current->policy |= SCHED_YIELD; - current->need_resched = 1; + spin_unlock_irq(&rq->lock); + + reacquire_kernel_lock(current); - spin_lock_irq(&runqueue_lock); - move_last_runqueue(current); - spin_unlock_irq(&runqueue_lock); - } return 0; } @@ -1105,7 +1324,7 @@ asmlinkage long sys_sched_rr_get_interval(pid_t pid, struct timespec *interval) { struct timespec t; - struct task_struct *p; + task_t *p; int retval = -EINVAL; if (pid < 0) @@ -1115,8 +1334,8 @@ read_lock(&tasklist_lock); p = find_process_by_pid(pid); if (p) - jiffies_to_timespec(p->policy & SCHED_FIFO ? 0 : NICE_TO_TICKS(p->nice), - &t); + jiffies_to_timespec(p->policy & SCHED_FIFO ? + 0 : TASK_TIMESLICE(p), &t); read_unlock(&tasklist_lock); if (p) retval = copy_to_user(interval, &t, sizeof(t)) ? -EFAULT : 0; @@ -1124,14 +1343,14 @@ return retval; } -static void show_task(struct task_struct * p) +static void show_task(task_t * p) { unsigned long free = 0; int state; static const char * stat_nam[] = { "R", "S", "D", "Z", "T", "W" }; printk("%-13.13s ", p->comm); - state = p->state ? ffz(~p->state) + 1 : 0; + state = p->state ? __ffs(p->state) + 1 : 0; if (((unsigned) state) < sizeof(stat_nam)/sizeof(char *)) printk(stat_nam[state]); else @@ -1172,7 +1391,7 @@ printk(" (NOTLB)\n"); { - extern void show_trace_task(struct task_struct *tsk); + extern void show_trace_task(task_t *tsk); show_trace_task(p); } } @@ -1194,7 +1413,7 @@ void show_state(void) { - struct task_struct *p; + task_t *p; #if (BITS_PER_LONG == 32) printk("\n" @@ -1217,121 +1436,88 @@ read_unlock(&tasklist_lock); } -/** - * reparent_to_init() - Reparent the calling kernel thread to the init task. - * - * If a kernel thread is launched as a result of a system call, or if - * it ever exits, it should generally reparent itself to init so that - * it is correctly cleaned up on exit. - * - * The various task state such as scheduling policy and priority may have - * been inherited fro a user process, so we reset them to sane values here. - * - * NOTE that reparent_to_init() gives the caller full capabilities. - */ -void reparent_to_init(void) +static inline void double_rq_lock(runqueue_t *rq1, runqueue_t *rq2) { - struct task_struct *this_task = current; - - write_lock_irq(&tasklist_lock); - - /* Reparent to init */ - REMOVE_LINKS(this_task); - this_task->p_pptr = child_reaper; - this_task->p_opptr = child_reaper; - SET_LINKS(this_task); - - /* Set the exit signal to SIGCHLD so we signal init on exit */ - this_task->exit_signal = SIGCHLD; - - /* We also take the runqueue_lock while altering task fields - * which affect scheduling decisions */ - spin_lock(&runqueue_lock); - - this_task->ptrace = 0; - this_task->nice = DEF_NICE; - this_task->policy = SCHED_OTHER; - /* cpus_allowed? */ - /* rt_priority? */ - /* signals? */ - this_task->cap_effective = CAP_INIT_EFF_SET; - this_task->cap_inheritable = CAP_INIT_INH_SET; - this_task->cap_permitted = CAP_FULL_SET; - this_task->keep_capabilities = 0; - memcpy(this_task->rlim, init_task.rlim, sizeof(*(this_task->rlim))); - this_task->user = INIT_USER; - - spin_unlock(&runqueue_lock); - write_unlock_irq(&tasklist_lock); + if (rq1 == rq2) + spin_lock(&rq1->lock); + else { + if (rq1 < rq2) { + spin_lock(&rq1->lock); + spin_lock(&rq2->lock); + } else { + spin_lock(&rq2->lock); + spin_lock(&rq1->lock); + } + } } -/* - * Put all the gunge required to become a kernel thread without - * attached user resources in one place where it belongs. - */ - -void daemonize(void) +static inline void double_rq_unlock(runqueue_t *rq1, runqueue_t *rq2) { - 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; - current->tty = NULL; - - /* Become as one with the init task */ - - exit_fs(current); /* current->fs->count--; */ - fs = init_task.fs; - current->fs = fs; - atomic_inc(&fs->count); - exit_files(current); - current->files = init_task.files; - atomic_inc(¤t->files->count); + spin_unlock(&rq1->lock); + if (rq1 != rq2) + spin_unlock(&rq2->lock); } -extern unsigned long wait_init_idle; - -void __init init_idle(void) +void init_idle(task_t *idle, int cpu) { - struct schedule_data * sched_data; - sched_data = &aligned_data[smp_processor_id()].schedule_data; + runqueue_t *idle_rq = cpu_rq(cpu), *rq = idle->array->rq; + unsigned long flags; - if (current != &init_task && task_on_runqueue(current)) { - printk("UGH! (%d:%d) was on the runqueue, removing.\n", - smp_processor_id(), current->pid); - del_from_runqueue(current); - } - sched_data->curr = current; - sched_data->last_schedule = get_cycles(); - clear_bit(current->processor, &wait_init_idle); + __save_flags(flags); + __cli(); + double_rq_lock(idle_rq, rq); + + idle_rq->curr = idle_rq->idle = idle; + deactivate_task(idle, rq); + idle->array = NULL; + idle->prio = MAX_PRIO; + idle->state = TASK_RUNNING; + idle->cpu = cpu; + double_rq_unlock(idle_rq, rq); + idle->need_resched = 1; + __restore_flags(flags); } -extern void init_timervecs (void); +extern void init_timervecs(void); +extern void timer_bh(void); +extern void tqueue_bh(void); +extern void immediate_bh(void); void __init sched_init(void) { + runqueue_t *rq; + int i, j, k; + + for (i = 0; i < NR_CPUS; i++) { + runqueue_t *rq = cpu_rq(i); + prio_array_t *array; + + rq->active = rq->arrays + 0; + rq->expired = rq->arrays + 1; + spin_lock_init(&rq->lock); + + for (j = 0; j < 2; j++) { + array = rq->arrays + j; + array->rq = rq; + array->lock = &rq->lock; + for (k = 0; k < MAX_PRIO; k++) { + INIT_LIST_HEAD(array->queue + k); + __clear_bit(k, array->bitmap); + } + // delimiter for bitsearch + __set_bit(MAX_PRIO, array->bitmap); + } + } /* * We have to do a little magic to get the first * process right in SMP mode. */ - int cpu = smp_processor_id(); - int nr; - - init_task.processor = cpu; - - for(nr = 0; nr < PIDHASH_SZ; nr++) - pidhash[nr] = NULL; + rq = this_rq(); + rq->curr = current; + rq->idle = current; + wake_up_process(current); init_timervecs(); - init_bh(TIMER_BH, timer_bh); init_bh(TQUEUE_BH, tqueue_bh); init_bh(IMMEDIATE_BH, immediate_bh); @@ -1340,5 +1526,5 @@ * The boot idle thread does lazy MMU switching as well: */ atomic_inc(&init_mm.mm_count); - enter_lazy_tlb(&init_mm, current, cpu); + enter_lazy_tlb(&init_mm, current, smp_processor_id()); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/signal.c linux.19pre5-ac1/kernel/signal.c --- linux.19p5/kernel/signal.c Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/kernel/signal.c Thu Mar 14 22:28:59 2002 @@ -507,12 +507,9 @@ * process of changing - but no harm is done by that * other than doing an extra (lightweight) IPI interrupt. */ - spin_lock(&runqueue_lock); - if (task_has_cpu(t) && t->processor != smp_processor_id()) - smp_send_reschedule(t->processor); - spin_unlock(&runqueue_lock); -#endif /* CONFIG_SMP */ - + if ((t->state == TASK_RUNNING) && (t->cpu != cpu())) + kick_if_running(t); +#endif if (t->state & TASK_INTERRUPTIBLE) { wake_up_process(t); return; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/softirq.c linux.19pre5-ac1/kernel/softirq.c --- linux.19p5/kernel/softirq.c Thu Apr 4 13:18:16 2002 +++ linux.19pre5-ac1/kernel/softirq.c Wed Feb 27 18:32:03 2002 @@ -259,10 +259,9 @@ while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) { current->state = TASK_RUNNING; - do { - current->policy |= SCHED_YIELD; - schedule(); - } while (test_bit(TASKLET_STATE_SCHED, &t->state)); + do + sys_sched_yield(); + while (test_bit(TASKLET_STATE_SCHED, &t->state)); } tasklet_unlock_wait(t); clear_bit(TASKLET_STATE_SCHED, &t->state); @@ -365,13 +364,13 @@ int cpu = cpu_logical_map(bind_cpu); daemonize(); - current->nice = 19; + set_user_nice(current, 19); sigfillset(¤t->blocked); /* Migrate to the right CPU */ - current->cpus_allowed = 1UL << cpu; - while (smp_processor_id() != cpu) - schedule(); + set_cpus_allowed(current, 1UL << cpu); + if (cpu() != cpu) + BUG(); sprintf(current->comm, "ksoftirqd_CPU%d", bind_cpu); @@ -396,7 +395,7 @@ } } -static __init int spawn_ksoftirqd(void) +__init int spawn_ksoftirqd(void) { int cpu; @@ -405,10 +404,8 @@ CLONE_FS | CLONE_FILES | CLONE_SIGNAL) < 0) printk("spawn_ksoftirqd() failed for cpu %d\n", cpu); else { - while (!ksoftirqd_task(cpu_logical_map(cpu))) { - current->policy |= SCHED_YIELD; - schedule(); - } + while (!ksoftirqd_task(cpu_logical_map(cpu))) + sys_sched_yield(); } } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/sys.c linux.19pre5-ac1/kernel/sys.c --- linux.19p5/kernel/sys.c Thu Apr 4 13:18:16 2002 +++ linux.19pre5-ac1/kernel/sys.c Wed Feb 27 18:32:03 2002 @@ -220,10 +220,10 @@ } if (error == -ESRCH) error = 0; - if (niceval < p->nice && !capable(CAP_SYS_NICE)) + if (niceval < task_nice(p) && !capable(CAP_SYS_NICE)) error = -EACCES; else - p->nice = niceval; + set_user_nice(p, niceval); } read_unlock(&tasklist_lock); @@ -249,7 +249,7 @@ long niceval; if (!proc_sel(p, which, who)) continue; - niceval = 20 - p->nice; + niceval = 20 - task_nice(p); if (niceval > retval) retval = niceval; } @@ -490,9 +490,10 @@ } } -static int set_user(uid_t new_ruid, int dumpclear) +int set_user(uid_t new_ruid, int dumpclear) { struct user_struct *new_user, *old_user; + struct task_struct *this_task = current; /* What if a process setreuid()'s and this brings the * new uid over his NPROC rlimit? We can check this now @@ -502,17 +503,16 @@ new_user = alloc_uid(new_ruid); if (!new_user) return -EAGAIN; - old_user = current->user; - atomic_dec(&old_user->processes); + old_user = this_task->user; atomic_inc(&new_user->processes); + atomic_dec(&old_user->processes); - if(dumpclear) - { - current->mm->dumpable = 0; + if (dumpclear && this_task->mm) { + this_task->mm->dumpable = 0; wmb(); } - current->uid = new_ruid; - current->user = new_user; + this_task->uid = new_ruid; + this_task->user = new_user; free_uid(old_user); return 0; } @@ -1128,6 +1128,12 @@ if (resource == RLIMIT_NOFILE) { if (new_rlim.rlim_cur > NR_OPEN || new_rlim.rlim_max > NR_OPEN) return -EPERM; + } else if (resource == RLIMIT_RSS && current->mm) { + /* rlimit is specified in bytes, convert to pages */ + unsigned long pages = RLIM_INFINITY; + if (new_rlim.rlim_cur != RLIM_INFINITY) + pages = new_rlim.rlim_cur >> PAGE_SHIFT; + current->mm->rlimit_rss = pages; } *old_rlim = new_rlim; return 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/sysctl.c linux.19pre5-ac1/kernel/sysctl.c --- linux.19p5/kernel/sysctl.c Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/kernel/sysctl.c Tue Feb 26 23:22:43 2002 @@ -260,6 +260,8 @@ }; static ctl_table vm_table[] = { + {VM_FREEPG, "freepages", + &freepages, sizeof(freepages_t), 0644, NULL, &proc_dointvec}, {VM_BDFLUSH, "bdflush", &bdf_prm, 9*sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec, NULL, &bdflush_min, &bdflush_max}, @@ -271,12 +273,12 @@ &pgt_cache_water, 2*sizeof(int), 0644, NULL, &proc_dointvec}, {VM_PAGE_CLUSTER, "page-cluster", &page_cluster, sizeof(int), 0644, NULL, &proc_dointvec}, + {VM_MAX_MAP_COUNT, "max_map_count", + &max_map_count, sizeof(int), 0644, NULL, &proc_dointvec}, {VM_MIN_READAHEAD, "min-readahead", &vm_min_readahead,sizeof(int), 0644, NULL, &proc_dointvec}, {VM_MAX_READAHEAD, "max-readahead", &vm_max_readahead,sizeof(int), 0644, NULL, &proc_dointvec}, - {VM_MAX_MAP_COUNT, "max_map_count", - &max_map_count, sizeof(int), 0644, NULL, &proc_dointvec}, {0} }; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/timer.c linux.19pre5-ac1/kernel/timer.c --- linux.19p5/kernel/timer.c Thu Apr 4 13:18:17 2002 +++ linux.19pre5-ac1/kernel/timer.c Wed Feb 27 18:32:03 2002 @@ -25,6 +25,8 @@ #include +struct kernel_stat kstat; + /* * Timekeeping variables */ @@ -582,18 +584,7 @@ int cpu = smp_processor_id(), system = user_tick ^ 1; update_one_process(p, user_tick, system, cpu); - if (p->pid) { - if (--p->counter <= 0) { - p->counter = 0; - p->need_resched = 1; - } - if (p->nice > 0) - kstat.per_cpu_nice[cpu] += user_tick; - else - kstat.per_cpu_user[cpu] += user_tick; - kstat.per_cpu_system[cpu] += system; - } else if (local_bh_count(cpu) || local_irq_count(cpu) > 1) - kstat.per_cpu_system[cpu] += system; + scheduler_tick(user_tick, system); } /* @@ -794,6 +785,89 @@ #endif +static void process_timeout(unsigned long __data) +{ + wake_up_process((task_t *)__data); +} + +/** + * schedule_timeout - sleep until timeout + * @timeout: timeout value in jiffies + * + * Make the current task sleep until @timeout jiffies have + * elapsed. The routine will return immediately unless + * the current task state has been set (see set_current_state()). + * + * You can set the task state as follows - + * + * %TASK_UNINTERRUPTIBLE - at least @timeout jiffies are guaranteed to + * pass before the routine returns. The routine will return 0 + * + * %TASK_INTERRUPTIBLE - the routine may return early if a signal is + * delivered to the current task. In this case the remaining time + * in jiffies will be returned, or 0 if the timer expired in time + * + * The current task state is guaranteed to be TASK_RUNNING when this + * routine returns. + * + * Specifying a @timeout value of %MAX_SCHEDULE_TIMEOUT will schedule + * the CPU away without a bound on the timeout. In this case the return + * value will be %MAX_SCHEDULE_TIMEOUT. + * + * In all cases the return value is guaranteed to be non-negative. + */ +signed long schedule_timeout(signed long timeout) +{ + struct timer_list timer; + unsigned long expire; + + switch (timeout) + { + case MAX_SCHEDULE_TIMEOUT: + /* + * These two special cases are useful to be comfortable + * in the caller. Nothing more. We could take + * MAX_SCHEDULE_TIMEOUT from one of the negative value + * but I' d like to return a valid offset (>=0) to allow + * the caller to do everything it want with the retval. + */ + schedule(); + goto out; + default: + /* + * Another bit of PARANOID. Note that the retval will be + * 0 since no piece of kernel is supposed to do a check + * for a negative retval of schedule_timeout() (since it + * should never happens anyway). You just have the printk() + * that will tell you if something is gone wrong and where. + */ + if (timeout < 0) + { + printk(KERN_ERR "schedule_timeout: wrong timeout " + "value %lx from %p\n", timeout, + __builtin_return_address(0)); + current->state = TASK_RUNNING; + goto out; + } + } + + expire = timeout + jiffies; + + init_timer(&timer); + timer.expires = expire; + timer.data = (unsigned long) current; + timer.function = process_timeout; + + add_timer(&timer); + schedule(); + del_timer_sync(&timer); + + timeout = expire - jiffies; + + out: + return timeout < 0 ? 0 : timeout; +} + /* Thread ID - the internal kernel "pid" */ asmlinkage long sys_gettid(void) { @@ -840,4 +914,3 @@ } return 0; } - diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/Config.in linux.19pre5-ac1/lib/Config.in --- linux.19p5/lib/Config.in Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/lib/Config.in Sat Mar 9 20:41:06 2002 @@ -0,0 +1,38 @@ +# +# Library configuration +# +mainmenu_option next_comment +comment 'Library routines' + +# +# Do we need the compression support? +# +if [ "$CONFIG_CRAMFS" = "y" -o \ + "$CONFIG_PPP_DEFLATE" = "y" -o \ + "$CONFIG_JFFS2_FS" = "y" -o \ + "$CONFIG_ZISOFS_FS" = "y" ]; then + define_tristate CONFIG_ZLIB_INFLATE y +else + if [ "$CONFIG_CRAMFS" = "m" -o \ + "$CONFIG_PPP_DEFLATE" = "m" -o \ + "$CONFIG_JFFS2_FS" = "m" -o \ + "$CONFIG_ZISOFS_FS" = "m" ]; then + define_tristate CONFIG_ZLIB_INFLATE m + else + tristate 'zlib decompression support' CONFIG_ZLIB_INFLATE + fi +fi + +if [ "$CONFIG_PPP_DEFLATE" = "y" -o \ + "$CONFIG_JFFS2_FS" = "y" ]; then + define_tristate CONFIG_ZLIB_DEFLATE y +else + if [ "$CONFIG_PPP_DEFLATE" = "m" -o \ + "$CONFIG_JFFS2_FS" = "m" ]; then + define_tristate CONFIG_ZLIB_DEFLATE m + else + tristate 'zlib compression support' CONFIG_ZLIB_DEFLATE + fi +fi + +endmenu diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/Makefile linux.19pre5-ac1/lib/Makefile --- linux.19p5/lib/Makefile Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/lib/Makefile Sat Mar 9 20:41:06 2002 @@ -8,7 +8,7 @@ L_TARGET := lib.a -export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o rbtree.o +export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o bust_spinlocks.o rbtree.o @@ -19,4 +19,10 @@ obj-y += dec_and_lock.o endif +subdir-$(CONFIG_ZLIB_INFLATE) += zlib_inflate +subdir-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate + +# Include the subdirs, if necessary. +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o)) + include $(TOPDIR)/Rules.make diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/rbtree.c linux.19pre5-ac1/lib/rbtree.c --- linux.19p5/lib/rbtree.c Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/lib/rbtree.c Mon Jan 28 17:51:37 2002 @@ -20,7 +20,6 @@ */ #include -#include static void __rb_rotate_left(rb_node_t * node, rb_root_t * root) { @@ -126,7 +125,6 @@ root->rb_node->rb_color = RB_BLACK; } -EXPORT_SYMBOL(rb_insert_color); static void __rb_erase_color(rb_node_t * node, rb_node_t * parent, rb_root_t * root) @@ -293,4 +291,3 @@ if (color == RB_BLACK) __rb_erase_color(child, parent, root); } -EXPORT_SYMBOL(rb_erase); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_deflate/Makefile linux.19pre5-ac1/lib/zlib_deflate/Makefile --- linux.19p5/lib/zlib_deflate/Makefile Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/lib/zlib_deflate/Makefile Sat Mar 9 20:41:06 2002 @@ -0,0 +1,18 @@ +# +# This is a modified version of zlib, which does all memory +# allocation ahead of time. +# +# This is the compression code, see zlib_inflate for the +# decompression code. +# + +O_TARGET := zlib_deflate.o + +export-objs := deflate_syms.o + +obj-y := deflate.o deftree.o deflate_syms.o +obj-m := $(O_TARGET) + +EXTRA_CFLAGS += -I $(TOPDIR)/lib/zlib_deflate + +include $(TOPDIR)/Rules.make diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_deflate/deflate.c linux.19pre5-ac1/lib/zlib_deflate/deflate.c --- linux.19p5/lib/zlib_deflate/deflate.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/lib/zlib_deflate/deflate.c Sat Mar 9 20:41:06 2002 @@ -0,0 +1,1250 @@ +/* +++ deflate.c */ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-1996 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in ftp://ds.internic.net/rfc/rfc1951.txt + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +#include +#include +#include "defutil.h" + + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +local block_state deflate_slow OF((deflate_state *s, int flush)); +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +local uInt longest_match OF((deflate_state *s, IPos cur_match)); + +#ifdef DEBUG_ZLIB +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */ + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + memset((charf *)s->head, 0, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int zlib_deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return zlib_deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, + DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int zlib_deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int noheader = 0; + static char* my_version = ZLIB_VERSION; + deflate_workspace *mem; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + + if (level == Z_DEFAULT_COMPRESSION) level = 6; + + mem = (deflate_workspace *) strm->workspace; + + if (windowBits < 0) { /* undocumented feature: suppress zlib header */ + noheader = 1; + windowBits = -windowBits; + } + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + s = (deflate_state *) &(mem->deflate_memory); + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->noheader = noheader; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) mem->window_memory; + s->prev = (Posf *) mem->prev_memory; + s->head = (Posf *) mem->head_memory; + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) mem->overlay_memory; + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return zlib_deflateReset(strm); +} + +/* ========================================================================= */ +int zlib_deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt length = dictLength; + uInt n; + IPos hash_head = 0; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) + return Z_STREAM_ERROR; + + s = (deflate_state *) strm->state; + if (s->status != INIT_STATE) return Z_STREAM_ERROR; + + strm->adler = zlib_adler32(strm->adler, dictionary, dictLength); + + if (length < MIN_MATCH) return Z_OK; + if (length > MAX_DIST(s)) { + length = MAX_DIST(s); +#ifndef USE_DICT_HEAD + dictionary += dictLength - length; /* use the tail of the dictionary */ +#endif + } + memcpy((charf *)s->window, dictionary, length); + s->strstart = length; + s->block_start = (long)length; + + /* Insert all strings in the hash table (except for the last two bytes). + * s->lookahead stays null, so s->ins_h will be recomputed at the next + * call of fill_window. + */ + s->ins_h = s->window[0]; + UPDATE_HASH(s, s->ins_h, s->window[1]); + for (n = 0; n <= length - MIN_MATCH; n++) { + INSERT_STRING(s, n, hash_head); + } + if (hash_head) hash_head = 0; /* to make compiler happy */ + return Z_OK; +} + +/* ========================================================================= */ +int zlib_deflateReset (strm) + z_streamp strm; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL) + return Z_STREAM_ERROR; + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->noheader < 0) { + s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */ + } + s->status = s->noheader ? BUSY_STATE : INIT_STATE; + strm->adler = 1; + s->last_flush = Z_NO_FLUSH; + + zlib_tr_init(s); + lm_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int zlib_deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = (deflate_state *) strm->state; + + if (level == Z_DEFAULT_COMPRESSION) { + level = 6; + } + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if (func != configuration_table[level].func && strm->total_in != 0) { + /* Flush the last buffer: */ + err = zlib_deflate(strm, Z_PARTIAL_FLUSH); + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + deflate_state *s = (deflate_state *) strm->state; + unsigned len = s->pending; + + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + if (strm->next_out != Z_NULL) { + memcpy(strm->next_out, s->pending_out, len); + strm->next_out += len; + } + s->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + s->pending -= len; + if (s->pending == 0) { + s->pending_out = s->pending_buf; + } +} + +/* ========================================================================= */ +int zlib_deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_FINISH || flush < 0) { + return Z_STREAM_ERROR; + } + s = (deflate_state *) strm->state; + + if ((strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + return Z_STREAM_ERROR; + } + if (strm->avail_out == 0) return Z_BUF_ERROR; + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the zlib header */ + if (s->status == INIT_STATE) { + + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags = (s->level-1) >> 1; + + if (level_flags > 3) level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = 1L; + } + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUFF_ERROR. + */ + } else if (strm->avail_in == 0 && flush <= old_flush && + flush != Z_FINISH) { + return Z_BUF_ERROR; + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + return Z_BUF_ERROR; + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = (*(configuration_table[s->level].func))(s, flush); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + zlib_tr_align(s); + } else if (flush == Z_PACKET_FLUSH) { + /* Output just the 3-bit `stored' block type value, + but not a zero length. */ + zlib_tr_stored_type_only(s); + } else { /* FULL_FLUSH or SYNC_FLUSH */ + zlib_tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->noheader) return Z_STREAM_END; + + /* Write the zlib trailer (adler32) */ + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + s->noheader = -1; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int zlib_deflateEnd (strm) + z_streamp strm; +{ + int status; + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = (deflate_state *) strm->state; + + status = s->status; + if (status != INIT_STATE && status != BUSY_STATE && + status != FINISH_STATE) { + return Z_STREAM_ERROR; + } + + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + */ +int zlib_deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + deflate_workspace *mem; + + + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = (deflate_state *) source->state; + + *dest = *source; + + mem = (deflate_workspace *) dest->workspace; + + ds = &(mem->deflate_memory); + + dest->state = (struct internal_state FAR *) ds; + *ds = *ss; + ds->strm = dest; + + ds->window = (Bytef *) mem->window_memory; + ds->prev = (Posf *) mem->prev_memory; + ds->head = (Posf *) mem->head_memory; + overlay = (ushf *) mem->overlay_memory; + ds->pending_buf = (uchf *) overlay; + + memcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + memcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); + memcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); + memcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(strm, buf, size) + z_streamp strm; + Bytef *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + if (!((deflate_state *)(strm->state))->noheader) { + strm->adler = zlib_adler32(strm->adler, strm->next_in, len); + } + memcpy(buf, strm->next_in, len); + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +} + +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2: + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return best_len; + return s->lookahead; +} + +#ifdef DEBUG_ZLIB +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (memcmp((charf *)s->window + match, + (charf *)s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if strstart == 0 + * and lookahead == 1 (input done one byte at time) + */ + more--; + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + } else if (s->strstart >= wsize+MAX_DIST(s)) { + + memcpy((charf *)s->window, (charf *)s->window+wsize, + (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); + more += wsize; + } + if (s->strm->avail_in == 0) return; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead >= MIN_MATCH) { + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, eof) { \ + zlib_tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (eof)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, eof) { \ + FLUSH_BLOCK_ONLY(s, eof); \ + if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + ulg max_block_size = 0xffff; + ulg max_start; + + if (max_block_size > s->pending_buf_size - 5) { + max_block_size = s->pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy != Z_HUFFMAN_ONLY) { + s->match_length = longest_match (s, hash_head); + } + /* longest_match() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + bflush = zlib_tr_tally(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in hash table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + bflush = zlib_tr_tally (s, 0, s->window[s->strstart]); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy != Z_HUFFMAN_ONLY) { + s->match_length = longest_match (s, hash_head); + } + /* longest_match() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED || + (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR))) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + bflush = zlib_tr_tally(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + if (zlib_tr_tally (s, 0, s->window[s->strstart-1])) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + zlib_tr_tally (s, 0, s->window[s->strstart-1]); + s->match_available = 0; + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +ZEXTERN int ZEXPORT zlib_deflate_workspacesize () +{ + return sizeof(deflate_workspace); +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_deflate/deflate_syms.c linux.19pre5-ac1/lib/zlib_deflate/deflate_syms.c --- linux.19p5/lib/zlib_deflate/deflate_syms.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/lib/zlib_deflate/deflate_syms.c Sat Mar 9 20:41:06 2002 @@ -0,0 +1,21 @@ +/* + * linux/lib/zlib_deflate/deflate_syms.c + * + * Exported symbols for the deflate functionality. + * + */ + +#include +#include + +#include + +EXPORT_SYMBOL(zlib_deflate_workspacesize); +EXPORT_SYMBOL(zlib_deflate); +EXPORT_SYMBOL(zlib_deflateInit_); +EXPORT_SYMBOL(zlib_deflateInit2_); +EXPORT_SYMBOL(zlib_deflateEnd); +EXPORT_SYMBOL(zlib_deflateReset); +EXPORT_SYMBOL(zlib_deflateCopy); +EXPORT_SYMBOL(zlib_deflateParams); +MODULE_LICENSE("GPL"); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_deflate/deftree.c linux.19pre5-ac1/lib/zlib_deflate/deftree.c --- linux.19p5/lib/zlib_deflate/deftree.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/lib/zlib_deflate/deftree.c Sat Mar 9 20:41:06 2002 @@ -0,0 +1,1096 @@ +/* +++ trees.c */ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-1996 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* From: trees.c,v 1.11 1996/07/24 13:41:06 me Exp $ */ + +/* #include "deflate.h" */ + +#include +#include "defutil.h" + +#ifdef DEBUG_ZLIB +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +#define Buf_size (8 * 2*sizeof(char)) +/* Number of bits used within bi_buf. (bi_buf might be implemented on + * more than 16 bits on some systems.) + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see zlib_tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +local uch dist_code[512]; +/* distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +local uch length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, ct_data *ltree, + ct_data *dtree)); +local void set_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifndef DEBUG_ZLIB +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG_ZLIB */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +#define d_code(dist) \ + ((dist) < 256 ? dist_code[dist] : dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. dist_code[256] and dist_code[257] are never + * used. + */ + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG_ZLIB +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (value << s->bi_valid); + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG_ZLIB */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (val << s->bi_valid);\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG_ZLIB */ + + +#define MAX(a,b) (a >= b ? a : b) +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. In a multi-threaded environment, + * this function may be called by two threads concurrently, but this is + * harmless since both invocations do exactly the same thing. + */ +local void tr_static_init() +{ + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; +} + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void zlib_tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->compressed_len = 0L; + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; + s->last_eob_len = 8; /* enough lookahead for inflate */ +#ifdef DEBUG_ZLIB + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if (tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void zlib_tr_stored_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; + + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* Send just the `stored block' type code without any length bytes or data. + */ +void zlib_tr_stored_type_only(s) + deflate_state *s; +{ + send_bits(s, (STORED_BLOCK << 1), 3); + bi_windup(s); + s->compressed_len = (s->compressed_len + 3) & ~7L; +} + + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + * The current inflate code requires 9 bits of lookahead. If the + * last two codes for the previous block (real code plus EOB) were coded + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + * the last real code. In this case we send two empty static blocks instead + * of one. (There are no problems if the previous block is stored or fixed.) + * To simplify the code, we assume the worst case of last real code encoded + * on one bit only. + */ +void zlib_tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ + bi_flush(s); + /* Of the 10 bits for the empty block, we have already sent + * (10 - bi_valid) bits. The lookahead for the last real code (before + * the EOB of the previous block) was thus at least one plus the length + * of the EOB plus what we have just sent of the empty static block. + */ + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); + s->compressed_len += 10L; + bi_flush(s); + } + s->last_eob_len = 7; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. This function + * returns the total compressed length for the file so far. + */ +ulg zlib_tr_flush_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is ascii or binary */ + if (s->data_type == Z_UNKNOWN) set_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute first the block length in bytes*/ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + + /* If compression failed and this is the first and last block, + * and if the .zip file can be seeked (to rewrite the local header), + * the whole file is transformed into a stored file: + */ +#ifdef STORED_FILE_OK +# ifdef FORCE_STORED_FILE + if (eof && s->compressed_len == 0L) { /* force stored file */ +# else + if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) { +# endif + /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */ + if (buf == (charf*)0) error ("block vanished"); + + copy_block(s, buf, (unsigned)stored_len, 0); /* without header */ + s->compressed_len = stored_len << 3; + s->method = STORED; + } else +#endif /* STORED_FILE_OK */ + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + zlib_tr_stored_block(s, buf, stored_len, eof); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+eof, 3); + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); + s->compressed_len += 3 + s->static_len; + } else { + send_bits(s, (DYN_TREES<<1)+eof, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); + s->compressed_len += 3 + s->opt_len; + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + init_block(s); + + if (eof) { + bi_windup(s); + s->compressed_len += 7; /* align on byte boundary */ + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*eof)); + + return s->compressed_len >> 3; +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int zlib_tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "zlib_tr_tally: bad match"); + + s->dyn_ltree[length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0xfff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + ct_data *ltree; /* literal tree */ + ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); + s->last_eob_len = ltree[END_BLOCK].Len; +} + +/* =========================================================================== + * Set the data type to ASCII or BINARY, using a crude approximation: + * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. + * IN assertion: the fields freq of dyn_ltree are set and the total of all + * frequencies does not exceed 64K (to fit in an int on 16 bit machines). + */ +local void set_data_type(s) + deflate_state *s; +{ + int n = 0; + unsigned ascii_freq = 0; + unsigned bin_freq = 0; + while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; + while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; + while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; + s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + s->last_eob_len = 8; /* enough lookahead for inflate */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG_ZLIB + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG_ZLIB + s->bits_sent += (ulg)len<<3; +#endif + /* bundle up the put_byte(s, *buf++) calls */ + memcpy(&s->pending_buf[s->pending], buf, len); + s->pending += len; +} + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_deflate/defutil.h linux.19pre5-ac1/lib/zlib_deflate/defutil.h --- linux.19p5/lib/zlib_deflate/defutil.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/lib/zlib_deflate/defutil.h Sat Mar 9 20:41:06 2002 @@ -0,0 +1,335 @@ + + + +#define Assert(err, str) +#define Trace(dummy) +#define Tracev(dummy) +#define Tracecv(err, dummy) +#define Tracevv(dummy) + + + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE 42 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct deflate_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + int pending; /* nb of bytes in the pending buffer */ + int noheader; /* suppress zlib header and adler32 */ + Byte data_type; /* UNKNOWN, BINARY or ASCII */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to supress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + ulg compressed_len; /* total bit length of compressed file */ + uInt matches; /* number of string matches in current block */ + int last_eob_len; /* bit length of EOB code for last block */ + +#ifdef DEBUG_ZLIB + ulg bits_sent; /* bit length of the compressed data */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + +} FAR deflate_state; + +typedef struct deflate_workspace { + /* State memory for the deflator */ + deflate_state deflate_memory; + Byte window_memory[2 * (1 << MAX_WBITS)]; + Pos prev_memory[1 << MAX_WBITS]; + Pos head_memory[1 << (MAX_MEM_LEVEL + 7)]; + char overlay_memory[(1 << (MAX_MEM_LEVEL + 6)) * (sizeof(ush)+2)]; +} deflate_workspace; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + + /* in trees.c */ +void zlib_tr_init OF((deflate_state *s)); +int zlib_tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +ulg zlib_tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); +void zlib_tr_align OF((deflate_state *s)); +void zlib_tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); +void zlib_tr_stored_type_only OF((deflate_state *)); + + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +static inline unsigned bi_reverse(unsigned code, /* the value to invert */ + int len) /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +static inline void bi_flush(deflate_state *s) +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +static inline void bi_windup(deflate_state *s) +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG_ZLIB + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/Makefile linux.19pre5-ac1/lib/zlib_inflate/Makefile --- linux.19p5/lib/zlib_inflate/Makefile Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/lib/zlib_inflate/Makefile Sat Mar 9 20:41:06 2002 @@ -0,0 +1,26 @@ +# +# This is a modified version of zlib, which does all memory +# allocation ahead of time. +# +# This is only the decompression, see zlib_deflate for the +# the compression +# +# Decompression needs to be serialized for each memory +# allocation. +# +# (The upsides of the simplification is that you can't get in +# any nasty situations wrt memory management, and that the +# uncompression can be done without blocking on allocation). +# + +O_TARGET := zlib_inflate.o + +export-objs := inflate_syms.o + +obj-y := infblock.o infcodes.o inffast.o inflate.o \ + inftrees.o infutil.o inflate_syms.o +obj-m := $(O_TARGET) + +EXTRA_CFLAGS += -I $(TOPDIR)/lib/zlib_inflate + +include $(TOPDIR)/Rules.make diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/infblock.c linux.19pre5-ac1/lib/zlib_inflate/infblock.c --- linux.19p5/lib/zlib_inflate/infblock.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/lib/zlib_inflate/infblock.c Sat Mar 9 20:41:06 2002 @@ -0,0 +1,355 @@ +/* infblock.c -- interpret and process block types to last block + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include "infblock.h" +#include "inftrees.h" +#include "infcodes.h" +#include "infutil.h" + +struct inflate_codes_state; + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +/* Table for deflate from PKZIP's appnote.txt. */ +local const uInt border[] = { /* Order of the bit length code lengths */ + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +/* + Notes beyond the 1.93a appnote.txt: + + 1. Distance pointers never point before the beginning of the output + stream. + 2. Distance pointers can point back across blocks, up to 32k away. + 3. There is an implied maximum of 7 bits for the bit length table and + 15 bits for the actual data. + 4. If only one code exists, then it is encoded using one bit. (Zero + would be more efficient, but perhaps a little confusing.) If two + codes exist, they are coded using one bit each (0 and 1). + 5. There is no way of sending zero distance codes--a dummy must be + sent if there are none. (History: a pre 2.0 version of PKZIP would + store blocks with no distance codes, but this was discovered to be + too harsh a criterion.) Valid only for 1.93a. 2.04c does allow + zero distance codes, which is sent as one code of zero bits in + length. + 6. There are up to 286 literal/length codes. Code 256 represents the + end-of-block. Note however that the static length tree defines + 288 codes just to fill out the Huffman codes. Codes 286 and 287 + cannot be used though, since there is no length base or extra bits + defined for them. Similarily, there are up to 30 distance codes. + However, static trees define 32 codes (all 5 bits) to fill out the + Huffman codes, but the last two had better not show up in the data. + 7. Unzip can check dynamic Huffman blocks for complete code sets. + The exception is that a single code would not be complete (see #4). + 8. The five bits following the block type is really the number of + literal codes sent minus 257. + 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits + (1+6+6). Therefore, to output three times the length, you output + three codes (1+1+1), whereas to output four times the same length, + you only need two codes (1+3). Hmm. + 10. In the tree reconstruction algorithm, Code = Code + Increment + only if BitLength(i) is not zero. (Pretty obvious.) + 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) + 12. Note: length code 284 can represent 227-258, but length code 285 + really is 258. The last length deserves its own, short code + since it gets used a lot in very redundant files. The length + 258 is special since 258 - 3 (the min match length) is 255. + 13. The literal/length and distance code bit lengths are read as a + single stream of lengths. It is possible (and advantageous) for + a repeat code (16, 17, or 18) to go across the boundary between + the two sets of lengths. + */ + + +void zlib_inflate_blocks_reset(s, z, c) +inflate_blocks_statef *s; +z_streamp z; +uLongf *c; +{ + if (c != Z_NULL) + *c = s->check; + if (s->mode == CODES) + zlib_inflate_codes_free(s->sub.decode.codes, z); + s->mode = TYPE; + s->bitk = 0; + s->bitb = 0; + s->read = s->write = s->window; + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0); +} + +inflate_blocks_statef *zlib_inflate_blocks_new(z, c, w) +z_streamp z; +check_func c; +uInt w; +{ + inflate_blocks_statef *s; + + s = &WS(z)->working_blocks_state; + s->hufts = WS(z)->working_hufts; + s->window = WS(z)->working_window; + s->end = s->window + w; + s->checkfn = c; + s->mode = TYPE; + zlib_inflate_blocks_reset(s, z, Z_NULL); + return s; +} + + +int zlib_inflate_blocks(s, z, r) +inflate_blocks_statef *s; +z_streamp z; +int r; +{ + uInt t; /* temporary storage */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input based on current state */ + while (1) switch (s->mode) + { + case TYPE: + NEEDBITS(3) + t = (uInt)b & 7; + s->last = t & 1; + switch (t >> 1) + { + case 0: /* stored */ + DUMPBITS(3) + t = k & 7; /* go to byte boundary */ + DUMPBITS(t) + s->mode = LENS; /* get length of stored block */ + break; + case 1: /* fixed */ + { + uInt bl, bd; + inflate_huft *tl, *td; + + zlib_inflate_trees_fixed(&bl, &bd, &tl, &td, z); + s->sub.decode.codes = zlib_inflate_codes_new(bl, bd, tl, td, z); + if (s->sub.decode.codes == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + } + DUMPBITS(3) + s->mode = CODES; + break; + case 2: /* dynamic */ + DUMPBITS(3) + s->mode = TABLE; + break; + case 3: /* illegal */ + DUMPBITS(3) + s->mode = B_BAD; + z->msg = (char*)"invalid block type"; + r = Z_DATA_ERROR; + LEAVE + } + break; + case LENS: + NEEDBITS(32) + if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) + { + s->mode = B_BAD; + z->msg = (char*)"invalid stored block lengths"; + r = Z_DATA_ERROR; + LEAVE + } + s->sub.left = (uInt)b & 0xffff; + b = k = 0; /* dump bits */ + s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); + break; + case STORED: + if (n == 0) + LEAVE + NEEDOUT + t = s->sub.left; + if (t > n) t = n; + if (t > m) t = m; + memcpy(q, p, t); + p += t; n -= t; + q += t; m -= t; + if ((s->sub.left -= t) != 0) + break; + s->mode = s->last ? DRY : TYPE; + break; + case TABLE: + NEEDBITS(14) + s->sub.trees.table = t = (uInt)b & 0x3fff; +#ifndef PKZIP_BUG_WORKAROUND + if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) + { + s->mode = B_BAD; + z->msg = (char*)"too many length or distance symbols"; + r = Z_DATA_ERROR; + LEAVE + } +#endif + { + s->sub.trees.blens = WS(z)->working_blens; + } + DUMPBITS(14) + s->sub.trees.index = 0; + s->mode = BTREE; + case BTREE: + while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) + { + NEEDBITS(3) + s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; + DUMPBITS(3) + } + while (s->sub.trees.index < 19) + s->sub.trees.blens[border[s->sub.trees.index++]] = 0; + s->sub.trees.bb = 7; + t = zlib_inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, + &s->sub.trees.tb, s->hufts, z); + if (t != Z_OK) + { + r = t; + if (r == Z_DATA_ERROR) + s->mode = B_BAD; + LEAVE + } + s->sub.trees.index = 0; + s->mode = DTREE; + case DTREE: + while (t = s->sub.trees.table, + s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) + { + inflate_huft *h; + uInt i, j, c; + + t = s->sub.trees.bb; + NEEDBITS(t) + h = s->sub.trees.tb + ((uInt)b & zlib_inflate_mask[t]); + t = h->bits; + c = h->base; + if (c < 16) + { + DUMPBITS(t) + s->sub.trees.blens[s->sub.trees.index++] = c; + } + else /* c == 16..18 */ + { + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + NEEDBITS(t + i) + DUMPBITS(t) + j += (uInt)b & zlib_inflate_mask[i]; + DUMPBITS(i) + i = s->sub.trees.index; + t = s->sub.trees.table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || + (c == 16 && i < 1)) + { + s->mode = B_BAD; + z->msg = (char*)"invalid bit length repeat"; + r = Z_DATA_ERROR; + LEAVE + } + c = c == 16 ? s->sub.trees.blens[i - 1] : 0; + do { + s->sub.trees.blens[i++] = c; + } while (--j); + s->sub.trees.index = i; + } + } + s->sub.trees.tb = Z_NULL; + { + uInt bl, bd; + inflate_huft *tl, *td; + inflate_codes_statef *c; + + bl = 9; /* must be <= 9 for lookahead assumptions */ + bd = 6; /* must be <= 9 for lookahead assumptions */ + t = s->sub.trees.table; + t = zlib_inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), + s->sub.trees.blens, &bl, &bd, &tl, &td, + s->hufts, z); + if (t != Z_OK) + { + if (t == (uInt)Z_DATA_ERROR) + s->mode = B_BAD; + r = t; + LEAVE + } + if ((c = zlib_inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + s->sub.decode.codes = c; + } + s->mode = CODES; + case CODES: + UPDATE + if ((r = zlib_inflate_codes(s, z, r)) != Z_STREAM_END) + return zlib_inflate_flush(s, z, r); + r = Z_OK; + zlib_inflate_codes_free(s->sub.decode.codes, z); + LOAD + if (!s->last) + { + s->mode = TYPE; + break; + } + s->mode = DRY; + case DRY: + FLUSH + if (s->read != s->write) + LEAVE + s->mode = B_DONE; + case B_DONE: + r = Z_STREAM_END; + LEAVE + case B_BAD: + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +} + + +int zlib_inflate_blocks_free(s, z) +inflate_blocks_statef *s; +z_streamp z; +{ + zlib_inflate_blocks_reset(s, z, Z_NULL); + return Z_OK; +} + + +void zlib_inflate_set_dictionary(s, d, n) +inflate_blocks_statef *s; +const Bytef *d; +uInt n; +{ + memcpy(s->window, d, n); + s->read = s->write = s->window + n; +} + + +/* Returns true if inflate is currently at the end of a block generated + * by Z_SYNC_FLUSH or Z_FULL_FLUSH. + * IN assertion: s != Z_NULL + */ +int zlib_inflate_blocks_sync_point(s) +inflate_blocks_statef *s; +{ + return s->mode == LENS; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/infblock.h linux.19pre5-ac1/lib/zlib_inflate/infblock.h --- linux.19p5/lib/zlib_inflate/infblock.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/lib/zlib_inflate/infblock.h Sat Mar 9 20:41:06 2002 @@ -0,0 +1,44 @@ +/* infblock.h -- header to use infblock.c + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef _INFBLOCK_H +#define _INFBLOCK_H + +struct inflate_blocks_state; +typedef struct inflate_blocks_state FAR inflate_blocks_statef; + +extern inflate_blocks_statef * zlib_inflate_blocks_new OF(( + z_streamp z, + check_func c, /* check function */ + uInt w)); /* window size */ + +extern int zlib_inflate_blocks OF(( + inflate_blocks_statef *, + z_streamp , + int)); /* initial return code */ + +extern void zlib_inflate_blocks_reset OF(( + inflate_blocks_statef *, + z_streamp , + uLongf *)); /* check value on output */ + +extern int zlib_inflate_blocks_free OF(( + inflate_blocks_statef *, + z_streamp)); + +extern void zlib_inflate_set_dictionary OF(( + inflate_blocks_statef *s, + const Bytef *d, /* dictionary */ + uInt n)); /* dictionary length */ + +extern int zlib_inflate_blocks_sync_point OF(( + inflate_blocks_statef *s)); + +#endif /* _INFBLOCK_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/infcodes.c linux.19pre5-ac1/lib/zlib_inflate/infcodes.c --- linux.19p5/lib/zlib_inflate/infcodes.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/lib/zlib_inflate/infcodes.c Sat Mar 9 20:41:06 2002 @@ -0,0 +1,204 @@ +/* infcodes.c -- process literals and length/distance pairs + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include "inftrees.h" +#include "infblock.h" +#include "infcodes.h" +#include "infutil.h" +#include "inffast.h" + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +inflate_codes_statef *zlib_inflate_codes_new(bl, bd, tl, td, z) +uInt bl, bd; +inflate_huft *tl; +inflate_huft *td; /* need separate declaration for Borland C++ */ +z_streamp z; +{ + inflate_codes_statef *c; + + c = &WS(z)->working_state; + { + c->mode = START; + c->lbits = (Byte)bl; + c->dbits = (Byte)bd; + c->ltree = tl; + c->dtree = td; + } + return c; +} + + +int zlib_inflate_codes(s, z, r) +inflate_blocks_statef *s; +z_streamp z; +int r; +{ + uInt j; /* temporary storage */ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + Bytef *f; /* pointer to copy strings from */ + inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input and output based on current state */ + while (1) switch (c->mode) + { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + case START: /* x: set up for LEN */ +#ifndef SLOW + if (m >= 258 && n >= 10) + { + UPDATE + r = zlib_inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); + LOAD + if (r != Z_OK) + { + c->mode = r == Z_STREAM_END ? WASH : BADCODE; + break; + } + } +#endif /* !SLOW */ + c->sub.code.need = c->lbits; + c->sub.code.tree = c->ltree; + c->mode = LEN; + case LEN: /* i: get length/literal/eob next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & zlib_inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e == 0) /* literal */ + { + c->sub.lit = t->base; + c->mode = LIT; + break; + } + if (e & 16) /* length */ + { + c->sub.copy.get = e & 15; + c->len = t->base; + c->mode = LENEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t + t->base; + break; + } + if (e & 32) /* end of block */ + { + c->mode = WASH; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid literal/length code"; + r = Z_DATA_ERROR; + LEAVE + case LENEXT: /* i: getting length extra (have base) */ + j = c->sub.copy.get; + NEEDBITS(j) + c->len += (uInt)b & zlib_inflate_mask[j]; + DUMPBITS(j) + c->sub.code.need = c->dbits; + c->sub.code.tree = c->dtree; + c->mode = DIST; + case DIST: /* i: get distance next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & zlib_inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e & 16) /* distance */ + { + c->sub.copy.get = e & 15; + c->sub.copy.dist = t->base; + c->mode = DISTEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t + t->base; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid distance code"; + r = Z_DATA_ERROR; + LEAVE + case DISTEXT: /* i: getting distance extra */ + j = c->sub.copy.get; + NEEDBITS(j) + c->sub.copy.dist += (uInt)b & zlib_inflate_mask[j]; + DUMPBITS(j) + c->mode = COPY; + case COPY: /* o: copying bytes in window, waiting for space */ +#ifndef __TURBOC__ /* Turbo C bug for following expression */ + f = (uInt)(q - s->window) < c->sub.copy.dist ? + s->end - (c->sub.copy.dist - (q - s->window)) : + q - c->sub.copy.dist; +#else + f = q - c->sub.copy.dist; + if ((uInt)(q - s->window) < c->sub.copy.dist) + f = s->end - (c->sub.copy.dist - (uInt)(q - s->window)); +#endif + while (c->len) + { + NEEDOUT + OUTBYTE(*f++) + if (f == s->end) + f = s->window; + c->len--; + } + c->mode = START; + break; + case LIT: /* o: got literal, waiting for output space */ + NEEDOUT + OUTBYTE(c->sub.lit) + c->mode = START; + break; + case WASH: /* o: got eob, possibly more output */ + if (k > 7) /* return unused byte, if any */ + { + k -= 8; + n++; + p--; /* can always return one */ + } + FLUSH + if (s->read != s->write) + LEAVE + c->mode = END; + case END: + r = Z_STREAM_END; + LEAVE + case BADCODE: /* x: got error */ + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +#ifdef NEED_DUMMY_RETURN + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ +#endif +} + + +void zlib_inflate_codes_free(c, z) +inflate_codes_statef *c; +z_streamp z; +{ +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/infcodes.h linux.19pre5-ac1/lib/zlib_inflate/infcodes.h --- linux.19p5/lib/zlib_inflate/infcodes.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/lib/zlib_inflate/infcodes.h Sat Mar 9 20:41:06 2002 @@ -0,0 +1,33 @@ +/* infcodes.h -- header to use infcodes.c + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef _INFCODES_H +#define _INFCODES_H + +#include "infblock.h" + +struct inflate_codes_state; +typedef struct inflate_codes_state FAR inflate_codes_statef; + +extern inflate_codes_statef *zlib_inflate_codes_new OF(( + uInt, uInt, + inflate_huft *, inflate_huft *, + z_streamp )); + +extern int zlib_inflate_codes OF(( + inflate_blocks_statef *, + z_streamp , + int)); + +extern void zlib_inflate_codes_free OF(( + inflate_codes_statef *, + z_streamp )); + +#endif /* _INFCODES_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/inffast.c linux.19pre5-ac1/lib/zlib_inflate/inffast.c --- linux.19p5/lib/zlib_inflate/inffast.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/lib/zlib_inflate/inffast.c Sat Mar 9 20:41:06 2002 @@ -0,0 +1,161 @@ +/* inffast.c -- process literals and length/distance pairs fast + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include "inftrees.h" +#include "infblock.h" +#include "infcodes.h" +#include "infutil.h" +#include "inffast.h" + +struct inflate_codes_state; + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +/* macros for bit input with no checking and for returning unused bytes */ +#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3;} + +/* Called with number of bytes left to write in window at least 258 + (the maximum string length) and number of input bytes available + at least ten. The ten bytes are six bytes for the longest length/ + distance pair plus four bytes for overloading the bit buffer. */ + +int zlib_inflate_fast(bl, bd, tl, td, s, z) +uInt bl, bd; +inflate_huft *tl; +inflate_huft *td; /* need separate declaration for Borland C++ */ +inflate_blocks_statef *s; +z_streamp z; +{ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + uInt ml; /* mask for literal/length tree */ + uInt md; /* mask for distance tree */ + uInt c; /* bytes to copy */ + uInt d; /* distance back to copy from */ + Bytef *r; /* copy source pointer */ + + /* load input, output, bit values */ + LOAD + + /* initialize masks */ + ml = zlib_inflate_mask[bl]; + md = zlib_inflate_mask[bd]; + + /* do until not enough input or output space for fast loop */ + do { /* assume called with m >= 258 && n >= 10 */ + /* get literal/length code */ + GRABBITS(20) /* max bits for literal/length code */ + if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) + { + DUMPBITS(t->bits) + *q++ = (Byte)t->base; + m--; + continue; + } + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits for length */ + e &= 15; + c = t->base + ((uInt)b & zlib_inflate_mask[e]); + DUMPBITS(e) + + /* decode distance base of block to copy */ + GRABBITS(15); /* max bits for distance code */ + e = (t = td + ((uInt)b & md))->exop; + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits to add to distance base */ + e &= 15; + GRABBITS(e) /* get extra bits (up to 13) */ + d = t->base + ((uInt)b & zlib_inflate_mask[e]); + DUMPBITS(e) + + /* do the copy */ + m -= c; + if ((uInt)(q - s->window) >= d) /* offset before dest */ + { /* just copy */ + r = q - d; + *q++ = *r++; c--; /* minimum count is three, */ + *q++ = *r++; c--; /* so unroll loop a little */ + } + else /* else offset after destination */ + { + e = d - (uInt)(q - s->window); /* bytes from offset to end */ + r = s->end - e; /* pointer to offset */ + if (c > e) /* if source crosses, */ + { + c -= e; /* copy to end of window */ + do { + *q++ = *r++; + } while (--e); + r = s->window; /* copy rest from start of window */ + } + } + do { /* copy all or what's left */ + *q++ = *r++; + } while (--c); + break; + } + else if ((e & 64) == 0) + { + t += t->base; + e = (t += ((uInt)b & zlib_inflate_mask[e]))->exop; + } + else + { + z->msg = (char*)"invalid distance code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); + break; + } + if ((e & 64) == 0) + { + t += t->base; + if ((e = (t += ((uInt)b & zlib_inflate_mask[e]))->exop) == 0) + { + DUMPBITS(t->bits) + *q++ = (Byte)t->base; + m--; + break; + } + } + else if (e & 32) + { + UNGRAB + UPDATE + return Z_STREAM_END; + } + else + { + z->msg = (char*)"invalid literal/length code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); + } while (m >= 258 && n >= 10); + + /* not enough input or output--restore pointers and return */ + UNGRAB + UPDATE + return Z_OK; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/inffast.h linux.19pre5-ac1/lib/zlib_inflate/inffast.h --- linux.19p5/lib/zlib_inflate/inffast.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/lib/zlib_inflate/inffast.h Sat Mar 9 20:41:06 2002 @@ -0,0 +1,17 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +extern int zlib_inflate_fast OF(( + uInt, + uInt, + inflate_huft *, + inflate_huft *, + inflate_blocks_statef *, + z_streamp )); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/inffixed.h linux.19pre5-ac1/lib/zlib_inflate/inffixed.h --- linux.19p5/lib/zlib_inflate/inffixed.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/lib/zlib_inflate/inffixed.h Sat Mar 9 20:41:06 2002 @@ -0,0 +1,151 @@ +/* inffixed.h -- table for decoding fixed codes + * Generated automatically by the maketree.c program + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +local uInt fixed_bl = 9; +local uInt fixed_bd = 5; +local inflate_huft fixed_tl[] = { + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224}, + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144}, + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208}, + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176}, + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240}, + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200}, + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168}, + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232}, + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152}, + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216}, + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184}, + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248}, + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196}, + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164}, + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228}, + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148}, + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212}, + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180}, + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244}, + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204}, + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172}, + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236}, + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156}, + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220}, + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188}, + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252}, + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194}, + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162}, + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226}, + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146}, + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210}, + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178}, + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242}, + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202}, + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170}, + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234}, + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154}, + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218}, + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186}, + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250}, + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198}, + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166}, + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230}, + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150}, + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214}, + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182}, + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246}, + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206}, + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174}, + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238}, + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158}, + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222}, + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190}, + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254}, + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193}, + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161}, + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225}, + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145}, + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209}, + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177}, + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241}, + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201}, + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169}, + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233}, + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153}, + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217}, + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185}, + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249}, + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197}, + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165}, + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229}, + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149}, + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213}, + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181}, + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245}, + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205}, + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173}, + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237}, + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157}, + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221}, + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189}, + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253}, + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195}, + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163}, + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227}, + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147}, + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211}, + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179}, + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243}, + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203}, + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171}, + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235}, + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155}, + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219}, + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187}, + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251}, + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199}, + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167}, + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231}, + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151}, + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215}, + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183}, + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247}, + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207}, + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175}, + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239}, + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159}, + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223}, + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191}, + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255} + }; +local inflate_huft fixed_td[] = { + {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097}, + {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385}, + {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193}, + {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577}, + {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145}, + {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577}, + {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289}, + {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577} + }; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/inflate.c linux.19pre5-ac1/lib/zlib_inflate/inflate.c --- linux.19p5/lib/zlib_inflate/inflate.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/lib/zlib_inflate/inflate.c Sat Mar 9 20:41:06 2002 @@ -0,0 +1,382 @@ +/* inflate.c -- zlib interface to inflate modules + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include +#include "infblock.h" +#include "infutil.h" + +int ZEXPORT zlib_inflate_workspacesize(void) +{ + return sizeof(struct inflate_workspace); +} + + +int ZEXPORT zlib_inflateReset(z) +z_streamp z; +{ + if (z == Z_NULL || z->state == Z_NULL || z->workspace == Z_NULL) + return Z_STREAM_ERROR; + z->total_in = z->total_out = 0; + z->msg = Z_NULL; + z->state->mode = z->state->nowrap ? BLOCKS : METHOD; + zlib_inflate_blocks_reset(z->state->blocks, z, Z_NULL); + return Z_OK; +} + + +int ZEXPORT zlib_inflateEnd(z) +z_streamp z; +{ + if (z == Z_NULL || z->state == Z_NULL || z->workspace == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->blocks != Z_NULL) + zlib_inflate_blocks_free(z->state->blocks, z); + z->state = Z_NULL; + return Z_OK; +} + + +int ZEXPORT zlib_inflateInit2_(z, w, version, stream_size) +z_streamp z; +int w; +const char *version; +int stream_size; +{ + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != sizeof(z_stream) || z->workspace == Z_NULL) + return Z_VERSION_ERROR; + + /* initialize state */ + if (z == Z_NULL) + return Z_STREAM_ERROR; + z->msg = Z_NULL; + z->state = &WS(z)->internal_state; + z->state->blocks = Z_NULL; + + /* handle undocumented nowrap option (no zlib header or check) */ + z->state->nowrap = 0; + if (w < 0) + { + w = - w; + z->state->nowrap = 1; + } + + /* set window size */ + if (w < 8 || w > 15) + { + zlib_inflateEnd(z); + return Z_STREAM_ERROR; + } + z->state->wbits = (uInt)w; + + /* create inflate_blocks state */ + if ((z->state->blocks = + zlib_inflate_blocks_new(z, z->state->nowrap ? Z_NULL : zlib_adler32, (uInt)1 << w)) + == Z_NULL) + { + zlib_inflateEnd(z); + return Z_MEM_ERROR; + } + + /* reset state */ + zlib_inflateReset(z); + return Z_OK; +} + + +/* + * At the end of a Deflate-compressed PPP packet, we expect to have seen + * a `stored' block type value but not the (zero) length bytes. + */ +static int zlib_inflate_packet_flush(inflate_blocks_statef *s) +{ + if (s->mode != LENS) + return Z_DATA_ERROR; + s->mode = TYPE; + return Z_OK; +} + + +int ZEXPORT zlib_inflateInit_(z, version, stream_size) +z_streamp z; +const char *version; +int stream_size; +{ + return zlib_inflateInit2_(z, DEF_WBITS, version, stream_size); +} + +#undef NEEDBYTE +#undef NEXTBYTE +#define NEEDBYTE {if(z->avail_in==0)goto empty;r=f;} +#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) + +int ZEXPORT zlib_inflate(z, f) +z_streamp z; +int f; +{ + int r, trv; + uInt b; + + if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL) + return Z_STREAM_ERROR; + trv = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; + r = Z_BUF_ERROR; + while (1) switch (z->state->mode) + { + case METHOD: + NEEDBYTE + if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) + { + z->state->mode = I_BAD; + z->msg = (char*)"unknown compression method"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + if ((z->state->sub.method >> 4) + 8 > z->state->wbits) + { + z->state->mode = I_BAD; + z->msg = (char*)"invalid window size"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + z->state->mode = FLAG; + case FLAG: + NEEDBYTE + b = NEXTBYTE; + if (((z->state->sub.method << 8) + b) % 31) + { + z->state->mode = I_BAD; + z->msg = (char*)"incorrect header check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + if (!(b & PRESET_DICT)) + { + z->state->mode = BLOCKS; + break; + } + z->state->mode = DICT4; + case DICT4: + NEEDBYTE + z->state->sub.check.need = (uLong)NEXTBYTE << 24; + z->state->mode = DICT3; + case DICT3: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 16; + z->state->mode = DICT2; + case DICT2: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 8; + z->state->mode = DICT1; + case DICT1: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE; + z->adler = z->state->sub.check.need; + z->state->mode = DICT0; + return Z_NEED_DICT; + case DICT0: + z->state->mode = I_BAD; + z->msg = (char*)"need dictionary"; + z->state->sub.marker = 0; /* can try inflateSync */ + return Z_STREAM_ERROR; + case BLOCKS: + r = zlib_inflate_blocks(z->state->blocks, z, r); + if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0) + r = zlib_inflate_packet_flush(z->state->blocks); + if (r == Z_DATA_ERROR) + { + z->state->mode = I_BAD; + z->state->sub.marker = 0; /* can try inflateSync */ + break; + } + if (r == Z_OK) + r = trv; + if (r != Z_STREAM_END) + return r; + r = trv; + zlib_inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); + if (z->state->nowrap) + { + z->state->mode = I_DONE; + break; + } + z->state->mode = CHECK4; + case CHECK4: + NEEDBYTE + z->state->sub.check.need = (uLong)NEXTBYTE << 24; + z->state->mode = CHECK3; + case CHECK3: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 16; + z->state->mode = CHECK2; + case CHECK2: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 8; + z->state->mode = CHECK1; + case CHECK1: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE; + + if (z->state->sub.check.was != z->state->sub.check.need) + { + z->state->mode = I_BAD; + z->msg = (char*)"incorrect data check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + z->state->mode = I_DONE; + case I_DONE: + return Z_STREAM_END; + case I_BAD: + return Z_DATA_ERROR; + default: + return Z_STREAM_ERROR; + } + empty: + if (f != Z_PACKET_FLUSH) + return r; + z->state->mode = I_BAD; + z->msg = (char *)"need more for packet flush"; + z->state->sub.marker = 0; /* can try inflateSync */ + return Z_DATA_ERROR; +} + + +int ZEXPORT zlib_inflateSync(z) +z_streamp z; +{ + uInt n; /* number of bytes to look at */ + Bytef *p; /* pointer to bytes */ + uInt m; /* number of marker bytes found in a row */ + uLong r, w; /* temporaries to save total_in and total_out */ + + /* set up */ + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->mode != I_BAD) + { + z->state->mode = I_BAD; + z->state->sub.marker = 0; + } + if ((n = z->avail_in) == 0) + return Z_BUF_ERROR; + p = z->next_in; + m = z->state->sub.marker; + + /* search */ + while (n && m < 4) + { + static const Byte mark[4] = {0, 0, 0xff, 0xff}; + if (*p == mark[m]) + m++; + else if (*p) + m = 0; + else + m = 4 - m; + p++, n--; + } + + /* restore */ + z->total_in += p - z->next_in; + z->next_in = p; + z->avail_in = n; + z->state->sub.marker = m; + + /* return no joy or set up to restart on a new block */ + if (m != 4) + return Z_DATA_ERROR; + r = z->total_in; w = z->total_out; + zlib_inflateReset(z); + z->total_in = r; z->total_out = w; + z->state->mode = BLOCKS; + return Z_OK; +} + + +/* Returns true if inflate is currently at the end of a block generated + * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH + * but removes the length bytes of the resulting empty stored block. When + * decompressing, PPP checks that at the end of input packet, inflate is + * waiting for these length bytes. + */ +int ZEXPORT zlib_inflateSyncPoint(z) +z_streamp z; +{ + if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL) + return Z_STREAM_ERROR; + return zlib_inflate_blocks_sync_point(z->state->blocks); +} + +/* + * This subroutine adds the data at next_in/avail_in to the output history + * without performing any output. The output buffer must be "caught up"; + * i.e. no pending output (hence s->read equals s->write), and the state must + * be BLOCKS (i.e. we should be willing to see the start of a series of + * BLOCKS). On exit, the output will also be caught up, and the checksum + * will have been updated if need be. + */ +static int zlib_inflate_addhistory(inflate_blocks_statef *s, + z_stream *z) +{ + uLong b; /* bit buffer */ /* NOT USED HERE */ + uInt k; /* bits in bit buffer */ /* NOT USED HERE */ + uInt t; /* temporary storage */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + + if (s->read != s->write) + return Z_STREAM_ERROR; + if (s->mode != TYPE) + return Z_DATA_ERROR; + + /* we're ready to rock */ + LOAD + /* while there is input ready, copy to output buffer, moving + * pointers as needed. + */ + while (n) { + t = n; /* how many to do */ + /* is there room until end of buffer? */ + if (t > m) t = m; + /* update check information */ + if (s->checkfn != Z_NULL) + s->check = (*s->checkfn)(s->check, q, t); + memcpy(q, p, t); + q += t; + p += t; + n -= t; + z->total_out += t; + s->read = q; /* drag read pointer forward */ +/* WWRAP */ /* expand WWRAP macro by hand to handle s->read */ + if (q == s->end) { + s->read = q = s->window; + m = WAVAIL; + } + } + UPDATE + return Z_OK; +} + + +/* + * This subroutine adds the data at next_in/avail_in to the output history + * without performing any output. The output buffer must be "caught up"; + * i.e. no pending output (hence s->read equals s->write), and the state must + * be BLOCKS (i.e. we should be willing to see the start of a series of + * BLOCKS). On exit, the output will also be caught up, and the checksum + * will have been updated if need be. + */ + +int ZEXPORT zlib_inflateIncomp(z) +z_stream *z; +{ + if (z->state->mode != BLOCKS) + return Z_DATA_ERROR; + return zlib_inflate_addhistory(z->state->blocks, z); +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/inflate_syms.c linux.19pre5-ac1/lib/zlib_inflate/inflate_syms.c --- linux.19p5/lib/zlib_inflate/inflate_syms.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/lib/zlib_inflate/inflate_syms.c Sat Mar 9 20:41:06 2002 @@ -0,0 +1,22 @@ +/* + * linux/lib/zlib_inflate/inflate_syms.c + * + * Exported symbols for the inflate functionality. + * + */ + +#include +#include + +#include + +EXPORT_SYMBOL(zlib_inflate_workspacesize); +EXPORT_SYMBOL(zlib_inflate); +EXPORT_SYMBOL(zlib_inflateInit_); +EXPORT_SYMBOL(zlib_inflateInit2_); +EXPORT_SYMBOL(zlib_inflateEnd); +EXPORT_SYMBOL(zlib_inflateSync); +EXPORT_SYMBOL(zlib_inflateReset); +EXPORT_SYMBOL(zlib_inflateSyncPoint); +EXPORT_SYMBOL(zlib_inflateIncomp); +MODULE_LICENSE("GPL"); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/inftrees.c linux.19pre5-ac1/lib/zlib_inflate/inftrees.c --- linux.19p5/lib/zlib_inflate/inftrees.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/lib/zlib_inflate/inftrees.c Sat Mar 9 20:41:06 2002 @@ -0,0 +1,391 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include "inftrees.h" +#include "infutil.h" + +static const char inflate_copyright[] = + " inflate 1.1.3 Copyright 1995-1998 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ +struct internal_state; + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + + +local int huft_build OF(( + uIntf *, /* code lengths in bits */ + uInt, /* number of codes */ + uInt, /* number of "simple" codes */ + const uIntf *, /* list of base values for non-simple codes */ + const uIntf *, /* list of extra bits for non-simple codes */ + inflate_huft * FAR*,/* result: starting table */ + uIntf *, /* maximum lookup bits (returns actual) */ + inflate_huft *, /* space for trees */ + uInt *, /* hufts used in space */ + uIntf * )); /* space for values */ + +/* Tables for deflate from PKZIP's appnote.txt. */ +local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + /* see note #13 above about 258 */ +local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */ +local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; +local const uInt cpdext[30] = { /* Extra bits for distance codes */ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + +/* + Huffman code decoding is performed using a multi-level table lookup. + The fastest way to decode is to simply build a lookup table whose + size is determined by the longest code. However, the time it takes + to build this table can also be a factor if the data being decoded + is not very long. The most common codes are necessarily the + shortest codes, so those codes dominate the decoding time, and hence + the speed. The idea is you can have a shorter table that decodes the + shorter, more probable codes, and then point to subsidiary tables for + the longer codes. The time it costs to decode the longer codes is + then traded against the time it takes to make longer tables. + + This results of this trade are in the variables lbits and dbits + below. lbits is the number of bits the first level table for literal/ + length codes can decode in one step, and dbits is the same thing for + the distance codes. Subsequent tables are also less than or equal to + those sizes. These values may be adjusted either when all of the + codes are shorter than that, in which case the longest code length in + bits is used, or when the shortest code is *longer* than the requested + table size, in which case the length of the shortest code in bits is + used. + + There are two different values for the two tables, since they code a + different number of possibilities each. The literal/length table + codes 286 possible values, or in a flat code, a little over eight + bits. The distance table codes 30 possible values, or a little less + than five bits, flat. The optimum values for speed end up being + about one bit more than those, so lbits is 8+1 and dbits is 5+1. + The optimum values may differ though from machine to machine, and + possibly even between compilers. Your mileage may vary. + */ + + +/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ +#define BMAX 15 /* maximum bit length of any code */ + +local int huft_build(b, n, s, d, e, t, m, hp, hn, v) +uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ +uInt n; /* number of codes (assumed <= 288) */ +uInt s; /* number of simple-valued codes (0..s-1) */ +const uIntf *d; /* list of base values for non-simple codes */ +const uIntf *e; /* list of extra bits for non-simple codes */ +inflate_huft * FAR *t; /* result: starting table */ +uIntf *m; /* maximum lookup bits, returns actual */ +inflate_huft *hp; /* space for trees */ +uInt *hn; /* hufts used in space */ +uIntf *v; /* working area: values in order of bit length */ +/* Given a list of code lengths and a maximum table size, make a set of + tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR + if the given code set is incomplete (the tables are still built in this + case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of + lengths), or Z_MEM_ERROR if not enough memory. */ +{ + + uInt a; /* counter for codes of length k */ + uInt c[BMAX+1]; /* bit length count table */ + uInt f; /* i repeats in table every f entries */ + int g; /* maximum code length */ + int h; /* table level */ + register uInt i; /* counter, current code */ + register uInt j; /* counter */ + register int k; /* number of bits in current code */ + int l; /* bits per table (returned in m) */ + uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */ + register uIntf *p; /* pointer into c[], b[], or v[] */ + inflate_huft *q; /* points to current table */ + struct inflate_huft_s r; /* table entry for structure assignment */ + inflate_huft *u[BMAX]; /* table stack */ + register int w; /* bits before this table == (l * h) */ + uInt x[BMAX+1]; /* bit offsets, then code stack */ + uIntf *xp; /* pointer into x */ + int y; /* number of dummy codes added */ + uInt z; /* number of entries in current table */ + + + /* Generate counts for each bit length */ + p = c; +#define C0 *p++ = 0; +#define C2 C0 C0 C0 C0 +#define C4 C2 C2 C2 C2 + C4 /* clear c[]--assume BMAX+1 is 16 */ + p = b; i = n; + do { + c[*p++]++; /* assume all entries <= BMAX */ + } while (--i); + if (c[0] == n) /* null input--all zero length codes */ + { + *t = (inflate_huft *)Z_NULL; + *m = 0; + return Z_OK; + } + + + /* Find minimum and maximum length, bound *m by those */ + l = *m; + for (j = 1; j <= BMAX; j++) + if (c[j]) + break; + k = j; /* minimum code length */ + if ((uInt)l < j) + l = j; + for (i = BMAX; i; i--) + if (c[i]) + break; + g = i; /* maximum code length */ + if ((uInt)l > i) + l = i; + *m = l; + + + /* Adjust last length count to fill out codes, if needed */ + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= c[j]) < 0) + return Z_DATA_ERROR; + if ((y -= c[i]) < 0) + return Z_DATA_ERROR; + c[i] += y; + + + /* Generate starting offsets into the value table for each length */ + x[1] = j = 0; + p = c + 1; xp = x + 2; + while (--i) { /* note that i == g from above */ + *xp++ = (j += *p++); + } + + + /* Make a table of values in order of bit lengths */ + p = b; i = 0; + do { + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); + n = x[g]; /* set n to length of v */ + + + /* Generate the Huffman codes and for each, make the table entries */ + x[0] = i = 0; /* first Huffman code is zero */ + p = v; /* grab values in bit order */ + h = -1; /* no tables yet--level -1 */ + w = -l; /* bits decoded == (l * h) */ + u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ + q = (inflate_huft *)Z_NULL; /* ditto */ + z = 0; /* ditto */ + + /* go through the bit lengths (k already is bits in shortest code) */ + for (; k <= g; k++) + { + a = c[k]; + while (a--) + { + /* here i is the Huffman code of length k bits for value *p */ + /* make tables up to required level */ + while (k > w + l) + { + h++; + w += l; /* previous table always l bits */ + + /* compute minimum size table less than or equal to l bits */ + z = g - w; + z = z > (uInt)l ? l : z; /* table size upper limit */ + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ + { /* too few codes for k-w bit table */ + f -= a + 1; /* deduct codes from patterns left */ + xp = c + k; + if (j < z) + while (++j < z) /* try smaller tables up to z bits */ + { + if ((f <<= 1) <= *++xp) + break; /* enough codes to use up j bits */ + f -= *xp; /* else deduct codes from patterns */ + } + } + z = 1 << j; /* table entries for j-bit table */ + + /* allocate new table */ + if (*hn + z > MANY) /* (note: doesn't matter for fixed) */ + return Z_MEM_ERROR; /* not enough memory */ + u[h] = q = hp + *hn; + *hn += z; + + /* connect to last table, if there is one */ + if (h) + { + x[h] = i; /* save pattern for backing up */ + r.bits = (Byte)l; /* bits to dump before this table */ + r.exop = (Byte)j; /* bits in this table */ + j = i >> (w - l); + r.base = (uInt)(q - u[h-1] - j); /* offset to this table */ + u[h-1][j] = r; /* connect to last table */ + } + else + *t = q; /* first table is returned result */ + } + + /* set up table entry in r */ + r.bits = (Byte)(k - w); + if (p >= v + n) + r.exop = 128 + 64; /* out of values--invalid code */ + else if (*p < s) + { + r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ + r.base = *p++; /* simple code is just the value */ + } + else + { + r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ + r.base = d[*p++ - s]; + } + + /* fill code-like entries with r */ + f = 1 << (k - w); + for (j = i >> w; j < z; j += f) + q[j] = r; + + /* backwards increment the k-bit code i */ + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + i ^= j; + + /* backup over finished tables */ + mask = (1 << w) - 1; /* needed on HP, cc -O bug */ + while ((i & mask) != x[h]) + { + h--; /* don't need to update q */ + w -= l; + mask = (1 << w) - 1; + } + } + } + + + /* Return Z_BUF_ERROR if we were given an incomplete table */ + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; +} + + +int zlib_inflate_trees_bits(c, bb, tb, hp, z) +uIntf *c; /* 19 code lengths */ +uIntf *bb; /* bits tree desired/actual depth */ +inflate_huft * FAR *tb; /* bits tree result */ +inflate_huft *hp; /* space for trees */ +z_streamp z; /* for messages */ +{ + int r; + uInt hn = 0; /* hufts used in space */ + uIntf *v; /* work area for huft_build */ + + v = WS(z)->tree_work_area_1; + r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, + tb, bb, hp, &hn, v); + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed dynamic bit lengths tree"; + else if (r == Z_BUF_ERROR || *bb == 0) + { + z->msg = (char*)"incomplete dynamic bit lengths tree"; + r = Z_DATA_ERROR; + } + return r; +} + +int zlib_inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z) +uInt nl; /* number of literal/length codes */ +uInt nd; /* number of distance codes */ +uIntf *c; /* that many (total) code lengths */ +uIntf *bl; /* literal desired/actual bit depth */ +uIntf *bd; /* distance desired/actual bit depth */ +inflate_huft * FAR *tl; /* literal/length tree result */ +inflate_huft * FAR *td; /* distance tree result */ +inflate_huft *hp; /* space for trees */ +z_streamp z; /* for messages */ +{ + int r; + uInt hn = 0; /* hufts used in space */ + uIntf *v; /* work area for huft_build */ + + /* allocate work area */ + v = WS(z)->tree_work_area_2; + + /* build literal/length tree */ + r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v); + if (r != Z_OK || *bl == 0) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed literal/length tree"; + else if (r != Z_MEM_ERROR) + { + z->msg = (char*)"incomplete literal/length tree"; + r = Z_DATA_ERROR; + } + return r; + } + + /* build distance tree */ + r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v); + if (r != Z_OK || (*bd == 0 && nl > 257)) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed distance tree"; + else if (r == Z_BUF_ERROR) { +#ifdef PKZIP_BUG_WORKAROUND + r = Z_OK; + } +#else + z->msg = (char*)"incomplete distance tree"; + r = Z_DATA_ERROR; + } + else if (r != Z_MEM_ERROR) + { + z->msg = (char*)"empty distance tree with lengths"; + r = Z_DATA_ERROR; + } + return r; +#endif + } + + /* done */ + return Z_OK; +} + + +/* build fixed tables only once--keep them here */ +#include "inffixed.h" + + +int zlib_inflate_trees_fixed(bl, bd, tl, td, z) +uIntf *bl; /* literal desired/actual bit depth */ +uIntf *bd; /* distance desired/actual bit depth */ +inflate_huft * FAR *tl; /* literal/length tree result */ +inflate_huft * FAR *td; /* distance tree result */ +z_streamp z; /* for memory allocation */ +{ + *bl = fixed_bl; + *bd = fixed_bd; + *tl = fixed_tl; + *td = fixed_td; + return Z_OK; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/inftrees.h linux.19pre5-ac1/lib/zlib_inflate/inftrees.h --- linux.19p5/lib/zlib_inflate/inftrees.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/lib/zlib_inflate/inftrees.h Sat Mar 9 20:41:06 2002 @@ -0,0 +1,63 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Huffman code lookup table entry--this entry is four bytes for machines + that have 16-bit pointers (e.g. PC's in the small or medium model). */ + +#ifndef _INFTREES_H +#define _INFTREES_H + +typedef struct inflate_huft_s FAR inflate_huft; + +struct inflate_huft_s { + union { + struct { + Byte Exop; /* number of extra bits or operation */ + Byte Bits; /* number of bits in this code or subcode */ + } what; + uInt pad; /* pad structure to a power of 2 (4 bytes for */ + } word; /* 16-bit, 8 bytes for 32-bit int's) */ + uInt base; /* literal, length base, distance base, + or table offset */ +}; + +/* Maximum size of dynamic tree. The maximum found in a long but non- + exhaustive search was 1004 huft structures (850 for length/literals + and 154 for distances, the latter actually the result of an + exhaustive search). The actual maximum is not known, but the + value below is more than safe. */ +#define MANY 1440 + +extern int zlib_inflate_trees_bits OF(( + uIntf *, /* 19 code lengths */ + uIntf *, /* bits tree desired/actual depth */ + inflate_huft * FAR *, /* bits tree result */ + inflate_huft *, /* space for trees */ + z_streamp)); /* for messages */ + +extern int zlib_inflate_trees_dynamic OF(( + uInt, /* number of literal/length codes */ + uInt, /* number of distance codes */ + uIntf *, /* that many (total) code lengths */ + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *, /* distance tree result */ + inflate_huft *, /* space for trees */ + z_streamp)); /* for messages */ + +extern int zlib_inflate_trees_fixed OF(( + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *, /* distance tree result */ + z_streamp)); /* for memory allocation */ + +#endif /* _INFTREES_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/infutil.c linux.19pre5-ac1/lib/zlib_inflate/infutil.c --- linux.19p5/lib/zlib_inflate/infutil.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/lib/zlib_inflate/infutil.c Sat Mar 9 20:41:06 2002 @@ -0,0 +1,87 @@ +/* inflate_util.c -- data and routines common to blocks and codes + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include "infblock.h" +#include "inftrees.h" +#include "infcodes.h" +#include "infutil.h" + +struct inflate_codes_state; + +/* And'ing with mask[n] masks the lower n bits */ +uInt zlib_inflate_mask[17] = { + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + + +/* copy as much as possible from the sliding window to the output area */ +int zlib_inflate_flush(s, z, r) +inflate_blocks_statef *s; +z_streamp z; +int r; +{ + uInt n; + Bytef *p; + Bytef *q; + + /* local copies of source and destination pointers */ + p = z->next_out; + q = s->read; + + /* compute number of bytes to copy as far as end of window */ + n = (uInt)((q <= s->write ? s->write : s->end) - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); + + /* copy as far as end of window */ + memcpy(p, q, n); + p += n; + q += n; + + /* see if more to copy at beginning of window */ + if (q == s->end) + { + /* wrap pointers */ + q = s->window; + if (s->write == s->end) + s->write = s->window; + + /* compute bytes to copy */ + n = (uInt)(s->write - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); + + /* copy */ + memcpy(p, q, n); + p += n; + q += n; + } + + /* update pointers */ + z->next_out = p; + s->read = q; + + /* done */ + return r; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/infutil.h linux.19pre5-ac1/lib/zlib_inflate/infutil.h --- linux.19p5/lib/zlib_inflate/infutil.h Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/lib/zlib_inflate/infutil.h Tue Mar 26 20:37:12 2002 @@ -0,0 +1,197 @@ +/* infutil.h -- types and macros common to blocks and codes + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef _INFUTIL_H +#define _INFUTIL_H + +#include +#include "inftrees.h" +#include "infcodes.h" + +typedef enum { + TYPE, /* get type bits (3, including end bit) */ + LENS, /* get lengths for stored */ + STORED, /* processing stored block */ + TABLE, /* get table lengths */ + BTREE, /* get bit lengths tree for a dynamic block */ + DTREE, /* get length, distance trees for a dynamic block */ + CODES, /* processing fixed or dynamic block */ + DRY, /* output remaining window bytes */ + B_DONE, /* finished last block, done */ + B_BAD} /* got a data error--stuck here */ +inflate_block_mode; + +/* inflate blocks semi-private state */ +struct inflate_blocks_state { + + /* mode */ + inflate_block_mode mode; /* current inflate_block mode */ + + /* mode dependent information */ + union { + uInt left; /* if STORED, bytes left to copy */ + struct { + uInt table; /* table lengths (14 bits) */ + uInt index; /* index into blens (or border) */ + uIntf *blens; /* bit lengths of codes */ + uInt bb; /* bit length tree depth */ + inflate_huft *tb; /* bit length decoding tree */ + } trees; /* if DTREE, decoding info for trees */ + struct { + inflate_codes_statef + *codes; + } decode; /* if CODES, current state */ + } sub; /* submode */ + uInt last; /* true if this block is the last block */ + + /* mode independent information */ + uInt bitk; /* bits in bit buffer */ + uLong bitb; /* bit buffer */ + inflate_huft *hufts; /* single malloc for tree space */ + Bytef *window; /* sliding window */ + Bytef *end; /* one byte after sliding window */ + Bytef *read; /* window read pointer */ + Bytef *write; /* window write pointer */ + check_func checkfn; /* check function */ + uLong check; /* check on output */ + +}; + + +/* defines for inflate input/output */ +/* update pointers and return */ +#define UPDBITS {s->bitb=b;s->bitk=k;} +#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} +#define UPDOUT {s->write=q;} +#define UPDATE {UPDBITS UPDIN UPDOUT} +#define LEAVE {UPDATE return zlib_inflate_flush(s,z,r);} +/* get bytes and bits */ +#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} +#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} +#define NEXTBYTE (n--,*p++) +#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} +/* output bytes */ +#define WAVAIL (uInt)(qread?s->read-q-1:s->end-q) +#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} +#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} +#define FLUSH {UPDOUT r=zlib_inflate_flush(s,z,r); LOADOUT} +#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} +#define OUTBYTE(a) {*q++=(Byte)(a);m--;} +/* load local pointers */ +#define LOAD {LOADIN LOADOUT} + +/* masks for lower bits (size given to avoid silly warnings with Visual C++) */ +extern uInt zlib_inflate_mask[17]; + +/* copy as much as possible from the sliding window to the output area */ +extern int zlib_inflate_flush OF(( + inflate_blocks_statef *, + z_streamp , + int)); + +/* inflate private state */ +typedef enum { + METHOD, /* waiting for method byte */ + FLAG, /* waiting for flag byte */ + DICT4, /* four dictionary check bytes to go */ + DICT3, /* three dictionary check bytes to go */ + DICT2, /* two dictionary check bytes to go */ + DICT1, /* one dictionary check byte to go */ + DICT0, /* waiting for inflateSetDictionary */ + BLOCKS, /* decompressing blocks */ + CHECK4, /* four check bytes to go */ + CHECK3, /* three check bytes to go */ + CHECK2, /* two check bytes to go */ + CHECK1, /* one check byte to go */ + I_DONE, /* finished check, done */ + I_BAD} /* got an error--stay here */ +inflate_mode; + +struct internal_state { + + /* mode */ + inflate_mode mode; /* current inflate mode */ + + /* mode dependent information */ + union { + uInt method; /* if FLAGS, method byte */ + struct { + uLong was; /* computed check value */ + uLong need; /* stream check value */ + } check; /* if CHECK, check values to compare */ + uInt marker; /* if BAD, inflateSync's marker bytes count */ + } sub; /* submode */ + + /* mode independent information */ + int nowrap; /* flag for no wrapper */ + uInt wbits; /* log2(window size) (8..15, defaults to 15) */ + inflate_blocks_statef + *blocks; /* current inflate_blocks state */ + +}; + +/* inflate codes private state */ +typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + START, /* x: set up for LEN */ + LEN, /* i: get length/literal/eob next */ + LENEXT, /* i: getting length extra (have base) */ + DIST, /* i: get distance next */ + DISTEXT, /* i: getting distance extra */ + COPY, /* o: copying bytes in window, waiting for space */ + LIT, /* o: got literal, waiting for output space */ + WASH, /* o: got eob, possibly still output waiting */ + END, /* x: got eob and all data flushed */ + BADCODE} /* x: got error */ +inflate_codes_mode; + +struct inflate_codes_state { + + /* mode */ + inflate_codes_mode mode; /* current inflate_codes mode */ + + /* mode dependent information */ + uInt len; + union { + struct { + inflate_huft *tree; /* pointer into tree */ + uInt need; /* bits needed */ + } code; /* if LEN or DIST, where in tree */ + uInt lit; /* if LIT, literal */ + struct { + uInt get; /* bits to get for extra */ + uInt dist; /* distance back to copy from */ + } copy; /* if EXT or COPY, where and how much */ + } sub; /* submode */ + + /* mode independent information */ + Byte lbits; /* ltree bits decoded per branch */ + Byte dbits; /* dtree bits decoder per branch */ + inflate_huft *ltree; /* literal/length/eob tree */ + inflate_huft *dtree; /* distance tree */ + +}; + +/* memory allocation for inflation */ + +struct inflate_workspace { + inflate_codes_statef working_state; + struct inflate_blocks_state working_blocks_state; + struct internal_state internal_state; + unsigned int tree_work_area_1[19]; + unsigned int tree_work_area_2[288]; + unsigned working_blens[258 + 0x1f + 0x1f]; + inflate_huft working_hufts[MANY]; + unsigned char working_window[1 << MAX_WBITS]; +}; + +#define WS(z) ((struct inflate_workspace *)(z->workspace)) + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/Makefile linux.19pre5-ac1/mm/Makefile --- linux.19p5/mm/Makefile Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/mm/Makefile Fri Mar 1 21:35:04 2002 @@ -14,7 +14,7 @@ obj-y := memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o \ vmalloc.o slab.o bootmem.o swap.o vmscan.o page_io.o \ page_alloc.o swap_state.o swapfile.o numa.o oom_kill.o \ - shmem.o + shmem.o rmap.o obj-$(CONFIG_HIGHMEM) += highmem.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/TODO linux.19pre5-ac1/mm/TODO --- linux.19p5/mm/TODO Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/mm/TODO Mon Jan 28 19:33:28 2002 @@ -0,0 +1,36 @@ + VM TODO list + +Forever valid TODO entries: + - keep up with the official kernel + - port over bugfixes + - minimise the diff by keeping code in sync where possible + +Easy short-term features: + - reclaim swap space from refill_inactive() + - simplify SMP locking + - replace foo()/foo_pgd()/foo_pmd()/foo_pte() stuff with + one single function using a for_each_pte() macro + for_each_pte(ptep, mm, start_address, end_address) + - stronger drop behind / unused object dropping, all the way + to the far end of the inactive list + - fix page_launder() to not eat horrible amounts of CPU or flush + all pages to disk at once + - better VM balancing, clean vs. dirty ratio + - fix loopback device deadlock + riel: nr_fract=70%, nr_fract_sync=80% + riel: setup a loopback fs ext2-on-ext2 + riel: boot with mem=64m + riel: then write a 500 meg file. + riel: current kernel livelocks. + +Long-term features: + - extensive VM statistics + - IO clustering for page_launder() and sync_old_buffers() + - readahead on per-VMA level (+ drop behind?) + - more graceful degradation when the load gets high + - reducing readahead + - unfair pageout so not all apps fall over + - memory objects, using pagecache and tmpfs for storage so + the memory object itself doesn't introduce any new overhead + - using the memory objects, removing page table copying from fork() + - load control able to deal with really extreme loads, swapping diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/bootmem.c linux.19pre5-ac1/mm/bootmem.c --- linux.19p5/mm/bootmem.c Thu Apr 4 13:18:17 2002 +++ linux.19pre5-ac1/mm/bootmem.c Mon Feb 18 20:39:46 2002 @@ -326,12 +326,11 @@ pg_data_t *pgdat = pgdat_list; void *ptr; - while (pgdat) { + for_each_pgdat(pgdat) if ((ptr = __alloc_bootmem_core(pgdat->bdata, size, align, goal))) return(ptr); - pgdat = pgdat->node_next; - } + /* * Whoops, we cannot satisfy the allocation request. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/filemap.c linux.19pre5-ac1/mm/filemap.c --- linux.19p5/mm/filemap.c Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/mm/filemap.c Tue Mar 26 19:12:32 2002 @@ -22,7 +22,9 @@ #include #include #include +#include #include +#include #include #include @@ -233,7 +235,7 @@ static void truncate_complete_page(struct page *page) { /* Leave it on the LRU if it gets converted into anonymous buffers */ - if (!page->buffers || do_flushpage(page, 0)) + if (!page->pte_chain && (!page->buffers || do_flushpage(page, 0))) lru_cache_del(page); /* @@ -453,6 +455,11 @@ return page; } +static struct page * __find_page(struct address_space * mapping, unsigned long index) +{ + return __find_page_nolock(mapping, index, *page_hash(mapping,index)); +} + static int do_buffer_fdatasync(struct list_head *head, unsigned long start, unsigned long end, int (*fn)(struct page *)) { struct list_head *curr; @@ -745,26 +752,6 @@ } /* - * Knuth recommends primes in approximately golden ratio to the maximum - * integer representable by a machine word for multiplicative hashing. - * Chuck Lever verified the effectiveness of this technique: - * http://www.citi.umich.edu/techreports/reports/citi-tr-00-1.pdf - * - * These primes are chosen to be bit-sparse, that is operations on - * them can use shifts and additions instead of multiplications for - * machines where multiplications are slow. - */ -#if BITS_PER_LONG == 32 -/* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */ -#define GOLDEN_RATIO_PRIME 0x9e370001UL -#elif BITS_PER_LONG == 64 -/* 2^63 + 2^61 - 2^57 + 2^54 - 2^51 - 2^18 + 1 */ -#define GOLDEN_RATIO_PRIME 0x9e37fffffffc0001UL -#else -#error Define GOLDEN_RATIO_PRIME for your wordsize. -#endif - -/* * In order to wait for pages to become available there must be * waitqueues associated with pages. By using a hash table of * waitqueues where the bucket discipline is to maintain all @@ -772,7 +759,8 @@ * become available, and for the woken contexts to check to be * sure the appropriate page became available, this saves space * at a cost of "thundering herd" phenomena during rare hash - * collisions. + * collisions. This cost is great enough that effective hashing + * is necessary to maintain performance. */ static inline wait_queue_head_t *page_waitqueue(struct page *page) { @@ -796,21 +784,35 @@ n <<= 2; hash += n; #else - /* On some cpus multiply is faster, on others gcc will do shifts */ hash *= GOLDEN_RATIO_PRIME; #endif - hash >>= zone->wait_table_shift; return &wait[hash]; } + /* * Wait for a page to get unlocked. * * This must be called with the caller "holding" the page, * ie with increased "page->count" so that the page won't * go away during the wait.. + * + * The waiting strategy is to get on a waitqueue determined + * by hashing. Waiters will then collide, and the newly woken + * task must then determine whether it was woken for the page + * it really wanted, and go back to sleep on the waitqueue if + * that wasn't it. With the waitqueue semantics, it never leaves + * the waitqueue unless it calls, so the loop moves forward one + * iteration every time there is + * (1) a collision + * and + * (2) one of the colliding pages is woken + * + * This is the thundering herd problem, but it is expected to + * be very rare due to the few pages that are actually being + * waited on at any given time and the quality of the hash function. */ void ___wait_on_page(struct page *page) { @@ -831,7 +833,11 @@ } /* - * Unlock the page and wake up sleepers in ___wait_on_page. + * unlock_page() is the other half of the story just above + * __wait_on_page(). Here a couple of quick checks are done + * and a couple of flags are set on the page, and then all + * of the waiters for all of the pages in the appropriate + * wait queue are woken. */ void unlock_page(struct page *page) { @@ -841,7 +847,14 @@ if (!test_and_clear_bit(PG_locked, &(page)->flags)) BUG(); smp_mb__after_clear_bit(); - if (waitqueue_active(waitqueue)) + + /* + * Although the default semantics of wake_up() are + * to wake all, here the specific function is used + * to make it even more explicit that a number of + * pages are being waited on here. + */ + if(waitqueue_active(waitqueue)) wake_up_all(waitqueue); } @@ -866,7 +879,12 @@ break; } __set_task_state(tsk, TASK_RUNNING); - remove_wait_queue(waitqueue, &wait); + remove_wait_queue(page_waitqueue(page), &wait); +} + +void wake_up_page(struct page *page) +{ + wake_up(page_waitqueue(page)); } /* @@ -1009,7 +1027,53 @@ /* - * Same as grab_cache_page, but do not wait if the page is unavailable. + * We combine this with read-ahead to deactivate pages when we + * think there's sequential IO going on. Note that this is + * harmless since we don't actually evict the pages from memory + * but just move them to the inactive list. + * + * TODO: + * - make the readahead code smarter + * - move readahead to the VMA level so we can do the same + * trick with mmap() + * + * Rik van Riel, 2000 + */ +static void drop_behind(struct file * file, unsigned long index) +{ + struct inode *inode = file->f_dentry->d_inode; + struct address_space *mapping = inode->i_mapping; + struct page *page; + unsigned long start; + + /* Nothing to drop-behind if we're on the first page. */ + if (!index) + return; + + if (index > file->f_rawin) + start = index - file->f_rawin; + else + start = 0; + + /* + * Go backwards from index-1 and drop all pages in the + * readahead window. Since the readahead window may have + * been increased since the last time we were called, we + * stop when the page isn't there. + */ + spin_lock(&pagemap_lru_lock); + while (--index >= start) { + spin_lock(&pagecache_lock); + page = __find_page(mapping, index); + spin_unlock(&pagecache_lock); + if (!page || !PageActive(page)) + break; + drop_page(page); + } + spin_unlock(&pagemap_lru_lock); +} + +/* Same as grab_cache_page, but do not wait if the page is unavailable. * This is intended for speculative data generators, where the data can * be regenerated if the page couldn't be grabbed. This routine should * be safe to call while holding the lock for another page. @@ -1279,6 +1343,12 @@ if (filp->f_ramax > max_readahead) filp->f_ramax = max_readahead; + /* + * Move the pages that have already been passed + * to the inactive list. + */ + drop_behind(filp, index); + #ifdef PROFILE_READAHEAD profile_readahead((reada_ok == 2), filp); #endif @@ -1287,25 +1357,6 @@ return; } -/* - * Mark a page as having seen activity. - * - * If it was already so marked, move it - * to the active queue and drop the referenced - * bit. Otherwise, just mark it for future - * action.. - */ -void mark_page_accessed(struct page *page) -{ - if (!PageActive(page) && PageReferenced(page)) { - activate_page(page); - ClearPageReferenced(page); - return; - } - - /* Mark the page referenced, AFTER checking for previous usage.. */ - SetPageReferenced(page); -} /* * This is a generic file read routine, and uses the @@ -1414,7 +1465,7 @@ * beginning or we just did an lseek. */ if (!offset || !filp->f_reada) - mark_page_accessed(page); + touch_page(page); /* * Ok, we have the page, and it's up-to-date, so @@ -1815,7 +1866,7 @@ nr = max; /* And limit it to a sane percentage of the inactive list.. */ - max = nr_inactive_pages / 2; + max = nr_inactive_clean_pages / 2; if (nr > max) nr = max; @@ -1960,7 +2011,7 @@ * Found the page and have a reference on it, need to check sharing * and possibly copy it over to another page.. */ - mark_page_accessed(page); + touch_page(page); flush_page_to_ram(page); return page; @@ -2839,7 +2890,7 @@ page = __read_cache_page(mapping, index, filler, data); if (IS_ERR(page)) goto out; - mark_page_accessed(page); + touch_page(page); if (Page_Uptodate(page)) goto out; @@ -2956,8 +3007,8 @@ * Check whether we've reached the file size limit. */ err = -EFBIG; - - if (limit != RLIM_INFINITY) { + + if (limit != RLIM_INFINITY && !S_ISBLK(inode->i_mode)) { if (pos >= limit) { send_sig(SIGXFSZ, current, 0); goto out; @@ -3036,6 +3087,7 @@ unsigned long index, offset; long page_fault; char *kaddr; + int deactivate = 1; /* * Try to find the page in the cache. If it isn't there, @@ -3044,8 +3096,10 @@ offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */ index = pos >> PAGE_CACHE_SHIFT; bytes = PAGE_CACHE_SIZE - offset; - if (bytes > count) + if (bytes > count) { bytes = count; + deactivate = 0; + } /* * Bring in the user page that we will copy from _first_. @@ -3089,8 +3143,11 @@ unlock: kunmap(page); /* Mark it unlocked again and drop the page.. */ - SetPageReferenced(page); UnlockPage(page); + if (deactivate) + deactivate_page(page); + else + touch_page(page); page_cache_release(page); if (status < 0) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/highmem.c linux.19pre5-ac1/mm/highmem.c --- linux.19p5/mm/highmem.c Thu Apr 4 13:18:17 2002 +++ linux.19pre5-ac1/mm/highmem.c Wed Feb 27 18:32:03 2002 @@ -354,9 +354,8 @@ /* we need to wait I/O completion */ run_task_queue(&tq_disk); - current->policy |= SCHED_YIELD; __set_current_state(TASK_RUNNING); - schedule(); + yield(); goto repeat_alloc; } @@ -392,9 +391,8 @@ /* we need to wait I/O completion */ run_task_queue(&tq_disk); - current->policy |= SCHED_YIELD; __set_current_state(TASK_RUNNING); - schedule(); + yield(); goto repeat_alloc; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/memory.c linux.19pre5-ac1/mm/memory.c --- linux.19p5/mm/memory.c Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/mm/memory.c Thu Mar 14 22:43:42 2002 @@ -34,6 +34,21 @@ * * 16.07.99 - Support of BIGMEM added by Gerhard Wichert, Siemens AG * (Gerhard.Wichert@pdb.siemens.de) + * 26.02.2002 - Added address space accounting + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include @@ -44,9 +59,11 @@ #include #include #include +#include #include #include +#include #include #include @@ -103,6 +120,7 @@ } pte = pte_offset(dir, 0); pmd_clear(dir); + pgtable_remove_rmap(pte); pte_free(pte); } @@ -237,9 +255,11 @@ if (pte_none(pte)) goto cont_copy_pte_range_noset; + /* pte contains position in swap, so copy. */ if (!pte_present(pte)) { swap_duplicate(pte_to_swp_entry(pte)); - goto cont_copy_pte_range; + set_pte(dst_pte, pte); + goto cont_copy_pte_range_noset; } ptepage = pte_page(pte); if ((!VALID_PAGE(ptepage)) || @@ -260,6 +280,7 @@ dst->rss++; cont_copy_pte_range: set_pte(dst_pte, pte); + page_add_rmap(ptepage, dst_pte); cont_copy_pte_range_noset: address += PAGE_SIZE; if (address >= end) goto out_unlock; @@ -315,8 +336,10 @@ continue; if (pte_present(pte)) { struct page *page = pte_page(pte); - if (VALID_PAGE(page) && !PageReserved(page)) + if (VALID_PAGE(page) && !PageReserved(page)) { freed ++; + page_remove_rmap(page, ptep); + } /* This will eventually call __free_pte on the pte. */ tlb_remove_page(tlb, ptep, address + offset); } else { @@ -981,7 +1004,9 @@ if (pte_same(*page_table, pte)) { if (PageReserved(old_page)) ++mm->rss; + page_remove_rmap(old_page, page_table); break_cow(vma, new_page, address, page_table); + page_add_rmap(new_page, page_table); lru_cache_add(new_page); /* Free the old page.. */ @@ -1094,6 +1119,10 @@ struct page *new_page; unsigned long offset; + /* Low on free memory ? Don't make things worse. */ + if (free_low(ALL_ZONES) < 0) + return; + /* * Get the number of handles we should do readahead io to. */ @@ -1142,7 +1171,7 @@ ret = 2; } - mark_page_accessed(page); + touch_page(page); lock_page(page); @@ -1173,6 +1202,7 @@ flush_page_to_ram(page); flush_icache_page(vma, page); set_pte(page_table, pte); + page_add_rmap(page, page_table); /* No need to invalidate - it was non-present before */ update_mmu_cache(vma, address, pte); @@ -1188,14 +1218,13 @@ static int do_anonymous_page(struct mm_struct * mm, struct vm_area_struct * vma, pte_t *page_table, int write_access, unsigned long addr) { pte_t entry; + struct page * page = ZERO_PAGE(addr); /* Read-only mapping of ZERO_PAGE. */ entry = pte_wrprotect(mk_pte(ZERO_PAGE(addr), vma->vm_page_prot)); /* ..except if it's a write access */ if (write_access) { - struct page *page; - /* Allocate our own private page. */ spin_unlock(&mm->page_table_lock); @@ -1214,10 +1243,10 @@ flush_page_to_ram(page); entry = pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot))); lru_cache_add(page); - mark_page_accessed(page); } set_pte(page_table, entry); + page_add_rmap(page, page_table); /* ignores ZERO_PAGE */ /* No need to invalidate - it was non-present before */ update_mmu_cache(vma, addr, entry); @@ -1272,6 +1301,8 @@ new_page = page; } + touch_page(new_page); + spin_lock(&mm->page_table_lock); /* * This silly early PAGE_DIRTY setting removes a race @@ -1292,6 +1323,7 @@ if (write_access) entry = pte_mkwrite(pte_mkdirty(entry)); set_pte(page_table, entry); + page_add_rmap(new_page, page_table); } else { /* One of our sibling threads was faster, back out. */ page_cache_release(new_page); @@ -1368,6 +1400,14 @@ current->state = TASK_RUNNING; pgd = pgd_offset(mm, address); + /* + * If we are over our RSS limit and the system needs memory, + * we will free memory for the non-hogs and slow down a bit. + */ + if (mm->rlimit_rss && mm->rss > mm->rlimit_rss && + free_high(ALL_ZONES) > 0) + rss_free_pages(GFP_HIGHUSER); + /* * We need the page table lock to synchronize with kswapd * and the SMP-safe atomic PTE updates. @@ -1449,6 +1489,7 @@ goto out; } } + pgtable_add_rmap(new, mm, address); pmd_populate(mm, pmd, new); } out: diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/mlock.c linux.19pre5-ac1/mm/mlock.c --- linux.19p5/mm/mlock.c Thu Apr 4 13:18:17 2002 +++ linux.19pre5-ac1/mm/mlock.c Tue Mar 19 15:22:17 2002 @@ -198,6 +198,7 @@ unsigned long lock_limit; int error = -ENOMEM; + vm_validate_enough("entering sys_mlock"); down_write(¤t->mm->mmap_sem); len = PAGE_ALIGN(len + (start & ~PAGE_MASK)); start &= PAGE_MASK; @@ -220,6 +221,7 @@ error = do_mlock(start, len, 1); out: up_write(¤t->mm->mmap_sem); + vm_validate_enough("exiting sys_mlock"); return error; } @@ -227,11 +229,13 @@ { int ret; + vm_validate_enough("entering sys_munlock"); down_write(¤t->mm->mmap_sem); len = PAGE_ALIGN(len + (start & ~PAGE_MASK)); start &= PAGE_MASK; ret = do_mlock(start, len, 0); up_write(¤t->mm->mmap_sem); + vm_validate_enough("exiting sys_munlock"); return ret; } @@ -268,6 +272,8 @@ unsigned long lock_limit; int ret = -EINVAL; + vm_validate_enough("entering sys_mlockall"); + down_write(¤t->mm->mmap_sem); if (!flags || (flags & ~(MCL_CURRENT | MCL_FUTURE))) goto out; @@ -287,15 +293,18 @@ ret = do_mlockall(flags); out: up_write(¤t->mm->mmap_sem); + vm_validate_enough("exiting sys_mlockall"); return ret; } asmlinkage long sys_munlockall(void) { int ret; + vm_validate_enough("entering sys_munlockall"); down_write(¤t->mm->mmap_sem); ret = do_mlockall(0); up_write(¤t->mm->mmap_sem); + vm_validate_enough("exiting sys_munlockall"); return ret; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/mmap.c linux.19pre5-ac1/mm/mmap.c --- linux.19p5/mm/mmap.c Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/mm/mmap.c Wed Apr 3 00:38:19 2002 @@ -1,8 +1,25 @@ /* * linux/mm/mmap.c - * * Written by obz. + * + * Address space accounting code + * (c) Copyright 2002 Red Hat Inc, All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #include #include #include @@ -46,51 +63,127 @@ int sysctl_overcommit_memory; int max_map_count = DEFAULT_MAX_MAP_COUNT; +atomic_t vm_committed_space = ATOMIC_INIT(0); /* Check that a process has enough memory to allocate a * new virtual mapping. */ -int vm_enough_memory(long pages) +int vm_enough_memory(long pages, int charge) { /* Stupid algorithm to decide if we have enough memory: while * simple, it hopefully works in most obvious cases.. Easy to * fool it, but this should catch most mistakes. - */ - /* 23/11/98 NJC: Somewhat less stupid version of algorithm, + * + * 23/11/98 NJC: Somewhat less stupid version of algorithm, * which tries to do "TheRightThing". Instead of using half of * (buffers+cache), use the minimum values. Allow an extra 2% * of num_physpages for safety margin. + * + * 2002/02/26 Alan Cox: Added two new modes that do real accounting */ + unsigned long free, allowed; + struct sysinfo i; - unsigned long free; + if(charge) + atomic_add(pages, &vm_committed_space); /* Sometimes we want to use more memory than we have. */ - if (sysctl_overcommit_memory) + if (sysctl_overcommit_memory == 1) return 1; + if (sysctl_overcommit_memory == 0) + { + /* The page cache contains buffer pages these days.. */ + free = atomic_read(&page_cache_size); + free += nr_free_pages(); + free += nr_swap_pages; + + /* + * This double-counts: the nrpages are both in the page-cache + * and in the swapper space. At the same time, this compensates + * for the swap-space over-allocation (ie "nr_swap_pages" being + * too small. + */ + free += swapper_space.nrpages; + + /* + * The code below doesn't account for free space in the inode + * and dentry slab cache, slab cache fragmentation, inodes and + * dentries which will become freeable under VM load, etc. + * Lets just hope all these (complex) factors balance out... + */ + free += (dentry_stat.nr_unused * sizeof(struct dentry)) >> PAGE_SHIFT; + free += (inodes_stat.nr_unused * sizeof(struct inode)) >> PAGE_SHIFT; + + if(free > pages) + return 1; + atomic_sub(pages, &vm_committed_space); + return 0; + } + allowed = total_swap_pages; + + if(sysctl_overcommit_memory == 2) + { + /* FIXME - need to add arch hooks to get the bits we need + without the higher overhead crap */ + si_meminfo(&i); + allowed += i.totalram >> 1; + } + if(atomic_read(&vm_committed_space) < allowed) + return 1; + if(charge) + atomic_sub(pages, &vm_committed_space); + return 0; + +} - /* The page cache contains buffer pages these days.. */ - free = atomic_read(&page_cache_size); - free += nr_free_pages(); - free += nr_swap_pages; +void vm_unacct_memory(long pages) +{ + atomic_sub(pages, &vm_committed_space); +} - /* - * This double-counts: the nrpages are both in the page-cache - * and in the swapper space. At the same time, this compensates - * for the swap-space over-allocation (ie "nr_swap_pages" being - * too small. - */ - free += swapper_space.nrpages; +void vm_unacct_vma(struct vm_area_struct *vma) +{ + int len = vma->vm_end - vma->vm_start; + if(vma->vm_flags & VM_ACCOUNT) + vm_unacct_memory(len >> PAGE_SHIFT); +} - /* - * The code below doesn't account for free space in the inode - * and dentry slab cache, slab cache fragmentation, inodes and - * dentries which will become freeable under VM load, etc. - * Lets just hope all these (complex) factors balance out... - */ - free += (dentry_stat.nr_unused * sizeof(struct dentry)) >> PAGE_SHIFT; - free += (inodes_stat.nr_unused * sizeof(struct inode)) >> PAGE_SHIFT; +/* + * Don't even bother telling me the locking is wrong - its a test + * routine and uniprocessor is quite sufficient.. + * + * To enable this debugging you must tweak the #if below, and build + * with no SYS5 shared memory (thats not validated yet) and non SMP + */ + +void vm_validate_enough(char *x) +{ +#if 0 + unsigned long count = 0UL; + struct mm_struct *mm; + struct vm_area_struct *vma; + struct list_head *mmp; + unsigned long flags; - return free > pages; + spin_lock_irqsave(&mmlist_lock, flags); + + list_for_each(mmp, &init_mm.mmlist) + { + mm = list_entry(mmp, struct mm_struct, mmlist); + for(vma = mm->mmap; vma!=NULL; vma=vma->vm_next) + { + if(vma->vm_flags & VM_ACCOUNT) + count += (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; + } + } + if(count != atomic_read(&vm_committed_space)) + { + printk("MM crappo accounting %s: %lu %ld.\n", + x, count, atomic_read(&vm_committed_space)); + atomic_set(&vm_committed_space, count); + } + spin_unlock_irqrestore(&mmlist_lock, flags); +#endif } /* Remove one vm structure from the inode's i_mapping address space. */ @@ -161,12 +254,13 @@ /* Always allow shrinking brk. */ if (brk <= mm->brk) { - if (!do_munmap(mm, newbrk, oldbrk-newbrk)) + if (!do_munmap(mm, newbrk, oldbrk-newbrk, 1)) goto set_brk; goto out; } /* Check against rlimit.. */ + /* FIXME: - this seems to be checked in do_brk.. */ rlim = current->rlim[RLIMIT_DATA].rlim_cur; if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim) goto out; @@ -176,7 +270,8 @@ goto out; /* Check if we have enough memory.. */ - if (!vm_enough_memory((newbrk-oldbrk) >> PAGE_SHIFT)) + /* FIXME: - this seems to be checked in do_brk.. */ + if (!vm_enough_memory((newbrk-oldbrk) >> PAGE_SHIFT, 0)) goto out; /* Ok, looks good - let it rip. */ @@ -399,7 +494,9 @@ int correct_wcount = 0; int error; rb_node_t ** rb_link, * rb_parent; + unsigned long charged = 0; + vm_validate_enough("entering do_mmap_pgoff"); if (file && (!file->f_op || !file->f_op->mmap)) return -ENODEV; @@ -482,7 +579,7 @@ munmap_back: vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent); if (vma && vma->vm_start < addr + len) { - if (do_munmap(mm, addr, len)) + if (do_munmap(mm, addr, len, 1)) return -ENOMEM; goto munmap_back; } @@ -492,11 +589,20 @@ > current->rlim[RLIMIT_AS].rlim_cur) return -ENOMEM; + /* FIXME - this ought to be a nice inline ! */ + if(sysctl_overcommit_memory > 1) + vm_flags &= ~MAP_NORESERVE; + /* Private writable mapping? Check memory availability.. */ - if ((vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE && - !(flags & MAP_NORESERVE) && - !vm_enough_memory(len >> PAGE_SHIFT)) - return -ENOMEM; + + if ((((vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE) || (file == NULL)) + && !(flags & MAP_NORESERVE)) + { + charged = len >> PAGE_SHIFT; + if(!vm_enough_memory(charged, 1)) + return -ENOMEM; + vm_flags |= VM_ACCOUNT; + } /* Can we just expand an old anonymous mapping? */ if (!file && !(vm_flags & VM_SHARED) && rb_parent) @@ -508,8 +614,9 @@ * not unmapped, but the maps are removed from the list. */ vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); + error = -ENOMEM; if (!vma) - return -ENOMEM; + goto unacct_error; vma->vm_mm = mm; vma->vm_start = addr; @@ -548,7 +655,14 @@ * Answer: Yes, several device drivers can do it in their * f_op->mmap method. -DaveM */ - addr = vma->vm_start; + if (addr != vma->vm_start) { + /* Since addr changed, we rely on the mmap op to prevent + * collisions with existing vmas and just use find_vma_prepare + * to update the tree pointers. + */ + addr = vma->vm_start; + find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent); + } vma_link(mm, vma, prev, rb_link, rb_parent); if (correct_wcount) @@ -560,6 +674,7 @@ mm->locked_vm += len >> PAGE_SHIFT; make_pages_present(addr, addr + len); } + vm_validate_enough("out from do_mmap_pgoff"); return addr; unmap_and_free_vma: @@ -572,6 +687,10 @@ zap_page_range(mm, vma->vm_start, vma->vm_end - vma->vm_start); free_vma: kmem_cache_free(vm_area_cachep, vma); +unacct_error: + if(charged) + vm_unacct_memory(charged); + vm_validate_enough("error path from do_mmap_pgoff"); return error; } @@ -714,6 +833,47 @@ return NULL; } +/* vma is the first one with address < vma->vm_end, + * and even address < vma->vm_start. Have to extend vma. */ +int expand_stack(struct vm_area_struct * vma, unsigned long address) +{ + unsigned long grow; + + vm_validate_enough("entering expand_stack"); + + /* + * vma->vm_start/vm_end cannot change under us because the caller is required + * to hold the mmap_sem in write mode. We need to get the spinlock only + * before relocating the vma range ourself. + */ + address &= PAGE_MASK; + spin_lock(&vma->vm_mm->page_table_lock); + grow = (vma->vm_start - address) >> PAGE_SHIFT; + + /* Overcommit.. */ + if(!vm_enough_memory(grow, 1)) { + spin_unlock(&vma->vm_mm->page_table_lock); + return -ENOMEM; + } + + if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur || + ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur) { + spin_unlock(&vma->vm_mm->page_table_lock); + vm_unacct_memory(grow); + vm_validate_enough("exiting expand_stack - FAIL"); + return -ENOMEM; + } + vma->vm_start = address; + vma->vm_pgoff -= grow; + vma->vm_mm->total_vm += grow; + if (vma->vm_flags & VM_LOCKED) + vma->vm_mm->locked_vm += grow; + spin_unlock(&vma->vm_mm->page_table_lock); + vm_validate_enough("exiting expand_stack"); + return 0; +} + + struct vm_area_struct * find_extend_vma(struct mm_struct * mm, unsigned long addr) { struct vm_area_struct * vma; @@ -761,7 +921,7 @@ */ static struct vm_area_struct * unmap_fixup(struct mm_struct *mm, struct vm_area_struct *area, unsigned long addr, size_t len, - struct vm_area_struct *extra) + struct vm_area_struct *extra, int acct) { struct vm_area_struct *mpnt; unsigned long end = addr + len; @@ -776,10 +936,15 @@ area->vm_ops->close(area); if (area->vm_file) fput(area->vm_file); + if(acct) + vm_unacct_vma(area); kmem_cache_free(vm_area_cachep, area); return extra; } + if(acct && (area->vm_flags & VM_ACCOUNT)) + vm_unacct_memory(len >> PAGE_SHIFT); + /* Work out to one of the ends. */ if (end == area->vm_end) { /* @@ -894,10 +1059,12 @@ * work. This now handles partial unmappings. * Jeremy Fitzhardine */ -int do_munmap(struct mm_struct *mm, unsigned long addr, size_t len) +int do_munmap(struct mm_struct *mm, unsigned long addr, size_t len, int acct) { struct vm_area_struct *mpnt, *prev, **npp, *free, *extra; + if(acct) vm_validate_enough("entering do_munmap"); + if ((addr & ~PAGE_MASK) || addr > TASK_SIZE || len > TASK_SIZE-addr) return -EINVAL; @@ -964,6 +1131,7 @@ (file = mpnt->vm_file) != NULL) { atomic_dec(&file->f_dentry->d_inode->i_writecount); } + remove_shared_vm_struct(mpnt); mm->map_count--; @@ -972,7 +1140,7 @@ /* * Fix the mapping, and free the old area if it wasn't reused. */ - extra = unmap_fixup(mm, mpnt, st, size, extra); + extra = unmap_fixup(mm, mpnt, st, size, extra, acct); if (file) atomic_inc(&file->f_dentry->d_inode->i_writecount); } @@ -983,6 +1151,7 @@ kmem_cache_free(vm_area_cachep, extra); free_pgtables(mm, prev, addr, addr+len); + if(acct) vm_validate_enough("exit -ok- do_munmap"); return 0; } @@ -993,7 +1162,7 @@ struct mm_struct *mm = current->mm; down_write(&mm->mmap_sem); - ret = do_munmap(mm, addr, len); + ret = do_munmap(mm, addr, len, 1); up_write(&mm->mmap_sem); return ret; } @@ -1010,6 +1179,9 @@ unsigned long flags; rb_node_t ** rb_link, * rb_parent; + vm_validate_enough("entering do_brk"); + + len = PAGE_ALIGN(len); if (!len) return addr; @@ -1030,7 +1202,7 @@ munmap_back: vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent); if (vma && vma->vm_start < addr + len) { - if (do_munmap(mm, addr, len)) + if (do_munmap(mm, addr, len, 1)) return -ENOMEM; goto munmap_back; } @@ -1043,10 +1215,10 @@ if (mm->map_count > max_map_count) return -ENOMEM; - if (!vm_enough_memory(len >> PAGE_SHIFT)) + if (!vm_enough_memory(len >> PAGE_SHIFT, 1)) return -ENOMEM; - flags = VM_DATA_DEFAULT_FLAGS | mm->def_flags; + flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags; /* Can we just expand an old anonymous mapping? */ if (rb_parent && vma_merge(mm, prev, rb_parent, addr, addr + len, flags)) @@ -1057,8 +1229,11 @@ */ vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (!vma) + { + /* We accounted this address space - undo it */ + vm_unacct_memory(len >> PAGE_SHIFT); return -ENOMEM; - + } vma->vm_mm = mm; vma->vm_start = addr; vma->vm_end = addr + len; @@ -1077,6 +1252,9 @@ mm->locked_vm += len >> PAGE_SHIFT; make_pages_present(addr, addr + len); } + + vm_validate_enough("exiting do_brk"); + return addr; } @@ -1118,6 +1296,10 @@ unsigned long end = mpnt->vm_end; unsigned long size = end - start; + /* If the VMA has been charged for, account for its removal */ + if (mpnt->vm_flags & VM_ACCOUNT) + vm_unacct_vma(mpnt); + if (mpnt->vm_ops) { if (mpnt->vm_ops->close) mpnt->vm_ops->close(mpnt); @@ -1137,6 +1319,9 @@ BUG(); clear_page_tables(mm, FIRST_USER_PGD_NR, USER_PTRS_PER_PGD); + + vm_validate_enough("exiting exit_mmap"); + } /* Insert vm structure into process list sorted by address diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/mprotect.c linux.19pre5-ac1/mm/mprotect.c --- linux.19p5/mm/mprotect.c Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/mm/mprotect.c Mon Mar 25 18:16:50 2002 @@ -2,6 +2,23 @@ * linux/mm/mprotect.c * * (C) Copyright 1994 Linus Torvalds + * + * Address space accounting code + * (c) Copyright 2002 Red Hat Inc, All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include @@ -241,11 +258,32 @@ { pgprot_t newprot; int error; + unsigned long charged = 0; if (newflags == vma->vm_flags) { *pprev = vma; return 0; } + +#ifdef COMPLETE_BOLLOCKS + /* + * If we take an anonymous mapped vma writable we + * increase our commit (was one page per file now one page + * per writable private instance) + * FIXME: shared private mapping R/O versus R/W accounting + */ + if(vma->vm_file != NULL && + ((vma->vm_flags & (VM_ACCOUNT|VM_SHARED)) == (VM_ACCOUNT|VM_SHARED)) && + ((newflags & PROT_WRITE) != (vma->vm_flags & PROT_WRITE))) + { + charged = (end - start) >> PAGE_SHIFT; + if(newflags & PROT_WRITE) + { + if(!vm_enough_memory(charged, 1)) + return -ENOMEM; + } + } +#endif newprot = protection_map[newflags & 0xf]; if (start == vma->vm_start) { if (end == vma->vm_end) @@ -258,8 +296,15 @@ error = mprotect_fixup_middle(vma, pprev, start, end, newflags, newprot); if (error) + { + if(newflags & PROT_WRITE) + vm_unacct_memory(charged); return error; - + } + /* Delayed accounting for reduction of memory use - done last to + avoid allocation races */ + if (charged && !(newflags & PROT_WRITE)) + vm_unacct_memory(charged); change_protection(start, end, newprot); return 0; } @@ -270,6 +315,8 @@ struct vm_area_struct * vma, * next, * prev; int error = -EINVAL; + vm_validate_enough("entering mprotect"); + if (start & ~PAGE_MASK) return -EINVAL; len = PAGE_ALIGN(len); @@ -333,5 +380,6 @@ } out: up_write(¤t->mm->mmap_sem); + vm_validate_enough("exiting mprotect"); return error; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/mremap.c linux.19pre5-ac1/mm/mremap.c --- linux.19p5/mm/mremap.c Thu Apr 4 13:18:17 2002 +++ linux.19pre5-ac1/mm/mremap.c Tue Mar 19 15:54:22 2002 @@ -2,6 +2,23 @@ * linux/mm/remap.c * * (C) Copyright 1996 Linus Torvalds + * + * Address space accounting code + * (c) Copyright 2002 Red Hat Inc, All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include @@ -13,8 +30,6 @@ #include #include -extern int vm_enough_memory(long pages); - static inline pte_t *get_one_pte(struct mm_struct *mm, unsigned long addr) { pgd_t * pgd; @@ -61,8 +76,14 @@ { int error = 0; pte_t pte; + struct page * page = NULL; + + if (pte_present(*src)) + page = pte_page(*src); if (!pte_none(*src)) { + if (page) + page_remove_rmap(page, src); pte = ptep_get_and_clear(src); if (!dst) { /* No dest? We must put it back. */ @@ -70,6 +91,8 @@ error++; } set_pte(dst, pte); + if (page) + page_add_rmap(page, dst); } return error; } @@ -130,6 +153,7 @@ struct vm_area_struct * new_vma, * next, * prev; int allocated_vma; + new_vma = NULL; next = find_vma_prev(mm, new_addr, &prev); if (next) { @@ -189,7 +213,8 @@ new_vma->vm_ops->open(new_vma); insert_vm_struct(current->mm, new_vma); } - do_munmap(current->mm, addr, old_len); + /* The old VMA has been accounted for, don't double account */ + do_munmap(current->mm, addr, old_len, 0); current->mm->total_vm += new_len >> PAGE_SHIFT; if (new_vma->vm_flags & VM_LOCKED) { current->mm->locked_vm += new_len >> PAGE_SHIFT; @@ -215,8 +240,11 @@ unsigned long old_len, unsigned long new_len, unsigned long flags, unsigned long new_addr) { + extern int sysctl_overcommit_memory; /* FIXME!! */ + struct vm_area_struct *vma; unsigned long ret = -EINVAL; + unsigned long charged = 0; if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE)) goto out; @@ -246,16 +274,17 @@ if ((addr <= new_addr) && (addr+old_len) > new_addr) goto out; - do_munmap(current->mm, new_addr, new_len); + do_munmap(current->mm, new_addr, new_len, 1); } /* * Always allow a shrinking remap: that just unmaps * the unnecessary pages.. + * do_munmap does all the needed commit accounting */ ret = addr; if (old_len >= new_len) { - do_munmap(current->mm, addr+new_len, old_len - new_len); + do_munmap(current->mm, addr+new_len, old_len - new_len, 1); if (!(flags & MREMAP_FIXED) || (new_addr == addr)) goto out; } @@ -285,12 +314,17 @@ if ((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 && - !(flags & MAP_NORESERVE) && - !vm_enough_memory((new_len - old_len) >> PAGE_SHIFT)) - goto out; + /* FIXME - this ought to be a nice inline ! */ + if(sysctl_overcommit_memory > 1) + flags &= ~MAP_NORESERVE; + + if(vma->vm_flags&VM_ACCOUNT) + { + charged = (new_len - old_len) >> PAGE_SHIFT; + if(!vm_enough_memory(charged, 1)) + goto out_nc; + } /* old_len exactly to the end of the area.. * And we're not relocating the area. */ @@ -313,6 +347,7 @@ addr + new_len); } ret = addr; + vm_validate_enough("mremap path1"); goto out; } } @@ -336,6 +371,12 @@ ret = move_vma(vma, addr, old_len, new_len, new_addr); } out: + if(ret & ~PAGE_MASK) + { + vm_unacct_memory(charged); + vm_validate_enough("mremap error path"); + } +out_nc: return ret; } @@ -345,8 +386,10 @@ { unsigned long ret; + vm_validate_enough("entry to mremap"); down_write(¤t->mm->mmap_sem); ret = do_mremap(addr, old_len, new_len, flags, new_addr); up_write(¤t->mm->mmap_sem); + vm_validate_enough("exit from mremap"); return ret; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/oom_kill.c linux.19pre5-ac1/mm/oom_kill.c --- linux.19p5/mm/oom_kill.c Thu Apr 4 13:18:17 2002 +++ linux.19pre5-ac1/mm/oom_kill.c Wed Feb 27 18:32:03 2002 @@ -82,7 +82,7 @@ * Niced processes are most likely less important, so double * their badness points. */ - if (p->nice > 0) + if (task_nice(p) > 0) points *= 2; /* @@ -110,8 +110,7 @@ /* * Simple selection loop. We chose the process with the highest - * number of 'points'. We need the locks to make sure that the - * list of task structs doesn't change while we look the other way. + * number of 'points'. We expect the caller will lock the tasklist. * * (not docbooked, we don't want this one cluttering up the manual) */ @@ -121,7 +120,6 @@ struct task_struct *p = NULL; struct task_struct *chosen = NULL; - read_lock(&tasklist_lock); for_each_task(p) { if (p->pid) { int points = badness(p); @@ -131,7 +129,6 @@ } } } - read_unlock(&tasklist_lock); return chosen; } @@ -149,7 +146,7 @@ * all the memory it needs. That way it should be able to * exit() and clear out its resources quickly... */ - p->counter = 5 * HZ; + p->time_slice = HZ; p->flags |= PF_MEMALLOC | PF_MEMDIE; /* This process has hardware access, be more careful. */ @@ -170,26 +167,31 @@ */ static void oom_kill(void) { - struct task_struct *p = select_bad_process(), *q; + struct task_struct *p, *q; + extern wait_queue_head_t kswapd_done; + + read_lock(&tasklist_lock); + p = select_bad_process(); /* Found nothing?!?! Either we hang forever, or we panic. */ if (p == NULL) panic("Out of memory and no killable processes...\n"); /* kill all processes that share the ->mm (i.e. all threads) */ - read_lock(&tasklist_lock); for_each_task(q) { if(q->mm == p->mm) oom_kill_task(q); } read_unlock(&tasklist_lock); + /* Chances are by this time our victim is sleeping on kswapd. */ + wake_up(&kswapd_done); + /* * Make kswapd go out of the way, so "p" has a good chance of * killing itself before someone else gets the chance to ask * for more memory. */ - current->policy |= SCHED_YIELD; - schedule(); + yield(); return; } @@ -198,7 +200,7 @@ */ void out_of_memory(void) { - static unsigned long first, last, count; + static unsigned long first, last, count, lastkill; unsigned long now, since; /* @@ -235,8 +237,18 @@ return; /* + * If we just killed a process, wait a while + * to give that task a chance to exit. This + * avoids killing multiple processes needlessly. + */ + since = now - lastkill; + if (since < HZ*5) + return; + + /* * Ok, really out of memory. Kill something. */ + lastkill = now; oom_kill(); reset: diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/page_alloc.c linux.19pre5-ac1/mm/page_alloc.c --- linux.19p5/mm/page_alloc.c Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/mm/page_alloc.c Wed Feb 27 18:32:03 2002 @@ -20,16 +20,21 @@ #include #include #include +#include #include +#include int nr_swap_pages; int nr_active_pages; -int nr_inactive_pages; -struct list_head inactive_list; -struct list_head active_list; +int nr_inactive_dirty_pages; +int nr_inactive_clean_pages; pg_data_t *pgdat_list; -/* Used to look up the address of the struct zone encoded in page->zone */ +/* + * The zone_table array is used to look up the address of the + * struct zone corresponding to a given zone number (ZONE_DMA, + * ZONE_NORMAL, or ZONE_HIGHMEM). + */ zone_t *zone_table[MAX_NR_ZONES*MAX_NR_NODES]; EXPORT_SYMBOL(zone_table); @@ -37,6 +42,8 @@ static int zone_balance_ratio[MAX_NR_ZONES] __initdata = { 128, 128, 128, }; static int zone_balance_min[MAX_NR_ZONES] __initdata = { 20 , 20, 20, }; static int zone_balance_max[MAX_NR_ZONES] __initdata = { 255 , 255, 255, }; +static int zone_extrafree_ratio[MAX_NR_ZONES] __initdata = { 128, 512, 0, }; +static int zone_extrafree_max[MAX_NR_ZONES] __initdata = { 1024 , 1024, 0, }; /* * Free_page() adds the page to the free lists. This is optimized for @@ -63,15 +70,17 @@ */ #define BAD_RANGE(zone, page) \ ( \ - (((page) - mem_map) >= ((zone)->zone_start_mapnr+(zone)->size)) \ + (((page) - mem_map) >= ((zone)->zone_start_mapnr+(zone)->size)) \ || (((page) - mem_map) < (zone)->zone_start_mapnr) \ || ((zone) != page_zone(page)) \ ) /* * Freeing function for a buddy system allocator. + * Contrary to prior comments, this is *NOT* hairy, and there + * is no reason for anyone not to understand it. * - * The concept of a buddy system is to maintain direct-mapped table + * The concept of a buddy system is to maintain direct-mapped tables * (containing bit values) for memory blocks of various "orders". * The bottom level table contains the map for the smallest allocatable * units of memory (here, pages), and each level above it describes @@ -112,16 +121,17 @@ BUG(); if (PageLocked(page)) BUG(); - if (PageLRU(page)) - BUG(); if (PageActive(page)) BUG(); + if (PageInactiveDirty(page)) + BUG(); + if (PageInactiveClean(page)) + BUG(); + if (page->pte_chain) + BUG(); page->flags &= ~((1<flags & PF_FREE_PAGES) - goto local_freelist; - back_local_freelist: - + page->age = PAGE_AGE_START; + zone = page_zone(page); mask = (~0UL) << order; @@ -150,7 +160,7 @@ /* * Move the buddy up one level. * This code is taking advantage of the identity: - * -mask = 1+~mask + * -mask = 1+~mask */ buddy1 = base + (page_idx ^ -mask); buddy2 = base + page_idx; @@ -168,17 +178,6 @@ memlist_add_head(&(base + page_idx)->list, &area->free_list); spin_unlock_irqrestore(&zone->lock, flags); - return; - - local_freelist: - if (current->nr_local_pages) - goto back_local_freelist; - if (in_interrupt()) - goto back_local_freelist; - - list_add(&page->list, ¤t->local_pages); - page->index = order; - current->nr_local_pages++; } #define MARK_USED(index, order, area) \ @@ -237,10 +236,7 @@ set_page_count(page, 1); if (BAD_RANGE(zone,page)) BUG(); - if (PageLRU(page)) - BUG(); - if (PageActive(page)) - BUG(); + DEBUG_LRU_PAGE(page); return page; } curr_order++; @@ -259,78 +255,83 @@ } #endif -static struct page * FASTCALL(balance_classzone(zone_t *, unsigned int, unsigned int, int *)); -static struct page * balance_classzone(zone_t * classzone, unsigned int gfp_mask, unsigned int order, int * freed) +/* + * If we are able to directly reclaim pages, we move pages from the + * inactive_clean list onto the free list until the zone has enough + * free pages or until the inactive_clean pages are exhausted. + * If we cannot do this work ourselves, call kswapd. + */ +void FASTCALL(fixup_freespace(zone_t * zone, int direct_reclaim)); +void fixup_freespace(zone_t * zone, int direct_reclaim) +{ + if (direct_reclaim) { + struct page * page; + do { + if ((page = reclaim_page(zone))) + __free_pages_ok(page, 0); + } while (page && zone->free_pages <= zone->pages_min); + } else + wakeup_kswapd(GFP_ATOMIC); +} + +#define PAGES_KERNEL 0 +#define PAGES_MIN 1 +#define PAGES_LOW 2 +#define PAGES_HIGH 3 + +/* + * This function does the dirty work for __alloc_pages + * and is separated out to keep the code size smaller. + * (suggested by Davem at 1:30 AM, typed by Rik at 6 AM) + */ +static struct page * __alloc_pages_limit(zonelist_t *zonelist, + unsigned long order, int limit, int direct_reclaim) { - struct page * page = NULL; - int __freed = 0; + zone_t **zone = zonelist->zones; + unsigned long water_mark = 0; - if (!(gfp_mask & __GFP_WAIT)) - goto out; - if (in_interrupt()) - BUG(); - - current->allocation_order = order; - current->flags |= PF_MEMALLOC | PF_FREE_PAGES; - - __freed = try_to_free_pages(classzone, gfp_mask, order); - - current->flags &= ~(PF_MEMALLOC | PF_FREE_PAGES); - - if (current->nr_local_pages) { - struct list_head * entry, * local_pages; - struct page * tmp; - int nr_pages; - - local_pages = ¤t->local_pages; - - if (likely(__freed)) { - /* pick from the last inserted so we're lifo */ - entry = local_pages->next; - do { - tmp = list_entry(entry, struct page, list); - if (tmp->index == order && memclass(page_zone(tmp), classzone)) { - list_del(entry); - current->nr_local_pages--; - set_page_count(tmp, 1); - page = tmp; - - if (page->buffers) - BUG(); - if (page->mapping) - BUG(); - if (!VALID_PAGE(page)) - BUG(); - if (PageSwapCache(page)) - BUG(); - if (PageLocked(page)) - BUG(); - if (PageLRU(page)) - BUG(); - if (PageActive(page)) - BUG(); - if (PageDirty(page)) - BUG(); + for (;;) { + zone_t *z = *(zone++); - break; - } - } while ((entry = entry->next) != local_pages); + if (!z) + break; + if (!z->size) + BUG(); + + /* + * We allocate if the number of (free + inactive_clean) + * pages is above the watermark. + */ + switch (limit) { + case PAGES_KERNEL: + water_mark = z->pages_min / 2; + break; + case PAGES_MIN: + water_mark = z->pages_min; + break; + case PAGES_LOW: + water_mark = z->pages_low; + break; + default: + case PAGES_HIGH: + water_mark = z->pages_high; } - nr_pages = current->nr_local_pages; - /* free in reverse order so that the global order will be lifo */ - while ((entry = local_pages->prev) != local_pages) { - list_del(entry); - tmp = list_entry(entry, struct page, list); - __free_pages_ok(tmp, tmp->index); - if (!nr_pages--) - BUG(); + if (z->free_pages + z->inactive_clean_pages >= water_mark) { + struct page *page = NULL; + /* If possible, reclaim a page directly. */ + if (direct_reclaim) + page = reclaim_page(z); + /* If that fails, fall back to rmqueue. */ + if (!page) + page = rmqueue(z, order); + if (page) + return page; } - current->nr_local_pages = 0; } - out: - *freed = __freed; - return page; + + /* Found nothing. */ + return NULL; } /* @@ -338,100 +339,247 @@ */ struct page * __alloc_pages(unsigned int gfp_mask, unsigned int order, zonelist_t *zonelist) { - unsigned long min; - zone_t **zone, * classzone; + zone_t **zone; + int min, direct_reclaim = 0; struct page * page; - int freed; + /* + * (If anyone calls gfp from interrupts nonatomically then it + * will sooner or later tripped up by a schedule().) + * + * We fall back to lower-level zones if allocation + * in a higher zone fails. + */ + + /* + * Can we take pages directly from the inactive_clean + * list? + */ + if (order == 0 && (gfp_mask & __GFP_WAIT)) + direct_reclaim = 1; + +try_again: + /* + * First, see if we have any zones with lots of free memory. + * + * We allocate free memory first because it doesn't contain + * any data we would want to cache. + */ zone = zonelist->zones; - classzone = *zone; min = 1UL << order; for (;;) { zone_t *z = *(zone++); if (!z) break; + if (!z->size) + BUG(); - min += z->pages_low; + min += z->pages_min; if (z->free_pages > min) { page = rmqueue(z, order); if (page) return page; - } + } else if (z->free_pages < z->pages_min) + fixup_freespace(z, direct_reclaim); + } + + /* + * Next, try to allocate a page from a zone with a HIGH + * amount of (free + inactive_clean) pages. + * + * If there is a lot of activity, inactive_target + * will be high and we'll have a good chance of + * finding a page using the HIGH limit. + */ + page = __alloc_pages_limit(zonelist, order, PAGES_HIGH, direct_reclaim); + if (page) + return page; + + /* + * Then try to allocate a page from a zone with more + * than zone->pages_low of (free + inactive_clean) pages. + * + * When the working set is very large and VM activity + * is low, we're most likely to have our allocation + * succeed here. + */ + page = __alloc_pages_limit(zonelist, order, PAGES_LOW, direct_reclaim); + if (page) + return page; + + /* + * OK, none of the zones on our zonelist has lots + * of pages free. + * + * We wake up kswapd, in the hope that kswapd will + * resolve this situation before memory gets tight. + * + * We'll also help a bit trying to free pages, this + * way statistics will make sure really fast allocators + * are slowed down more than slow allocators and other + * programs in the system shouldn't be impacted as much + * by the hogs. + */ + wakeup_kswapd(gfp_mask); + + /* + * After waking up kswapd, we try to allocate a page + * from any zone which isn't critical yet. + * + * Kswapd should, in most situations, bring the situation + * back to normal in no time. + */ + page = __alloc_pages_limit(zonelist, order, PAGES_MIN, direct_reclaim); + if (page) + return page; + + /* + * Kernel allocations can eat a few emergency pages. + * We should be able to run without this, find out why + * the SCSI layer isn't happy ... + */ + if (gfp_mask & __GFP_HIGH) { + page = __alloc_pages_limit(zonelist, order, PAGES_KERNEL, direct_reclaim); + if (page) + return page; } - classzone->need_balance = 1; - mb(); - if (waitqueue_active(&kswapd_wait)) - wake_up_interruptible(&kswapd_wait); + /* + * Oh well, we didn't succeed. + */ + if (!(current->flags & PF_MEMALLOC)) { + /* + * Are we dealing with a higher order allocation? + * + * If so, try to defragment some memory. + */ + if (order > 0 && (gfp_mask & __GFP_WAIT)) + goto defragment; + + /* + * If we arrive here, we are really tight on memory. + * Since kswapd didn't succeed in freeing pages for us, + * we need to help it. + * + * Single page allocs loop until the allocation succeeds. + * Multi-page allocs can fail due to memory fragmentation; + * in that case we bail out to prevent infinite loops and + * hanging device drivers ... + * + * Another issue are GFP_NOFS allocations; because they + * do not have __GFP_FS set it's possible we cannot make + * any progress freeing pages, in that case it's better + * to give up than to deadlock the kernel looping here. + * + * NFS: we must yield the CPU (to rpciod) to avoid deadlock. + */ + if (gfp_mask & __GFP_WAIT) { + __set_current_state(TASK_RUNNING); + yield(); + if (!order || free_high(ALL_ZONES) >= 0) { + int progress = try_to_free_pages(gfp_mask); + if (progress || (gfp_mask & __GFP_FS)) + goto try_again; + /* + * Fail if no progress was made and the + * allocation may not be able to block on IO. + */ + return NULL; + } + } + } + /* + * Final phase: allocate anything we can! + * + * Higher order allocations, GFP_ATOMIC allocations and + * recursive allocations (PF_MEMALLOC) end up here. + * + * Only recursive allocations can use the very last pages + * in the system, otherwise it would be just too easy to + * deadlock the system... + */ zone = zonelist->zones; min = 1UL << order; for (;;) { - unsigned long local_min; zone_t *z = *(zone++); + struct page * page = NULL; if (!z) break; - local_min = z->pages_min; - if (!(gfp_mask & __GFP_WAIT)) - local_min >>= 2; - min += local_min; - if (z->free_pages > min) { + /* + * SUBTLE: direct_reclaim is only possible if the task + * becomes PF_MEMALLOC while looping above. This will + * happen when the OOM killer selects this task for + * death. + */ + if (direct_reclaim) { + page = reclaim_page(z); + if (page) + return page; + } + + /* XXX: is pages_min/4 a good amount to reserve for this? */ + min += z->pages_min / 4; + if (z->free_pages > min || ((current->flags & PF_MEMALLOC) && !in_interrupt())) { page = rmqueue(z, order); if (page) return page; } } + goto out_failed; - /* here we're in the low on memory slow path */ -rebalance: - if (current->flags & (PF_MEMALLOC | PF_MEMDIE)) { + /* + * Naive "defragmentation" for higher-order allocations. First we + * free the inactive_clean pages to see if we can allocate our + * allocation, then we call page_launder() to clean some dirty + * pages, and last we try once more. + * + * We might want to turn this into something which defragments + * memory based on physical page, simply by looking for unmapped + * pages next to pages on the free list... + */ +defragment: + { + int freed = 0; +defragment_again: zone = zonelist->zones; for (;;) { zone_t *z = *(zone++); if (!z) break; - - page = rmqueue(z, order); - if (page) - return page; + if (!z->size) + continue; + while (z->inactive_clean_pages) { + struct page * page; + /* Move one page to the free list. */ + page = reclaim_page(z); + if (!page) + break; + __free_page(page); + /* Try if the allocation succeeds. */ + page = rmqueue(z, order); + if (page) + return page; + } } - return NULL; - } - - /* Atomic allocations - we can't balance anything */ - if (!(gfp_mask & __GFP_WAIT)) - return NULL; - - page = balance_classzone(classzone, gfp_mask, order, &freed); - if (page) - return page; - - zone = zonelist->zones; - min = 1UL << order; - for (;;) { - zone_t *z = *(zone++); - if (!z) - break; - min += z->pages_min; - if (z->free_pages > min) { - page = rmqueue(z, order); - if (page) - return page; + /* XXX: do real defragmentation instead of calling launder ? */ + if (!freed) { + freed = 1; + current->flags |= PF_MEMALLOC; + try_to_free_pages(gfp_mask); + current->flags &= ~PF_MEMALLOC; + goto defragment_again; } } - /* Don't let big-order allocations loop */ - if (order > 3) - return NULL; - - /* Yield for kswapd, and try again */ - current->policy |= SCHED_YIELD; - __set_current_state(TASK_RUNNING); - schedule(); - goto rebalance; + +out_failed: + /* No luck.. */ +// printk(KERN_ERR "__alloc_pages: %lu-order allocation failed.\n", order); + return NULL; } /* @@ -479,14 +627,11 @@ { unsigned int sum; zone_t *zone; - pg_data_t *pgdat = pgdat_list; sum = 0; - while (pgdat) { - for (zone = pgdat->node_zones; zone < pgdat->node_zones + MAX_NR_ZONES; zone++) - sum += zone->free_pages; - pgdat = pgdat->node_next; - } + for_each_zone(zone) + sum += zone->free_pages; + return sum; } @@ -495,23 +640,21 @@ */ unsigned int nr_free_buffer_pages (void) { - pg_data_t *pgdat = pgdat_list; + pg_data_t *pgdat; unsigned int sum = 0; - do { + for_each_pgdat(pgdat) { zonelist_t *zonelist = pgdat->node_zonelists + (GFP_USER & GFP_ZONEMASK); zone_t **zonep = zonelist->zones; zone_t *zone; for (zone = *zonep++; zone; zone = *zonep++) { - unsigned long size = zone->size; - unsigned long high = zone->pages_high; - if (size > high) - sum += size - high; + sum += zone->free_pages; + sum += zone->inactive_clean_pages; + sum += zone->inactive_dirty_pages; } - pgdat = pgdat->node_next; - } while (pgdat); + } return sum; } @@ -519,13 +662,12 @@ #if CONFIG_HIGHMEM unsigned int nr_free_highpages (void) { - pg_data_t *pgdat = pgdat_list; + pg_data_t *pgdat; unsigned int pages = 0; - while (pgdat) { + for_each_pgdat(pgdat) pages += pgdat->node_zones[ZONE_HIGHMEM].free_pages; - pgdat = pgdat->node_next; - } + return pages; } #endif @@ -562,10 +704,18 @@ tmpdat = tmpdat->node_next; } - printk("( Active: %d, inactive: %d, free: %d )\n", - nr_active_pages, - nr_inactive_pages, - nr_free_pages()); + printk("Free pages: %6dkB (%6dkB HighMem)\n", + nr_free_pages() << (PAGE_SHIFT-10), + nr_free_highpages() << (PAGE_SHIFT-10)); + + printk("( Active: %d, inactive_dirty: %d, inactive_clean: %d, free: %d (%d %d %d) )\n", + nr_active_pages, + nr_inactive_dirty_pages, + nr_inactive_clean_pages, + nr_free_pages(), + freepages.min, + freepages.low, + freepages.high); for (type = 0; type < MAX_NR_ZONES; type++) { struct list_head *head, *curr; @@ -662,7 +812,8 @@ * The constant PAGES_PER_WAITQUEUE specifies the ratio of pages to * waitqueues, i.e. the size of the waitq table given the number of pages. */ -#define PAGES_PER_WAITQUEUE 256 + +#define PAGES_PER_WAITQUEUE 256 static inline unsigned long wait_table_size(unsigned long pages) { @@ -670,19 +821,13 @@ pages /= PAGES_PER_WAITQUEUE; - while (size < pages) + while(size < pages) size <<= 1; - /* - * Once we have dozens or even hundreds of threads sleeping - * on IO we've got bigger problems than wait queue collision. - * Limit the size of the wait table to a reasonable size. - */ - size = min(size, 4096UL); - return size; } + /* * This is an integer logarithm so that shifts can be used later * to extract the more random high bits from the multiplicative @@ -693,6 +838,7 @@ return ffz(~size); } + #define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1)) /* @@ -725,9 +871,6 @@ printk("On node %d totalpages: %lu\n", nid, realtotalpages); - INIT_LIST_HEAD(&active_list); - INIT_LIST_HEAD(&inactive_list); - /* * Some architectures (with lots of mem and discontinous memory * maps) have to search for a good mem_map area: @@ -750,10 +893,10 @@ offset = lmem_map - mem_map; for (j = 0; j < MAX_NR_ZONES; j++) { zone_t *zone = pgdat->node_zones + j; - unsigned long mask; + unsigned long mask, extrafree = 0; unsigned long size, realsize; - zone_table[nid * MAX_NR_ZONES + j] = zone; + zone_table[j] = zone; realsize = size = zones_size[j]; if (zholes_size) realsize -= zholes_size[j]; @@ -764,13 +907,23 @@ zone->lock = SPIN_LOCK_UNLOCKED; zone->zone_pgdat = pgdat; zone->free_pages = 0; + zone->inactive_clean_pages = 0; + zone->inactive_dirty_pages = 0; zone->need_balance = 0; + INIT_LIST_HEAD(&zone->active_list); + INIT_LIST_HEAD(&zone->inactive_dirty_list); + INIT_LIST_HEAD(&zone->inactive_clean_list); + if (!size) continue; /* - * The per-page waitqueue mechanism uses hashed waitqueues - * per zone. + * The per-page waitqueue mechanism requires hash tables + * whose buckets are waitqueues. These hash tables are + * per-zone, and dynamically sized according to the size + * of the zone so as to maintain a good ratio of waiters + * to hash table buckets. Right here we just allocate + * and initialize them for later use (in filemap.c) */ zone->wait_table_size = wait_table_size(size); zone->wait_table_shift = @@ -784,15 +937,36 @@ pgdat->nr_zones = j+1; + /* + * On large memory machines we keep extra memory + * free for kernel allocations. + */ + if (zone_extrafree_ratio[j]) + extrafree = min_t(int, (realtotalpages / zone_extrafree_ratio[j]), zone_extrafree_max[j]); + if (extrafree < zone_balance_max[j]) + extrafree = 0; + mask = (realsize / zone_balance_ratio[j]); if (mask < zone_balance_min[j]) mask = zone_balance_min[j]; - else if (mask > zone_balance_max[j]) - mask = zone_balance_max[j]; - zone->pages_min = mask; - zone->pages_low = mask*2; - zone->pages_high = mask*3; - + zone->pages_min = extrafree + min(mask, (unsigned long)zone_balance_max[j]); + zone->pages_low = extrafree + mask*2; + zone->pages_high = extrafree + mask*3; + zone->pages_plenty = extrafree + mask*6; + /* + * Add these free targets to the global free target; + * we have to be SURE that freepages.high is higher + * than SUM [zone->pages_min] for all zones, otherwise + * we may have bad bad problems. + * + * This means we cannot make the freepages array writable + * in /proc, but have to add a separate extra_free_target + * for people who require it to catch load spikes in eg. + * gigabit ethernet routing... + */ + freepages.min += zone->pages_min; + freepages.low += zone->pages_low; + freepages.high += zone->pages_high; zone->zone_mem_map = mem_map + offset; zone->zone_start_mapnr = offset; zone->zone_start_paddr = zone_start_paddr; @@ -807,9 +981,9 @@ */ for (i = 0; i < size; i++) { struct page *page = mem_map + offset + i; - set_page_zone(page, nid * MAX_NR_ZONES + j); - set_page_count(page, 0); - SetPageReserved(page); + set_page_zone(page, pgdat->node_id * MAX_NR_ZONES + j); + init_page_count(page); + __SetPageReserved(page); memlist_init(&page->list); if (j != ZONE_HIGHMEM) set_page_address(page, __va(zone_start_paddr)); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/rmap.c linux.19pre5-ac1/mm/rmap.c --- linux.19p5/mm/rmap.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/mm/rmap.c Wed Feb 13 01:06:43 2002 @@ -0,0 +1,384 @@ +/* + * mm/rmap.c - physical to virtual reverse mappings + * + * Copyright 2001, Rik van Riel + * Released under the General Public License (GPL). + * + * + * Simple, low overhead pte-based reverse mapping scheme. + * This is kept modular because we may want to experiment + * with object-based reverse mapping schemes. Please try + * to keep this thing as modular as possible. + */ + +/* + * Locking: + * - the page->pte_chain is protected by the pagemap_lru_lock, + * we probably want to change this to a per-page lock in the + * future + * - because swapout locking is opposite to the locking order + * in the page fault path, the swapout path uses trylocks + * on the mm->page_table_lock + */ +#include +#include +#include + +#include +#include +#include + +/* #define DEBUG_RMAP */ + +/* + * Shared pages have a chain of pte_chain structures, used to locate + * all the mappings to this page. We only need a pointer to the pte + * here, the page struct for the page table page contains the process + * it belongs to and the offset within that process. + * + * A singly linked list should be fine for most, if not all, workloads. + * On fork-after-exec the mapping we'll be removing will still be near + * the start of the list, on mixed application systems the short-lived + * processes will have their mappings near the start of the list and + * in systems with long-lived applications the relative overhead of + * exit() will be lower since the applications are long-lived. + */ +struct pte_chain { + struct pte_chain * next; + pte_t * ptep; +}; + +static struct pte_chain * pte_chain_freelist; +static inline struct pte_chain * pte_chain_alloc(void); +static inline void pte_chain_free(struct pte_chain *, struct pte_chain *, struct page *); +static void alloc_new_pte_chains(void); + +/** + * page_referenced - test if the page was referenced + * @page: the page to test + * + * Quick test_and_clear_referenced for all mappings to a page, + * returns the number of processes which referenced the page. + * Caller needs to hold the pagemap_lru_lock. + */ +int FASTCALL(page_referenced(struct page *)); +int page_referenced(struct page * page) +{ + struct pte_chain * pc; + int referenced = 0; + + if (PageTestandClearReferenced(page)) + referenced++; + + /* Check all the page tables mapping this page. */ + for (pc = page->pte_chain; pc; pc = pc->next) { + if (ptep_test_and_clear_young(pc->ptep)) + referenced++; + } + + return referenced; +} + +/** + * page_add_rmap - add reverse mapping entry to a page + * @page: the page to add the mapping to + * @ptep: the page table entry mapping this page + * + * Add a new pte reverse mapping to a page. + * The caller needs to hold the mm->page_table_lock. + */ +void FASTCALL(page_add_rmap(struct page *, pte_t *)); +void page_add_rmap(struct page * page, pte_t * ptep) +{ + struct pte_chain * pte_chain; + + if (!VALID_PAGE(page) || PageReserved(page)) + return; + + spin_lock(&pagemap_lru_lock); +#ifdef DEBUG_RMAP + if (!page || !ptep) + BUG(); + if (!pte_present(*ptep)) + BUG(); + if (!ptep_to_mm(ptep)); + BUG(); + { + struct pte_chain * pc; + for (pc = page->pte_chain; pc; pc = pc->next) { + if (pc->ptep == ptep) + BUG(); + } + } +#endif + pte_chain = pte_chain_alloc(); + + /* Hook up the pte_chain to the page. */ + pte_chain->ptep = ptep; + pte_chain->next = page->pte_chain; + page->pte_chain = pte_chain; + + spin_unlock(&pagemap_lru_lock); +} + +/** + * page_remove_rmap - take down reverse mapping to a page + * @page: page to remove mapping from + * @ptep: page table entry to remove + * + * Removes the reverse mapping from the pte_chain of the page, + * after that the caller can clear the page table entry and free + * the page. + * Caller needs to hold the mm->page_table_lock. + */ +void FASTCALL(page_remove_rmap(struct page *, pte_t *)); +void page_remove_rmap(struct page * page, pte_t * ptep) +{ + struct pte_chain * pc, * prev_pc = NULL; + + if (!page || !ptep) + BUG(); + if (!VALID_PAGE(page) || PageReserved(page)) + return; + + spin_lock(&pagemap_lru_lock); + for (pc = page->pte_chain; pc; prev_pc = pc, pc = pc->next) { + if (pc->ptep == ptep) { + pte_chain_free(pc, prev_pc, page); + goto out; + } + } +#ifdef DEBUG_RMAP + /* Not found. This should NEVER happen! */ + printk(KERN_ERR "page_remove_rmap: pte_chain %p not present.\n", ptep); + printk(KERN_ERR "page_remove_rmap: only found: "); + for (pc = page->pte_chain; pc; pc = pc->next) + printk("%p ", pc->ptep); + printk("\n"); + printk(KERN_ERR "page_remove_rmap: driver cleared PG_reserved ?\n"); +#endif + +out: + spin_unlock(&pagemap_lru_lock); + return; + +} + +/** + * try_to_unmap_one - worker function for try_to_unmap + * @page: page to unmap + * @ptep: page table entry to unmap from page + * + * Internal helper function for try_to_unmap, called for each page + * table entry mapping a page. Because locking order here is opposite + * to the locking order used by the page fault path, we use trylocks. + * Locking: + * pagemap_lru_lock page_launder() + * page lock page_launder(), trylock + * mm->page_table_lock try_to_unmap_one(), trylock + */ +int FASTCALL(try_to_unmap_one(struct page *, pte_t *)); +int try_to_unmap_one(struct page * page, pte_t * ptep) +{ + unsigned long address = ptep_to_address(ptep); + struct mm_struct * mm = ptep_to_mm(ptep); + struct vm_area_struct * vma; + pte_t pte; + int ret; + + if (!mm) + BUG(); + + /* + * We need the page_table_lock to protect us from page faults, + * munmap, fork, etc... + */ + if (!spin_trylock(&mm->page_table_lock)) + return SWAP_AGAIN; + + /* During mremap, it's possible pages are not in a VMA. */ + vma = find_vma(mm, address); + if (!vma) { + ret = SWAP_FAIL; + goto out_unlock; + } + + /* The page is mlock()d, we cannot swap it out. */ + if (vma->vm_flags & VM_LOCKED) { + ret = SWAP_FAIL; + goto out_unlock; + } + + /* Nuke the page table entry. */ + pte = ptep_get_and_clear(ptep); + flush_tlb_page(vma, address); + flush_cache_page(vma, address); + + /* Store the swap location in the pte. See handle_pte_fault() ... */ + if (PageSwapCache(page)) { + swp_entry_t entry; + entry.val = page->index; + swap_duplicate(entry); + set_pte(ptep, swp_entry_to_pte(entry)); + } + + /* Move the dirty bit to the physical page now the pte is gone. */ + if (pte_dirty(pte)) + set_page_dirty(page); + + mm->rss--; + page_cache_release(page); + ret = SWAP_SUCCESS; + +out_unlock: + spin_unlock(&mm->page_table_lock); + return ret; +} + +/** + * try_to_unmap - try to remove all page table mappings to a page + * @page: the page to get unmapped + * + * Tries to remove all the page table entries which are mapping this + * page, used in the pageout path. Caller must hold pagemap_lru_lock + * and the page lock. Return values are: + * + * SWAP_SUCCESS - we succeeded in removing all mappings + * SWAP_AGAIN - we missed a trylock, try again later + * SWAP_FAIL - the page is unswappable + * SWAP_ERROR - an error occurred + */ +int FASTCALL(try_to_unmap(struct page *)); +int try_to_unmap(struct page * page) +{ + struct pte_chain * pc, * next_pc, * prev_pc = NULL; + int ret = SWAP_SUCCESS; + + /* This page should not be on the pageout lists. */ + if (!VALID_PAGE(page) || PageReserved(page)) + BUG(); + if (!PageLocked(page)) + BUG(); + /* We need backing store to swap out a page. */ + if (!page->mapping) + BUG(); + + for (pc = page->pte_chain; pc; pc = next_pc) { + next_pc = pc->next; + switch (try_to_unmap_one(page, pc->ptep)) { + case SWAP_SUCCESS: + /* Free the pte_chain struct. */ + pte_chain_free(pc, prev_pc, page); + break; + case SWAP_AGAIN: + /* Skip this pte, remembering status. */ + prev_pc = pc; + ret = SWAP_AGAIN; + continue; + case SWAP_FAIL: + return SWAP_FAIL; + case SWAP_ERROR: + return SWAP_ERROR; + } + } + + return ret; +} + +/** + * page_over_rsslimit - test if the page is over its RSS limit + * @page - page to test + * + * This function returns true if the process owning this page + * is over its RSS (resident set size) limit. For shared pages + * we make the optimisation of only checking the first process + * in the pte_chain list, this should catch hogs while not + * evicting pages shared by many processes. + * The caller needs to hold the pagemap_lru_lock. + */ +int FASTCALL(page_over_rsslimit(struct page *)); +int page_over_rsslimit(struct page * page) +{ + struct pte_chain * pte_chain = page->pte_chain; + struct mm_struct * mm; + pte_t * ptep; + + /* No process is using the page. */ + if (!pte_chain) + return 0; + + ptep = pte_chain->ptep; + mm = ptep_to_mm(ptep); + + return mm->rlimit_rss && (mm->rss > mm->rlimit_rss); +} + +/** + * pte_chain_free - free pte_chain structure + * @pte_chain: pte_chain struct to free + * @prev_pte_chain: previous pte_chain on the list (may be NULL) + * @page: page this pte_chain hangs off (may be NULL) + * + * This function unlinks pte_chain from the singly linked list it + * may be on and adds the pte_chain to the free list. May also be + * called for new pte_chain structures which aren't on any list yet. + * Caller needs to hold the pagemap_lru_list. + */ +static inline void pte_chain_free(struct pte_chain * pte_chain, struct pte_chain * prev_pte_chain, struct page * page) +{ + if (prev_pte_chain) + prev_pte_chain->next = pte_chain->next; + else if (page) + page->pte_chain = pte_chain->next; + + pte_chain->ptep = NULL; + pte_chain->next = pte_chain_freelist; + pte_chain_freelist = pte_chain; +} + +/** + * pte_chain_alloc - allocate a pte_chain struct + * + * Returns a pointer to a fresh pte_chain structure. Allocates new + * pte_chain structures as required. + * Caller needs to hold the pagemap_lru_lock. + */ +static inline struct pte_chain * pte_chain_alloc(void) +{ + struct pte_chain * pte_chain; + + /* Allocate new pte_chain structs as needed. */ + if (!pte_chain_freelist) + alloc_new_pte_chains(); + + /* Grab the first pte_chain from the freelist. */ + pte_chain = pte_chain_freelist; + pte_chain_freelist = pte_chain->next; + pte_chain->next = NULL; + + return pte_chain; +} + +/** + * alloc_new_pte_chains - convert a free page to pte_chain structures + * + * Grabs a free page and converts it to pte_chain structures. We really + * should pre-allocate these earlier in the pagefault path or come up + * with some other trick. + * + * Note that we cannot use the slab cache because the pte_chain structure + * is way smaller than the minimum size of a slab cache allocation. + */ +static void alloc_new_pte_chains(void) +{ + struct pte_chain * pte_chain = (void *) get_zeroed_page(GFP_ATOMIC); + int i = PAGE_SIZE / sizeof(struct pte_chain); + + if (pte_chain) { + for (; i-- > 0; pte_chain++) + pte_chain_free(pte_chain, NULL, NULL); + } else { + /* Yeah yeah, I'll fix the pte_chain allocation ... */ + panic("Fix pte_chain allocation, you lazy bastard!\n"); + } +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/shmem.c linux.19pre5-ac1/mm/shmem.c --- linux.19p5/mm/shmem.c Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/mm/shmem.c Thu Apr 4 16:14:15 2002 @@ -5,8 +5,25 @@ * 2000 Transmeta Corp. * 2000-2001 Christoph Rohland * 2000-2001 SAP AG + * 2002 Red Hat Inc. + * TODO: + * Accounting needs verification + * We need to verify all the security fixes from generic_file_write are + * now there * - * This file is released under the GPL. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 */ /* @@ -21,6 +38,8 @@ #include #include #include +#include +#include #include #include #include @@ -330,10 +349,39 @@ up(&info->sem); } +static int shmem_notify_change(struct dentry * dentry, struct iattr *attr) +{ + struct inode *inode = dentry->d_inode; + int error; + + if(attr->ia_valid & ATTR_SIZE) + { + + /* + * Account swap file usage based on new file size + */ + long change = (attr->ia_size>>PAGE_SHIFT) - (inode->i_size>>PAGE_SHIFT); + + if(attr->ia_size > inode->i_size) + { + if(!vm_enough_memory(change,1)) + return -ENOMEM; + } + else + vm_unacct_memory(-change); + } + error = inode_change_ok(inode, attr); + if (!error) { + error = inode_setattr(inode, attr); + } + return error; +} + static void shmem_delete_inode(struct inode * inode) { struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb); + vm_unacct_memory((inode->i_size)>> PAGE_SHIFT); inode->i_size = 0; if (inode->i_op->truncate == shmem_truncate){ spin_lock (&shmem_ilock); @@ -740,6 +788,13 @@ static struct inode_operations shmem_symlink_inode_operations; static struct inode_operations shmem_symlink_inline_operations; +/* + * This is a copy of generic_file_write slightly modified. It would + * help no end if it were kept remotely up to date with the + * generic_file_write changes. I don't alas see a good way to merge + * it back and use the generic one -- Alan + */ + static ssize_t shmem_file_write(struct file *file,const char *buf,size_t count,loff_t *ppos) { @@ -751,6 +806,7 @@ unsigned long written; long status; int err; + loff_t maxpos; if ((ssize_t) count < 0) return -EINVAL; @@ -763,43 +819,111 @@ pos = *ppos; err = -EINVAL; if (pos < 0) - goto out; + goto out_nc; err = file->f_error; if (err) { file->f_error = 0; - goto out; + goto out_nc; } written = 0; if (file->f_flags & O_APPEND) pos = inode->i_size; + + maxpos = inode->i_size; + if(pos + count > inode->i_size) + { + maxpos = pos + count; + if(!vm_enough_memory((maxpos-inode->i_size)>>PAGE_SHIFT, 1)) + { + err = -ENOMEM; + goto out_nc; + } + } /* * Check whether we've reached the file size limit. */ err = -EFBIG; + if (limit != RLIM_INFINITY) { if (pos >= limit) { send_sig(SIGXFSZ, current, 0); goto out; } - if (count > limit - pos) { + if (pos > 0xFFFFFFFFULL || count > limit - (u32)pos) { + /* send_sig(SIGXFSZ, current, 0); */ + count = limit - (u32)pos; + } + } + + /* + * LFS rule + */ + if ( pos + count > MAX_NON_LFS && !(file->f_flags&O_LARGEFILE)) { + if (pos >= MAX_NON_LFS) { send_sig(SIGXFSZ, current, 0); - count = limit - pos; + goto out; + } + if (count > MAX_NON_LFS - (u32)pos) { + /* send_sig(SIGXFSZ, current, 0); */ + count = MAX_NON_LFS - (u32)pos; } } - status = 0; - if (count) { - remove_suid(inode); - inode->i_ctime = inode->i_mtime = CURRENT_TIME; + /* + * Are we about to exceed the fs block limit ? + * + * If we have written data it becomes a short write + * If we have exceeded without writing data we send + * a signal and give them an EFBIG. + * + * Linus frestrict idea will clean these up nicely.. + */ + + if (!S_ISBLK(inode->i_mode)) { + if (pos >= inode->i_sb->s_maxbytes) + { + if (count || pos > inode->i_sb->s_maxbytes) { + send_sig(SIGXFSZ, current, 0); + err = -EFBIG; + goto out; + } + /* zero-length writes at ->s_maxbytes are OK */ + } + + if (pos + count > inode->i_sb->s_maxbytes) + count = inode->i_sb->s_maxbytes - pos; + } else { + if (is_read_only(inode->i_rdev)) { + err = -EPERM; + goto out; + } + if (pos >= inode->i_size) { + if (count || pos > inode->i_size) { + err = -ENOSPC; + goto out; + } + } + + if (pos + count > inode->i_size) + count = inode->i_size - pos; } + err = 0; + if (count == 0) + goto out; + status = 0; + + remove_suid(inode); + inode->i_ctime = inode->i_mtime = CURRENT_TIME; + while (count) { unsigned long bytes, index, offset; char *kaddr; + int deactivate = 1; /* * Try to find the page in the cache. If it isn't there, @@ -810,6 +934,7 @@ bytes = PAGE_CACHE_SIZE - offset; if (bytes > count) { bytes = count; + deactivate = 0; } /* @@ -838,7 +963,7 @@ } kaddr = kmap(page); - status = copy_from_user(kaddr+offset, buf, bytes); + status = __copy_from_user(kaddr+offset, buf, bytes); kunmap(page); if (status) goto fail_write; @@ -856,6 +981,10 @@ unlock: /* Mark it unlocked again and drop the page.. */ UnlockPage(page); + if (deactivate) + deactivate_page(page); + else + touch_page(page); page_cache_release(page); if (status < 0) @@ -865,6 +994,10 @@ err = written ? written : status; out: + /* Short writes give back address space */ + if(inode->i_size != maxpos) + vm_unacct_memory((maxpos-inode->i_size)>>PAGE_SHIFT); +out_nc: up(&inode->i_sem); return err; fail_write: @@ -1350,6 +1483,7 @@ static struct inode_operations shmem_inode_operations = { truncate: shmem_truncate, + setattr: shmem_notify_change, }; static struct file_operations shmem_dir_operations = { @@ -1448,17 +1582,16 @@ */ struct file *shmem_file_setup(char * name, loff_t size) { - int error; + int error = -ENOMEM; struct file *file; struct inode * inode; struct dentry *dentry, *root; struct qstr this; - int vm_enough_memory(long pages); if (size > (unsigned long long) SHMEM_MAX_BLOCKS << PAGE_CACHE_SHIFT) return ERR_PTR(-EINVAL); - if (!vm_enough_memory((size) >> PAGE_CACHE_SHIFT)) + if (!vm_enough_memory((size) >> PAGE_CACHE_SHIFT, 1)) return ERR_PTR(-ENOMEM); this.name = name; @@ -1467,7 +1600,7 @@ root = shm_mnt->mnt_root; dentry = d_alloc(root, &this); if (!dentry) - return ERR_PTR(-ENOMEM); + goto put_memory; error = -ENFILE; file = get_empty_filp(); @@ -1493,6 +1626,8 @@ put_filp(file); put_dentry: dput (dentry); +put_memory: + vm_unacct_memory((size) >> PAGE_CACHE_SHIFT); return ERR_PTR(error); } /* diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/slab.c linux.19pre5-ac1/mm/slab.c --- linux.19p5/mm/slab.c Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/mm/slab.c Fri Mar 15 22:20:00 2002 @@ -72,6 +72,7 @@ #include #include #include +#include #include /* @@ -910,34 +911,45 @@ #define drain_cpu_caches(cachep) do { } while (0) #endif -static int __kmem_cache_shrink(kmem_cache_t *cachep) +/** + * Called with the &cachep->spinlock held, returns number of slabs released + */ +static int __kmem_cache_shrink_locked(kmem_cache_t *cachep) { - slab_t *slabp; - int ret; - - drain_cpu_caches(cachep); - - spin_lock_irq(&cachep->spinlock); + slab_t *slabp; + int ret = 0; - /* If the cache is growing, stop shrinking. */ - while (!cachep->growing) { - struct list_head *p; + /* If the cache is growing, stop shrinking. */ + while (!cachep->growing) { + struct list_head *p; - p = cachep->slabs_free.prev; - if (p == &cachep->slabs_free) - break; + p = cachep->slabs_free.prev; + if (p == &cachep->slabs_free) + break; - slabp = list_entry(cachep->slabs_free.prev, slab_t, list); + slabp = list_entry(cachep->slabs_free.prev, slab_t, list); #if DEBUG - if (slabp->inuse) - BUG(); + if (slabp->inuse) + BUG(); #endif - list_del(&slabp->list); + list_del(&slabp->list); - spin_unlock_irq(&cachep->spinlock); - kmem_slab_destroy(cachep, slabp); - spin_lock_irq(&cachep->spinlock); - } + spin_unlock_irq(&cachep->spinlock); + kmem_slab_destroy(cachep, slabp); + ret++; + spin_lock_irq(&cachep->spinlock); + } + return ret; +} + +static int __kmem_cache_shrink(kmem_cache_t *cachep) +{ + int ret; + + drain_cpu_caches(cachep); + + spin_lock_irq(&cachep->spinlock); + __kmem_cache_shrink_locked(cachep); ret = !list_empty(&cachep->slabs_full) || !list_empty(&cachep->slabs_partial); spin_unlock_irq(&cachep->spinlock); return ret; @@ -959,6 +971,24 @@ } /** + * kmem_cache_shrink_nr - Shrink a cache returning pages released + */ +int kmem_cache_shrink_nr(kmem_cache_t *cachep) +{ + int ret; + + if (!cachep || in_interrupt() || !is_chained_kmem_cache(cachep)) + BUG(); + + drain_cpu_caches(cachep); + + spin_lock_irq(&cachep->spinlock); + ret = __kmem_cache_shrink_locked(cachep); + spin_unlock_irq(&cachep->spinlock); + return ret<<(cachep->gfporder); +} + +/** * kmem_cache_destroy - delete a cache * @cachep: the cache to destroy * diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/swap.c linux.19pre5-ac1/mm/swap.c --- linux.19p5/mm/swap.c Thu Apr 4 13:18:17 2002 +++ linux.19pre5-ac1/mm/swap.c Wed Feb 13 01:06:43 2002 @@ -15,15 +15,29 @@ #include #include -#include #include #include #include +#include #include #include /* for copy_to/from_user */ #include +/* + * We identify three levels of free memory. We never let free mem + * fall below the freepages.min except for atomic allocations. We + * start background swapping if we fall below freepages.high free + * pages, and we begin intensive swapping below freepages.low. + * + * Actual initialization is done in mm/page_alloc.c + */ +freepages_t freepages = { + 0, /* freepages.min */ + 0, /* freepages.low */ + 0 /* freepages.high */ +}; + /* How many pages do we try to swap or page in/out together? */ int page_cluster; @@ -33,17 +47,102 @@ 8, /* do swap I/O in clusters of this size */ }; +/** + * (de)activate_page - move pages from/to active and inactive lists + * @page: the page we want to move + * @nolock - are we already holding the pagemap_lru_lock? + * + * Deactivate_page will move an active page to the right + * inactive list, while activate_page will move a page back + * from one of the inactive lists to the active list. If + * called on a page which is not on any of the lists, the + * page is left alone. + */ +void FASTCALL(deactivate_page_nolock(struct page *)); +void deactivate_page_nolock(struct page * page) +{ + /* + * Don't touch it if it's not on the active list. + * (some pages aren't on any list at all) + */ + ClearPageReferenced(page); + page->age = 0; + if (PageActive(page)) { + del_page_from_active_list(page); + add_page_to_inactive_dirty_list(page); + } +} + +void FASTCALL(deactivate_page(struct page *)); +void deactivate_page(struct page * page) +{ + spin_lock(&pagemap_lru_lock); + deactivate_page_nolock(page); + spin_unlock(&pagemap_lru_lock); +} + +/** + * drop_page - like deactivate_page, but try inactive_clean list + * @page: the page to drop + * + * Try to move a page to the inactive_clean list, this succeeds if the + * page is clean and not in use by anybody. If the page cannot be placed + * on the inactive_clean list it is placed on the inactive_dirty list + * instead. + * + * Note: this function gets called with the pagemap_lru_lock held. + */ +void FASTCALL(drop_page(struct page *)); +void drop_page(struct page * page) +{ + if (!TryLockPage(page)) { + if (page->mapping && page->buffers) { + page_cache_get(page); + spin_unlock(&pagemap_lru_lock); + try_to_release_page(page, GFP_NOIO); + spin_lock(&pagemap_lru_lock); + page_cache_release(page); + } + UnlockPage(page); + } + + /* Make sure the page really is reclaimable. */ + if (!page->mapping || PageDirty(page) || page->pte_chain || + page->buffers || page_count(page) > 1) + deactivate_page_nolock(page); + + else if (page_count(page) == 1) { + ClearPageReferenced(page); + page->age = 0; + if (PageActive(page)) { + del_page_from_active_list(page); + add_page_to_inactive_clean_list(page); + } else if (PageInactiveDirty(page)) { + del_page_from_inactive_dirty_list(page); + add_page_to_inactive_clean_list(page); + } + } +} + /* * Move an inactive page to the active list. */ -static inline void activate_page_nolock(struct page * page) +void FASTCALL(activate_page_nolock(struct page *)); +void activate_page_nolock(struct page * page) { - if (PageLRU(page) && !PageActive(page)) { - del_page_from_inactive_list(page); + if (PageInactiveDirty(page)) { + del_page_from_inactive_dirty_list(page); + add_page_to_active_list(page); + } else if (PageInactiveClean(page)) { + del_page_from_inactive_clean_list(page); add_page_to_active_list(page); } + + /* Make sure the page gets a fair chance at staying active. */ + page->age = max((int)page->age, PAGE_AGE_START); } +void FASTCALL(activate_page(struct page *)); void activate_page(struct page * page) { spin_lock(&pagemap_lru_lock); @@ -55,11 +154,12 @@ * lru_cache_add: add a page to the page lists * @page: the page to add */ +void FASTCALL(lru_cache_add(struct page *)); void lru_cache_add(struct page * page) { - if (!TestSetPageLRU(page)) { + if (!PageLRU(page)) { spin_lock(&pagemap_lru_lock); - add_page_to_inactive_list(page); + add_page_to_active_list(page); spin_unlock(&pagemap_lru_lock); } } @@ -71,14 +171,15 @@ * This function is for when the caller already holds * the pagemap_lru_lock. */ +void FASTCALL(__lru_cache_del(struct page *)); void __lru_cache_del(struct page * page) { - if (TestClearPageLRU(page)) { - if (PageActive(page)) { - del_page_from_active_list(page); - } else { - del_page_from_inactive_list(page); - } + if (PageActive(page)) { + del_page_from_active_list(page); + } else if (PageInactiveDirty(page)) { + del_page_from_inactive_dirty_list(page); + } else if (PageInactiveClean(page)) { + del_page_from_inactive_clean_list(page); } } @@ -86,6 +187,7 @@ * lru_cache_del: remove a page from the page lists * @page: the page to remove */ +void FASTCALL(lru_cache_del(struct page *)); void lru_cache_del(struct page * page) { spin_lock(&pagemap_lru_lock); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/swap_state.c linux.19pre5-ac1/mm/swap_state.c --- linux.19p5/mm/swap_state.c Thu Apr 4 13:18:17 2002 +++ linux.19pre5-ac1/mm/swap_state.c Mon Jan 28 19:33:28 2002 @@ -89,6 +89,40 @@ return 0; } +/** + * add_to_swap - allocate swap space for a page + * @page: page we want to move to swap + * + * Allocate swap space for the page and add the page to the + * swap cache. Caller needs to hold the page lock. + */ +int add_to_swap(struct page * page) +{ + swp_entry_t entry; + + if (!PageLocked(page)) + BUG(); + + for (;;) { + entry = get_swap_page(); + if (!entry.val) + return 0; + /* + * Add it to the swap cache and mark it dirty + * (adding to the page cache will clear the dirty + * and uptodate bits, so we need to do it again) + */ + if (add_to_swap_cache(page, entry) == 0) { + SetPageUptodate(page); + set_page_dirty(page); + swap_free(entry); + return 1; + } + /* Raced with "speculative" read_swap_cache_async */ + swap_free(entry); + } +} + /* * This must be called only on pages that have * been verified to be in the swap cache. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/swapfile.c linux.19pre5-ac1/mm/swapfile.c --- linux.19p5/mm/swapfile.c Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/mm/swapfile.c Mon Jan 28 19:33:28 2002 @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -373,6 +374,7 @@ return; get_page(page); set_pte(dir, pte_mkold(mk_pte(page, vma->vm_page_prot))); + page_add_rmap(page, dir); swap_free(entry); ++vma->vm_mm->rss; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/vmscan.c linux.19pre5-ac1/mm/vmscan.c --- linux.19p5/mm/vmscan.c Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/mm/vmscan.c Wed Mar 20 15:58:46 2002 @@ -1,6 +1,9 @@ /* * linux/mm/vmscan.c * + * The pageout daemon, decides which pages to evict (swap out) and + * does the actual work of freeing them. + * * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds * * Swap reorganised 29.12.95, Stephen Tweedie. @@ -20,9 +23,13 @@ #include #include #include +#include +#include #include +static void refill_freelist(void); +static void wakeup_memwaiters(void); /* * The "priority" of VM scanning is how much of the queues we * will scan in one go. A value of 6 for DEF_PRIORITY implies @@ -31,371 +38,275 @@ */ #define DEF_PRIORITY (6) -/* - * The swap-out function returns 1 if it successfully - * scanned all the pages it was asked to (`count'). - * It returns zero if it couldn't do anything, - * - * rss may decrease because pages are shared, but this - * doesn't count as having freed a page. - */ - -/* mm->page_table_lock is held. mmap_sem is not held */ -static inline int try_to_swap_out(struct mm_struct * mm, struct vm_area_struct* vma, unsigned long address, pte_t * page_table, struct page *page, zone_t * classzone) +static inline void age_page_up(struct page *page) { - pte_t pte; - swp_entry_t entry; + page->age = min((int) (page->age + PAGE_AGE_ADV), PAGE_AGE_MAX); +} - /* Don't look at this pte if it's been accessed recently. */ - if ((vma->vm_flags & VM_LOCKED) || ptep_test_and_clear_young(page_table)) { - mark_page_accessed(page); - return 0; - } +static inline void age_page_down(struct page *page) +{ + page->age -= min(PAGE_AGE_DECL, (int)page->age); +} - /* Don't bother unmapping pages that are active */ - if (PageActive(page)) - return 0; +static inline int page_mapping_inuse(struct page * page) +{ + struct address_space * mapping = page->mapping; - /* Don't bother replenishing zones not under pressure.. */ - if (!memclass(page_zone(page), classzone)) - return 0; + /* Page is in somebody's page tables. */ + if (page->pte_chain) + return 1; - if (TryLockPage(page)) + /* XXX: does this happen ? */ + if (!mapping) return 0; - /* From this point on, the odds are that we're going to - * nuke this pte, so read and clear the pte. This hook - * is needed on CPUs which update the accessed and dirty - * bits in hardware. - */ - flush_cache_page(vma, address); - pte = ptep_get_and_clear(page_table); - flush_tlb_page(vma, address); + /* File is mmaped by somebody. */ + if (mapping->i_mmap || mapping->i_mmap_shared) + return 1; - if (pte_dirty(pte)) - set_page_dirty(page); - - /* - * Is the page already in the swap cache? If so, then - * we can just drop our reference to it without doing - * any IO - it's already up-to-date on disk. - */ - if (PageSwapCache(page)) { - entry.val = page->index; - swap_duplicate(entry); -set_swap_pte: - set_pte(page_table, swp_entry_to_pte(entry)); -drop_pte: - mm->rss--; - UnlockPage(page); - { - int freeable = page_count(page) - !!page->buffers <= 2; - page_cache_release(page); - return freeable; - } - } + return 0; +} - /* - * Is it a clean page? Then it must be recoverable - * by just paging it in again, and we can just drop - * it.. or if it's dirty but has backing store, - * just mark the page dirty and drop it. - * - * However, this won't actually free any real - * memory, as the page will just be in the page cache - * somewhere, and as such we should just continue - * our scan. - * - * Basically, this just makes it possible for us to do - * some real work in the future in "refill_inactive()". - */ - if (page->mapping) - goto drop_pte; - if (!PageDirty(page)) - goto drop_pte; +/** + * reclaim_page - reclaims one page from the inactive_clean list + * @zone: reclaim a page from this zone + * + * The pages on the inactive_clean can be instantly reclaimed. + * The tests look impressive, but most of the time we'll grab + * the first page of the list and exit successfully. + */ +struct page * reclaim_page(zone_t * zone) +{ + struct page * page = NULL; + struct list_head * page_lru; + swp_entry_t entry = {0}; + int maxscan; /* - * Anonymous buffercache pages can be left behind by - * concurrent truncate and pagefault. + * We need to hold the pagecache_lock around all tests to make sure + * reclaim_page() cannot race with find_get_page() and friends. */ - if (page->buffers) - goto preserve; + spin_lock(&pagemap_lru_lock); + spin_lock(&pagecache_lock); + maxscan = zone->inactive_clean_pages; + while (maxscan-- && !list_empty(&zone->inactive_clean_list)) { + page_lru = zone->inactive_clean_list.prev; + page = list_entry(page_lru, struct page, lru); - /* - * This is a dirty, swappable page. First of all, - * get a suitable swap entry for it, and make sure - * we have the swap cache set up to associate the - * page with that swap entry. - */ - for (;;) { - entry = get_swap_page(); - if (!entry.val) - break; - /* Add it to the swap cache and mark it dirty - * (adding to the page cache will clear the dirty - * and uptodate bits, so we need to do it again) - */ - if (add_to_swap_cache(page, entry) == 0) { - SetPageUptodate(page); - set_page_dirty(page); - goto set_swap_pte; + /* Wrong page on list?! (list corruption, should not happen) */ + if (unlikely(!PageInactiveClean(page))) { + printk("VM: reclaim_page, wrong page on list.\n"); + list_del(page_lru); + page_zone(page)->inactive_clean_pages--; + continue; } - /* Raced with "speculative" read_swap_cache_async */ - swap_free(entry); - } - /* No swap space left */ -preserve: - set_pte(page_table, pte); - UnlockPage(page); - return 0; -} - -/* mm->page_table_lock is held. mmap_sem is not held */ -static inline int swap_out_pmd(struct mm_struct * mm, struct vm_area_struct * vma, pmd_t *dir, unsigned long address, unsigned long end, int count, zone_t * classzone) -{ - pte_t * pte; - unsigned long pmd_end; - - if (pmd_none(*dir)) - return count; - if (pmd_bad(*dir)) { - pmd_ERROR(*dir); - pmd_clear(dir); - return count; - } - - pte = pte_offset(dir, address); - - pmd_end = (address + PMD_SIZE) & PMD_MASK; - if (end > pmd_end) - end = pmd_end; + /* Page is being freed */ + if (unlikely(page_count(page)) == 0) { + list_del(page_lru); + list_add(page_lru, &zone->inactive_clean_list); + continue; + } - do { - if (pte_present(*pte)) { - struct page *page = pte_page(*pte); + /* Page cannot be reclaimed ? Move to inactive_dirty list. */ + if (unlikely(page->pte_chain || page->buffers || + PageReferenced(page) || PageDirty(page) || + page_count(page) > 1 || TryLockPage(page))) { + del_page_from_inactive_clean_list(page); + add_page_to_inactive_dirty_list(page); + continue; + } - if (VALID_PAGE(page) && !PageReserved(page)) { - count -= try_to_swap_out(mm, vma, address, pte, page, classzone); - if (!count) { - address += PAGE_SIZE; - break; - } - } + /* OK, remove the page from the caches. */ + if (PageSwapCache(page)) { + entry.val = page->index; + __delete_from_swap_cache(page); + goto found_page; } - address += PAGE_SIZE; - pte++; - } while (address && (address < end)); - mm->swap_address = address; - return count; -} -/* mm->page_table_lock is held. mmap_sem is not held */ -static inline int swap_out_pgd(struct mm_struct * mm, struct vm_area_struct * vma, pgd_t *dir, unsigned long address, unsigned long end, int count, zone_t * classzone) -{ - pmd_t * pmd; - unsigned long pgd_end; + if (page->mapping) { + __remove_inode_page(page); + goto found_page; + } - if (pgd_none(*dir)) - return count; - if (pgd_bad(*dir)) { - pgd_ERROR(*dir); - pgd_clear(dir); - return count; + /* We should never ever get here. */ + printk(KERN_ERR "VM: reclaim_page, found unknown page\n"); + list_del(page_lru); + zone->inactive_clean_pages--; + UnlockPage(page); } + spin_unlock(&pagecache_lock); + spin_unlock(&pagemap_lru_lock); + return NULL; - pmd = pmd_offset(dir, address); - - pgd_end = (address + PGDIR_SIZE) & PGDIR_MASK; - if (pgd_end && (end > pgd_end)) - end = pgd_end; - - do { - count = swap_out_pmd(mm, vma, pmd, address, end, count, classzone); - if (!count) - break; - address = (address + PMD_SIZE) & PMD_MASK; - pmd++; - } while (address && (address < end)); - return count; -} - -/* mm->page_table_lock is held. mmap_sem is not held */ -static inline int swap_out_vma(struct mm_struct * mm, struct vm_area_struct * vma, unsigned long address, int count, zone_t * classzone) -{ - pgd_t *pgdir; - unsigned long end; - - /* Don't swap out areas which are reserved */ - if (vma->vm_flags & VM_RESERVED) - return count; - - pgdir = pgd_offset(mm, address); - - end = vma->vm_end; - if (address >= end) - BUG(); - do { - count = swap_out_pgd(mm, vma, pgdir, address, end, count, classzone); - if (!count) - break; - address = (address + PGDIR_SIZE) & PGDIR_MASK; - pgdir++; - } while (address && (address < end)); - return count; +found_page: + del_page_from_inactive_clean_list(page); + spin_unlock(&pagecache_lock); + spin_unlock(&pagemap_lru_lock); + if (entry.val) + swap_free(entry); + UnlockPage(page); + page->age = PAGE_AGE_START; + if (page_count(page) != 1) + printk("VM: reclaim_page, found page with count %d!\n", + page_count(page)); + return page; } -/* Placeholder for swap_out(): may be updated by fork.c:mmput() */ -struct mm_struct *swap_mm = &init_mm; - -/* - * Returns remaining count of pages to be swapped out by followup call. +/** + * page_dirty - do we need to write the data out to disk + * @page: page to test + * + * Returns true if the page contains data which needs to + * be written to disk. Doesn't test the page tables (yet?). */ -static inline int swap_out_mm(struct mm_struct * mm, int count, int * mmcounter, zone_t * classzone) +static inline int page_dirty(struct page *page) { - unsigned long address; - struct vm_area_struct* vma; + struct buffer_head *tmp, *bh; - /* - * Find the proper vm-area after freezing the vma chain - * and ptes. - */ - spin_lock(&mm->page_table_lock); - address = mm->swap_address; - if (address == TASK_SIZE || swap_mm != mm) { - /* We raced: don't count this mm but try again */ - ++*mmcounter; - goto out_unlock; - } - vma = find_vma(mm, address); - if (vma) { - if (address < vma->vm_start) - address = vma->vm_start; - - for (;;) { - count = swap_out_vma(mm, vma, address, count, classzone); - vma = vma->vm_next; - if (!vma) - break; - if (!count) - goto out_unlock; - address = vma->vm_start; - } - } - /* Indicate that we reached the end of address space */ - mm->swap_address = TASK_SIZE; + if (PageDirty(page)) + return 1; -out_unlock: - spin_unlock(&mm->page_table_lock); - return count; -} + if (page->mapping && !page->buffers) + return 0; -static int FASTCALL(swap_out(unsigned int priority, unsigned int gfp_mask, zone_t * classzone)); -static int swap_out(unsigned int priority, unsigned int gfp_mask, zone_t * classzone) -{ - int counter, nr_pages = SWAP_CLUSTER_MAX; - struct mm_struct *mm; + tmp = bh = page->buffers; - counter = mmlist_nr; do { - if (unlikely(current->need_resched)) { - __set_current_state(TASK_RUNNING); - schedule(); - } - - spin_lock(&mmlist_lock); - mm = swap_mm; - while (mm->swap_address == TASK_SIZE || mm == &init_mm) { - mm->swap_address = 0; - mm = list_entry(mm->mmlist.next, struct mm_struct, mmlist); - if (mm == swap_mm) - goto empty; - swap_mm = mm; - } - - /* Make sure the mm doesn't disappear when we drop the lock.. */ - atomic_inc(&mm->mm_users); - spin_unlock(&mmlist_lock); - - nr_pages = swap_out_mm(mm, nr_pages, &counter, classzone); - - mmput(mm); - - if (!nr_pages) + if (tmp->b_state & ((1<= 0); + tmp = tmp->b_this_page; + } while (tmp != bh); return 0; - -empty: - spin_unlock(&mmlist_lock); - return 0; } -static int FASTCALL(shrink_cache(int nr_pages, zone_t * classzone, unsigned int gfp_mask, int priority)); -static int shrink_cache(int nr_pages, zone_t * classzone, unsigned int gfp_mask, int priority) +/** + * page_launder_zone - clean dirty inactive pages, move to inactive_clean list + * @zone: zone to free pages in + * @gfp_mask: what operations we are allowed to do + * + * This function is called when we are low on free / inactive_clean + * pages, its purpose is to refill the free/clean list as efficiently + * as possible. + * + * This means we do writes asynchronously as long as possible and will + * only sleep on IO when we don't have another option. Since writeouts + * cause disk seeks and make read IO slower, we skip writes alltogether + * when the amount of dirty pages is small. + * + * This code is heavily inspired by the FreeBSD source code. Thanks + * go out to Matthew Dillon. + */ +#define CAN_DO_FS ((gfp_mask & __GFP_FS) && should_write) +int page_launder_zone(zone_t * zone, int gfp_mask, int priority) { + int maxscan, cleaned_pages, target; struct list_head * entry; - int max_scan = nr_inactive_pages / priority; - int max_mapped = min((nr_pages << (10 - priority)), max_scan / 10); + target = free_plenty(zone); + cleaned_pages = 0; + + /* The main launder loop. */ spin_lock(&pagemap_lru_lock); - while (--max_scan >= 0 && (entry = inactive_list.prev) != &inactive_list) { + maxscan = zone->inactive_dirty_pages >> priority; + while (maxscan-- && !list_empty(&zone->inactive_dirty_list)) { struct page * page; - - if (unlikely(current->need_resched)) { + + /* Low latency reschedule point */ + if (current->need_resched) { spin_unlock(&pagemap_lru_lock); - __set_current_state(TASK_RUNNING); schedule(); spin_lock(&pagemap_lru_lock); continue; } + entry = zone->inactive_dirty_list.prev; page = list_entry(entry, struct page, lru); - if (unlikely(!PageLRU(page))) - BUG(); - if (unlikely(PageActive(page))) - BUG(); + if (cleaned_pages > target) + break; list_del(entry); - list_add(entry, &inactive_list); + list_add(entry, &zone->inactive_dirty_list); + + /* Wrong page on list?! (list corruption, should not happen) */ + if (!PageInactiveDirty(page)) { + printk("VM: page_launder, wrong page on list.\n"); + list_del(entry); + nr_inactive_dirty_pages--; + page_zone(page)->inactive_dirty_pages--; + continue; + } /* - * Zero page counts can happen because we unlink the pages - * _after_ decrementing the usage count.. + * The page is in active use or really unfreeable. Move to + * the active list and adjust the page age if needed. */ - if (unlikely(!page_count(page))) + if (page_referenced(page) && page_mapping_inuse(page) && + !page_over_rsslimit(page)) { + del_page_from_inactive_dirty_list(page); + add_page_to_active_list(page); + page->age = max((int)page->age, PAGE_AGE_START); continue; + } - if (!memclass(page_zone(page), classzone)) + /* + * Page is being freed, don't worry about it. + */ + if (unlikely(page_count(page)) == 0) continue; - /* Racy check to avoid trylocking when not worthwhile */ - if (!page->buffers && (page_count(page) != 1 || !page->mapping)) - goto page_mapped; - /* * The page is locked. IO in progress? * Move it to the back of the list. */ - if (unlikely(TryLockPage(page))) { - if (PageLaunder(page) && (gfp_mask & __GFP_FS)) { - page_cache_get(page); - spin_unlock(&pagemap_lru_lock); - wait_on_page(page); + if (unlikely(TryLockPage(page))) + continue; + + /* + * Anonymous process memory without backing store. Try to + * allocate it some swap space here. + * + * XXX: implement swap clustering ? + */ + if (page->pte_chain && !page->mapping && !page->buffers) { + page_cache_get(page); + spin_unlock(&pagemap_lru_lock); + if (!add_to_swap(page)) { + activate_page(page); + UnlockPage(page); page_cache_release(page); spin_lock(&pagemap_lru_lock); + continue; + } + page_cache_release(page); + spin_lock(&pagemap_lru_lock); + } + + /* + * The page is mapped into the page tables of one or more + * processes. Try to unmap it here. + */ + if (page->pte_chain) { + switch (try_to_unmap(page)) { + case SWAP_ERROR: + case SWAP_FAIL: + goto page_active; + case SWAP_AGAIN: + UnlockPage(page); + continue; + case SWAP_SUCCESS: + ; /* try to free the page below */ } - continue; } - if (PageDirty(page) && is_page_cache_freeable(page) && page->mapping) { + if (PageDirty(page) && page->mapping) { /* * It is not critical here to write it only if * the page is unmapped beause any direct writer * like O_DIRECT would set the PG_dirty bitflag - * on the phisical page after having successfully + * on the physical page after having successfully * pinned it and after the I/O to the page is finished, * so the direct writes to the page cannot get lost. */ @@ -424,7 +335,7 @@ if (page->buffers) { spin_unlock(&pagemap_lru_lock); - /* avoid to free a locked page */ + /* To avoid freeing our page before we're done. */ page_cache_get(page); if (try_to_release_page(page, gfp_mask)) { @@ -442,14 +353,14 @@ /* effectively free the page here */ page_cache_release(page); - if (--nr_pages) - continue; - break; + cleaned_pages++; + continue; } else { /* - * The page is still in pagecache so undo the stuff - * before the try_to_release_page since we've not - * finished and we can now try the next step. + * We freed the buffers but may have + * slept; undo the stuff we did before + * try_to_release_page and fall through + * to the next step. */ page_cache_release(page); @@ -465,232 +376,272 @@ } } - spin_lock(&pagecache_lock); /* - * this is the non-racy check for busy page. + * If the page is really freeable now, move it to the + * inactive_clean list. + * + * We re-test everything since the page could have been + * used by somebody else while we waited on IO above. + * This test is not safe from races, but only the one + * in reclaim_page() needs to be. */ - if (!page->mapping || !is_page_cache_freeable(page)) { - spin_unlock(&pagecache_lock); + if (page->mapping && !PageDirty(page) && !page->pte_chain && + page_count(page) == 1) { + del_page_from_inactive_dirty_list(page); + add_page_to_inactive_clean_list(page); UnlockPage(page); -page_mapped: - if (--max_mapped >= 0) - continue; - + cleaned_pages++; + } else { /* - * Alert! We've found too many mapped pages on the - * inactive list, so we start swapping out now! + * OK, we don't know what to do with the page. + * It's no use keeping it here, so we move it to + * the active list. */ - spin_unlock(&pagemap_lru_lock); - swap_out(priority, gfp_mask, classzone); - return nr_pages; +page_active: + del_page_from_inactive_dirty_list(page); + add_page_to_active_list(page); + UnlockPage(page); + } + } + spin_unlock(&pagemap_lru_lock); + + /* Return the number of pages moved to the inactive_clean list. */ + return cleaned_pages; +} + +/** + * page_launder - clean dirty inactive pages, move to inactive_clean list + * @gfp_mask: what operations we are allowed to do + * + * This function iterates over all zones and calls page_launder_zone(), + * balancing still needs to be added... + */ +int page_launder(int gfp_mask) +{ + int maxtry = 1 << DEF_PRIORITY; + struct zone_struct * zone; + int freed = 0; + + /* Global balancing while we have a global shortage. */ + while (maxtry-- && free_high(ALL_ZONES) >= 0) { + for_each_zone(zone) + if (free_plenty(zone) >= 0) + freed += page_launder_zone(zone, gfp_mask, 6); + } + + /* Clean up the remaining zones with a serious shortage, if any. */ + for_each_zone(zone) + if (free_min(zone) >= 0) + freed += page_launder_zone(zone, gfp_mask, 0); + + return freed; +} + +/** + * refill_inactive_zone - scan the active list and find pages to deactivate + * @priority: how much are we allowed to scan + * + * This function will scan a portion of the active list of a zone to find + * unused pages, those pages will then be moved to the inactive list. + */ +int refill_inactive_zone(struct zone_struct * zone, int priority) +{ + int maxscan = zone->active_pages >> priority; + int target = inactive_high(zone); + struct list_head * page_lru; + int nr_deactivated = 0; + struct page * page; + + /* Take the lock while messing with the list... */ + spin_lock(&pagemap_lru_lock); + while (maxscan-- && !list_empty(&zone->active_list)) { + page_lru = zone->active_list.prev; + page = list_entry(page_lru, struct page, lru); + + /* Wrong page on list?! (list corruption, should not happen) */ + if (unlikely(!PageActive(page))) { + printk("VM: refill_inactive, wrong page on list.\n"); + list_del(page_lru); + nr_active_pages--; + continue; } /* - * It is critical to check PageDirty _after_ we made sure - * the page is freeable* so not in use by anybody. + * If the object the page is in is not in use we don't + * bother with page aging. If the page is touched again + * while on the inactive_clean list it'll be reactivated. */ - if (PageDirty(page)) { - spin_unlock(&pagecache_lock); - UnlockPage(page); + if (!page_mapping_inuse(page)) { + drop_page(page); continue; } - /* point of no return */ - if (likely(!PageSwapCache(page))) { - __remove_inode_page(page); - spin_unlock(&pagecache_lock); + /* + * Do aging on the pages. + */ + if (page_referenced(page)) { + age_page_up(page); } else { - swp_entry_t swap; - swap.val = page->index; - __delete_from_swap_cache(page); - spin_unlock(&pagecache_lock); - swap_free(swap); + age_page_down(page); } - __lru_cache_del(page); - UnlockPage(page); - - /* effectively free the page here */ - page_cache_release(page); + /* + * If the page age is 'hot' and the process using the + * page doesn't exceed its RSS limit we keep the page. + * Otherwise we move it to the inactive_dirty list. + */ + if (page->age && !page_over_rsslimit(page)) { + list_del(page_lru); + list_add(page_lru, &zone->active_list); + } else { + deactivate_page_nolock(page); + if (++nr_deactivated > target) + break; + } - if (--nr_pages) - continue; - break; + /* Low latency reschedule point */ + if (current->need_resched) { + spin_unlock(&pagemap_lru_lock); + schedule(); + spin_lock(&pagemap_lru_lock); + } } spin_unlock(&pagemap_lru_lock); - return nr_pages; + return nr_deactivated; } -/* - * This moves pages from the active list to - * the inactive list. +/** + * refill_inactive - checks all zones and refills the inactive list as needed * - * We move them the other way when we see the - * reference bit on the page. + * This function tries to balance page eviction from all zones by aging + * the pages from each zone in the same ratio until the global inactive + * shortage is resolved. After that it does one last "clean-up" scan to + * fix up local inactive shortages. */ -static void refill_inactive(int nr_pages) +int refill_inactive(void) { - struct list_head * entry; - - spin_lock(&pagemap_lru_lock); - entry = active_list.prev; - while (nr_pages && entry != &active_list) { - struct page * page; + int maxtry = 1 << DEF_PRIORITY; + zone_t * zone; + int ret = 0; - page = list_entry(entry, struct page, lru); - entry = entry->prev; - if (PageTestandClearReferenced(page)) { - list_del(&page->lru); - list_add(&page->lru, &active_list); - continue; + /* Global balancing while we have a global shortage. */ + while (maxtry-- && inactive_low(ALL_ZONES) >= 0) { + for_each_zone(zone) { + if (inactive_high(zone) >= 0) + ret += refill_inactive_zone(zone, DEF_PRIORITY); } + } - nr_pages--; - - del_page_from_active_list(page); - add_page_to_inactive_list(page); - SetPageReferenced(page); + /* Local balancing for zones which really need it. */ + for_each_zone(zone) { + if (inactive_min(zone) >= 0) + ret += refill_inactive_zone(zone, 0); } - spin_unlock(&pagemap_lru_lock); + + return ret; } -static int FASTCALL(shrink_caches(zone_t * classzone, int priority, unsigned int gfp_mask, int nr_pages)); -static int shrink_caches(zone_t * classzone, int priority, unsigned int gfp_mask, int nr_pages) +/** + * background_aging - slow background aging of zones + * @priority: priority at which to scan + * + * When the VM load is low or nonexistant, this function is + * called once a second to "sort" the pages in the VM. This + * way we know which pages to evict once a load spike happens. + * The effects of this function are very slow, the CPU usage + * should be minimal to nonexistant under most loads. + */ +static inline void background_aging(int priority) { - int chunk_size = nr_pages; - unsigned long ratio; + struct zone_struct * zone; - nr_pages -= kmem_cache_reap(gfp_mask); - if (nr_pages <= 0) - return 0; - - nr_pages = chunk_size; - /* try to keep the active list 2/3 of the size of the cache */ - ratio = (unsigned long) nr_pages * nr_active_pages / ((nr_inactive_pages + 1) * 2); - refill_inactive(ratio); + for_each_zone(zone) + if (inactive_high(zone) > 0) + refill_inactive_zone(zone, priority); +} - nr_pages = shrink_cache(nr_pages, classzone, gfp_mask, priority); - if (nr_pages <= 0) - return 0; +/* + * Worker function for kswapd and try_to_free_pages, we get + * called whenever there is a shortage of free/inactive_clean + * pages. + * + * This function will also move pages to the inactive list, + * if needed. + */ +static int do_try_to_free_pages(unsigned int gfp_mask) +{ + int ret = 0; - shrink_dcache_memory(priority, gfp_mask); - shrink_icache_memory(priority, gfp_mask); + /* + * Eat memory from filesystem page cache, buffer cache, + * dentry, inode and filesystem quota caches. + */ + ret += page_launder(gfp_mask); + ret += shrink_dcache_memory(DEF_PRIORITY, gfp_mask); + ret += shrink_icache_memory(1, gfp_mask); #ifdef CONFIG_QUOTA - shrink_dqcache_memory(DEF_PRIORITY, gfp_mask); + ret += shrink_dqcache_memory(DEF_PRIORITY, gfp_mask); #endif - return nr_pages; -} + /* + * Move pages from the active list to the inactive list. + */ + refill_inactive(); -int try_to_free_pages(zone_t *classzone, unsigned int gfp_mask, unsigned int order) -{ - int priority = DEF_PRIORITY; - int nr_pages = SWAP_CLUSTER_MAX; + /* + * Reclaim unused slab cache memory. + */ + ret += kmem_cache_reap(gfp_mask); - gfp_mask = pf_gfp_mask(gfp_mask); - do { - nr_pages = shrink_caches(classzone, priority, gfp_mask, nr_pages); - if (nr_pages <= 0) - return 1; - } while (--priority); + refill_freelist(); + + /* Start IO when needed. */ + if (free_plenty(ALL_ZONES) > 0 || free_low(ANY_ZONE) > 0) + run_task_queue(&tq_disk); /* * Hmm.. Cache shrink failed - time to kill something? * Mhwahahhaha! This is the part I really like. Giggle. */ - out_of_memory(); - return 0; -} + if (!ret && free_min(ANY_ZONE) > 0) + out_of_memory(); -DECLARE_WAIT_QUEUE_HEAD(kswapd_wait); - -static int check_classzone_need_balance(zone_t * classzone) -{ - zone_t * first_classzone; - - first_classzone = classzone->zone_pgdat->node_zones; - while (classzone >= first_classzone) { - if (classzone->free_pages > classzone->pages_high) - return 0; - classzone--; - } - return 1; + return ret; } -static int kswapd_balance_pgdat(pg_data_t * pgdat) +/** + * refill_freelist - move inactive_clean pages to free list if needed + * + * Move some pages from the inactive_clean lists to the free + * lists so atomic allocations have pages to work from. This + * function really only does something when we don't have a + * userspace load on __alloc_pages(). + * + * We refill the freelist in a bump from pages_min to pages_min * 2 + * in order to give the buddy allocator something to play with. + */ +static void refill_freelist(void) { - int need_more_balance = 0, i; + struct page * page; zone_t * zone; - for (i = pgdat->nr_zones-1; i >= 0; i--) { - zone = pgdat->node_zones + i; - if (unlikely(current->need_resched)) - schedule(); - if (!zone->need_balance) + for_each_zone(zone) { + if (!zone->size || zone->free_pages >= zone->pages_min) continue; - if (!try_to_free_pages(zone, GFP_KSWAPD, 0)) { - zone->need_balance = 0; - __set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ); - continue; - } - if (check_classzone_need_balance(zone)) - need_more_balance = 1; - else - zone->need_balance = 0; - } - - return need_more_balance; -} - -static void kswapd_balance(void) -{ - int need_more_balance; - pg_data_t * pgdat; - - do { - need_more_balance = 0; - pgdat = pgdat_list; - do - need_more_balance |= kswapd_balance_pgdat(pgdat); - while ((pgdat = pgdat->node_next)); - } while (need_more_balance); -} -static int kswapd_can_sleep_pgdat(pg_data_t * pgdat) -{ - zone_t * zone; - int i; - - for (i = pgdat->nr_zones-1; i >= 0; i--) { - zone = pgdat->node_zones + i; - if (!zone->need_balance) - continue; - return 0; + while (zone->free_pages < zone->pages_min * 2) { + page = reclaim_page(zone); + if (!page) + break; + __free_page(page); + } } - - return 1; } -static int kswapd_can_sleep(void) -{ - pg_data_t * pgdat; - - pgdat = pgdat_list; - do { - if (kswapd_can_sleep_pgdat(pgdat)) - continue; - return 0; - } while ((pgdat = pgdat->node_next)); - - return 1; -} - -/* - * The background pageout daemon, started as a kernel thread - * from the init process. +/** + * kswapd - the background pageout daemon (kernel thread) * * This basically trickles out pages so that we have _some_ * free memory available even if there is no other activity @@ -704,7 +655,6 @@ int kswapd(void *unused) { struct task_struct *tsk = current; - DECLARE_WAITQUEUE(wait, tsk); daemonize(); strcpy(tsk->comm, "kswapd"); @@ -728,24 +678,156 @@ * Kswapd main loop. */ for (;;) { - __set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&kswapd_wait, &wait); + static long recalc = 0; - mb(); - if (kswapd_can_sleep()) - schedule(); + /* + * We try to rebalance the VM either when we have a + * global shortage of free pages or when one particular + * zone is very short on free pages. + */ + if (free_high(ALL_ZONES) >= 0 || free_low(ANY_ZONE) > 0) + do_try_to_free_pages(GFP_KSWAPD); + + refill_freelist(); + + /* Once a second ... */ + if (time_after(jiffies, recalc + HZ)) { + recalc = jiffies; - __set_current_state(TASK_RUNNING); + /* Do background page aging. */ + background_aging(DEF_PRIORITY); + } + + wakeup_memwaiters(); + } +} + +static int kswapd_overloaded; +DECLARE_WAIT_QUEUE_HEAD(kswapd_wait); +DECLARE_WAIT_QUEUE_HEAD(kswapd_done); +#define VM_SHOULD_SLEEP ((free_low(ALL_ZONES) > (freepages.min / 2)) && \ + !kswapd_overloaded) + +/** + * wakeup_kswapd - wake up the pageout daemon + * gfp_mask: page freeing flags + * + * This function wakes up kswapd and can, under heavy VM pressure, + * put the calling task to sleep temporarily. + */ +void wakeup_kswapd(unsigned int gfp_mask) +{ + DECLARE_WAITQUEUE(wait, current); + + /* If we're in the memory freeing business ourself, don't sleep + * but just wake kswapd and go back to businesss. + */ + if (current->flags & PF_MEMALLOC) { + wake_up_interruptible(&kswapd_wait); + return; + } + + /* We need all of kswapd's GFP flags, otherwise we can't sleep on it. + * We still wake kswapd of course. + */ + if ((gfp_mask & GFP_KSWAPD) != GFP_KSWAPD) { + wake_up_interruptible(&kswapd_wait); + return; + } + + add_wait_queue(&kswapd_done, &wait); + set_current_state(TASK_UNINTERRUPTIBLE); + + /* Wake kswapd .... */ + wake_up_interruptible(&kswapd_wait); + + /* ... and check if we need to wait on it */ + if (VM_SHOULD_SLEEP) + schedule(); + set_current_state(TASK_RUNNING); + remove_wait_queue(&kswapd_done, &wait); +} + +static void wakeup_memwaiters(void) +{ + DECLARE_WAITQUEUE(wait, current); + + add_wait_queue(&kswapd_wait, &wait); + set_current_state(TASK_INTERRUPTIBLE); + + /* Don't let the processes waiting on memory get stuck, ever. */ + wake_up(&kswapd_done); + + /* Enough free RAM, we can easily keep up with memory demand. */ + if (free_high(ALL_ZONES) <= 0) { + schedule_timeout(HZ); remove_wait_queue(&kswapd_wait, &wait); + return; + } + remove_wait_queue(&kswapd_wait, &wait); - /* - * If we actually get into a low-memory situation, - * the processes needing more memory will wake us - * up on a more timely basis. - */ - kswapd_balance(); - run_task_queue(&tq_disk); + /* OK, the VM is very loaded. Sleep instead of using all CPU. */ + kswapd_overloaded = 1; + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ / 4); + kswapd_overloaded = 0; + return; +} + +/** + * try_to_free_pages - run the pageout code ourselves + * gfp_mask: mask of things the pageout code is allowed to do + * + * When the load on the system gets higher, it can happen + * that kswapd no longer manages to keep enough memory + * free. In those cases user programs allocating memory + * will call try_to_free_pages() and help the pageout code. + * This has the effects of freeing memory and slowing down + * the largest memory hogs a bit. + */ +int try_to_free_pages(unsigned int gfp_mask) +{ + int ret = 1; + + gfp_mask = pf_gfp_mask(gfp_mask); + if (gfp_mask & __GFP_WAIT) { + current->flags |= PF_MEMALLOC; + ret = do_try_to_free_pages(gfp_mask); + current->flags &= ~PF_MEMALLOC; } + + return ret; +} + +/** + * rss_free_pages - run part of the pageout code and slow down a bit + * @gfp_mask: mask of things the pageout code is allowed to do + * + * This function is called when a task is over its RSS limit and + * has a page fault. It's goal is to free some memory so non-hogs + * can run faster and slow down itself when needed so it won't eat + * the memory non-hogs can use. + */ +void rss_free_pages(unsigned int gfp_mask) +{ + long pause = 0; + + if (current->flags & PF_MEMALLOC) + return; + + current->flags |= PF_MEMALLOC; + + do { + page_launder(gfp_mask); + + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(pause); + set_current_state(TASK_RUNNING); + pause++; + } while (free_high(ALL_ZONES) >= 0); + + current->flags &= ~PF_MEMALLOC; + return; } static int __init kswapd_init(void) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/802/p8022.c linux.19pre5-ac1/net/802/p8022.c --- linux.19p5/net/802/p8022.c Thu Apr 4 13:18:41 2002 +++ linux.19pre5-ac1/net/802/p8022.c Tue Mar 19 19:15:34 2002 @@ -11,11 +11,10 @@ * matches. The control byte is ignored and handling of such items * is up to the routine passed the frame. * - * Unlike the 802.3 datalink we have a list of 802.2 entries as there - * are multiple protocols to demux. The list is currently short (3 or - * 4 entries at most). The current demux assumes this. + * Unlike the 802.3 datalink we have a list of 802.2 entries as + * there are multiple protocols to demux. The list is currently + * short (3 or 4 entries at most). The current demux assumes this. */ - #include #include #include @@ -25,8 +24,13 @@ #include #include -static struct datalink_proto *p8022_list = NULL; +extern void llc_register_sap(unsigned char sap, + int (*rcvfunc)(struct sk_buff *, + struct net_device *, + struct packet_type *)); +extern void llc_unregister_sap(unsigned char sap); +static struct datalink_proto *p8022_list; /* * We don't handle the loopback SAP stuff, the extended * 802.2 command set, multicast SAP identifiers and non UI @@ -34,91 +38,68 @@ * IP and Appletalk phase 2. See the llc_* routines for * support libraries if your protocol needs these. */ - static struct datalink_proto *find_8022_client(unsigned char type) { - struct datalink_proto *proto; - - for (proto = p8022_list; - ((proto != NULL) && (*(proto->type) != type)); - proto = proto->next) - ; + struct datalink_proto *proto = p8022_list; + while (proto && *(proto->type) != type) + proto = proto->next; return proto; } -int p8022_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) +int p8022_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt) { - struct datalink_proto *proto; + struct datalink_proto *proto; + int rc = 0; proto = find_8022_client(*(skb->h.raw)); - if (proto != NULL) - { - skb->h.raw += 3; - skb->nh.raw += 3; - skb_pull(skb,3); - return proto->rcvfunc(skb, dev, pt); + if (!proto) { + skb->sk = NULL; + kfree_skb(skb); + goto out; } - - skb->sk = NULL; - kfree_skb(skb); - return 0; + skb->h.raw += 3; + skb->nh.raw += 3; + skb_pull(skb, 3); + rc = proto->rcvfunc(skb, dev, pt); +out: return rc; } static void p8022_datalink_header(struct datalink_proto *dl, - struct sk_buff *skb, unsigned char *dest_node) + struct sk_buff *skb, unsigned char *dest_node) { - struct net_device *dev = skb->dev; - unsigned char *rawp; + struct net_device *dev = skb->dev; + unsigned char *rawp = skb_push(skb, 3); - rawp = skb_push(skb,3); *rawp++ = dl->type[0]; *rawp++ = dl->type[0]; - *rawp = 0x03; /* UI */ + *rawp = 0x03; /* UI */ dev->hard_header(skb, dev, ETH_P_802_3, dest_node, NULL, skb->len); } -static struct packet_type p8022_packet_type = -{ - 0, /* MUTTER ntohs(ETH_P_8022),*/ - NULL, /* All devices */ - p8022_rcv, - NULL, - NULL, -}; - -EXPORT_SYMBOL(register_8022_client); -EXPORT_SYMBOL(unregister_8022_client); - -static int __init p8022_init(void) -{ - p8022_packet_type.type=htons(ETH_P_802_2); - dev_add_pack(&p8022_packet_type); - return 0; -} - -module_init(p8022_init); - -struct datalink_proto *register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct net_device *, struct packet_type *)) -{ - struct datalink_proto *proto; - - if (find_8022_client(type) != NULL) - return NULL; - - proto = (struct datalink_proto *) kmalloc(sizeof(*proto), GFP_ATOMIC); - if (proto != NULL) { - proto->type[0] = type; - proto->type_len = 1; - proto->rcvfunc = rcvfunc; - proto->header_length = 3; - proto->datalink_header = p8022_datalink_header; - proto->string_name = "802.2"; - proto->next = p8022_list; - p8022_list = proto; +struct datalink_proto *register_8022_client(unsigned char type, + int (*rcvfunc)(struct sk_buff *, + struct net_device *, + struct packet_type *)) +{ + struct datalink_proto *proto = NULL; + + if (find_8022_client(type)) + goto out; + proto = kmalloc(sizeof(*proto), GFP_ATOMIC); + if (proto) { + proto->type[0] = type; + proto->type_len = 1; + proto->rcvfunc = rcvfunc; + proto->header_length = 3; + proto->datalink_header = p8022_datalink_header; + proto->string_name = "802.2"; + proto->next = p8022_list; + p8022_list = proto; + llc_register_sap(type, p8022_rcv); } - - return proto; +out: return proto; } void unregister_8022_client(unsigned char type) @@ -128,17 +109,18 @@ save_flags(flags); cli(); - - while ((tmp = *clients) != NULL) - { + while (*clients) { + tmp = *clients; if (tmp->type[0] == type) { *clients = tmp->next; kfree(tmp); + llc_unregister_sap(type); break; - } else { - clients = &tmp->next; } + clients = &tmp->next; } - restore_flags(flags); } + +EXPORT_SYMBOL(register_8022_client); +EXPORT_SYMBOL(unregister_8022_client); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/802/tr.c linux.19pre5-ac1/net/802/tr.c --- linux.19p5/net/802/tr.c Thu Apr 4 13:18:41 2002 +++ linux.19pre5-ac1/net/802/tr.c Tue Mar 19 19:15:34 2002 @@ -36,7 +36,8 @@ #include #include -static void tr_source_route(struct sk_buff *skb, struct trh_hdr *trh, struct net_device *dev); +void tr_source_route(struct sk_buff *skb, struct trh_hdr *trh, + struct net_device *dev); static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev); static void rif_check_expire(unsigned long dummy); @@ -65,7 +66,7 @@ * up a lot. */ -rif_cache rif_table[RIF_TABLE_SIZE]={ NULL, }; +rif_cache rif_table[RIF_TABLE_SIZE]; static spinlock_t rif_lock = SPIN_LOCK_UNLOCKED; @@ -230,7 +231,8 @@ * We try to do source routing... */ -static void tr_source_route(struct sk_buff *skb,struct trh_hdr *trh,struct net_device *dev) +void tr_source_route(struct sk_buff *skb, struct trh_hdr *trh, + struct net_device *dev) { int i, slack; unsigned int hash; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/Config.in linux.19pre5-ac1/net/Config.in --- linux.19p5/net/Config.in Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/net/Config.in Tue Mar 26 18:51:18 2002 @@ -43,6 +43,10 @@ if [ "$CONFIG_INET" = "y" -a "$CONFIG_ATM_LANE" != "n" ]; then tristate ' Multi-Protocol Over ATM (MPOA) support' CONFIG_ATM_MPOA fi + tristate ' RFC1483/2684 Bridged protocols' CONFIG_ATM_BR2684 + if [ "$CONFIG_ATM_BR2684" != "n" ]; then + bool ' Per-VC IP filter kludge' CONFIG_ATM_BR2684_IPFILTER + fi fi fi tristate '802.1Q VLAN Support' CONFIG_VLAN_8021Q @@ -61,11 +65,12 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then tristate 'CCITT X.25 Packet Layer (EXPERIMENTAL)' CONFIG_X25 tristate 'LAPB Data Link Driver (EXPERIMENTAL)' CONFIG_LAPB - bool '802.2 LLC (EXPERIMENTAL)' CONFIG_LLC + tristate 'ANSI/IEEE 802.2 Data link layer protocol' CONFIG_LLC + if [ "$CONFIG_LLC" != "n" ]; then + # When NETBEUI is added the following line will be a tristate + define_bool CONFIG_LLC_UI y + fi bool 'Frame Diverter (EXPERIMENTAL)' CONFIG_NET_DIVERT -# if [ "$CONFIG_LLC" = "y" ]; then -# bool ' Netbeui (EXPERIMENTAL)' CONFIG_NETBEUI -# fi if [ "$CONFIG_INET" = "y" ]; then tristate 'Acorn Econet/AUN protocols (EXPERIMENTAL)' CONFIG_ECONET fi diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/Makefile linux.19pre5-ac1/net/Makefile --- linux.19p5/net/Makefile Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/net/Makefile Mon Mar 25 18:17:25 2002 @@ -7,7 +7,7 @@ O_TARGET := network.o -mod-subdirs := ipv4/netfilter ipv6/netfilter ipx irda bluetooth atm netlink sched core +mod-subdirs := ipv4/netfilter ipv6/netfilter ipx irda bluetooth atm netlink sched llc core export-objs := netsyms.o subdir-y := core ethernet @@ -45,7 +45,7 @@ subdir-$(CONFIG_DECNET) += decnet subdir-$(CONFIG_ECONET) += econet subdir-$(CONFIG_VLAN_8021Q) += 8021q - +subdir-$(CONFIG_LLC) += llc obj-y := socket.o $(join $(subdir-y), $(patsubst %,/%.o,$(notdir $(subdir-y)))) ifeq ($(CONFIG_NET),y) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/atm/Makefile linux.19pre5-ac1/net/atm/Makefile --- linux.19p5/net/atm/Makefile Thu Apr 4 13:18:48 2002 +++ linux.19pre5-ac1/net/atm/Makefile Tue Mar 26 18:51:18 2002 @@ -21,6 +21,15 @@ NEED_IPCOM = ipcommon.o endif +ifeq ($(CONFIG_ATM_BR2684),y) + NEED_IPCOM = ipcommon.o +else + ifeq ($(CONFIG_ATM_BR2684),m) + NEED_IPCOM = ipcommon.o + endif +endif +obj-$(CONFIG_ATM_BR2684) += br2684.o + ifeq ($(CONFIG_NET_SCH_ATM),y) NEED_IPCOM = ipcommon.o endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/atm/br2684.c linux.19pre5-ac1/net/atm/br2684.c --- linux.19p5/net/atm/br2684.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/net/atm/br2684.c Tue Mar 26 18:52:38 2002 @@ -0,0 +1,802 @@ +/* +Experimental ethernet netdevice using ATM AAL5 as underlying carrier +(RFC1483 obsoleted by RFC2684) for Linux 2.4 +Author: Marcell GAL, 2000, XDSL Ltd, Hungary +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ipcommon.h" + +/* + * Define this to use a version of the code which interacts with the higher + * layers in a more intellegent way, by always reserving enough space for + * our header at the begining of the packet. However, there may still be + * some problems with programs like tcpdump. In 2.5 we'll sort out what + * we need to do to get this perfect. For now we just will copy the packet + * if we need space for the header + */ +/* #define FASTER_VERSION */ + +#ifdef DEBUG +#define DPRINTK(format, args...) printk(KERN_DEBUG "br2684: " format, ##args) +#else +#define DPRINTK(format, args...) +#endif + +#ifdef SKB_DEBUG +static void skb_debug(const struct sk_buff *skb) +{ +#define NUM2PRINT 50 + char buf[NUM2PRINT * 3 + 1]; /* 3 chars per byte */ + int i = 0; + for (i = 0; i < skb->len && i < NUM2PRINT; i++) { + sprintf(buf + i * 3, "%2.2x ", 0xff & skb->data[i]); + } + printk(KERN_DEBUG "br2684: skb: %s\n", buf); +} +#else +#define skb_debug(skb) do {} while (0) +#endif + +static unsigned char llc_oui_pid_pad[] = + { 0xAA, 0xAA, 0x03, 0x00, 0x80, 0xC2, 0x00, 0x07, 0x00, 0x00 }; +#define PADLEN (2) + +enum br2684_encaps { + e_vc = BR2684_ENCAPS_VC, + e_llc = BR2684_ENCAPS_LLC, +}; + +struct br2684_vcc { + struct atm_vcc *atmvcc; + struct br2684_dev *brdev; + /* keep old push,pop functions for chaining */ + void (*old_push)(struct atm_vcc *vcc,struct sk_buff *skb); + /* void (*old_pop)(struct atm_vcc *vcc,struct sk_buff *skb); */ + enum br2684_encaps encaps; + struct list_head brvccs; +#ifdef CONFIG_ATM_BR2684_IPFILTER + struct br2684_filter filter; +#endif /* CONFIG_ATM_BR2684_IPFILTER */ +#ifndef FASTER_VERSION + unsigned copies_needed, copies_failed; +#endif /* FASTER_VERSION */ +}; + +struct br2684_dev { + struct net_device net_dev; + struct list_head br2684_devs; + int number; + struct list_head brvccs; /* one device <=> one vcc (before xmas) */ + struct net_device_stats stats; + int mac_was_set; +}; + +/* + * This lock should be held for writing any time the list of devices or + * their attached vcc's could be altered. It should be held for reading + * any time these are being queried. Note that we sometimes need to + * do read-locking under interrupt context, so write locking must block + * the current CPU's interrupts + */ +static rwlock_t devs_lock = RW_LOCK_UNLOCKED; + +static LIST_HEAD(br2684_devs); + +static inline struct br2684_dev *BRPRIV(const struct net_device *net_dev) +{ + return list_entry(net_dev, struct br2684_dev, net_dev); +} + +static inline struct br2684_dev *list_entry_brdev(const struct list_head *le) +{ + return list_entry(le, struct br2684_dev, br2684_devs); +} + +static inline struct br2684_vcc *BR2684_VCC(const struct atm_vcc *atmvcc) +{ + return (struct br2684_vcc *) (atmvcc->user_back); +} + +static inline struct br2684_vcc *list_entry_brvcc(const struct list_head *le) +{ + return list_entry(le, struct br2684_vcc, brvccs); +} + +/* Caller should hold read_lock(&devs_lock) */ +static struct br2684_dev *br2684_find_dev(const struct br2684_if_spec *s) +{ + struct list_head *lh; + struct br2684_dev *brdev; + switch (s->method) { + case BR2684_FIND_BYNUM: + list_for_each(lh, &br2684_devs) { + brdev = list_entry_brdev(lh); + if (brdev->number == s->spec.devnum) + return brdev; + } + break; + case BR2684_FIND_BYIFNAME: + list_for_each(lh, &br2684_devs) { + brdev = list_entry_brdev(lh); + if (!strncmp(brdev->net_dev.name, s->spec.ifname, + sizeof brdev->net_dev.name)) + return brdev; + } + break; + } + return NULL; +} + +/* + * Send a packet out a particular vcc. Not to useful right now, but paves + * the way for multiple vcc's per itf. Returns true if we can send, + * otherwise false + */ +static int br2684_xmit_vcc(struct sk_buff *skb, struct br2684_dev *brdev, + struct br2684_vcc *brvcc) +{ + struct atm_vcc *atmvcc; +#ifdef FASTER_VERSION + if (brvcc->encaps == e_llc) + memcpy(skb_push(skb, 8), llc_oui_pid_pad, 8); + /* last 2 bytes of llc_oui_pid_pad are managed by header routines; + yes, you got it: 8 + 2 = sizeof(llc_oui_pid_pad) + */ +#else + int minheadroom = (brvcc->encaps == e_llc) ? 10 : 2; + if (skb_headroom(skb) < minheadroom) { + struct sk_buff *skb2 = skb_realloc_headroom(skb, minheadroom); + brvcc->copies_needed++; + dev_kfree_skb(skb); + if (skb2 == NULL) { + brvcc->copies_failed++; + return 0; + } + skb = skb2; + } + skb_push(skb, minheadroom); + if (brvcc->encaps == e_llc) + memcpy(skb->data, llc_oui_pid_pad, 10); + else + memset(skb->data, 0, 2); +#endif /* FASTER_VERSION */ + skb_debug(skb); + + ATM_SKB(skb)->vcc = atmvcc = brvcc->atmvcc; + DPRINTK("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, atmvcc, atmvcc->dev); + if (!atm_may_send(atmvcc, skb->truesize)) { + /* we free this here for now, because we cannot know in a higher + layer whether the skb point it supplied wasn't freed yet. + now, it always is. + */ + dev_kfree_skb(skb); + return 0; + } + atomic_add(skb->truesize, &atmvcc->tx_inuse); + ATM_SKB(skb)->iovcnt = 0; + ATM_SKB(skb)->atm_options = atmvcc->atm_options; + brdev->stats.tx_packets++; + brdev->stats.tx_bytes += skb->len; + atmvcc->send(atmvcc, skb); + return 1; +} + +static inline struct br2684_vcc *pick_outgoing_vcc(struct sk_buff *skb, + struct br2684_dev *brdev) +{ + return list_empty(&brdev->brvccs) ? NULL : + list_entry_brvcc(brdev->brvccs.next); /* 1 vcc/dev right now */ +} + +static int br2684_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct br2684_dev *brdev = BRPRIV(dev); + struct br2684_vcc *brvcc; + + DPRINTK("br2684_start_xmit, skb->dst=%p\n", skb->dst); + read_lock(&devs_lock); + brvcc = pick_outgoing_vcc(skb, brdev); + if (brvcc == NULL) { + DPRINTK("no vcc attached to dev %s\n", dev->name); + brdev->stats.tx_errors++; + brdev->stats.tx_carrier_errors++; + /* netif_stop_queue(dev); */ + dev_kfree_skb(skb); + read_unlock(&devs_lock); + return -EUNATCH; + } + if (!br2684_xmit_vcc(skb, brdev, brvcc)) { + /* + * We should probably use netif_*_queue() here, but that + * involves added complication. We need to walk before + * we can run + */ + /* don't free here! this pointer might be no longer valid! + dev_kfree_skb(skb); + */ + brdev->stats.tx_errors++; + brdev->stats.tx_fifo_errors++; + } + read_unlock(&devs_lock); + return 0; +} + +static struct net_device_stats *br2684_get_stats(struct net_device *dev) +{ + DPRINTK("br2684_get_stats\n"); + return &BRPRIV(dev)->stats; +} + +#ifdef FASTER_VERSION +/* + * These mirror eth_header and eth_header_cache. They are not usually + * exported for use in modules, so we grab them from net_device + * after ether_setup() is done with it. Bit of a hack. + */ +static int (*my_eth_header)(struct sk_buff *, struct net_device *, + unsigned short, void *, void *, unsigned); +static int (*my_eth_header_cache)(struct neighbour *, struct hh_cache *); + +static int +br2684_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, void *daddr, void *saddr, unsigned len) +{ + u16 *pad_before_eth; + int t = my_eth_header(skb, dev, type, daddr, saddr, len); + if (t > 0) { + pad_before_eth = (u16 *) skb_push(skb, 2); + *pad_before_eth = 0; + return dev->hard_header_len; /* or return 16; ? */ + } else + return t; +} + +static int +br2684_header_cache(struct neighbour *neigh, struct hh_cache *hh) +{ +/* hh_data is 16 bytes long. if encaps is ether-llc we need 24, so +xmit will add the additional header part in that case */ + u16 *pad_before_eth = (u16 *)(hh->hh_data); + int t = my_eth_header_cache(neigh, hh); + DPRINTK("br2684_header_cache, neigh=%p, hh_cache=%p\n", neigh, hh); + if (t < 0) + return t; + else { + *pad_before_eth = 0; + hh->hh_len = PADLEN + ETH_HLEN; + } + return 0; +} + +/* + * This is similar to eth_type_trans, which cannot be used because of + * our dev->hard_header_len + */ +static inline unsigned short br_type_trans(struct sk_buff *skb, + struct net_device *dev) +{ + struct ethhdr *eth; + unsigned char *rawp; + eth = skb->mac.ethernet; + + if (*eth->h_dest & 1) { + if (memcmp(eth->h_dest, dev->broadcast, ETH_ALEN) == 0) + skb->pkt_type = PACKET_BROADCAST; + else + skb->pkt_type = PACKET_MULTICAST; + } + + else if (memcmp(eth->h_dest, dev->dev_addr, ETH_ALEN)) + skb->pkt_type = PACKET_OTHERHOST; + + if (ntohs(eth->h_proto) >= 1536) + return eth->h_proto; + + rawp = skb->data; + + /* + * This is a magic hack to spot IPX packets. Older Novell breaks + * the protocol design and runs IPX over 802.3 without an 802.2 LLC + * layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This + * won't work for fault tolerant netware but does for the rest. + */ + if (*(unsigned short *) rawp == 0xFFFF) + return htons(ETH_P_802_3); + + /* + * Real 802.2 LLC + */ + return htons(ETH_P_802_2); +} +#endif /* FASTER_VERSION */ + +/* + * We remember when the MAC gets set, so we don't override it later with + * the ESI of the ATM card of the first VC + */ +static int (*my_eth_mac_addr)(struct net_device *, void *); +static int br2684_mac_addr(struct net_device *dev, void *p) +{ + int err = my_eth_mac_addr(dev, p); + if (!err) + BRPRIV(dev)->mac_was_set = 1; + return err; +} + +#ifdef CONFIG_ATM_BR2684_IPFILTER +/* this IOCTL is experimental. */ +static int br2684_setfilt(struct atm_vcc *atmvcc, unsigned long arg) +{ + struct br2684_vcc *brvcc; + struct br2684_filter_set fs; + + if (copy_from_user(&fs, (void *) arg, sizeof fs)) + return -EFAULT; + if (fs.ifspec.method != BR2684_FIND_BYNOTHING) { + /* + * This is really a per-vcc thing, but we can also search + * by device + */ + struct br2684_dev *brdev; + read_lock(&devs_lock); + brdev = br2684_find_dev(&fs.ifspec); + if (brdev == NULL || list_empty(&brdev->brvccs) || + brdev->brvccs.next != brdev->brvccs.prev) /* >1 VCC */ + brvcc = NULL; + else + brvcc = list_entry_brvcc(brdev->brvccs.next); + read_unlock(&devs_lock); + if (brvcc == NULL) + return -ESRCH; + } else + brvcc = BR2684_VCC(atmvcc); + memcpy(&brvcc->filter, &fs.filter, sizeof(brvcc->filter)); + return 0; +} + +/* Returns 1 if packet should be dropped */ +static inline int +packet_fails_filter(u16 type, struct br2684_vcc *brvcc, struct sk_buff *skb) +{ + if (brvcc->filter.netmask == 0) + return 0; /* no filter in place */ + if (type == __constant_htons(ETH_P_IP) && + (((struct iphdr *) (skb->data))->daddr & brvcc->filter. + netmask) == brvcc->filter.prefix) + return 0; + if (type == __constant_htons(ETH_P_ARP)) + return 0; + /* TODO: we should probably filter ARPs too.. don't want to have + * them returning values that don't make sense, or is that ok? + */ + return 1; /* drop */ +} +#endif /* CONFIG_ATM_BR2684_IPFILTER */ + +static void br2684_close_vcc(struct br2684_vcc *brvcc) +{ + DPRINTK("removing VCC %p from dev %p\n", brvcc, brvcc->brdev); + write_lock_irq(&devs_lock); + list_del(&brvcc->brvccs); + write_unlock_irq(&devs_lock); + brvcc->atmvcc->user_back = NULL; /* what about vcc->recvq ??? */ + brvcc->old_push(brvcc->atmvcc, NULL); /* pass on the bad news */ + kfree(brvcc); + MOD_DEC_USE_COUNT; +} + +/* when AAL5 PDU comes in: */ +static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb) +{ + struct br2684_vcc *brvcc = BR2684_VCC(atmvcc); + struct br2684_dev *brdev = brvcc->brdev; + int plen = sizeof(llc_oui_pid_pad) + ETH_HLEN; + + DPRINTK("br2684_push\n"); + + if (skb == NULL) { /* skb==NULL means VCC is being destroyed */ + br2684_close_vcc(brvcc); + if (list_empty(&brdev->brvccs)) { + read_lock(&devs_lock); + list_del(&brdev->br2684_devs); + read_unlock(&devs_lock); + unregister_netdev(&brdev->net_dev); + kfree(brdev); + } + return; + } + + skb_debug(skb); + atm_return(atmvcc, skb->truesize); + DPRINTK("skb from brdev %p\n", brdev); + if (brvcc->encaps == e_llc) { + /* let us waste some time for checking the encapsulation. + Note, that only 7 char is checked so frames with a valid FCS + are also accepted (but FCS is not checked of course) */ + if (memcmp(skb->data, llc_oui_pid_pad, 7)) { + brdev->stats.rx_errors++; + dev_kfree_skb(skb); + return; + } + } else { + plen = PADLEN + ETH_HLEN; /* pad, dstmac,srcmac, ethtype */ + /* first 2 chars should be 0 */ + if (*((u16 *) (skb->data)) != 0) { + brdev->stats.rx_errors++; + dev_kfree_skb(skb); + return; + } + } + if (skb->len < plen) { + brdev->stats.rx_errors++; + dev_kfree_skb(skb); /* dev_ not needed? */ + return; + } + +#ifdef FASTER_VERSION + /* FIXME: tcpdump shows that pointer to mac header is 2 bytes earlier, + than should be. What else should I set? */ + skb_pull(skb, plen); + skb->mac.raw = ((char *) (skb->data)) - ETH_HLEN; + skb->pkt_type = PACKET_HOST; +#ifdef CONFIG_BR2684_FAST_TRANS + skb->protocol = ((u16 *) skb->data)[-1]; +#else /* some protocols might require this: */ + skb->protocol = br_type_trans(skb, &brdev->net_dev); +#endif /* CONFIG_BR2684_FAST_TRANS */ +#else + skb_pull(skb, plen - ETH_HLEN); + skb->protocol = eth_type_trans(skb, &brdev->net_dev); +#endif /* FASTER_VERSION */ +#ifdef CONFIG_ATM_BR2684_IPFILTER + if (packet_fails_filter(skb->protocol, brvcc, skb)) { + brdev->stats.rx_dropped++; + dev_kfree_skb(skb); + return; + } +#endif /* CONFIG_ATM_BR2684_IPFILTER */ + skb->dev = &brdev->net_dev; + ATM_SKB(skb)->vcc = atmvcc; /* needed ? */ + DPRINTK("received packet's protocol: %x\n", ntohs(skb->protocol)); + skb_debug(skb); + if (!(brdev->net_dev.flags & IFF_UP)) { /* sigh, interface is down */ + brdev->stats.rx_dropped++; + dev_kfree_skb(skb); + return; + } + brdev->stats.rx_packets++; + brdev->stats.rx_bytes += skb->len; + netif_rx(skb); +} + +static int br2684_regvcc(struct atm_vcc *atmvcc, unsigned long arg) +{ +/* assign a vcc to a dev +Note: we do not have explicit unassign, but look at _push() +*/ + int err; + struct br2684_vcc *brvcc; + struct sk_buff_head copy; + struct sk_buff *skb; + struct br2684_dev *brdev; + struct atm_backend_br2684 be; + + MOD_INC_USE_COUNT; + if (copy_from_user(&be, (void *) arg, sizeof be)) { + MOD_DEC_USE_COUNT; + return -EFAULT; + } + write_lock_irq(&devs_lock); + brdev = br2684_find_dev(&be.ifspec); + if (brdev == NULL) { + printk(KERN_ERR + "br2684: tried to attach to non-existant device\n"); + err = -ENXIO; + goto error; + } + if (atmvcc->push == NULL) { + err = -EBADFD; + goto error; + } + if (!list_empty(&brdev->brvccs)) { /* Only 1 VCC/dev right now */ + err = -EEXIST; + goto error; + } + if (be.fcs_in != BR2684_FCSIN_NO || be.fcs_out != BR2684_FCSOUT_NO || + be.fcs_auto || be.has_vpiid || be.send_padding || (be.encaps != + BR2684_ENCAPS_VC && be.encaps != BR2684_ENCAPS_LLC) || + be.min_size != 0) { + err = -EINVAL; + goto error; + } + brvcc = kmalloc(sizeof(struct br2684_vcc), GFP_KERNEL); + if (!brvcc) { + err = -ENOMEM; + goto error; + } + memset(brvcc, 0, sizeof(struct br2684_vcc)); + DPRINTK("br2684_regvcc vcc=%p, encaps=%d, brvcc=%p\n", atmvcc, be.encaps, + brvcc); + if (list_empty(&brdev->brvccs) && !brdev->mac_was_set) { + unsigned char *esi = atmvcc->dev->esi; + if (esi[0] | esi[1] | esi[2] | esi[3] | esi[4] | esi[5]) + memcpy(brdev->net_dev.dev_addr, esi, + brdev->net_dev.addr_len); + else + brdev->net_dev.dev_addr[2] = 1; + } + list_add(&brvcc->brvccs, &brdev->brvccs); + write_unlock_irq(&devs_lock); + brvcc->brdev = brdev; + brvcc->atmvcc = atmvcc; + atmvcc->user_back = brvcc; + brvcc->encaps = (enum br2684_encaps) be.encaps; + brvcc->old_push = atmvcc->push; + barrier(); + atmvcc->push = br2684_push; + skb_queue_head_init(©); + skb_migrate(&atmvcc->recvq, ©); + while ((skb = skb_dequeue(©))) { + BRPRIV(skb->dev)->stats.rx_bytes -= skb->len; + BRPRIV(skb->dev)->stats.rx_packets--; + br2684_push(atmvcc, skb); + } + return 0; + error: + write_unlock_irq(&devs_lock); + MOD_DEC_USE_COUNT; + return err; +} + +static int br2684_create(unsigned long arg) +{ + int err; + struct br2684_dev *brdev; + struct atm_newif_br2684 ni; + + DPRINTK("br2684_create\n"); + /* + * We track module use by vcc's NOT the devices they're on. We're + * protected here against module death by the kernel_lock, but if + * we need to sleep we should make sure that the module doesn't + * disappear under us. + */ + MOD_INC_USE_COUNT; + if (copy_from_user(&ni, (void *) arg, sizeof ni)) { + MOD_DEC_USE_COUNT; + return -EFAULT; + } + if (ni.media != BR2684_MEDIA_ETHERNET || ni.mtu != 1500) { + MOD_DEC_USE_COUNT; + return -EINVAL; + } + if ((brdev = kmalloc(sizeof(struct br2684_dev), GFP_KERNEL)) == NULL) { + MOD_DEC_USE_COUNT; + return -ENOMEM; + } + memset(brdev, 0, sizeof(struct br2684_dev)); + INIT_LIST_HEAD(&brdev->brvccs); + + write_lock_irq(&devs_lock); + brdev->number = list_empty(&br2684_devs) ? 1 : + list_entry_brdev(br2684_devs.prev)->number + 1; + list_add_tail(&brdev->br2684_devs, &br2684_devs); + write_unlock_irq(&devs_lock); + + if (ni.ifname[0] != '\0') { + memcpy(brdev->net_dev.name, ni.ifname, + sizeof(brdev->net_dev.name)); + brdev->net_dev.name[sizeof(brdev->net_dev.name) - 1] = '\0'; + } else + sprintf(brdev->net_dev.name, "nas%d", brdev->number); + DPRINTK("registered netdev %s\n", brdev->net_dev.name); + ether_setup(&brdev->net_dev); + brdev->mac_was_set = 0; +#ifdef FASTER_VERSION + my_eth_header = brdev->net_dev.hard_header; + brdev->net_dev.hard_header = br2684_header; + my_eth_header_cache = brdev->net_dev.hard_header_cache; + brdev->net_dev.hard_header_cache = br2684_header_cache; + brdev->net_dev.hard_header_len = sizeof(llc_oui_pid_pad) + ETH_HLEN; /* 10 + 14 */ +#endif + my_eth_mac_addr = brdev->net_dev.set_mac_address; + brdev->net_dev.set_mac_address = br2684_mac_addr; + brdev->net_dev.hard_start_xmit = br2684_start_xmit; + brdev->net_dev.get_stats = br2684_get_stats; + + /* open, stop, do_ioctl ? */ + err = register_netdev(&brdev->net_dev); + MOD_DEC_USE_COUNT; + if (err < 0) { + printk(KERN_ERR "br2684_create: register_netdev failed\n"); + write_lock_irq(&devs_lock); + list_del(&brdev->br2684_devs); + write_unlock_irq(&devs_lock); + kfree(brdev); + return err; + } + return 0; +} + +/* + * This handles ioctls actually performed on our vcc - we must return + * -ENOIOCTLCMD for any unrecognized ioctl + */ +static int br2684_ioctl(struct atm_vcc *atmvcc, unsigned int cmd, + unsigned long arg) +{ + int err; + switch(cmd) { + case ATM_SETBACKEND: + case ATM_NEWBACKENDIF: { + atm_backend_t b; + MOD_INC_USE_COUNT; + err = get_user(b, (atm_backend_t *) arg); + MOD_DEC_USE_COUNT; + if (err) + return -EFAULT; + if (b != ATM_BACKEND_BR2684) + return -ENOIOCTLCMD; + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + if (cmd == ATM_SETBACKEND) + return br2684_regvcc(atmvcc, arg); + else + return br2684_create(arg); + } +#ifdef CONFIG_ATM_BR2684_IPFILTER + case BR2684_SETFILT: + if (atmvcc->push != br2684_push) + return -ENOIOCTLCMD; + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + MOD_INC_USE_COUNT; + err = br2684_setfilt(atmvcc, arg); + MOD_DEC_USE_COUNT; + return err; +#endif /* CONFIG_ATM_BR2684_IPFILTER */ + } + return -ENOIOCTLCMD; +} + +/* Never put more than 256 bytes in at once */ +static int br2684_proc_engine(loff_t pos, char *buf) +{ + struct list_head *lhd, *lhc; + struct br2684_dev *brdev; + struct br2684_vcc *brvcc; + list_for_each(lhd, &br2684_devs) { + brdev = list_entry_brdev(lhd); + if (pos-- == 0) + return sprintf(buf, "dev %.16s: num=%d, mac=%02X:%02X:" + "%02X:%02X:%02X:%02X (%s)\n", brdev->net_dev.name, + brdev->number, + brdev->net_dev.dev_addr[0], + brdev->net_dev.dev_addr[1], + brdev->net_dev.dev_addr[2], + brdev->net_dev.dev_addr[3], + brdev->net_dev.dev_addr[4], + brdev->net_dev.dev_addr[5], + brdev->mac_was_set ? "set" : "auto"); + list_for_each(lhc, &brdev->brvccs) { + brvcc = list_entry_brvcc(lhc); + if (pos-- == 0) + return sprintf(buf, " vcc %d.%d.%d: encaps=%s" +#ifndef FASTER_VERSION + ", failed copies %u/%u" +#endif /* FASTER_VERSION */ + "\n", brvcc->atmvcc->dev->number, + brvcc->atmvcc->vpi, brvcc->atmvcc->vci, + (brvcc->encaps == e_llc) ? "LLC" : "VC" +#ifndef FASTER_VERSION + , brvcc->copies_failed + , brvcc->copies_needed +#endif /* FASTER_VERSION */ + ); +#ifdef CONFIG_ATM_BR2684_IPFILTER +#define b1(var, byte) ((u8 *) &brvcc->filter.var)[byte] +#define bs(var) b1(var, 0), b1(var, 1), b1(var, 2), b1(var, 3) + if (brvcc->filter.netmask != 0 && pos-- == 0) + return sprintf(buf, " filter=%d.%d.%d.%d/" + "%d.%d.%d.%d\n", bs(prefix), bs(netmask)); +#undef bs +#undef b1 +#endif /* CONFIG_ATM_BR2684_IPFILTER */ + } + } + return 0; +} + +static ssize_t br2684_proc_read(struct file *file, char *buf, size_t count, + loff_t *pos) +{ + unsigned long page; + int len = 0, x, left; + page = get_free_page(GFP_KERNEL); + if (!page) + return -ENOMEM; + left = PAGE_SIZE - 256; + if (count < left) + left = count; + read_lock(&devs_lock); + for (;;) { + x = br2684_proc_engine(*pos, &((char *) page)[len]); + if (x == 0) + break; + if (x > left) + /* + * This should only happen if the user passed in + * a "count" too small for even one line + */ + x = -EINVAL; + if (x < 0) { + len = x; + break; + } + len += x; + left -= x; + (*pos)++; + if (left < 256) + break; + } + read_unlock(&devs_lock); + if (len > 0 && copy_to_user(buf, (char *) page, len)) + len = -EFAULT; + free_page(page); + return len; +} + +static struct file_operations br2684_proc_operations = { + read: br2684_proc_read, +}; + +extern struct proc_dir_entry *atm_proc_root; /* from proc.c */ + +extern int (*br2684_ioctl_hook)(struct atm_vcc *, unsigned int, unsigned long); + +/* the following avoids some spurious warnings from the compiler */ +#define UNUSED __attribute__((unused)) + +static int __init UNUSED br2684_init(void) +{ + struct proc_dir_entry *p; + if ((p = create_proc_entry("br2684", 0, atm_proc_root)) == NULL) + return -ENOMEM; + p->proc_fops = &br2684_proc_operations; + br2684_ioctl_hook = br2684_ioctl; + return 0; +} + +static void __exit UNUSED br2684_exit(void) +{ + struct br2684_dev *brdev; + br2684_ioctl_hook = NULL; + remove_proc_entry("br2684", atm_proc_root); + while (!list_empty(&br2684_devs)) { + brdev = list_entry_brdev(br2684_devs.next); + unregister_netdev(&brdev->net_dev); + list_del(&brdev->br2684_devs); + kfree(brdev); + } +} + +module_init(br2684_init); +module_exit(br2684_exit); + +MODULE_AUTHOR("Marcell GAL"); +MODULE_DESCRIPTION("RFC2684 bridged protocols over ATM/AAL5"); +MODULE_LICENSE("GPL"); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/atm/common.c linux.19pre5-ac1/net/atm/common.c --- linux.19p5/net/atm/common.c Thu Apr 4 13:18:48 2002 +++ linux.19pre5-ac1/net/atm/common.c Tue Mar 26 18:51:18 2002 @@ -63,6 +63,13 @@ EXPORT_SYMBOL(pppoatm_ioctl_hook); #endif +#if defined(CONFIG_ATM_BR2684) || defined(CONFIG_ATM_BR2684_MODULE) +int (*br2684_ioctl_hook)(struct atm_vcc *, unsigned int, unsigned long); +#endif +#ifdef CONFIG_ATM_BR2684_MODULE +EXPORT_SYMBOL(br2684_ioctl_hook); +#endif + #include "resources.h" /* atm_find_dev */ #include "common.h" /* prototypes */ #include "protocols.h" /* atm_init_ */ @@ -785,6 +792,14 @@ goto done; } #endif +#if defined(CONFIG_ATM_BR2684) || defined(CONFIG_ATM_BR2684_MODULE) + if (br2684_ioctl_hook) { + ret_val = br2684_ioctl_hook(vcc, cmd, arg); + if (ret_val != -ENOIOCTLCMD) + goto done; + } +#endif + if (get_user(buf,&((struct atmif_sioc *) arg)->arg)) { ret_val = -EFAULT; goto done; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/atm/proc.c linux.19pre5-ac1/net/atm/proc.c --- linux.19p5/net/atm/proc.c Thu Apr 4 13:18:48 2002 +++ linux.19pre5-ac1/net/atm/proc.c Tue Mar 26 18:51:18 2002 @@ -551,9 +551,12 @@ digits = 0; for (num = dev->number; num; num /= 10) digits++; if (!digits) digits++; - dev->proc_name = kmalloc(strlen(dev->type)+digits+2,GFP_KERNEL); - if (!dev->proc_name) goto fail1; + + dev->proc_name = kmalloc(strlen(dev->type) + digits + 2, GFP_ATOMIC); + if (!dev->proc_name) + goto fail1; sprintf(dev->proc_name,"%s:%d",dev->type, dev->number); + dev->proc_entry = create_proc_entry(dev->proc_name, 0, atm_proc_root); if (!dev->proc_entry) goto fail0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/atm/resources.c linux.19pre5-ac1/net/atm/resources.c --- linux.19p5/net/atm/resources.c Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/net/atm/resources.c Tue Mar 26 18:51:21 2002 @@ -27,15 +27,14 @@ struct atm_vcc *nodev_vccs = NULL; extern spinlock_t atm_dev_lock; -/* Caller must hold atm_dev_lock. */ -static struct atm_dev *__alloc_atm_dev(const char *type) + +static struct atm_dev *alloc_atm_dev(const char *type) { struct atm_dev *dev; dev = kmalloc(sizeof(*dev), GFP_ATOMIC); - if (!dev) - return NULL; - memset(dev, 0, sizeof(*dev)); + if (!dev) return NULL; + memset(dev,0,sizeof(*dev)); dev->type = type; dev->signal = ATM_PHY_SIG_UNKNOWN; dev->link_rate = ATM_OC3_PCR; @@ -43,118 +42,100 @@ dev->prev = last_dev; - if (atm_devs) - last_dev->next = dev; - else - atm_devs = dev; + if (atm_devs) last_dev->next = dev; + else atm_devs = dev; last_dev = dev; - return dev; } -/* Caller must hold atm_dev_lock. */ -static void __free_atm_dev(struct atm_dev *dev) -{ - if (dev->prev) - dev->prev->next = dev->next; - else - atm_devs = dev->next; - - if (dev->next) - dev->next->prev = dev->prev; - else - last_dev = dev->prev; +static void free_atm_dev(struct atm_dev *dev) +{ + if (dev->prev) dev->prev->next = dev->next; + else atm_devs = dev->next; + if (dev->next) dev->next->prev = dev->prev; + else last_dev = dev->prev; kfree(dev); } -/* Caller must hold atm_dev_lock. */ struct atm_dev *atm_find_dev(int number) { struct atm_dev *dev; for (dev = atm_devs; dev; dev = dev->next) - if (dev->ops && dev->number == number) - return dev; + if (dev->ops && dev->number == number) return dev; return NULL; } -struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, - int number, atm_dev_flags_t *flags) +struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops, + int number,atm_dev_flags_t *flags) { - struct atm_dev *dev; + struct atm_dev *dev = NULL; spin_lock(&atm_dev_lock); - dev = __alloc_atm_dev(type); + dev = alloc_atm_dev(type); if (!dev) { printk(KERN_ERR "atm_dev_register: no space for dev %s\n", - type); + type); goto done; } if (number != -1) { if (atm_find_dev(number)) { - __free_atm_dev(dev); - dev = NULL; - goto done; + free_atm_dev(dev); + return NULL; } dev->number = number; } else { dev->number = 0; - while (atm_find_dev(dev->number)) - dev->number++; + while (atm_find_dev(dev->number)) dev->number++; } dev->vccs = dev->last = NULL; dev->dev_data = NULL; barrier(); dev->ops = ops; - if (flags) + if (flags) dev->flags = *flags; - else - memset(&dev->flags, 0, sizeof(dev->flags)); - memset(&dev->stats, 0, sizeof(dev->stats)); - + else + memset(&dev->flags,0,sizeof(dev->flags)); + memset((void *) &dev->stats,0,sizeof(dev->stats)); #ifdef CONFIG_PROC_FS - if (ops->proc_read) { + if (ops->proc_read) if (atm_proc_dev_register(dev) < 0) { printk(KERN_ERR "atm_dev_register: " - "atm_proc_dev_register failed for dev %s\n", - type); - __free_atm_dev(dev); - dev = NULL; + "atm_proc_dev_register failed for dev %s\n",type); + free_atm_dev(dev); goto done; } - } #endif done: - spin_unlock(&atm_dev_lock); - + spin_unlock(&atm_dev_lock); return dev; } + void atm_dev_deregister(struct atm_dev *dev) { #ifdef CONFIG_PROC_FS - if (dev->ops->proc_read) - atm_proc_dev_deregister(dev); + if (dev->ops->proc_read) atm_proc_dev_deregister(dev); #endif spin_lock(&atm_dev_lock); - __free_atm_dev(dev); + free_atm_dev(dev); spin_unlock(&atm_dev_lock); } void shutdown_atm_dev(struct atm_dev *dev) { if (dev->vccs) { - set_bit(ATM_DF_CLOSE, &dev->flags); + set_bit(ATM_DF_CLOSE,&dev->flags); return; } - if (dev->ops->dev_close) - dev->ops->dev_close(dev); + if (dev->ops->dev_close) dev->ops->dev_close(dev); atm_dev_deregister(dev); } + /* Handler for sk->destruct, invoked by sk_free() */ static void atm_free_sock(struct sock *sk) { @@ -167,48 +148,44 @@ struct atm_vcc *vcc; sk = sk_alloc(family, GFP_KERNEL, 1); - if (!sk) - return NULL; + if (!sk) return NULL; vcc = sk->protinfo.af_atm = kmalloc(sizeof(*vcc),GFP_KERNEL); if (!vcc) { sk_free(sk); return NULL; } - sock_init_data(NULL, sk); + sock_init_data(NULL,sk); sk->destruct = atm_free_sock; memset(vcc,0,sizeof(*vcc)); vcc->sk = sk; - if (nodev_vccs) - nodev_vccs->prev = vcc; + if (nodev_vccs) nodev_vccs->prev = vcc; vcc->prev = NULL; vcc->next = nodev_vccs; nodev_vccs = vcc; return sk; } + static void unlink_vcc(struct atm_vcc *vcc,struct atm_dev *hold_dev) { - if (vcc->prev) - vcc->prev->next = vcc->next; - else if (vcc->dev) - vcc->dev->vccs = vcc->next; - else - nodev_vccs = vcc->next; - if (vcc->next) - vcc->next->prev = vcc->prev; - else if (vcc->dev) - vcc->dev->last = vcc->prev; + if (vcc->prev) vcc->prev->next = vcc->next; + else if (vcc->dev) vcc->dev->vccs = vcc->next; + else nodev_vccs = vcc->next; + if (vcc->next) vcc->next->prev = vcc->prev; + else if (vcc->dev) vcc->dev->last = vcc->prev; if (vcc->dev && vcc->dev != hold_dev && !vcc->dev->vccs && test_bit(ATM_DF_CLOSE,&vcc->dev->flags)) shutdown_atm_dev(vcc->dev); } + void free_atm_vcc_sk(struct sock *sk) { - unlink_vcc(sk->protinfo.af_atm, NULL); + unlink_vcc(sk->protinfo.af_atm,NULL); sk_free(sk); } + void bind_vcc(struct atm_vcc *vcc,struct atm_dev *dev) { unlink_vcc(vcc,dev); @@ -216,20 +193,19 @@ if (dev) { vcc->next = NULL; vcc->prev = dev->last; - if (dev->vccs) - dev->last->next = vcc; - else - dev->vccs = vcc; + if (dev->vccs) dev->last->next = vcc; + else dev->vccs = vcc; dev->last = vcc; - } else { - if (nodev_vccs) - nodev_vccs->prev = vcc; + } + else { + if (nodev_vccs) nodev_vccs->prev = vcc; vcc->next = nodev_vccs; vcc->prev = NULL; nodev_vccs = vcc; } } + EXPORT_SYMBOL(atm_dev_register); EXPORT_SYMBOL(atm_dev_deregister); EXPORT_SYMBOL(atm_find_dev); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/core/Makefile linux.19pre5-ac1/net/core/Makefile --- linux.19p5/net/core/Makefile Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/net/core/Makefile Wed Apr 3 00:39:40 2002 @@ -9,7 +9,7 @@ O_TARGET := core.o -export-objs := netfilter.o profile.o +export-objs := ext8022.o netfilter.o profile.o obj-y := sock.o skbuff.o iovec.o datagram.o scm.o @@ -23,6 +23,10 @@ obj-$(CONFIG_NET) += dev.o dev_mcast.o dst.o neighbour.o rtnetlink.o utils.o +ifneq ($(CONFIG_LLC),n) +obj-y += ext8022.o +endif + obj-$(CONFIG_NETFILTER) += netfilter.o obj-$(CONFIG_NET_DIVERT) += dv.o obj-$(CONFIG_NET_PROFILE) += profile.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/core/ext8022.c linux.19pre5-ac1/net/core/ext8022.c --- linux.19p5/net/core/ext8022.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/net/core/ext8022.c Tue Mar 19 19:15:34 2002 @@ -0,0 +1,76 @@ +/* + * (ext8022.c) + * + * Copyright (c) 1997 by Procom Technology, Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +#include +#include +#include +#include + +typedef int (*func_type)(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt); +static int llc_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *); + +static func_type llc_sap_table[128]; +static int llc_users; + +static struct packet_type llc_packet_type = { + type: __constant_htons(ETH_P_802_2), + func: llc_rcv, +}; +static struct packet_type llc_tr_packet_type = { + type: __constant_htons(ETH_P_TR_802_2), + func: llc_rcv, +}; + +static int llc_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt) +{ + unsigned char n = (*(skb->h.raw)) >> 1; + + br_read_lock(BR_LLC_LOCK); + if (llc_sap_table[n]) + llc_sap_table[n](skb, dev, pt); + else + kfree_skb(skb); + br_read_unlock(BR_LLC_LOCK); + return 0; +} + +void llc_register_sap(unsigned char sap, func_type rcvfunc) +{ + sap >>= 1; + br_write_lock_bh(BR_LLC_LOCK); + llc_sap_table[sap] = rcvfunc; + if (!llc_users) { + dev_add_pack(&llc_packet_type); + dev_add_pack(&llc_tr_packet_type); + } + llc_users++; + br_write_unlock_bh(BR_LLC_LOCK); +} + +void llc_unregister_sap(unsigned char sap) +{ + sap >>= 1; + br_write_lock_bh(BR_LLC_LOCK); + llc_sap_table[sap] = NULL; + if (!--llc_users) { + dev_remove_pack(&llc_packet_type); + dev_remove_pack(&llc_tr_packet_type); + } + br_write_unlock_bh(BR_LLC_LOCK); +} + +EXPORT_SYMBOL(llc_register_sap); +EXPORT_SYMBOL(llc_unregister_sap); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/ipv4/route.c linux.19pre5-ac1/net/ipv4/route.c --- linux.19p5/net/ipv4/route.c Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/net/ipv4/route.c Thu Apr 4 14:07:08 2002 @@ -2487,9 +2487,10 @@ if (!rt_hash_table) panic("Failed to allocate IP route cache hash table\n"); - printk(KERN_INFO "IP: routing cache hash table of %u buckets, %ldKbytes\n", - rt_hash_mask, - (long) (rt_hash_mask * sizeof(struct rt_hash_bucket)) / 1024); + printk(KERN_INFO "IP: routing cache hash table of" + " %u buckets, %ldKbytes\n", + rt_hash_mask, + (long) (rt_hash_mask * sizeof(struct rt_hash_bucket)) / 1024); for (rt_hash_log = 0; (1 << rt_hash_log) != rt_hash_mask; rt_hash_log++) /* NOTHING */; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/ipv4/tcp_output.c linux.19pre5-ac1/net/ipv4/tcp_output.c --- linux.19p5/net/ipv4/tcp_output.c Thu Apr 4 13:21:17 2002 +++ linux.19pre5-ac1/net/ipv4/tcp_output.c Thu Apr 4 14:08:09 2002 @@ -1010,8 +1010,7 @@ skb = alloc_skb(MAX_TCP_HEADER, GFP_KERNEL); if (skb) break; - current->policy |= SCHED_YIELD; - schedule(); + yield(); } /* Reserve space for headers and prepare control bits. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/Makefile linux.19pre5-ac1/net/llc/Makefile --- linux.19p5/net/llc/Makefile Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/net/llc/Makefile Tue Mar 19 19:15:34 2002 @@ -0,0 +1,38 @@ +########################################################################### +# Makefile for the Linux 802.2 LLC (fully-functional) layer. +# +# Note 1! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definition is now in the main makefile... +# +# Copyright (c) 1997 by Procom Technology,Inc. +# 2001 by Arnaldo Carvalho de Melo +# +# This program can be redistributed or modified under the terms of the +# GNU General Public License as published by the Free Software Foundation. +# This program is distributed without any warranty or implied warranty +# of merchantability or fitness for a particular purpose. +# +# See the GNU General Public License for more details. +########################################################################### + +O_TARGET := llc.o + +obj-y := llc_if.o llc_c_ev.o llc_c_ac.o llc_mac.o llc_sap.o llc_s_st.o \ + llc_main.o llc_s_ac.o llc_conn.o llc_c_st.o llc_stat.o llc_actn.o \ + llc_s_ev.o llc_evnt.o llc_pdu.o + +ifeq ($(CONFIG_LLC_UI),y) + obj-y += llc_sock.o +endif + +# Objects that export symbols. +export-objs := llc_if.o + +ifeq ($(CONFIG_LLC),m) + obj-m += $(O_TARGET) +endif + +include $(TOPDIR)/Rules.make diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_actn.c linux.19pre5-ac1/net/llc/llc_actn.c --- linux.19p5/net/llc/llc_actn.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/net/llc/llc_actn.c Tue Mar 19 19:15:34 2002 @@ -0,0 +1,147 @@ +/* + * llc_actn.c - Implementation of actions of station component of LLC + * + * Description : + * Functions in this module are implementation of station component actions. + * Details of actions can be found in IEEE-802.2 standard document. + * All functions have one station and one event as input argument. All of + * them return 0 On success and 1 otherwise. + * + * Copyright (c) 1997 by Procom Technology, Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include + +static void llc_station_ack_tmr_callback(unsigned long timeout_data); + +int llc_station_ac_start_ack_timer(struct llc_station *station, + struct llc_station_state_ev *ev) +{ + del_timer(&station->ack_timer); + station->ack_timer.expires = jiffies + LLC_ACK_TIME * HZ; + station->ack_timer.data = (unsigned long)station; + station->ack_timer.function = llc_station_ack_tmr_callback; + add_timer(&station->ack_timer); + station->ack_tmr_running = 1; + return 0; +} + +int llc_station_ac_set_retry_cnt_0(struct llc_station *station, + struct llc_station_state_ev *ev) +{ + station->retry_count = 0; + return 0; +} + +int llc_station_ac_inc_retry_cnt_by_1(struct llc_station *station, + struct llc_station_state_ev *ev) +{ + station->retry_count++; + return 0; +} + +int llc_station_ac_set_xid_r_cnt_0(struct llc_station *station, + struct llc_station_state_ev *ev) +{ + station->xid_r_count = 0; + return 0; +} + +int llc_station_ac_inc_xid_r_cnt_by_1(struct llc_station *station, + struct llc_station_state_ev *ev) +{ + station->xid_r_count++; + return 0; +} + +int llc_station_ac_send_null_dsap_xid_c(struct llc_station *station, + struct llc_station_state_ev *ev) +{ + int rc = 1; + struct sk_buff *skb = llc_alloc_frame(); + + if (!skb) + goto out; + rc = 0; + llc_pdu_header_init(skb, LLC_PDU_TYPE_U, 0, 0, LLC_PDU_CMD); + llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 127); + lan_hdrs_init(skb, station->mac_sa, station->mac_sa); + llc_station_send_pdu(station, skb); +out: return rc; +} + +int llc_station_ac_send_xid_r(struct llc_station *station, + struct llc_station_state_ev *ev) +{ + u8 mac_da[ETH_ALEN], dsap; + int rc = 1; + struct sk_buff *ev_skb; + struct sk_buff* skb = llc_alloc_frame(); + + if (!skb) + goto out; + rc = 0; + ev_skb = ev->data.pdu.skb; + skb->dev = ev_skb->dev; + llc_pdu_decode_sa(ev_skb, mac_da); + llc_pdu_decode_ssap(ev_skb, &dsap); + llc_pdu_header_init(skb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP); + llc_pdu_init_as_xid_rsp(skb, LLC_XID_NULL_CLASS_2, 127); + lan_hdrs_init(skb, station->mac_sa, mac_da); + llc_station_send_pdu(station, skb); +out: return rc; +} + +int llc_station_ac_send_test_r(struct llc_station *station, + struct llc_station_state_ev *ev) +{ + u8 mac_da[ETH_ALEN], dsap; + int rc = 1; + struct sk_buff *ev_skb; + struct sk_buff *skb = llc_alloc_frame(); + + if (!skb) + goto out; + rc = 0; + ev_skb = ev->data.pdu.skb; + skb->dev = ev_skb->dev; + llc_pdu_decode_sa(ev_skb, mac_da); + llc_pdu_decode_ssap(ev_skb, &dsap); + llc_pdu_header_init(skb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP); + llc_pdu_init_as_test_rsp(skb, ev_skb); + lan_hdrs_init(skb, station->mac_sa, mac_da); + llc_station_send_pdu(station, skb); +out: return rc; +} + +int llc_station_ac_report_status(struct llc_station *station, + struct llc_station_state_ev *ev) +{ + return 0; +} + +static void llc_station_ack_tmr_callback(unsigned long timeout_data) +{ + struct llc_station *station = (struct llc_station *)timeout_data; + struct llc_station_state_ev *ev; + + station->ack_tmr_running = 0; + ev = llc_station_alloc_ev(station); + if (ev) { + ev->type = LLC_STATION_EV_TYPE_ACK_TMR; + ev->data.tmr.timer_specific = NULL; + llc_station_send_ev(station, ev); + } +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_c_ac.c linux.19pre5-ac1/net/llc/llc_c_ac.c --- linux.19p5/net/llc/llc_c_ac.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/net/llc/llc_c_ac.c Tue Mar 19 19:15:34 2002 @@ -0,0 +1,1645 @@ +/* + * llc_c_ac.c - actions performed during connection state transition. + * + * Description: + * Functions in this module are implementation of connection component actions + * Details of actions can be found in IEEE-802.2 standard document. + * All functions have one connection and one event as input argument. All of + * them return 0 On success and 1 otherwise. + * + * Copyright (c) 1997 by Procom Technology, Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data); +static void llc_conn_ack_tmr_cb(unsigned long timeout_data); +static void llc_conn_rej_tmr_cb(unsigned long timeout_data); +static void llc_conn_busy_tmr_cb(unsigned long timeout_data); +static int llc_conn_ac_inc_vs_by_1(struct sock *sk, + struct llc_conn_state_ev *ev); +static void llc_process_tmr_ev(struct sock *sk, struct llc_conn_state_ev *ev); +static int llc_conn_ac_data_confirm(struct sock *sk, + struct llc_conn_state_ev *ev); + +#define INCORRECT 0 + +int llc_conn_ac_clear_remote_busy(struct sock *sk, struct llc_conn_state_ev *ev) +{ + struct llc_opt *llc = llc_sk(sk); + + if (llc->remote_busy_flag) { + u8 nr; + llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + llc->remote_busy_flag = 0; + del_timer(&llc->busy_state_timer.timer); + llc->busy_state_timer.running = 0; + nr = LLC_I_GET_NR(rx_pdu); + llc_conn_resend_i_pdu_as_cmd(sk, nr, 0); + } + return 0; +} + +int llc_conn_ac_conn_ind(struct sock *sk, struct llc_conn_state_ev *ev) +{ + int rc = 1; + struct sk_buff *skb = ev->data.pdu.skb; + union llc_u_prim_data *prim_data = llc_ind_prim.data; + struct llc_prim_if_block *prim = &llc_ind_prim; + struct llc_sap *sap; + struct llc_opt *llc = llc_sk(sk); + + llc_pdu_decode_dsap(skb, &prim_data->conn.daddr.lsap); + sap = llc_sap_find(prim_data->conn.daddr.lsap); + if (sap) { + llc_pdu_decode_sa(skb, llc->daddr.mac); + llc_pdu_decode_da(skb, llc->laddr.mac); + llc->dev = skb->dev; + prim_data->conn.pri = 0; + prim_data->conn.sk = sk; + prim_data->conn.dev = skb->dev; + memcpy(&prim_data->conn.daddr, &llc->laddr, sizeof(llc->laddr)); + memcpy(&prim_data->conn.saddr, &llc->daddr, sizeof(llc->daddr)); + prim->data = prim_data; + prim->prim = LLC_CONN_PRIM; + prim->sap = llc->sap; + ev->flag = 1; + ev->ind_prim = prim; + rc = 0; + } + return rc; +} + +int llc_conn_ac_conn_confirm(struct sock *sk, struct llc_conn_state_ev *ev) +{ + union llc_u_prim_data *prim_data = llc_cfm_prim.data; + struct sk_buff *skb = ev->data.pdu.skb; + /* FIXME: wtf, this is global, so the whole thing is really non + * reentrant... */ + struct llc_prim_if_block *prim = &llc_cfm_prim; + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + + prim_data->conn.sk = sk; + prim_data->conn.pri = 0; + prim_data->conn.status = ev->status; + prim_data->conn.link = llc->link; + if (skb) + prim_data->conn.dev = skb->dev; + else + printk(KERN_ERR __FUNCTION__ "ev->data.pdu.skb == NULL\n"); + prim->data = prim_data; + prim->prim = LLC_CONN_PRIM; + prim->sap = sap; + ev->flag = 1; + ev->cfm_prim = prim; + return 0; +} + +static int llc_conn_ac_data_confirm(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + struct llc_prim_if_block *prim = &llc_cfm_prim; + union llc_u_prim_data *prim_data = llc_cfm_prim.data; + + prim_data->data.sk = sk; + prim_data->data.pri = 0; + prim_data->data.link = llc_sk(sk)->link; + prim_data->data.status = LLC_STATUS_RECEIVED; + prim_data->data.skb = NULL; + prim->data = prim_data; + prim->prim = LLC_DATA_PRIM; + prim->sap = llc_sk(sk)->sap; + ev->flag = 1; + ev->cfm_prim = prim; + return 0; +} + +int llc_conn_ac_data_ind(struct sock *sk, struct llc_conn_state_ev *ev) +{ + llc_conn_rtn_pdu(sk, ev->data.pdu.skb, ev); + return 0; +} + +int llc_conn_ac_disc_ind(struct sock *sk, struct llc_conn_state_ev *ev) +{ + u8 reason = 0; + int rc = 1; + union llc_u_prim_data *prim_data = llc_ind_prim.data; + struct llc_prim_if_block *prim = &llc_ind_prim; + + if (ev->type == LLC_CONN_EV_TYPE_PDU) { + llc_pdu_un_t *rx_pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw; + + if (!LLC_PDU_IS_RSP(rx_pdu) && + !LLC_PDU_TYPE_IS_U(rx_pdu) && + LLC_U_PDU_RSP(rx_pdu) == LLC_2_PDU_RSP_DM) { + reason = LLC_DISC_REASON_RX_DM_RSP_PDU; + rc = 0; + } else if (!LLC_PDU_IS_CMD(rx_pdu) && + !LLC_PDU_TYPE_IS_U(rx_pdu) && + LLC_U_PDU_CMD(rx_pdu) == LLC_2_PDU_CMD_DISC) { + reason = LLC_DISC_REASON_RX_DISC_CMD_PDU; + rc = 0; + } + } else if (ev->type == LLC_CONN_EV_TYPE_ACK_TMR) { + reason = LLC_DISC_REASON_ACK_TMR_EXP; + rc = 0; + } else { + reason = 0; + rc = 1; + } + if (!rc) { + prim_data->disc.sk = sk; + prim_data->disc.reason = reason; + prim_data->disc.link = llc_sk(sk)->link; + prim->data = prim_data; + prim->prim = LLC_DISC_PRIM; + prim->sap = llc_sk(sk)->sap; + ev->flag = 1; + ev->ind_prim = prim; + } + return rc; +} + +int llc_conn_ac_disc_confirm(struct sock *sk, struct llc_conn_state_ev *ev) +{ + union llc_u_prim_data *prim_data = llc_cfm_prim.data; + struct llc_prim_if_block *prim = &llc_cfm_prim; + + prim_data->disc.sk = sk; + prim_data->disc.reason = ev->status; + prim_data->disc.link = llc_sk(sk)->link; + prim->data = prim_data; + prim->prim = LLC_DISC_PRIM; + prim->sap = llc_sk(sk)->sap; + ev->flag = 1; + ev->cfm_prim = prim; + return 0; +} + +int llc_conn_ac_rst_ind(struct sock *sk, struct llc_conn_state_ev *ev) +{ + u8 reason = 0; + int rc = 1; + llc_pdu_un_t *rx_pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw; + union llc_u_prim_data *prim_data = llc_ind_prim.data; + struct llc_prim_if_block *prim = &llc_ind_prim; + struct llc_opt *llc = llc_sk(sk); + + switch (ev->type) { + case LLC_CONN_EV_TYPE_PDU: + if (!LLC_PDU_IS_RSP(rx_pdu) && + !LLC_PDU_TYPE_IS_U(rx_pdu) && + LLC_U_PDU_RSP(rx_pdu) == LLC_2_PDU_RSP_FRMR) { + reason = LLC_RESET_REASON_LOCAL; + rc = 0; + } else if (!LLC_PDU_IS_CMD(rx_pdu) && + !LLC_PDU_TYPE_IS_U(rx_pdu) && + LLC_U_PDU_CMD(rx_pdu) == + LLC_2_PDU_CMD_SABME) { + reason = LLC_RESET_REASON_REMOTE; + rc = 0; + } else { + reason = 0; + rc = 1; + } + break; + case LLC_CONN_EV_TYPE_ACK_TMR: + case LLC_CONN_EV_TYPE_P_TMR: + case LLC_CONN_EV_TYPE_REJ_TMR: + case LLC_CONN_EV_TYPE_BUSY_TMR: + if (llc->retry_count > llc->n2) { + reason = LLC_RESET_REASON_LOCAL; + rc = 0; + } else + rc = 1; + break; + } + if (!rc) { + prim_data->res.sk = sk; + prim_data->res.reason = reason; + prim_data->res.link = llc->link; + prim->data = prim_data; + prim->prim = LLC_RESET_PRIM; + prim->sap = llc->sap; + ev->flag = 1; + ev->ind_prim = prim; + } + return rc; +} + +int llc_conn_ac_rst_confirm(struct sock *sk, struct llc_conn_state_ev *ev) +{ + union llc_u_prim_data *prim_data = llc_cfm_prim.data; + struct llc_prim_if_block *prim = &llc_cfm_prim; + + prim_data->res.sk = sk; + prim_data->res.link = llc_sk(sk)->link; + prim->data = prim_data; + prim->prim = LLC_RESET_PRIM; + prim->sap = llc_sk(sk)->sap; + ev->flag = 1; + ev->cfm_prim = prim; + return 0; +} + +int llc_conn_ac_report_status(struct sock *sk, struct llc_conn_state_ev *ev) +{ + return 0; +} + +int llc_conn_ac_clear_remote_busy_if_f_eq_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + if (!LLC_PDU_IS_RSP(rx_pdu) && + !LLC_PDU_TYPE_IS_I(rx_pdu) && + !LLC_I_PF_IS_1(rx_pdu) && llc_sk(sk)->ack_pf) + llc_conn_ac_clear_remote_busy(sk, ev); + return 0; +} + +int llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + if (llc_sk(sk)->data_flag == 2) { + del_timer(&llc_sk(sk)->rej_sent_timer.timer); + llc_sk(sk)->rej_sent_timer.running = 0; + } + return 0; +} + +int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + int rc = 1; + struct sk_buff *skb = llc_alloc_frame(); + + if (skb) { + u8 p_bit = 1; + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + + skb->dev = llc->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_CMD); + llc_pdu_init_as_disc_cmd(skb, p_bit); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + llc_conn_ac_set_p_flag_1(sk, ev); + return rc; +} + +int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + int rc = 1; + struct sk_buff *skb = llc_alloc_frame(); + + if (skb) { + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + struct sk_buff *rx_skb = ev->data.pdu.skb; + u8 f_bit; + + skb->dev = llc->dev; + llc_pdu_decode_pf_bit(rx_skb, &f_bit); + llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_RSP); + llc_pdu_init_as_dm_rsp(skb, f_bit); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + return rc; +} + +int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + int rc = 1; + struct sk_buff *skb = llc_alloc_frame(); + + if (skb) { + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + u8 f_bit = 1; + + skb->dev = llc->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_RSP); + llc_pdu_init_as_dm_rsp(skb, f_bit); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + return rc; +} + +int llc_conn_ac_send_dm_rsp_f_set_f_flag(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + int rc = 1; + struct sk_buff *skb = llc_alloc_frame(); + + if (skb) { + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + u8 f_bit = llc->f_flag; + + skb->dev = llc->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_RSP); + llc_pdu_init_as_dm_rsp(skb, f_bit); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + return rc; +} + +int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + u8 f_bit; + int rc = 1; + struct sk_buff *skb, *ev_skb = ev->data.pdu.skb; + llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev_skb->nh.raw; + struct llc_opt *llc = llc_sk(sk); + + llc->rx_pdu_hdr = (u32)*((u32 *)rx_pdu); + if (!LLC_PDU_IS_CMD(rx_pdu)) + llc_pdu_decode_pf_bit(ev_skb, &f_bit); + else + f_bit = 0; + skb = llc_alloc_frame(); + if (skb) { + struct llc_sap *sap = llc->sap; + + skb->dev = llc->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_RSP); + llc_pdu_init_as_frmr_rsp(skb, rx_pdu, f_bit, llc->vS, + llc->vR, INCORRECT); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + return rc; +} + +int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + int rc = 1; + struct sk_buff *skb = llc_alloc_frame(); + + if (skb) { + u8 f_bit = 0; + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)&llc->rx_pdu_hdr; + + skb->dev = llc->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_RSP); + llc_pdu_init_as_frmr_rsp(skb, rx_pdu, f_bit, llc->vS, + llc->vR, INCORRECT); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + return rc; +} + +int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + u8 f_bit; + int rc = 1; + struct sk_buff *skb; + + llc_pdu_decode_pf_bit(ev->data.pdu.skb, &f_bit); + skb = llc_alloc_frame(); + if (skb) { + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + skb->dev = llc->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_RSP); + llc_pdu_init_as_frmr_rsp(skb, rx_pdu, f_bit, llc->vS, + llc->vR, INCORRECT); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + return rc; +} + +int llc_conn_ac_send_i_cmd_p_set_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + u8 p_bit = 1; + struct sk_buff *skb = ev->data.prim.data->data->data.skb; + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + + llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_CMD); + llc_pdu_init_as_i_cmd(skb, p_bit, llc->vS, llc->vR); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + llc_conn_send_pdu(sk, skb); + llc_conn_ac_inc_vs_by_1(sk, ev); + return 0; +} + +int llc_conn_ac_send_i_cmd_p_set_0(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + u8 p_bit = 0; + struct sk_buff *skb = ev->data.prim.data->data->data.skb; + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + + llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_CMD); + llc_pdu_init_as_i_cmd(skb, p_bit, llc->vS, llc->vR); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + llc_conn_send_pdu(sk, skb); + llc_conn_ac_inc_vs_by_1(sk, ev); + return 0; +} + +int llc_conn_ac_resend_i_cmd_p_set_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + u8 nr = LLC_I_GET_NR(rx_pdu); + + llc_conn_resend_i_pdu_as_cmd(sk, nr, 1); + return 0; +} + +int llc_conn_ac_resend_i_cmd_p_set_1_or_send_rr(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + u8 nr = LLC_I_GET_NR(rx_pdu); + int rc = llc_conn_ac_send_rr_cmd_p_set_1(sk, ev); + + if (!rc) + llc_conn_resend_i_pdu_as_cmd(sk, nr, 0); + return rc; +} + +int llc_conn_ac_send_i_xxx_x_set_0(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + u8 p_bit = 0; + struct sk_buff *skb = ev->data.prim.data->data->data.skb; + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + + llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_CMD); + llc_pdu_init_as_i_cmd(skb, p_bit, llc->vS, llc->vR); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + llc_conn_send_pdu(sk, skb); + llc_conn_ac_inc_vs_by_1(sk, ev); + return 0; +} + +int llc_conn_ac_resend_i_xxx_x_set_0(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + u8 nr = LLC_I_GET_NR(rx_pdu); + + llc_conn_resend_i_pdu_as_cmd(sk, nr, 0); + return 0; +} + +int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + u8 nr; + u8 f_bit = 0; + llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + int rc = 1; + struct sk_buff *skb = llc_alloc_frame(); + + if (skb) { + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + + skb->dev = llc->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_RSP); + llc_pdu_init_as_rr_rsp(skb, f_bit, llc->vR); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + if (rc) { + nr = LLC_I_GET_NR(rx_pdu); + rc = 0; + llc_conn_resend_i_pdu_as_cmd(sk, nr, f_bit); + } + return rc; +} + +int llc_conn_ac_resend_i_rsp_f_set_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + u8 nr = LLC_I_GET_NR(rx_pdu); + + llc_conn_resend_i_pdu_as_rsp(sk, nr, 1); + return 0; +} + +int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + int rc = 1; + struct sk_buff *skb = llc_alloc_frame(); + + if (skb) { + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + u8 p_bit = 1; + + skb->dev = llc->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_CMD); + llc_pdu_init_as_rej_cmd(skb, p_bit, llc->vR); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + return rc; +} + +int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + int rc = 1; + struct sk_buff *skb = llc_alloc_frame(); + + if (skb) { + u8 f_bit = 1; + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + + skb->dev = llc->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_RSP); + llc_pdu_init_as_rej_rsp(skb, f_bit, llc->vR); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + return rc; +} + +int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + int rc = 1; + struct sk_buff *skb = llc_alloc_frame(); + + if (skb) { + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + u8 f_bit = 0; + + skb->dev = llc->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_RSP); + llc_pdu_init_as_rej_rsp(skb, f_bit, llc->vR); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + return rc; +} + +int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + int rc = 1; + struct sk_buff *skb = llc_alloc_frame(); + + if (skb) { + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + u8 p_bit = 1; + + skb->dev = llc->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_CMD); + llc_pdu_init_as_rnr_cmd(skb, p_bit, llc->vR); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + return rc; +} + +int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + int rc = 1; + struct sk_buff *skb = llc_alloc_frame(); + + if (skb) { + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + u8 f_bit = 1; + + skb->dev = llc->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_RSP); + llc_pdu_init_as_rnr_rsp(skb, f_bit, llc->vR); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + return rc; +} + +int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + int rc = 1; + struct sk_buff *skb = llc_alloc_frame(); + + if (skb) { + u8 f_bit = 0; + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + + skb->dev = llc->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_RSP); + llc_pdu_init_as_rnr_rsp(skb, f_bit, llc->vR); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + return rc; +} + +int llc_conn_ac_set_remote_busy(struct sock *sk, struct llc_conn_state_ev *ev) +{ + struct llc_opt *llc = llc_sk(sk); + + if (!llc->remote_busy_flag) { + llc->remote_busy_flag = 1; + llc->busy_state_timer.timer.expires = jiffies + + llc->busy_state_timer.expire * HZ; + llc->busy_state_timer.timer.data = (unsigned long)sk; + llc->busy_state_timer.timer.function = llc_conn_busy_tmr_cb; + add_timer(&llc->busy_state_timer.timer); + llc->busy_state_timer.running = 1; + } + return 0; +} + +int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + int rc = 1; + struct sk_buff *skb = llc_alloc_frame(); + + if (skb) { + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + u8 f_bit = 0; + + skb->dev = llc->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_RSP); + llc_pdu_init_as_rnr_rsp(skb, f_bit, llc->vR); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + return rc; +} + +int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + int rc = 1; + struct sk_buff *skb = llc_alloc_frame(); + + if (skb) { + u8 p_bit = 1; + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + + skb->dev = llc->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_CMD); + llc_pdu_init_as_rr_cmd(skb, p_bit, llc->vR); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + return rc; +} + +int llc_conn_ac_send_ack_cmd_p_set_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + int rc = 1; + struct sk_buff *skb = llc_alloc_frame(); + + if (skb) { + u8 p_bit = 1; + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + + skb->dev = llc->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_CMD); + llc_pdu_init_as_rr_cmd(skb, p_bit, llc->vR); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + return rc; +} + +int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + int rc = 1; + struct sk_buff *skb = llc_alloc_frame(); + + if (skb) { + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + u8 f_bit = 1; + + skb->dev = llc->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_RSP); + llc_pdu_init_as_rr_rsp(skb, f_bit, llc->vR); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + return rc; +} + +int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + int rc = 1; + struct sk_buff *skb = llc_alloc_frame(); + + if (skb) { + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + u8 f_bit = 1; + + skb->dev = llc->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_RSP); + llc_pdu_init_as_rr_rsp(skb, f_bit, llc->vR); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + return rc; +} + +int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + int rc = 1; + struct sk_buff *skb = llc_alloc_frame(); + + if (skb) { + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + u8 f_bit = 0; + + skb->dev = llc->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_RSP); + llc_pdu_init_as_rr_rsp(skb, f_bit, llc->vR); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + return rc; +} + +int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + int rc = 1; + struct sk_buff *skb = llc_alloc_frame(); + + if (skb) { + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + u8 f_bit = 0; + + skb->dev = llc->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_RSP); + llc_pdu_init_as_rr_rsp(skb, f_bit, llc->vR); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + return rc; +} + +int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + int rc = 1; + struct sk_buff *skb = llc_alloc_frame(); + struct llc_opt *llc = llc_sk(sk); + u8 p_bit = 1; + + if (skb) { + struct llc_sap *sap = llc->sap; + u8 *dmac = llc->daddr.mac; + + if (llc->dev->flags & IFF_LOOPBACK) + dmac = llc->dev->dev_addr; + skb->dev = llc->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_CMD); + llc_pdu_init_as_sabme_cmd(skb, p_bit); + lan_hdrs_init(skb, llc->dev->dev_addr, dmac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + llc->p_flag = p_bit; + return rc; +} + +int llc_conn_ac_send_ua_rsp_f_set_f_flag(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + int rc = 1; + struct sk_buff *skb = llc_alloc_frame(); + + if (skb) { + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + u8 f_bit = llc->f_flag; + + skb->dev = llc->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_RSP); + llc_pdu_init_as_ua_rsp(skb, f_bit); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + return rc; +} + +int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + u8 f_bit; + int rc = 1; + struct sk_buff *rx_skb = ev->data.pdu.skb; + struct sk_buff *skb; + + llc_pdu_decode_pf_bit(rx_skb, &f_bit); + skb = llc_alloc_frame(); + if (skb) { + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + + skb->dev = llc->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_RSP); + llc_pdu_init_as_ua_rsp(skb, f_bit); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + return rc; +} + +int llc_conn_ac_set_s_flag_0(struct sock *sk, struct llc_conn_state_ev *ev) +{ + llc_sk(sk)->s_flag = 0; + return 0; +} + +int llc_conn_ac_set_s_flag_1(struct sock *sk, struct llc_conn_state_ev *ev) +{ + llc_sk(sk)->s_flag = 1; + return 0; +} + +int llc_conn_ac_start_p_timer(struct sock *sk, struct llc_conn_state_ev *ev) +{ + struct llc_opt *llc = llc_sk(sk); + + llc->p_flag = 1; + del_timer(&llc->pf_cycle_timer.timer); + llc->pf_cycle_timer.timer.expires = jiffies + + llc->pf_cycle_timer.expire * HZ; + llc->pf_cycle_timer.timer.data = (unsigned long)sk; + llc->pf_cycle_timer.timer.function = llc_conn_pf_cycle_tmr_cb; + add_timer(&llc->pf_cycle_timer.timer); + llc->pf_cycle_timer.running = 1; + return 0; +} + +/** + * llc_conn_ac_send_ack_if_needed - check if ack is needed + * @sk: current connection structure + * @ev: current event + * + * Checks number of received PDUs which have not been acknowledged, yet, + * If number of them reaches to "npta"(Number of PDUs To Acknowledge) then + * sends an RR response as acknowledgement for them. Returns 0 for + * success, 1 otherwise. + */ +int llc_conn_ac_send_ack_if_needed(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + u8 pf_bit; + struct sk_buff *skb = ev->data.pdu.skb; + struct llc_opt *llc = llc_sk(sk); + + llc_pdu_decode_pf_bit(skb, &pf_bit); + llc->ack_pf |= pf_bit & 1; + if (!llc->ack_must_be_send) { + llc->first_pdu_Ns = llc->vR; + llc->ack_must_be_send = 1; + llc->ack_pf = pf_bit & 1; + } + if (((llc->vR - llc->first_pdu_Ns + 129) % 128) >= llc->npta) { + llc_conn_ac_send_rr_rsp_f_set_ackpf(sk, ev); + llc->ack_must_be_send = 0; + llc->ack_pf = 0; + llc_conn_ac_inc_npta_value(sk, ev); + } + return 0; +} + +/** + * llc_conn_ac_rst_sendack_flag - resets ack_must_be_send flag + * @sk: current connection structure + * @ev: current event + * + * This action resets ack_must_be_send flag of given connection, this flag + * indicates if there is any PDU which has not been acknowledged yet. + * Returns 0 for success, 1 otherwise. + */ +int llc_conn_ac_rst_sendack_flag(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_sk(sk)->ack_must_be_send = llc_sk(sk)->ack_pf = 0; + return 0; +} + +/** + * llc_conn_ac_send_i_rsp_f_set_ackpf - acknowledge received PDUs + * @sk: current connection structure + * @ev: current event + * + * Sends an I response PDU with f-bit set to ack_pf flag as acknowledge to + * all received PDUs which have not been acknowledged, yet. ack_pf flag is + * set to one if one PDU with p-bit set to one is received. Returns 0 for + * success, 1 otherwise. + */ +int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + struct sk_buff *skb = ev->data.prim.data->data->data.skb; + struct llc_opt *llc = llc_sk(sk); + u8 p_bit = llc->ack_pf; + struct llc_sap *sap = llc->sap; + + llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_RSP); + llc_pdu_init_as_i_cmd(skb, p_bit, llc->vS, llc->vR); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + llc_conn_send_pdu(sk, skb); + llc_conn_ac_inc_vs_by_1(sk, ev); + return 0; +} + +/** + * llc_conn_ac_send_i_as_ack - sends an I-format PDU to acknowledge rx PDUs + * @sk: current connection structure. + * @ev: current event. + * + * This action sends an I-format PDU as acknowledge to received PDUs which + * have not been acknowledged, yet, if there is any. By using of this + * action number of acknowledgements decreases, this technic is called + * piggy backing. Returns 0 for success, 1 otherwise. + */ +int llc_conn_ac_send_i_as_ack(struct sock *sk, struct llc_conn_state_ev *ev) +{ + struct llc_opt *llc = llc_sk(sk); + + if (llc->ack_must_be_send) { + llc_conn_ac_send_i_rsp_f_set_ackpf(sk, ev); + llc->ack_must_be_send = 0 ; + llc->ack_pf = 0; + } else + llc_conn_ac_send_i_cmd_p_set_0(sk, ev); + return 0; +} + +/** + * llc_conn_ac_send_rr_rsp_f_set_ackpf - ack all rx PDUs not yet acked + * @sk: current connection structure. + * @ev: current event. + * + * This action sends an RR response with f-bit set to ack_pf flag as + * acknowledge to all received PDUs which have not been acknowledged, yet, + * if there is any. ack_pf flag indicates if a PDU has been received with + * p-bit set to one. Returns 0 for success, 1 otherwise. + */ +int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + int rc = 1; + struct sk_buff *skb = llc_alloc_frame(); + + if (skb) { + struct llc_opt *llc = llc_sk(sk); + struct llc_sap *sap = llc->sap; + u8 f_bit = llc->ack_pf; + + skb->dev = llc->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap, + llc->daddr.lsap, LLC_PDU_RSP); + llc_pdu_init_as_rr_rsp(skb, f_bit, llc->vR); + lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); + rc = 0; + llc_conn_send_pdu(sk, skb); + } + return rc; +} + +/** + * llc_conn_ac_inc_npta_value - tries to make value of npta greater + * @sk: current connection structure. + * @ev: current event. + * + * After "inc_cntr" times calling of this action, "npta" increase by one. + * this action tries to make vale of "npta" greater as possible; number of + * acknowledgements decreases by increasing of "npta". Returns 0 for + * success, 1 otherwise. + */ +int llc_conn_ac_inc_npta_value(struct sock *sk, struct llc_conn_state_ev *ev) +{ + struct llc_opt *llc = llc_sk(sk); + + if (!llc->inc_cntr) { + llc->dec_step = 0; + llc->dec_cntr = llc->inc_cntr = 2; + ++llc->npta; + if (llc->npta > 127) + llc->npta = 127 ; + } else + --llc->inc_cntr; + return 0; +} + +/** + * llc_conn_ac_adjust_npta_by_rr - decreases "npta" by one + * @sk: current connection structure. + * @ev: current event. + * + * After receiving "dec_cntr" times RR command, this action decreases + * "npta" by one. Returns 0 for success, 1 otherwise. + */ +int llc_conn_ac_adjust_npta_by_rr(struct sock *sk, struct llc_conn_state_ev *ev) +{ + struct llc_opt *llc = llc_sk(sk); + + if (!llc->connect_step && !llc->remote_busy_flag) { + if (!llc->dec_step) { + if (!llc->dec_cntr) { + llc->inc_cntr = llc->dec_cntr = 2; + if (llc->npta > 0) + llc->npta = llc->npta - 1; + } else + llc->dec_cntr -=1; + } + } else + llc->connect_step = 0 ; + return 0; +} + +/** + * llc_conn_ac_adjust_npta_by_rnr - decreases "npta" by one + * @sk: current connection structure. + * @ev: current event. + * + * After receiving "dec_cntr" times RNR command, this action decreases + * "npta" by one. Returns 0 for success, 1 otherwise. + */ +int llc_conn_ac_adjust_npta_by_rnr(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + struct llc_opt *llc = llc_sk(sk); + + if (llc->remote_busy_flag) + if (!llc->dec_step) { + if (!llc->dec_cntr) { + llc->inc_cntr = llc->dec_cntr = 2; + if (llc->npta > 0) + --llc->npta; + } else + --llc->dec_cntr; + } + return 0; +} + +/** + * llc_conn_ac_dec_tx_win_size - decreases tx window size + * @sk: current connection structure. + * @ev: current event. + * + * After receiving of a REJ command or response, transmit window size is + * decreased by number of PDUs which are outstanding yet. Returns 0 for + * success, 1 otherwise. + */ +int llc_conn_ac_dec_tx_win_size(struct sock *sk, struct llc_conn_state_ev *ev) +{ + struct llc_opt *llc = llc_sk(sk); + u8 unacked_pdu = skb_queue_len(&llc->pdu_unack_q); + + llc->k -= unacked_pdu; + if (llc->k < 2) + llc->k = 2; + return 0; +} + +/** + * llc_conn_ac_inc_tx_win_size - tx window size is inc by 1 + * @sk: current connection structure. + * @ev: current event. + * + * After receiving an RR response with f-bit set to one, transmit window + * size is increased by one. Returns 0 for success, 1 otherwise. + */ +int llc_conn_ac_inc_tx_win_size(struct sock *sk, struct llc_conn_state_ev *ev) +{ + struct llc_opt *llc = llc_sk(sk); + + llc->k += 1; + if (llc->k > 128) + llc->k = 128 ; + return 0; +} + +int llc_conn_ac_stop_all_timers(struct sock *sk, struct llc_conn_state_ev *ev) +{ + struct llc_opt *llc = llc_sk(sk); + + del_timer(&llc->pf_cycle_timer.timer); + llc->pf_cycle_timer.running = 0; + del_timer(&llc->ack_timer.timer); + llc->ack_timer.running = 0; + del_timer(&llc->rej_sent_timer.timer); + llc->rej_sent_timer.running = 0; + del_timer(&llc->busy_state_timer.timer); + llc->busy_state_timer.running = 0; + llc->ack_must_be_send = 0; + llc->ack_pf = 0; + return 0; +} + +int llc_conn_ac_stop_other_timers(struct sock *sk, struct llc_conn_state_ev *ev) +{ + struct llc_opt *llc = llc_sk(sk); + + del_timer(&llc->rej_sent_timer.timer); + llc->rej_sent_timer.running = 0; + del_timer(&llc->pf_cycle_timer.timer); + llc->pf_cycle_timer.running = 0; + del_timer(&llc->busy_state_timer.timer); + llc->busy_state_timer.running = 0; + llc->ack_must_be_send = 0; + llc->ack_pf = 0; + return 0; +} + +int llc_conn_ac_start_ack_timer(struct sock *sk, struct llc_conn_state_ev *ev) +{ + struct llc_opt *llc = llc_sk(sk); + + del_timer(&llc->ack_timer.timer); + llc->ack_timer.timer.expires = jiffies + llc->ack_timer.expire * HZ; + llc->ack_timer.timer.data = (unsigned long)sk; + llc->ack_timer.timer.function = llc_conn_ack_tmr_cb; + add_timer(&llc->ack_timer.timer); + llc->ack_timer.running = 1; + return 0; +} + +int llc_conn_ac_start_rej_timer(struct sock *sk, struct llc_conn_state_ev *ev) +{ + struct llc_opt *llc = llc_sk(sk); + + del_timer(&llc->rej_sent_timer.timer); + llc->rej_sent_timer.timer.expires = jiffies + + llc->rej_sent_timer.expire * HZ; + llc->rej_sent_timer.timer.data = (unsigned long)sk; + llc->rej_sent_timer.timer.function = llc_conn_rej_tmr_cb; + add_timer(&llc->rej_sent_timer.timer); + llc->rej_sent_timer.running = 1; + return 0; +} + +int llc_conn_ac_start_ack_tmr_if_not_running(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + struct llc_opt *llc = llc_sk(sk); + + if (!llc->ack_timer.running) { + llc->ack_timer.timer.expires = jiffies + + llc->ack_timer.expire * HZ; + llc->ack_timer.timer.data = (unsigned long)sk; + llc->ack_timer.timer.function = llc_conn_ack_tmr_cb; + add_timer(&llc->ack_timer.timer); + llc->ack_timer.running = 1; + } + return 0; +} + +int llc_conn_ac_stop_ack_timer(struct sock *sk, struct llc_conn_state_ev *ev) +{ + del_timer(&llc_sk(sk)->ack_timer.timer); + llc_sk(sk)->ack_timer.running = 0; + return 0; +} + +int llc_conn_ac_stop_p_timer(struct sock *sk, struct llc_conn_state_ev *ev) +{ + struct llc_opt *llc = llc_sk(sk); + + del_timer(&llc->pf_cycle_timer.timer); + llc->pf_cycle_timer.running = 0; + llc->p_flag = 0; + return 0; +} + +int llc_conn_ac_stop_rej_timer(struct sock *sk, struct llc_conn_state_ev *ev) +{ + del_timer(&llc_sk(sk)->rej_sent_timer.timer); + llc_sk(sk)->rej_sent_timer.running = 0; + return 0; +} + +int llc_conn_ac_upd_nr_received(struct sock *sk, struct llc_conn_state_ev *ev) +{ + int acked; + u16 unacked = 0; + u8 fbit; + struct sk_buff *skb = ev->data.pdu.skb; + llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)skb->nh.raw; + struct llc_opt *llc = llc_sk(sk); + + llc->last_nr = PDU_SUPV_GET_Nr(rx_pdu); + acked = llc_conn_remove_acked_pdus(sk, llc->last_nr, &unacked); + /* On loopback we don't queue I frames in unack_pdu_q queue. */ + if (acked > 0 || (llc->dev->flags & IFF_LOOPBACK)) { + llc->retry_count = 0; + del_timer(&llc->ack_timer.timer); + llc->ack_timer.running = 0; + if (llc->failed_data_req) { + /* already, we did not accept data from upper + * layer(tx_window full or unacceptable state). now, we + * can send data and must inform to upper layer. */ + llc->failed_data_req = 0; + llc_conn_ac_data_confirm(sk, ev); + } + if (unacked) { + llc->ack_timer.timer.expires = jiffies + + llc->ack_timer.expire * HZ; + llc->ack_timer.timer.data = (unsigned long)sk; + llc->ack_timer.timer.function = llc_conn_ack_tmr_cb; + add_timer(&llc->ack_timer.timer); + llc->ack_timer.running = 1; + } + } else if (llc->failed_data_req) { + llc_pdu_decode_pf_bit(skb, &fbit); + if (fbit == 1) { + llc->failed_data_req = 0; + llc_conn_ac_data_confirm(sk, ev); + } + } + return 0; +} + +int llc_conn_ac_upd_p_flag(struct sock *sk, struct llc_conn_state_ev *ev) +{ + struct sk_buff *skb = ev->data.pdu.skb; + llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)skb->nh.raw; + u8 f_bit; + + if (!LLC_PDU_IS_RSP(rx_pdu) && + !llc_pdu_decode_pf_bit(skb, &f_bit) && f_bit) { + llc_sk(sk)->p_flag = 0; + llc_conn_ac_stop_p_timer(sk, ev); + } + return 0; +} + +int llc_conn_ac_set_data_flag_2(struct sock *sk, struct llc_conn_state_ev *ev) +{ + llc_sk(sk)->data_flag = 2; + return 0; +} + +int llc_conn_ac_set_data_flag_0(struct sock *sk, struct llc_conn_state_ev *ev) +{ + llc_sk(sk)->data_flag = 0; + return 0; +} + +int llc_conn_ac_set_data_flag_1(struct sock *sk, struct llc_conn_state_ev *ev) +{ + llc_sk(sk)->data_flag = 1; + return 0; +} + +int llc_conn_ac_set_data_flag_1_if_data_flag_eq_0(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + if (!llc_sk(sk)->data_flag) + llc_sk(sk)->data_flag = 1; + return 0; +} + +int llc_conn_ac_set_p_flag_0(struct sock *sk, struct llc_conn_state_ev *ev) +{ + llc_sk(sk)->p_flag = 0; + return 0; +} + +int llc_conn_ac_set_p_flag_1(struct sock *sk, struct llc_conn_state_ev *ev) +{ + llc_sk(sk)->p_flag = 1; + return 0; +} + +int llc_conn_ac_set_remote_busy_0(struct sock *sk, struct llc_conn_state_ev *ev) +{ + llc_sk(sk)->remote_busy_flag = 0; + return 0; +} + +int llc_conn_ac_set_cause_flag_0(struct sock *sk, struct llc_conn_state_ev *ev) +{ + llc_sk(sk)->cause_flag = 0; + return 0; +} + +int llc_conn_ac_set_cause_flag_1(struct sock *sk, struct llc_conn_state_ev *ev) +{ + llc_sk(sk)->cause_flag = 1; + return 0; +} + +int llc_conn_ac_set_retry_cnt_0(struct sock *sk, struct llc_conn_state_ev *ev) +{ + llc_sk(sk)->retry_count = 0; + return 0; +} + +int llc_conn_ac_inc_retry_cnt_by_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_sk(sk)->retry_count++; + return 0; +} + +int llc_conn_ac_set_vr_0(struct sock *sk, struct llc_conn_state_ev *ev) +{ + llc_sk(sk)->vR = 0; + return 0; +} + +int llc_conn_ac_inc_vr_by_1(struct sock *sk, struct llc_conn_state_ev *ev) +{ + llc_sk(sk)->vR = PDU_GET_NEXT_Vr(llc_sk(sk)->vR); + return 0; +} + +int llc_conn_ac_set_vs_0(struct sock *sk, struct llc_conn_state_ev *ev) +{ + llc_sk(sk)->vS = 0; + return 0; +} + +int llc_conn_ac_set_vs_nr(struct sock *sk, struct llc_conn_state_ev *ev) +{ + llc_sk(sk)->vS = llc_sk(sk)->last_nr; + return 0; +} + +int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct llc_conn_state_ev *ev) +{ + llc_sk(sk)->vS = (llc_sk(sk)->vS + 1) % 128; + return 0; +} + +int llc_conn_ac_set_f_flag_p(struct sock *sk, struct llc_conn_state_ev *ev) +{ + llc_pdu_decode_pf_bit(ev->data.pdu.skb, &llc_sk(sk)->f_flag); + return 0; +} + +void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data) +{ + struct sock *sk = (struct sock *)timeout_data; + struct llc_conn_state_ev *ev; + + llc_sk(sk)->pf_cycle_timer.running = 0; + ev = llc_conn_alloc_ev(sk); + if (ev) { + ev->type = LLC_CONN_EV_TYPE_P_TMR; + ev->data.tmr.timer_specific = NULL; + llc_process_tmr_ev(sk, ev); + } +} + +static void llc_conn_busy_tmr_cb(unsigned long timeout_data) +{ + struct sock *sk = (struct sock *)timeout_data; + struct llc_conn_state_ev *ev; + + llc_sk(sk)->busy_state_timer.running = 0; + ev = llc_conn_alloc_ev(sk); + if (ev) { + ev->type = LLC_CONN_EV_TYPE_BUSY_TMR; + ev->data.tmr.timer_specific = NULL; + llc_process_tmr_ev(sk, ev); + } +} + +void llc_conn_ack_tmr_cb(unsigned long timeout_data) +{ + struct sock* sk = (struct sock *)timeout_data; + struct llc_conn_state_ev *ev; + + llc_sk(sk)->ack_timer.running = 0; + ev = llc_conn_alloc_ev(sk); + if (ev) { + ev->type = LLC_CONN_EV_TYPE_ACK_TMR; + ev->data.tmr.timer_specific = NULL; + llc_process_tmr_ev(sk, ev); + } +} + +static void llc_conn_rej_tmr_cb(unsigned long timeout_data) +{ + struct sock *sk = (struct sock *)timeout_data; + struct llc_conn_state_ev *ev; + + llc_sk(sk)->rej_sent_timer.running = 0; + ev = llc_conn_alloc_ev(sk); + if (ev) { + ev->type = LLC_CONN_EV_TYPE_REJ_TMR; + ev->data.tmr.timer_specific = NULL; + llc_process_tmr_ev(sk, ev); + } +} + +int llc_conn_ac_rst_vs(struct sock *sk, struct llc_conn_state_ev *ev) +{ + llc_sk(sk)->X = llc_sk(sk)->vS; + llc_conn_ac_set_vs_nr(sk, ev); + return 0; +} + +int llc_conn_ac_upd_vs(struct sock *sk, struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + u8 nr = PDU_SUPV_GET_Nr(rx_pdu); + + if (llc_circular_between(llc_sk(sk)->vS, nr, llc_sk(sk)->X)) + llc_conn_ac_set_vs_nr(sk, ev); + return 0; +} + +/* + * Non-standard actions; these not contained in IEEE specification; for + * our own usage + */ +/** + * llc_conn_disc - removes connection from SAP list and frees it + * @sk: closed connection + * @ev: occurred event + * + * Returns 2, to indicate the state machine that the connection was freed. + */ +int llc_conn_disc(struct sock *sk, struct llc_conn_state_ev *ev) +{ + llc_sap_unassign_sock(llc_sk(sk)->sap, sk); + llc_sock_free(sk); + return 2; +} + +/** + * llc_conn_reset - resets connection + * @sk : reseting connection. + * @ev: occurred event. + * + * Stop all timers, empty all queues and reset all flags. + */ +int llc_conn_reset(struct sock *sk, struct llc_conn_state_ev *ev) +{ + llc_sock_reset(sk); + return 0; +} + +/** + * llc_circular_between - designates that b is between a and c or not + * @a: lower bound + * @b: element to see if is between a and b + * @c: upper bound + * + * This function designates that b is between a and c or not (for example, + * 0 is between 127 and 1). Returns 1 if b is between a and c, 0 + * otherwise. + */ +u8 llc_circular_between(u8 a, u8 b, u8 c) +{ + b = b - a; + c = c - a; + return b <= c; +} + +/** + * llc_process_tmr_ev - timer backend + * @sk: active connection + * @ev: occurred event + * + * This function is called from timer callback functions. When connection + * is busy (during sending a data frame) timer expiration event must be + * queued. Otherwise this event can be sent to connection state machine. + * Queued events will process by process_rxframes_events function after + * sending data frame. Returns 0 for success, 1 otherwise. + */ +static void llc_process_tmr_ev(struct sock *sk, struct llc_conn_state_ev *ev) +{ + bh_lock_sock(sk); + if (llc_sk(sk)->state == LLC_CONN_OUT_OF_SVC) { + printk(KERN_WARNING "timer called on closed connection\n"); + llc_conn_free_ev(ev); + goto out; + } + if (!sk->lock.users) + llc_conn_send_ev(sk, ev); + else { + struct sk_buff *skb = alloc_skb(1, GFP_ATOMIC); + + if (skb) { + skb->cb[0] = LLC_EVENT; + skb->data = (void *)ev; + sk_add_backlog(sk, skb); + } else + llc_conn_free_ev(ev); + } +out: bh_unlock_sock(sk); +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_c_ev.c linux.19pre5-ac1/net/llc/llc_c_ev.c --- linux.19p5/net/llc/llc_c_ev.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/net/llc/llc_c_ev.c Tue Mar 19 19:15:34 2002 @@ -0,0 +1,872 @@ +/* + * llc_c_ev.c - Connection component state transition event qualifiers + * + * A 'state' consists of a number of possible event matching functions, + * the actions associated with each being executed when that event is + * matched; a 'state machine' accepts events in a serial fashion from an + * event queue. Each event is passed to each successive event matching + * function until a match is made (the event matching function returns + * success, or '0') or the list of event matching functions is exhausted. + * If a match is made, the actions associated with the event are executed + * and the state is changed to that event's transition state. Before some + * events are recognized, even after a match has been made, a certain + * number of 'event qualifier' functions must also be executed. If these + * all execute successfully, then the event is finally executed. + * + * These event functions must return 0 for success, to show a matched + * event, of 1 if the event does not match. Event qualifier functions + * must return a 0 for success or a non-zero for failure. Each function + * is simply responsible for verifying one single thing and returning + * either a success or failure. + * + * All of followed event functions are described in 802.2 LLC Protocol + * standard document except two functions that we added that will explain + * in their comments, at below. + * + * Copyright (c) 1997 by Procom Technology, Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include + +#if 0 +#define dprintk(args...) printk(KERN_DEBUG args) +#else +#define dprintk(args...) +#endif + +extern u16 llc_circular_between(u8 a, u8 b, u8 c); + +/** + * llc_util_ns_inside_rx_window - check if sequence number is in rx window + * @ns: sequence number of received pdu. + * @vr: sequence number which receiver expects to receive. + * @rw: receive window size of receiver. + * + * Checks if sequence number of received PDU is in range of receive + * window. Returns 0 for success, 1 otherwise + */ +static u16 llc_util_ns_inside_rx_window(u8 ns, u8 vr, u8 rw) +{ + return !llc_circular_between(vr, ns, + (vr + rw - 1) % LLC_2_SEQ_NBR_MODULO); +} + +/** + * llc_util_nr_inside_tx_window - check if sequence number is in tx window + * @sk: current connection. + * @nr: N(R) of received PDU. + * + * This routine checks if N(R) of received PDU is in range of transmit + * window; on the other hand checks if received PDU acknowledges some + * outstanding PDUs that are in transmit window. Returns 0 for success, 1 + * otherwise. + */ +static u16 llc_util_nr_inside_tx_window(struct sock *sk, u8 nr) +{ + u8 nr1, nr2; + struct sk_buff *skb; + llc_pdu_sn_t *pdu; + struct llc_opt *llc = llc_sk(sk); + int rc = 0; + + if (llc->dev->flags & IFF_LOOPBACK) + goto out; + rc = 1; + if (!skb_queue_len(&llc->pdu_unack_q)) + goto out; + skb = skb_peek(&llc->pdu_unack_q); + pdu = (llc_pdu_sn_t *)skb->nh.raw; + nr1 = LLC_I_GET_NS(pdu); + skb = skb_peek_tail(&llc->pdu_unack_q); + pdu = (llc_pdu_sn_t *)skb->nh.raw; + nr2 = LLC_I_GET_NS(pdu); + rc = !llc_circular_between(nr1, nr, (nr2 + 1) % LLC_2_SEQ_NBR_MODULO); +out: return rc; +} + +int llc_conn_ev_conn_req(struct sock *sk, struct llc_conn_state_ev *ev) +{ + return ev->data.prim.prim == LLC_CONN_PRIM && + ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1; +} + +int llc_conn_ev_conn_resp(struct sock *sk, struct llc_conn_state_ev *ev) +{ + return ev->data.prim.prim == LLC_CONN_PRIM && + ev->data.prim.type == LLC_PRIM_TYPE_RESP ? 0 : 1; +} + +int llc_conn_ev_data_req(struct sock *sk, struct llc_conn_state_ev *ev) +{ + return ev->data.prim.prim == LLC_DATA_PRIM && + ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1; +} + +int llc_conn_ev_disc_req(struct sock *sk, struct llc_conn_state_ev *ev) +{ + return ev->data.prim.prim == LLC_DISC_PRIM && + ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1; +} + +int llc_conn_ev_rst_req(struct sock *sk, struct llc_conn_state_ev *ev) +{ + return ev->data.prim.prim == LLC_RESET_PRIM && + ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1; +} + +int llc_conn_ev_rst_resp(struct sock *sk, struct llc_conn_state_ev *ev) +{ + return ev->data.prim.prim == LLC_RESET_PRIM && + ev->data.prim.type == LLC_PRIM_TYPE_RESP ? 0 : 1; +} + +int llc_conn_ev_local_busy_detected(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + return ev->type == LLC_CONN_EV_TYPE_SIMPLE && + ev->data.a.ev == LLC_CONN_EV_LOCAL_BUSY_DETECTED ? 0 : 1; +} + +int llc_conn_ev_local_busy_cleared(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + return ev->type == LLC_CONN_EV_TYPE_SIMPLE && + ev->data.a.ev == LLC_CONN_EV_LOCAL_BUSY_CLEARED ? 0 : 1; +} + +int llc_conn_ev_rx_bad_pdu(struct sock *sk, struct llc_conn_state_ev *ev) +{ + return 1; +} + +int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw; + + return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_U(pdu) && + LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC ? 0 : 1; +} + +int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw; + + return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_U(pdu) && + LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM ? 0 : 1; +} + +int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw; + + return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_U(pdu) && + LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR ? 0 : 1; +} + +int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && + !LLC_I_PF_IS_0(pdu) && + LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1; +} + +int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && + !LLC_I_PF_IS_1(pdu) && + LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1; +} + +int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + u8 vr = llc_sk(sk)->vR; + u8 ns = LLC_I_GET_NS(pdu); + + return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && + !LLC_I_PF_IS_0(pdu) && ns != vr && + !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1; +} + +int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + u8 vr = llc_sk(sk)->vR; + u8 ns = LLC_I_GET_NS(pdu); + + return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && + !LLC_I_PF_IS_1(pdu) && ns != vr && + !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1; +} + +int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t * pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + u8 vr = llc_sk(sk)->vR; + u8 ns = LLC_I_GET_NS(pdu); + u16 rc = !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && ns != vr && + llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1; + if (!rc) + dprintk(KERN_WARNING "rx_i_cmd_p_bit_set_x_inval_ns matched," + "state = %d, ns = %d, vr = %d\n", + llc_sk(sk)->state, ns, vr); + return rc; +} + +int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && + !LLC_I_PF_IS_0(pdu) && + LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1; +} + +int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && + !LLC_I_PF_IS_1(pdu) && + LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1; +} + +int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && + LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1; +} + +int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + u8 vr = llc_sk(sk)->vR; + u8 ns = LLC_I_GET_NS(pdu); + + return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && + !LLC_I_PF_IS_0(pdu) && ns != vr && + !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1; +} + +int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + u8 vr = llc_sk(sk)->vR; + u8 ns = LLC_I_GET_NS(pdu); + + return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && + !LLC_I_PF_IS_1(pdu) && ns != vr && + !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1; +} + +int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + u8 vr = llc_sk(sk)->vR; + u8 ns = LLC_I_GET_NS(pdu); + + return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && ns != vr && + !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1; +} + +int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + u8 vr = llc_sk(sk)->vR; + u8 ns = LLC_I_GET_NS(pdu); + u16 rc = !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && ns != vr && + llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1; + if (!rc) + dprintk(KERN_WARNING "conn_ev_rx_i_rsp_fbit_set_x_inval_ns " + "matched : state = %d, ns = %d, vr = %d\n", + llc_sk(sk)->state, ns, vr); + return rc; +} + +int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_S(pdu) && + !LLC_S_PF_IS_0(pdu) && + LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_REJ ? 0 : 1; +} + +int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_S(pdu) && + !LLC_S_PF_IS_1(pdu) && + LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_REJ ? 0 : 1; +} + +int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) && + !LLC_S_PF_IS_0(pdu) && + LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1; +} + +int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) && + !LLC_S_PF_IS_1(pdu) && + LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1; +} + +int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw; + + return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) && + LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1; +} + +int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_S(pdu) && + !LLC_S_PF_IS_0(pdu) && + LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RNR ? 0 : 1; +} + +int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_S(pdu) && + !LLC_S_PF_IS_1(pdu) && + LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RNR ? 0 : 1; +} + +int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) && + !LLC_S_PF_IS_0(pdu) && + LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RNR ? 0 : 1; +} + +int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) && + !LLC_S_PF_IS_1(pdu) && + LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RNR ? 0 : 1; +} + +int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_S(pdu) && + !LLC_S_PF_IS_0(pdu) && + LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RR ? 0 : 1; +} + +int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_S(pdu) && + !LLC_S_PF_IS_1(pdu) && + LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RR ? 0 : 1; +} + +int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) && + !LLC_S_PF_IS_0(pdu) && + LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR ? 0 : 1; +} + +int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) && + !LLC_S_PF_IS_1(pdu) && + LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR ? 0 : 1; +} + +int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw; + + return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_U(pdu) && + LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME ? 0 : 1; +} + +int llc_conn_ev_rx_ua_rsp_fbit_set_x(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw; + + return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_U(pdu) && + LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_UA ? 0 : 1; +} + +int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + u16 rc = 1; + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + if (!LLC_PDU_IS_CMD(pdu)) { + if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) { + if (!LLC_I_PF_IS_1(pdu)) + rc = 0; + } else if (!LLC_PDU_TYPE_IS_U(pdu) && !LLC_U_PF_IS_1(pdu)) + rc = 0; + } + return rc; +} + +int llc_conn_ev_rx_xxx_cmd_pbit_set_0(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + u16 rc = 1; + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + if (!LLC_PDU_IS_CMD(pdu)) { + if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) { + if (!LLC_I_PF_IS_0(pdu)) + rc = 0; + } else if (!LLC_PDU_TYPE_IS_U(pdu)) + switch (LLC_U_PDU_CMD(pdu)) { + case LLC_2_PDU_CMD_SABME: + case LLC_2_PDU_CMD_DISC: + if (!LLC_U_PF_IS_0(pdu)) + rc = 0; + break; + } + } + return rc; +} + +int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + u16 rc = 1; + llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw; + + if (!LLC_PDU_IS_CMD(pdu)) { + if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) + rc = 0; + else if (!LLC_PDU_TYPE_IS_U(pdu)) + switch (LLC_U_PDU_CMD(pdu)) { + case LLC_2_PDU_CMD_SABME: + case LLC_2_PDU_CMD_DISC: + rc = 0; + break; + } + } + return rc; +} + +int llc_conn_ev_rx_xxx_rsp_fbit_set_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + u16 rc = 1; + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + if (!LLC_PDU_IS_RSP(pdu)) { + if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) { + if (!LLC_I_PF_IS_1(pdu)) + rc = 0; + } else if (!LLC_PDU_TYPE_IS_U(pdu)) + switch (LLC_U_PDU_RSP(pdu)) { + case LLC_2_PDU_RSP_UA: + case LLC_2_PDU_RSP_DM: + case LLC_2_PDU_RSP_FRMR: + if (!LLC_U_PF_IS_1(pdu)) + rc = 0; + break; + } + } + return rc; +} + +int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + u16 rc = 1; + llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw; + + if (!LLC_PDU_IS_RSP(pdu)) { + if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) + rc = 0; + else if (!LLC_PDU_TYPE_IS_U(pdu)) + switch (LLC_U_PDU_RSP(pdu)) { + case LLC_2_PDU_RSP_UA: + case LLC_2_PDU_RSP_DM: + case LLC_2_PDU_RSP_FRMR: + rc = 0; + break; + } + } + + return rc; +} + +int llc_conn_ev_rx_xxx_yyy(struct sock *sk, struct llc_conn_state_ev *ev) +{ + u16 rc = 1; + llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw; + + if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) + rc = 0; + else if (!LLC_PDU_TYPE_IS_U(pdu)) + switch (LLC_U_PDU_CMD(pdu)) { + case LLC_2_PDU_CMD_SABME: + case LLC_2_PDU_CMD_DISC: + case LLC_2_PDU_RSP_UA: + case LLC_2_PDU_RSP_DM: + case LLC_2_PDU_RSP_FRMR: + rc = 0; + break; + } + return rc; +} + +int llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + u16 rc = 1; + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + u8 vs = llc_sk(sk)->vS; + u8 nr = LLC_I_GET_NR(pdu); + + if (!LLC_PDU_IS_CMD(pdu)) { + if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) { + if (nr != vs && + llc_util_nr_inside_tx_window(sk, nr)) { + dprintk(KERN_ERR "conn_ev_rx_zzz_cmd_inv_nr " + "matched, state = %d, vs = %d, " + "nr = %d\n", llc_sk(sk)->state, vs, nr); + rc = 0; + } + } + } + return rc; +} + +int llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + u16 rc = 1; + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + u8 vs = llc_sk(sk)->vS; + u8 nr = LLC_I_GET_NR(pdu); + + if (!LLC_PDU_IS_RSP(pdu)) { + if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) { + if (nr != vs && + llc_util_nr_inside_tx_window(sk, nr)) { + rc = 0; + dprintk(KERN_ERR "conn_ev_rx_zzz_fbit_set" + "_x_inval_nr matched, state = %d, " + "vs = %d, nr = %d\n", + llc_sk(sk)->state, vs, nr); + } + } + } + return rc; +} + +int llc_conn_ev_rx_any_frame(struct sock *sk, struct llc_conn_state_ev *ev) +{ + return 0; +} + +int llc_conn_ev_p_tmr_exp(struct sock *sk, struct llc_conn_state_ev *ev) +{ + return ev->type != LLC_CONN_EV_TYPE_P_TMR; +} + +int llc_conn_ev_ack_tmr_exp(struct sock *sk, struct llc_conn_state_ev *ev) +{ + return ev->type != LLC_CONN_EV_TYPE_ACK_TMR; +} + +int llc_conn_ev_rej_tmr_exp(struct sock *sk, struct llc_conn_state_ev *ev) +{ + return ev->type != LLC_CONN_EV_TYPE_REJ_TMR; +} + +int llc_conn_ev_busy_tmr_exp(struct sock *sk, struct llc_conn_state_ev *ev) +{ + return ev->type != LLC_CONN_EV_TYPE_BUSY_TMR; +} + +int llc_conn_ev_any_tmr_exp(struct sock *sk, struct llc_conn_state_ev *ev) +{ + + return ev->type == LLC_CONN_EV_TYPE_P_TMR || + ev->type == LLC_CONN_EV_TYPE_ACK_TMR || + ev->type == LLC_CONN_EV_TYPE_REJ_TMR || + ev->type == LLC_CONN_EV_TYPE_BUSY_TMR ? 0 : 1; +} + +int llc_conn_ev_init_p_f_cycle(struct sock *sk, struct llc_conn_state_ev *ev) +{ + return 1; +} + +int llc_conn_ev_tx_buffer_full(struct sock *sk, struct llc_conn_state_ev *ev) +{ + return ev->type == LLC_CONN_EV_TYPE_SIMPLE && + ev->data.a.ev == LLC_CONN_EV_TX_BUFF_FULL ? 0 : 1; +} + +/* --------------------- EVENT QUALIFIER FUNCTIONS ----------------------- * + * these functions simply verify the value of a state flag associated with + * the connection and return either a 0 for success or a non-zero value + * for not-success; verify the event is the type we expect + * ----------------------------------------------------------------------- */ + +int llc_conn_ev_qlfy_data_flag_eq_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + return llc_sk(sk)->data_flag != 1; +} + +int llc_conn_ev_qlfy_data_flag_eq_0(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + return llc_sk(sk)->data_flag; +} + +int llc_conn_ev_qlfy_data_flag_eq_2(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + return llc_sk(sk)->data_flag != 2; +} + +int llc_conn_ev_qlfy_p_flag_eq_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + return llc_sk(sk)->p_flag != 1; +} + +/** + * conn_ev_qlfy_last_frame_eq_1 - checks if frame is last in tx window + * @sk: current connection structure. + * @ev: current event. + * + * This function determines when frame which is sent, is last frame of + * transmit window, if it is then this function return zero else return + * one. This function is used for sending last frame of transmit window + * as I-format command with p-bit set to one. Returns 0 if frame is last + * frame, 1 otherwise. + */ +int llc_conn_ev_qlfy_last_frame_eq_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + return !(skb_queue_len(&llc_sk(sk)->pdu_unack_q) + 1 == llc_sk(sk)->k); +} + +/** + * conn_ev_qlfy_last_frame_eq_0 - checks if frame isn't last in tx window + * @sk: current connection structure. + * @ev: current event. + * + * This function determines when frame which is sent, isn't last frame of + * transmit window, if it isn't then this function return zero else return + * one. Returns 0 if frame isn't last frame, 1 otherwise. + */ +int llc_conn_ev_qlfy_last_frame_eq_0(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + return skb_queue_len(&llc_sk(sk)->pdu_unack_q) + 1 == llc_sk(sk)->k; +} + +int llc_conn_ev_qlfy_p_flag_eq_0(struct sock *sk, struct llc_conn_state_ev *ev) +{ + return llc_sk(sk)->p_flag; +} + +int llc_conn_ev_qlfy_p_flag_eq_f(struct sock *sk, struct llc_conn_state_ev *ev) +{ + u8 f_bit; + struct sk_buff *skb; + + if (ev->type == LLC_CONN_EV_TYPE_PDU) + skb = ev->data.pdu.skb; + else + skb = ev->data.prim.data->data->conn.skb; + llc_pdu_decode_pf_bit(skb, &f_bit); + return llc_sk(sk)->p_flag == f_bit ? 0 : 1; +} + +int llc_conn_ev_qlfy_remote_busy_eq_0(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + return llc_sk(sk)->remote_busy_flag; +} + +int llc_conn_ev_qlfy_remote_busy_eq_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + return !llc_sk(sk)->remote_busy_flag; +} + +int llc_conn_ev_qlfy_retry_cnt_lt_n2(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + return !(llc_sk(sk)->retry_count < llc_sk(sk)->n2); +} + +int llc_conn_ev_qlfy_retry_cnt_gte_n2(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + return !(llc_sk(sk)->retry_count >= llc_sk(sk)->n2); +} + +int llc_conn_ev_qlfy_s_flag_eq_1(struct sock *sk, struct llc_conn_state_ev *ev) +{ + return !llc_sk(sk)->s_flag; +} + +int llc_conn_ev_qlfy_s_flag_eq_0(struct sock *sk, struct llc_conn_state_ev *ev) +{ + return llc_sk(sk)->s_flag; +} + +int llc_conn_ev_qlfy_cause_flag_eq_1(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + return !llc_sk(sk)->cause_flag; +} + +int llc_conn_ev_qlfy_cause_flag_eq_0(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + return llc_sk(sk)->cause_flag; +} + +int llc_conn_ev_qlfy_init_p_f_cycle(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + return 0; +} + +int llc_conn_ev_qlfy_set_status_conn(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + ev->status = LLC_STATUS_CONN; + return 0; +} + +int llc_conn_ev_qlfy_set_status_disc(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + ev->status = LLC_STATUS_DISC; + return 0; +} + +int llc_conn_ev_qlfy_set_status_impossible(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + ev->status = LLC_STATUS_IMPOSSIBLE; + return 0; +} + +int llc_conn_ev_qlfy_set_status_failed(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + ev->status = LLC_STATUS_FAILED; + return 0; +} + +int llc_conn_ev_qlfy_set_status_remote_busy(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + ev->status = LLC_STATUS_REMOTE_BUSY; + return 0; +} + +int llc_conn_ev_qlfy_set_status_received(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + ev->status = LLC_STATUS_RECEIVED; + return 0; +} + +int llc_conn_ev_qlfy_set_status_refuse(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + ev->status = LLC_STATUS_REFUSE; + return 0; +} + +int llc_conn_ev_qlfy_set_status_conflict(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + ev->status = LLC_STATUS_CONFLICT; + return 0; +} + +int llc_conn_ev_qlfy_set_status_rst_done(struct sock *sk, + struct llc_conn_state_ev *ev) +{ + ev->status = LLC_STATUS_RESET_DONE; + return 0; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_c_st.c linux.19pre5-ac1/net/llc/llc_c_st.c --- linux.19p5/net/llc/llc_c_st.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/net/llc/llc_c_st.c Tue Mar 19 19:15:34 2002 @@ -0,0 +1,4897 @@ +/* + * llc_c_st.c - This module contains state transition of connection component. + * + * Description of event functions and actions there is in 802.2 LLC standard, + * or in "llc_c_ac.c" and "llc_c_ev.c" modules. + * + * Copyright (c) 1997 by Procom Technology, Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include + +#define LLC_NO_EVENT_QUALIFIERS NULL +#define LLC_NO_TRANSITION_ACTIONS NULL + +/* ----------------- COMMON CONNECTION STATE transitions ----------------- * + * Common transitions for + * LLC_CONN_STATE_NORMAL, + * LLC_CONN_STATE_BUSY, + * LLC_CONN_STATE_REJ, + * LLC_CONN_STATE_AWAIT, + * LLC_CONN_STATE_AWAIT_BUSY and + * LLC_CONN_STATE_AWAIT_REJ states + */ +/* State transitions for LLC_CONN_EV_DISC_REQ event */ +static llc_conn_action_t llc_common_actions_1[] = { + llc_conn_ac_send_disc_cmd_p_set_x, + llc_conn_ac_start_ack_timer, + llc_conn_ac_stop_other_timers, + llc_conn_ac_set_retry_cnt_0, + llc_conn_ac_set_cause_flag_1, + NULL +}; + +static struct llc_conn_state_trans llc_common_state_trans_1 = { + llc_conn_ev_disc_req, + LLC_CONN_STATE_D_CONN, + LLC_NO_EVENT_QUALIFIERS, + llc_common_actions_1 +}; + +/* State transitions for LLC_CONN_EV_RESET_REQ event */ +static llc_conn_action_t llc_common_actions_2[] = { + llc_conn_ac_send_sabme_cmd_p_set_x, + llc_conn_ac_start_ack_timer, + llc_conn_ac_stop_other_timers, + llc_conn_ac_set_retry_cnt_0, + llc_conn_ac_set_cause_flag_1, + NULL +}; + +static struct llc_conn_state_trans llc_common_state_trans_2 = { + llc_conn_ev_rst_req, + LLC_CONN_STATE_RESET, + LLC_NO_EVENT_QUALIFIERS, + llc_common_actions_2 +}; + +/* State transitions for LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X event */ +static llc_conn_action_t llc_common_actions_3[] = { + llc_conn_ac_stop_all_timers, + llc_conn_ac_set_vs_0, + llc_conn_ac_set_vr_0, + llc_conn_ac_send_ua_rsp_f_set_p, + llc_conn_ac_rst_ind, + llc_conn_ac_set_p_flag_0, + llc_conn_ac_set_remote_busy_0, + llc_conn_reset, + NULL +}; + +static struct llc_conn_state_trans llc_common_state_trans_3 = { + llc_conn_ev_rx_sabme_cmd_pbit_set_x, + LLC_CONN_STATE_NORMAL, + LLC_NO_EVENT_QUALIFIERS, + llc_common_actions_3 +}; + +/* State transitions for LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X event */ +static llc_conn_action_t llc_common_actions_4[] = { + llc_conn_ac_stop_all_timers, + llc_conn_ac_send_ua_rsp_f_set_p, + llc_conn_ac_disc_ind, + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_common_state_trans_4 = { + llc_conn_ev_rx_disc_cmd_pbit_set_x, + LLC_CONN_STATE_ADM, + LLC_NO_EVENT_QUALIFIERS, + llc_common_actions_4 +}; + +/* State transitions for LLC_CONN_EV_RX_FRMR_RSP_Fbit_SET_X event */ +static llc_conn_action_t llc_common_actions_5[] = { + llc_conn_ac_send_sabme_cmd_p_set_x, + llc_conn_ac_start_ack_timer, + llc_conn_ac_stop_other_timers, + llc_conn_ac_set_retry_cnt_0, + llc_conn_ac_rst_ind, + llc_conn_ac_set_cause_flag_0, + llc_conn_reset, + NULL +}; + +static struct llc_conn_state_trans llc_common_state_trans_5 = { + llc_conn_ev_rx_frmr_rsp_fbit_set_x, + LLC_CONN_STATE_RESET, + LLC_NO_EVENT_QUALIFIERS, + llc_common_actions_5 +}; + +/* State transitions for LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X event */ +static llc_conn_action_t llc_common_actions_6[] = { + llc_conn_ac_disc_ind, + llc_conn_ac_stop_all_timers, + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_common_state_trans_6 = { + llc_conn_ev_rx_dm_rsp_fbit_set_x, + LLC_CONN_STATE_ADM, + LLC_NO_EVENT_QUALIFIERS, + llc_common_actions_6 +}; + +/* State transitions for LLC_CONN_EV_RX_ZZZ_CMD_Pbit_SET_X_INVAL_Nr event */ +static llc_conn_action_t llc_common_actions_7a[] = { + llc_conn_ac_send_frmr_rsp_f_set_x, + llc_conn_ac_start_ack_timer, + llc_conn_ac_stop_other_timers, + llc_conn_ac_set_retry_cnt_0, + NULL +}; + +static struct llc_conn_state_trans llc_common_state_trans_7a = { + llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr, + LLC_CONN_STATE_ERROR, + LLC_NO_EVENT_QUALIFIERS, + llc_common_actions_7a +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_X_INVAL_Ns event */ +static llc_conn_action_t llc_common_actions_7b[] = { + llc_conn_ac_send_frmr_rsp_f_set_x, + llc_conn_ac_start_ack_timer, + llc_conn_ac_stop_other_timers, + llc_conn_ac_set_retry_cnt_0, + NULL +}; + +static struct llc_conn_state_trans llc_common_state_trans_7b = { + llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns, + LLC_CONN_STATE_ERROR, + LLC_NO_EVENT_QUALIFIERS, + llc_common_actions_7b +}; + +/* State transitions for LLC_CONN_EV_RX_ZZZ_RSP_Fbit_SET_X_INVAL_Nr event */ +static llc_conn_action_t llc_common_actions_8a[] = { + llc_conn_ac_send_frmr_rsp_f_set_x, + llc_conn_ac_start_ack_timer, + llc_conn_ac_stop_other_timers, + llc_conn_ac_set_retry_cnt_0, + NULL +}; + +static struct llc_conn_state_trans llc_common_state_trans_8a = { + llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr, + LLC_CONN_STATE_ERROR, + LLC_NO_EVENT_QUALIFIERS, + llc_common_actions_8a +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_X_INVAL_Ns event */ +static llc_conn_action_t llc_common_actions_8b[] = { + llc_conn_ac_send_frmr_rsp_f_set_x, + llc_conn_ac_start_ack_timer, + llc_conn_ac_stop_other_timers, + llc_conn_ac_set_retry_cnt_0, + NULL +}; + +static struct llc_conn_state_trans llc_common_state_trans_8b = { + llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns, + LLC_CONN_STATE_ERROR, + LLC_NO_EVENT_QUALIFIERS, + llc_common_actions_8b +}; + +/* State transitions for LLC_CONN_EV_RX_BAD_PDU event */ +static llc_conn_action_t llc_common_actions_8c[] = { + llc_conn_ac_send_frmr_rsp_f_set_x, + llc_conn_ac_start_ack_timer, + llc_conn_ac_stop_other_timers, + llc_conn_ac_set_retry_cnt_0, + NULL +}; + +static struct llc_conn_state_trans llc_common_state_trans_8c = { + llc_conn_ev_rx_bad_pdu, + LLC_CONN_STATE_ERROR, + LLC_NO_EVENT_QUALIFIERS, + llc_common_actions_8c +}; + +/* State transitions for LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X event */ +static llc_conn_action_t llc_common_actions_9[] = { + llc_conn_ac_send_frmr_rsp_f_set_x, + llc_conn_ac_start_ack_timer, + llc_conn_ac_stop_other_timers, + llc_conn_ac_set_retry_cnt_0, + NULL +}; + +static struct llc_conn_state_trans llc_common_state_trans_9 = { + llc_conn_ev_rx_ua_rsp_fbit_set_x, + LLC_CONN_STATE_ERROR, + LLC_NO_EVENT_QUALIFIERS, + llc_common_actions_9 +}; + +/* State transitions for LLC_CONN_EV_RX_XXX_RSP_Fbit_SET_1 event */ +#if 0 +static llc_conn_ev_qfyr_t llc_common_ev_qfyrs_10[] = { + llc_conn_ev_qlfy_p_flag_eq_0, + NULL +}; + +static llc_conn_action_t llc_common_actions_10[] = { + llc_conn_ac_send_frmr_rsp_f_set_x, + llc_conn_ac_start_ack_timer, + llc_conn_ac_stop_other_timers, + llc_conn_ac_set_retry_cnt_0, + NULL +}; + +static struct llc_conn_state_trans llc_common_state_trans_10 = { + llc_conn_ev_rx_xxx_rsp_fbit_set_1, + LLC_CONN_STATE_ERROR, + llc_common_ev_qfyrs_10, + llc_common_actions_10 +}; +#endif + +/* State transitions for LLC_CONN_EV_P_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_common_ev_qfyrs_11a[] = { + llc_conn_ev_qlfy_retry_cnt_gte_n2, + NULL +}; + +static llc_conn_action_t llc_common_actions_11a[] = { + llc_conn_ac_send_sabme_cmd_p_set_x, + llc_conn_ac_start_ack_timer, + llc_conn_ac_stop_other_timers, + llc_conn_ac_set_retry_cnt_0, + llc_conn_ac_set_cause_flag_0, + NULL +}; + +static struct llc_conn_state_trans llc_common_state_trans_11a = { + llc_conn_ev_p_tmr_exp, + LLC_CONN_STATE_RESET, + llc_common_ev_qfyrs_11a, + llc_common_actions_11a +}; + +/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_common_ev_qfyrs_11b[] = { + llc_conn_ev_qlfy_retry_cnt_gte_n2, + NULL +}; + +static llc_conn_action_t llc_common_actions_11b[] = { + llc_conn_ac_send_sabme_cmd_p_set_x, + llc_conn_ac_start_ack_timer, + llc_conn_ac_stop_other_timers, + llc_conn_ac_set_retry_cnt_0, + llc_conn_ac_set_cause_flag_0, + NULL +}; + +static struct llc_conn_state_trans llc_common_state_trans_11b = { + llc_conn_ev_ack_tmr_exp, + LLC_CONN_STATE_RESET, + llc_common_ev_qfyrs_11b, + llc_common_actions_11b +}; + +/* State transitions for LLC_CONN_EV_REJ_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_common_ev_qfyrs_11c[] = { + llc_conn_ev_qlfy_retry_cnt_gte_n2, + NULL +}; + +static llc_conn_action_t llc_common_actions_11c[] = { + llc_conn_ac_send_sabme_cmd_p_set_x, + llc_conn_ac_start_ack_timer, + llc_conn_ac_stop_other_timers, + llc_conn_ac_set_retry_cnt_0, + llc_conn_ac_set_cause_flag_0, + NULL +}; + +static struct llc_conn_state_trans llc_common_state_trans_11c = { + llc_conn_ev_rej_tmr_exp, + LLC_CONN_STATE_RESET, + llc_common_ev_qfyrs_11c, + llc_common_actions_11c +}; + +/* State transitions for LLC_CONN_EV_BUSY_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_common_ev_qfyrs_11d[] = { + llc_conn_ev_qlfy_retry_cnt_gte_n2, + NULL +}; + +static llc_conn_action_t llc_common_actions_11d[] = { + llc_conn_ac_send_sabme_cmd_p_set_x, + llc_conn_ac_start_ack_timer, + llc_conn_ac_stop_other_timers, + llc_conn_ac_set_retry_cnt_0, + llc_conn_ac_set_cause_flag_0, + NULL +}; + +static struct llc_conn_state_trans llc_common_state_trans_11d = { + llc_conn_ev_busy_tmr_exp, + LLC_CONN_STATE_RESET, + llc_common_ev_qfyrs_11d, + llc_common_actions_11d +}; + +/* + * Common dummy state transition; must be last entry for all state + * transition groups - it'll be on .bss, so will be zeroed. + */ +static struct llc_conn_state_trans llc_common_state_trans_n; + +/* --------------------- LLC_CONN_STATE_ADM transitions -------------------- */ +/* State transitions for LLC_CONN_EV_CONN_REQ event */ +static llc_conn_action_t llc_adm_actions_1[] = { + llc_conn_ac_send_sabme_cmd_p_set_x, + llc_conn_ac_start_ack_timer, + llc_conn_ac_set_retry_cnt_0, + llc_conn_ac_set_s_flag_0, + NULL +}; + +static struct llc_conn_state_trans llc_adm_state_trans_1 = { + llc_conn_ev_conn_req, + LLC_CONN_STATE_SETUP, + LLC_NO_EVENT_QUALIFIERS, + llc_adm_actions_1 +}; + +/* State transitions for LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X event */ +static llc_conn_action_t llc_adm_actions_2[] = { + llc_conn_ac_send_ua_rsp_f_set_p, + llc_conn_ac_set_vs_0, + llc_conn_ac_set_vr_0, + llc_conn_ac_set_retry_cnt_0, + llc_conn_ac_set_p_flag_0, + llc_conn_ac_set_remote_busy_0, + llc_conn_ac_conn_ind, + NULL +}; + +static struct llc_conn_state_trans llc_adm_state_trans_2 = { + llc_conn_ev_rx_sabme_cmd_pbit_set_x, + LLC_CONN_STATE_NORMAL, + LLC_NO_EVENT_QUALIFIERS, + llc_adm_actions_2 +}; + +/* State transitions for LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X event */ +static llc_conn_action_t llc_adm_actions_3[] = { + llc_conn_ac_send_dm_rsp_f_set_p, + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_adm_state_trans_3 = { + llc_conn_ev_rx_disc_cmd_pbit_set_x, + LLC_CONN_STATE_ADM, + LLC_NO_EVENT_QUALIFIERS, + llc_adm_actions_3 +}; + +/* State transitions for LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_adm_actions_4[] = { + llc_conn_ac_send_dm_rsp_f_set_1, + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_adm_state_trans_4 = { + llc_conn_ev_rx_xxx_cmd_pbit_set_1, + LLC_CONN_STATE_ADM, + LLC_NO_EVENT_QUALIFIERS, + llc_adm_actions_4 +}; + +/* State transitions for LLC_CONN_EV_RX_XXX_YYY event */ +static llc_conn_action_t llc_adm_actions_5[] = { + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_adm_state_trans_5 = { + llc_conn_ev_rx_any_frame, + LLC_CONN_OUT_OF_SVC, + LLC_NO_EVENT_QUALIFIERS, + llc_adm_actions_5 +}; + +/* + * Array of pointers; + * one to each transition + */ +static struct llc_conn_state_trans *llc_adm_state_transitions[] = { + &llc_adm_state_trans_1, /* Request */ + &llc_common_state_trans_n, + &llc_common_state_trans_n, /* local_busy */ + &llc_common_state_trans_n, /* init_pf_cycle */ + &llc_common_state_trans_n, /* timer */ + &llc_adm_state_trans_2, /* Receive frame */ + &llc_adm_state_trans_3, + &llc_adm_state_trans_4, + &llc_adm_state_trans_5, + &llc_common_state_trans_n +}; + +/* --------------------- LLC_CONN_STATE_SETUP transitions ----------------- */ +/* State transitions for LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X event */ +static llc_conn_action_t llc_setup_actions_1[] = { + llc_conn_ac_send_ua_rsp_f_set_p, + llc_conn_ac_set_vs_0, + llc_conn_ac_set_vr_0, + llc_conn_ac_set_s_flag_1, + NULL +}; + +static struct llc_conn_state_trans llc_setup_state_trans_1 = { + llc_conn_ev_rx_sabme_cmd_pbit_set_x, + LLC_CONN_STATE_SETUP, + LLC_NO_EVENT_QUALIFIERS, + llc_setup_actions_1 +}; + +/* State transitions for LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X event */ +static llc_conn_ev_qfyr_t llc_setup_ev_qfyrs_2[] = { + llc_conn_ev_qlfy_p_flag_eq_f, + llc_conn_ev_qlfy_set_status_conn, + NULL +}; + +static llc_conn_action_t llc_setup_actions_2[] = { + llc_conn_ac_stop_ack_timer, + llc_conn_ac_set_vs_0, + llc_conn_ac_set_vr_0, + llc_conn_ac_upd_p_flag, + llc_conn_ac_set_remote_busy_0, + llc_conn_ac_conn_confirm, + NULL +}; + +static struct llc_conn_state_trans llc_setup_state_trans_2 = { + llc_conn_ev_rx_ua_rsp_fbit_set_x, + LLC_CONN_STATE_NORMAL, + llc_setup_ev_qfyrs_2, + llc_setup_actions_2 +}; + +/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_setup_ev_qfyrs_3[] = { + llc_conn_ev_qlfy_s_flag_eq_1, + llc_conn_ev_qlfy_set_status_conn, + NULL +}; + +static llc_conn_action_t llc_setup_actions_3[] = { + llc_conn_ac_set_p_flag_0, + llc_conn_ac_set_remote_busy_0, + llc_conn_ac_conn_confirm, + NULL +}; + +static struct llc_conn_state_trans llc_setup_state_trans_3 = { + llc_conn_ev_ack_tmr_exp, + LLC_CONN_STATE_NORMAL, + llc_setup_ev_qfyrs_3, + llc_setup_actions_3 +}; + +/* State transitions for LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X event */ +static llc_conn_ev_qfyr_t llc_setup_ev_qfyrs_4[] = { + llc_conn_ev_qlfy_set_status_disc, + NULL +}; + +static llc_conn_action_t llc_setup_actions_4[] = { + llc_conn_ac_send_dm_rsp_f_set_p, + llc_conn_ac_stop_ack_timer, + llc_conn_ac_conn_confirm, + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_setup_state_trans_4 = { + llc_conn_ev_rx_disc_cmd_pbit_set_x, + LLC_CONN_STATE_ADM, + llc_setup_ev_qfyrs_4, + llc_setup_actions_4 +}; + +/* State transitions for LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X event */ +static llc_conn_ev_qfyr_t llc_setup_ev_qfyrs_5[] = { + llc_conn_ev_qlfy_set_status_disc, + NULL +}; + +static llc_conn_action_t llc_setup_actions_5[] = { + llc_conn_ac_stop_ack_timer, + llc_conn_ac_conn_confirm, + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_setup_state_trans_5 = { + llc_conn_ev_rx_dm_rsp_fbit_set_x, + LLC_CONN_STATE_ADM, + llc_setup_ev_qfyrs_5, + llc_setup_actions_5 +}; + +/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_setup_ev_qfyrs_7[] = { + llc_conn_ev_qlfy_retry_cnt_lt_n2, + llc_conn_ev_qlfy_s_flag_eq_0, + NULL +}; + +static llc_conn_action_t llc_setup_actions_7[] = { + llc_conn_ac_send_sabme_cmd_p_set_x, + llc_conn_ac_start_ack_timer, + llc_conn_ac_inc_retry_cnt_by_1, + NULL +}; + +static struct llc_conn_state_trans llc_setup_state_trans_7 = { + llc_conn_ev_ack_tmr_exp, + LLC_CONN_STATE_SETUP, + llc_setup_ev_qfyrs_7, + llc_setup_actions_7 +}; + +/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_setup_ev_qfyrs_8[] = { + llc_conn_ev_qlfy_retry_cnt_gte_n2, + llc_conn_ev_qlfy_s_flag_eq_0, + llc_conn_ev_qlfy_set_status_failed, + NULL +}; + +static llc_conn_action_t llc_setup_actions_8[] = { + llc_conn_ac_conn_confirm, + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_setup_state_trans_8 = { + llc_conn_ev_ack_tmr_exp, + LLC_CONN_STATE_ADM, + llc_setup_ev_qfyrs_8, + llc_setup_actions_8 +}; + +/* + * Array of pointers; + * one to each transition + */ +static struct llc_conn_state_trans *llc_setup_state_transitions[] = { + &llc_common_state_trans_n, /* Request */ + &llc_common_state_trans_n, /* local busy */ + &llc_common_state_trans_n, /* init_pf_cycle */ + &llc_setup_state_trans_3, /* Timer */ + &llc_setup_state_trans_7, + &llc_setup_state_trans_8, + &llc_common_state_trans_n, + &llc_setup_state_trans_1, /* Receive frame */ + &llc_setup_state_trans_2, + &llc_setup_state_trans_4, + &llc_setup_state_trans_5, + &llc_common_state_trans_n +}; + +/* -------------------- LLC_CONN_STATE_NORMAL transitions ------------------ */ +/* State transitions for LLC_CONN_EV_DATA_REQ event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_1[] = { + llc_conn_ev_qlfy_remote_busy_eq_0, + llc_conn_ev_qlfy_p_flag_eq_0, + llc_conn_ev_qlfy_last_frame_eq_0, + NULL +}; + +static llc_conn_action_t llc_normal_actions_1[] = { + llc_conn_ac_send_i_as_ack, + llc_conn_ac_start_ack_tmr_if_not_running, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_1 = { + llc_conn_ev_data_req, + LLC_CONN_STATE_NORMAL, + llc_normal_ev_qfyrs_1, + llc_normal_actions_1 +}; + +/* State transitions for LLC_CONN_EV_DATA_REQ event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_2[] = { + llc_conn_ev_qlfy_remote_busy_eq_0, + llc_conn_ev_qlfy_p_flag_eq_0, + llc_conn_ev_qlfy_last_frame_eq_1, + NULL +}; + +static llc_conn_action_t llc_normal_actions_2[] = { + llc_conn_ac_send_i_cmd_p_set_1, + llc_conn_ac_start_p_timer, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_2 = { + llc_conn_ev_data_req, + LLC_CONN_STATE_NORMAL, + llc_normal_ev_qfyrs_2, + llc_normal_actions_2 +}; + +/* State transitions for LLC_CONN_EV_DATA_REQ event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_2_1[] = { + llc_conn_ev_qlfy_remote_busy_eq_1, + llc_conn_ev_qlfy_set_status_remote_busy, + NULL +}; + +/* just one member, NULL, .bss zeroes it */ +static llc_conn_action_t llc_normal_actions_2_1[1]; + +static struct llc_conn_state_trans llc_normal_state_trans_2_1 = { + llc_conn_ev_data_req, + LLC_CONN_STATE_NORMAL, + llc_normal_ev_qfyrs_2_1, + llc_normal_actions_2_1 +}; + +/* State transitions for LLC_CONN_EV_LOCAL_BUSY_DETECTED event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_3[] = { + llc_conn_ev_qlfy_p_flag_eq_0, + NULL +}; + +static llc_conn_action_t llc_normal_actions_3[] = { + llc_conn_ac_rst_sendack_flag, + llc_conn_ac_send_rnr_xxx_x_set_0, + llc_conn_ac_set_data_flag_0, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_3 = { + llc_conn_ev_local_busy_detected, + LLC_CONN_STATE_BUSY, + llc_normal_ev_qfyrs_3, + llc_normal_actions_3 +}; + +/* State transitions for LLC_CONN_EV_LOCAL_BUSY_DETECTED event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_4[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_normal_actions_4[] = { + llc_conn_ac_rst_sendack_flag, + llc_conn_ac_send_rnr_xxx_x_set_0, + llc_conn_ac_set_data_flag_0, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_4 = { + llc_conn_ev_local_busy_detected, + LLC_CONN_STATE_BUSY, + llc_normal_ev_qfyrs_4, + llc_normal_actions_4 +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_5a[] = { + llc_conn_ev_qlfy_p_flag_eq_0, + NULL +}; + +static llc_conn_action_t llc_normal_actions_5a[] = { + llc_conn_ac_rst_sendack_flag, + llc_conn_ac_send_rej_xxx_x_set_0, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_p_flag, + llc_conn_ac_start_rej_timer, + llc_conn_ac_clear_remote_busy_if_f_eq_1, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_5a = { + llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns, + LLC_CONN_STATE_REJ, + llc_normal_ev_qfyrs_5a, + llc_normal_actions_5a +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_5b[] = { + llc_conn_ev_qlfy_p_flag_eq_0, + NULL +}; + +static llc_conn_action_t llc_normal_actions_5b[] = { + llc_conn_ac_rst_sendack_flag, + llc_conn_ac_send_rej_xxx_x_set_0, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_p_flag, + llc_conn_ac_start_rej_timer, + llc_conn_ac_clear_remote_busy_if_f_eq_1, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_5b = { + llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns, + LLC_CONN_STATE_REJ, + llc_normal_ev_qfyrs_5b, + llc_normal_actions_5b +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_1_UNEXPD_Ns event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_5c[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_normal_actions_5c[] = { + llc_conn_ac_rst_sendack_flag, + llc_conn_ac_send_rej_xxx_x_set_0, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_p_flag, + llc_conn_ac_start_rej_timer, + llc_conn_ac_clear_remote_busy_if_f_eq_1, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_5c = { + llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns, + LLC_CONN_STATE_REJ, + llc_normal_ev_qfyrs_5c, + llc_normal_actions_5c +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_6a[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_normal_actions_6a[] = { + llc_conn_ac_rst_sendack_flag, + llc_conn_ac_send_rej_xxx_x_set_0, + llc_conn_ac_upd_nr_received, + llc_conn_ac_start_rej_timer, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_6a = { + llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns, + LLC_CONN_STATE_REJ, + llc_normal_ev_qfyrs_6a, + llc_normal_actions_6a +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_6b[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_normal_actions_6b[] = { + llc_conn_ac_rst_sendack_flag, + llc_conn_ac_send_rej_xxx_x_set_0, + llc_conn_ac_upd_nr_received, + llc_conn_ac_start_rej_timer, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_6b = { + llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns, + LLC_CONN_STATE_REJ, + llc_normal_ev_qfyrs_6b, + llc_normal_actions_6b +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns event */ +static llc_conn_action_t llc_normal_actions_7[] = { + llc_conn_ac_rst_sendack_flag, + llc_conn_ac_send_rej_rsp_f_set_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_start_rej_timer, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_7 = { + llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns, + LLC_CONN_STATE_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_normal_actions_7 +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_X event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_8a[] = { + llc_conn_ev_qlfy_p_flag_eq_f, + NULL +}; + +static llc_conn_action_t llc_normal_actions_8[] = { + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_data_ind, + llc_conn_ac_upd_p_flag, + llc_conn_ac_upd_nr_received, + llc_conn_ac_clear_remote_busy_if_f_eq_1, + llc_conn_ac_send_ack_if_needed, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_8a = { + llc_conn_ev_rx_i_rsp_fbit_set_x, + LLC_CONN_STATE_NORMAL, + llc_normal_ev_qfyrs_8a, + llc_normal_actions_8 +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_8b[] = { + llc_conn_ev_qlfy_p_flag_eq_0, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_8b = { + llc_conn_ev_rx_i_cmd_pbit_set_0, + LLC_CONN_STATE_NORMAL, + llc_normal_ev_qfyrs_8b, + llc_normal_actions_8 +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0 event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_9a[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_normal_actions_9a[] = { + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_data_ind, + llc_conn_ac_send_ack_if_needed, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_9a = { + llc_conn_ev_rx_i_rsp_fbit_set_0, + LLC_CONN_STATE_NORMAL, + llc_normal_ev_qfyrs_9a, + llc_normal_actions_9a +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_9b[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_normal_actions_9b[] = { + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_data_ind, + llc_conn_ac_send_ack_if_needed, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_9b = { + llc_conn_ev_rx_i_cmd_pbit_set_0, + LLC_CONN_STATE_NORMAL, + llc_normal_ev_qfyrs_9b, + llc_normal_actions_9b +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_normal_actions_10[] = { + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_send_ack_rsp_f_set_1, + llc_conn_ac_rst_sendack_flag, + llc_conn_ac_upd_nr_received, + llc_conn_ac_data_ind, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_10 = { + llc_conn_ev_rx_i_cmd_pbit_set_1, + LLC_CONN_STATE_NORMAL, + LLC_NO_EVENT_QUALIFIERS, + llc_normal_actions_10 +}; + +/* State transitions for * LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0 event */ +static llc_conn_action_t llc_normal_actions_11a[] = { + llc_conn_ac_upd_p_flag, + llc_conn_ac_upd_nr_received, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_11a = { + llc_conn_ev_rx_rr_cmd_pbit_set_0, + LLC_CONN_STATE_NORMAL, + LLC_NO_EVENT_QUALIFIERS, + llc_normal_actions_11a +}; + +/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0 event */ +static llc_conn_action_t llc_normal_actions_11b[] = { + llc_conn_ac_upd_p_flag, + llc_conn_ac_upd_nr_received, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_11b = { + llc_conn_ev_rx_rr_rsp_fbit_set_0, + LLC_CONN_STATE_NORMAL, + LLC_NO_EVENT_QUALIFIERS, + llc_normal_actions_11b +}; + +/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1 event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_11c[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_normal_actions_11c[] = { + llc_conn_ac_upd_p_flag, + llc_conn_ac_upd_nr_received, + llc_conn_ac_inc_tx_win_size, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_11c = { + llc_conn_ev_rx_rr_rsp_fbit_set_1, + LLC_CONN_STATE_NORMAL, + llc_normal_ev_qfyrs_11c, + llc_normal_actions_11c +}; + +/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_normal_actions_12[] = { + llc_conn_ac_send_ack_rsp_f_set_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_adjust_npta_by_rr, + llc_conn_ac_rst_sendack_flag, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_12 = { + llc_conn_ev_rx_rr_cmd_pbit_set_1, + LLC_CONN_STATE_NORMAL, + LLC_NO_EVENT_QUALIFIERS, + llc_normal_actions_12 +}; + +/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0 event */ +static llc_conn_action_t llc_normal_actions_13a[] = { + llc_conn_ac_upd_p_flag, + llc_conn_ac_upd_nr_received, + llc_conn_ac_set_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_13a = { + llc_conn_ev_rx_rnr_cmd_pbit_set_0, + LLC_CONN_STATE_NORMAL, + LLC_NO_EVENT_QUALIFIERS, + llc_normal_actions_13a +}; + +/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0 event */ +static llc_conn_action_t llc_normal_actions_13b[] = { + llc_conn_ac_upd_p_flag, + llc_conn_ac_upd_nr_received, + llc_conn_ac_set_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_13b = { + llc_conn_ev_rx_rnr_rsp_fbit_set_0, + LLC_CONN_STATE_NORMAL, + LLC_NO_EVENT_QUALIFIERS, + llc_normal_actions_13b +}; + +/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1 event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_13c[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_normal_actions_13c[] = { + llc_conn_ac_upd_p_flag, + llc_conn_ac_upd_nr_received, + llc_conn_ac_set_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_13c = { + llc_conn_ev_rx_rnr_rsp_fbit_set_1, + LLC_CONN_STATE_NORMAL, + llc_normal_ev_qfyrs_13c, + llc_normal_actions_13c +}; + +/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_normal_actions_14[] = { + llc_conn_ac_send_rr_rsp_f_set_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_adjust_npta_by_rnr, + llc_conn_ac_rst_sendack_flag, + llc_conn_ac_set_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_14 = { + llc_conn_ev_rx_rnr_cmd_pbit_set_1, + LLC_CONN_STATE_NORMAL, + LLC_NO_EVENT_QUALIFIERS, + llc_normal_actions_14 +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_15a[] = { + llc_conn_ev_qlfy_p_flag_eq_0, + NULL +}; + +static llc_conn_action_t llc_normal_actions_15a[] = { + llc_conn_ac_set_vs_nr, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_p_flag, + llc_conn_ac_dec_tx_win_size, + llc_conn_ac_resend_i_xxx_x_set_0, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_15a = { + llc_conn_ev_rx_rej_cmd_pbit_set_0, + LLC_CONN_STATE_NORMAL, + llc_normal_ev_qfyrs_15a, + llc_normal_actions_15a +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_X event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_15b[] = { + llc_conn_ev_qlfy_p_flag_eq_f, + NULL +}; + +static llc_conn_action_t llc_normal_actions_15b[] = { + llc_conn_ac_set_vs_nr, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_p_flag, + llc_conn_ac_dec_tx_win_size, + llc_conn_ac_resend_i_xxx_x_set_0, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_15b = { + llc_conn_ev_rx_rej_rsp_fbit_set_x, + LLC_CONN_STATE_NORMAL, + llc_normal_ev_qfyrs_15b, + llc_normal_actions_15b +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_16a[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_normal_actions_16a[] = { + llc_conn_ac_set_vs_nr, + llc_conn_ac_upd_nr_received, + llc_conn_ac_dec_tx_win_size, + llc_conn_ac_resend_i_xxx_x_set_0, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_16a = { + llc_conn_ev_rx_rej_cmd_pbit_set_0, + LLC_CONN_STATE_NORMAL, + llc_normal_ev_qfyrs_16a, + llc_normal_actions_16a +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0 event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_16b[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_normal_actions_16b[] = { + llc_conn_ac_set_vs_nr, + llc_conn_ac_upd_nr_received, + llc_conn_ac_dec_tx_win_size, + llc_conn_ac_resend_i_xxx_x_set_0, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_16b = { + llc_conn_ev_rx_rej_rsp_fbit_set_0, + LLC_CONN_STATE_NORMAL, + llc_normal_ev_qfyrs_16b, + llc_normal_actions_16b +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_normal_actions_17[] = { + llc_conn_ac_set_vs_nr, + llc_conn_ac_upd_nr_received, + llc_conn_ac_dec_tx_win_size, + llc_conn_ac_resend_i_rsp_f_set_1, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_17 = { + llc_conn_ev_rx_rej_cmd_pbit_set_1, + LLC_CONN_STATE_NORMAL, + LLC_NO_EVENT_QUALIFIERS, + llc_normal_actions_17 +}; + +/* State transitions for LLC_CONN_EV_INIT_P_F_CYCLE event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_18[] = { + llc_conn_ev_qlfy_p_flag_eq_0, + NULL +}; + +static llc_conn_action_t llc_normal_actions_18[] = { + llc_conn_ac_send_rr_cmd_p_set_1, + llc_conn_ac_start_p_timer, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_18 = { + llc_conn_ev_init_p_f_cycle, + LLC_CONN_STATE_NORMAL, + llc_normal_ev_qfyrs_18, + llc_normal_actions_18 +}; + +/* State transitions for LLC_CONN_EV_P_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_19[] = { + llc_conn_ev_qlfy_retry_cnt_lt_n2, + NULL +}; + +static llc_conn_action_t llc_normal_actions_19[] = { + llc_conn_ac_rst_sendack_flag, + llc_conn_ac_send_rr_cmd_p_set_1, + llc_conn_ac_rst_vs, + llc_conn_ac_start_p_timer, + llc_conn_ac_inc_retry_cnt_by_1, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_19 = { + llc_conn_ev_p_tmr_exp, + LLC_CONN_STATE_AWAIT, + llc_normal_ev_qfyrs_19, + llc_normal_actions_19 +}; + +/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_20a[] = { + llc_conn_ev_qlfy_p_flag_eq_0, + llc_conn_ev_qlfy_retry_cnt_lt_n2, + NULL +}; + +static llc_conn_action_t llc_normal_actions_20a[] = { + llc_conn_ac_rst_sendack_flag, + llc_conn_ac_send_rr_cmd_p_set_1, + llc_conn_ac_rst_vs, + llc_conn_ac_start_p_timer, + llc_conn_ac_inc_retry_cnt_by_1, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_20a = { + llc_conn_ev_ack_tmr_exp, + LLC_CONN_STATE_AWAIT, + llc_normal_ev_qfyrs_20a, + llc_normal_actions_20a +}; + +/* State transitions for LLC_CONN_EV_BUSY_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_20b[] = { + llc_conn_ev_qlfy_p_flag_eq_0, + llc_conn_ev_qlfy_retry_cnt_lt_n2, + NULL +}; + +static llc_conn_action_t llc_normal_actions_20b[] = { + llc_conn_ac_rst_sendack_flag, + llc_conn_ac_send_rr_cmd_p_set_1, + llc_conn_ac_rst_vs, + llc_conn_ac_start_p_timer, + llc_conn_ac_inc_retry_cnt_by_1, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_20b = { + llc_conn_ev_busy_tmr_exp, + LLC_CONN_STATE_AWAIT, + llc_normal_ev_qfyrs_20b, + llc_normal_actions_20b +}; + +/* State transitions for LLC_CONN_EV_TX_BUFF_FULL event */ +static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_21[] = { + llc_conn_ev_qlfy_p_flag_eq_0, + NULL +}; + +static llc_conn_action_t llc_normal_actions_21[] = { + llc_conn_ac_send_rr_cmd_p_set_1, + llc_conn_ac_start_p_timer, + NULL +}; + +static struct llc_conn_state_trans llc_normal_state_trans_21 = { + llc_conn_ev_tx_buffer_full, + LLC_CONN_STATE_NORMAL, + llc_normal_ev_qfyrs_21, + llc_normal_actions_21 +}; + +/* + * Array of pointers; + * one to each transition + */ +static struct llc_conn_state_trans *llc_normal_state_transitions[] = { + &llc_normal_state_trans_1, /* Requests */ + &llc_normal_state_trans_2, + &llc_normal_state_trans_2_1, + &llc_common_state_trans_1, + &llc_common_state_trans_2, + &llc_common_state_trans_n, + &llc_normal_state_trans_21, + &llc_normal_state_trans_3, /* Local busy */ + &llc_normal_state_trans_4, + &llc_common_state_trans_n, + &llc_normal_state_trans_18, /* Init pf cycle */ + &llc_common_state_trans_n, + &llc_common_state_trans_11a, /* Timers */ + &llc_common_state_trans_11b, + &llc_common_state_trans_11c, + &llc_common_state_trans_11d, + &llc_normal_state_trans_19, + &llc_normal_state_trans_20a, + &llc_normal_state_trans_20b, + &llc_common_state_trans_n, + &llc_normal_state_trans_8b, /* Receive frames */ + &llc_normal_state_trans_9b, + &llc_normal_state_trans_10, + &llc_normal_state_trans_11b, + &llc_normal_state_trans_11c, + &llc_normal_state_trans_5a, + &llc_normal_state_trans_5b, + &llc_normal_state_trans_5c, + &llc_normal_state_trans_6a, + &llc_normal_state_trans_6b, + &llc_normal_state_trans_7, + &llc_normal_state_trans_8a, + &llc_normal_state_trans_9a, + &llc_normal_state_trans_11a, + &llc_normal_state_trans_12, + &llc_normal_state_trans_13a, + &llc_normal_state_trans_13b, + &llc_normal_state_trans_13c, + &llc_normal_state_trans_14, + &llc_normal_state_trans_15a, + &llc_normal_state_trans_15b, + &llc_normal_state_trans_16a, + &llc_normal_state_trans_16b, + &llc_normal_state_trans_17, + &llc_common_state_trans_3, + &llc_common_state_trans_4, + &llc_common_state_trans_5, + &llc_common_state_trans_6, + &llc_common_state_trans_7a, + &llc_common_state_trans_7b, + &llc_common_state_trans_8a, + &llc_common_state_trans_8b, + &llc_common_state_trans_8c, + &llc_common_state_trans_9, + /*&llc_common_state_trans_10, */ + &llc_common_state_trans_n +}; + +/* --------------------- LLC_CONN_STATE_BUSY transitions ------------------- */ +/* State transitions for LLC_CONN_EV_DATA_REQ event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_1[] = { + llc_conn_ev_qlfy_remote_busy_eq_0, + llc_conn_ev_qlfy_p_flag_eq_0, + NULL +}; + +static llc_conn_action_t llc_busy_actions_1[] = { + llc_conn_ac_send_i_xxx_x_set_0, + llc_conn_ac_start_ack_tmr_if_not_running, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_1 = { + llc_conn_ev_data_req, + LLC_CONN_STATE_BUSY, + llc_busy_ev_qfyrs_1, + llc_busy_actions_1 +}; + +/* State transitions for LLC_CONN_EV_DATA_REQ event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_2[] = { + llc_conn_ev_qlfy_remote_busy_eq_0, + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_busy_actions_2[] = { + llc_conn_ac_send_i_xxx_x_set_0, + llc_conn_ac_start_ack_tmr_if_not_running, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_2 = { + llc_conn_ev_data_req, + LLC_CONN_STATE_BUSY, + llc_busy_ev_qfyrs_2, + llc_busy_actions_2 +}; + +/* State transitions for LLC_CONN_EV_DATA_REQ event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_2_1[] = { + llc_conn_ev_qlfy_remote_busy_eq_1, + llc_conn_ev_qlfy_set_status_remote_busy, + NULL +}; + +/* just one member, NULL, .bss zeroes it */ +static llc_conn_action_t llc_busy_actions_2_1[1]; + +static struct llc_conn_state_trans llc_busy_state_trans_2_1 = { + llc_conn_ev_data_req, + LLC_CONN_STATE_BUSY, + llc_busy_ev_qfyrs_2_1, + llc_busy_actions_2_1 +}; + +/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_3[] = { + llc_conn_ev_qlfy_data_flag_eq_1, + llc_conn_ev_qlfy_p_flag_eq_0, + NULL +}; + +static llc_conn_action_t llc_busy_actions_3[] = { + llc_conn_ac_send_rej_xxx_x_set_0, + llc_conn_ac_start_rej_timer, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_3 = { + llc_conn_ev_local_busy_cleared, + LLC_CONN_STATE_REJ, + llc_busy_ev_qfyrs_3, + llc_busy_actions_3 +}; + +/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_4[] = { + llc_conn_ev_qlfy_data_flag_eq_1, + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_busy_actions_4[] = { + llc_conn_ac_send_rej_xxx_x_set_0, + llc_conn_ac_start_rej_timer, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_4 = { + llc_conn_ev_local_busy_cleared, + LLC_CONN_STATE_REJ, + llc_busy_ev_qfyrs_4, + llc_busy_actions_4 +}; + +/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_5[] = { + llc_conn_ev_qlfy_data_flag_eq_0, + llc_conn_ev_qlfy_p_flag_eq_0, + NULL +}; + +static llc_conn_action_t llc_busy_actions_5[] = { + llc_conn_ac_send_rr_xxx_x_set_0, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_5 = { + llc_conn_ev_local_busy_cleared, + LLC_CONN_STATE_NORMAL, + llc_busy_ev_qfyrs_5, + llc_busy_actions_5 +}; + +/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_6[] = { + llc_conn_ev_qlfy_data_flag_eq_0, + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_busy_actions_6[] = { + llc_conn_ac_send_rr_xxx_x_set_0, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_6 = { + llc_conn_ev_local_busy_cleared, + LLC_CONN_STATE_NORMAL, + llc_busy_ev_qfyrs_6, + llc_busy_actions_6 +}; + +/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_7[] = { + llc_conn_ev_qlfy_data_flag_eq_2, + llc_conn_ev_qlfy_p_flag_eq_0, + NULL +}; + +static llc_conn_action_t llc_busy_actions_7[] = { + llc_conn_ac_send_rr_xxx_x_set_0, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_7 = { + llc_conn_ev_local_busy_cleared, + LLC_CONN_STATE_REJ, + llc_busy_ev_qfyrs_7, + llc_busy_actions_7 +}; + +/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_8[] = { + llc_conn_ev_qlfy_data_flag_eq_2, + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_busy_actions_8[] = { + llc_conn_ac_send_rr_xxx_x_set_0, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_8 = { + llc_conn_ev_local_busy_cleared, + LLC_CONN_STATE_REJ, + llc_busy_ev_qfyrs_8, + llc_busy_actions_8 +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_X_UNEXPD_Ns event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_9a[] = { + llc_conn_ev_qlfy_p_flag_eq_f, + NULL +}; + +static llc_conn_action_t llc_busy_actions_9a[] = { + llc_conn_ac_opt_send_rnr_xxx_x_set_0, + llc_conn_ac_upd_p_flag, + llc_conn_ac_upd_nr_received, + llc_conn_ac_set_data_flag_1_if_data_flag_eq_0, + llc_conn_ac_clear_remote_busy_if_f_eq_1, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_9a = { + llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns, + LLC_CONN_STATE_BUSY, + llc_busy_ev_qfyrs_9a, + llc_busy_actions_9a +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_9b[] = { + llc_conn_ev_qlfy_p_flag_eq_0, + NULL +}; + +static llc_conn_action_t llc_busy_actions_9b[] = { + llc_conn_ac_opt_send_rnr_xxx_x_set_0, + llc_conn_ac_upd_p_flag, + llc_conn_ac_upd_nr_received, + llc_conn_ac_set_data_flag_1_if_data_flag_eq_0, + llc_conn_ac_clear_remote_busy_if_f_eq_1, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_9b = { + llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns, + LLC_CONN_STATE_BUSY, + llc_busy_ev_qfyrs_9b, + llc_busy_actions_9b +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_10a[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_busy_actions_10a[] = { + llc_conn_ac_opt_send_rnr_xxx_x_set_0, + llc_conn_ac_upd_nr_received, + llc_conn_ac_set_data_flag_1_if_data_flag_eq_0, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_10a = { + llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns, + LLC_CONN_STATE_BUSY, + llc_busy_ev_qfyrs_10a, + llc_busy_actions_10a +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_10b[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_busy_actions_10b[] = { + llc_conn_ac_opt_send_rnr_xxx_x_set_0, + llc_conn_ac_upd_nr_received, + llc_conn_ac_set_data_flag_1_if_data_flag_eq_0, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_10b = { + llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns, + LLC_CONN_STATE_BUSY, + llc_busy_ev_qfyrs_10b, + llc_busy_actions_10b +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns event */ +static llc_conn_action_t llc_busy_actions_11[] = { + llc_conn_ac_send_rnr_rsp_f_set_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_set_data_flag_1_if_data_flag_eq_0, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_11 = { + llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns, + LLC_CONN_STATE_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_busy_actions_11 +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_busy_actions_12[] = { + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_data_ind, + llc_conn_ac_send_rnr_rsp_f_set_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2, + llc_conn_ac_set_data_flag_0, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_12 = { + llc_conn_ev_rx_i_cmd_pbit_set_1, + LLC_CONN_STATE_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_busy_actions_12 +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_X event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_13a[] = { + llc_conn_ev_qlfy_p_flag_eq_f, + NULL +}; + +static llc_conn_action_t llc_busy_actions_13a[] = { + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_data_ind, + llc_conn_ac_upd_p_flag, + llc_conn_ac_opt_send_rnr_xxx_x_set_0, + llc_conn_ac_upd_nr_received, + llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2, + llc_conn_ac_set_data_flag_0, + llc_conn_ac_clear_remote_busy_if_f_eq_1, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_13a = { + llc_conn_ev_rx_i_rsp_fbit_set_x, + LLC_CONN_STATE_BUSY, + llc_busy_ev_qfyrs_13a, + llc_busy_actions_13a +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_13b[] = { + llc_conn_ev_qlfy_p_flag_eq_0, + NULL +}; + +static llc_conn_action_t llc_busy_actions_13b[] = { + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_data_ind, + llc_conn_ac_upd_p_flag, + llc_conn_ac_opt_send_rnr_xxx_x_set_0, + llc_conn_ac_upd_nr_received, + llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2, + llc_conn_ac_set_data_flag_0, + llc_conn_ac_clear_remote_busy_if_f_eq_1, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_13b = { + llc_conn_ev_rx_i_cmd_pbit_set_0, + LLC_CONN_STATE_BUSY, + llc_busy_ev_qfyrs_13b, + llc_busy_actions_13b +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0 event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_14a[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_busy_actions_14a[] = { + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_data_ind, + llc_conn_ac_opt_send_rnr_xxx_x_set_0, + llc_conn_ac_upd_nr_received, + llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2, + llc_conn_ac_set_data_flag_0, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_14a = { + llc_conn_ev_rx_i_rsp_fbit_set_0, + LLC_CONN_STATE_BUSY, + llc_busy_ev_qfyrs_14a, + llc_busy_actions_14a +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_14b[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_busy_actions_14b[] = { + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_data_ind, + llc_conn_ac_opt_send_rnr_xxx_x_set_0, + llc_conn_ac_upd_nr_received, + llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2, + llc_conn_ac_set_data_flag_0, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_14b = { + llc_conn_ev_rx_i_cmd_pbit_set_0, + LLC_CONN_STATE_BUSY, + llc_busy_ev_qfyrs_14b, + llc_busy_actions_14b +}; + +/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0 event */ +static llc_conn_action_t llc_busy_actions_15a[] = { + llc_conn_ac_upd_p_flag, + llc_conn_ac_upd_nr_received, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_15a = { + llc_conn_ev_rx_rr_cmd_pbit_set_0, + LLC_CONN_STATE_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_busy_actions_15a +}; + +/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0 event */ +static llc_conn_action_t llc_busy_actions_15b[] = { + llc_conn_ac_upd_p_flag, + llc_conn_ac_upd_nr_received, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_15b = { + llc_conn_ev_rx_rr_rsp_fbit_set_0, + LLC_CONN_STATE_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_busy_actions_15b +}; + +/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1 event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_15c[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_busy_actions_15c[] = { + llc_conn_ac_upd_p_flag, + llc_conn_ac_upd_nr_received, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_15c = { + llc_conn_ev_rx_rr_rsp_fbit_set_1, + LLC_CONN_STATE_BUSY, + llc_busy_ev_qfyrs_15c, + llc_busy_actions_15c +}; + +/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_busy_actions_16[] = { + llc_conn_ac_send_rnr_rsp_f_set_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_16 = { + llc_conn_ev_rx_rr_cmd_pbit_set_1, + LLC_CONN_STATE_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_busy_actions_16 +}; + +/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0 event */ +static llc_conn_action_t llc_busy_actions_17a[] = { + llc_conn_ac_upd_p_flag, + llc_conn_ac_upd_nr_received, + llc_conn_ac_set_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_17a = { + llc_conn_ev_rx_rnr_cmd_pbit_set_0, + LLC_CONN_STATE_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_busy_actions_17a +}; + +/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0 event */ +static llc_conn_action_t llc_busy_actions_17b[] = { + llc_conn_ac_upd_p_flag, + llc_conn_ac_upd_nr_received, + llc_conn_ac_set_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_17b = { + llc_conn_ev_rx_rnr_rsp_fbit_set_0, + LLC_CONN_STATE_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_busy_actions_17b +}; + +/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1 event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_17c[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_busy_actions_17c[] = { + llc_conn_ac_upd_p_flag, + llc_conn_ac_upd_nr_received, + llc_conn_ac_set_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_17c = { + llc_conn_ev_rx_rnr_rsp_fbit_set_1, + LLC_CONN_STATE_BUSY, + llc_busy_ev_qfyrs_17c, + llc_busy_actions_17c +}; + +/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_busy_actions_18[] = { + llc_conn_ac_send_rnr_rsp_f_set_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_set_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_18 = { + llc_conn_ev_rx_rnr_cmd_pbit_set_1, + LLC_CONN_STATE_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_busy_actions_18 +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_19a[] = { + llc_conn_ev_qlfy_p_flag_eq_0, + NULL +}; + +static llc_conn_action_t llc_busy_actions_19a[] = { + llc_conn_ac_set_vs_nr, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_p_flag, + llc_conn_ac_resend_i_xxx_x_set_0, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_19a = { + llc_conn_ev_rx_rej_cmd_pbit_set_0, + LLC_CONN_STATE_BUSY, + llc_busy_ev_qfyrs_19a, + llc_busy_actions_19a +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_X event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_19b[] = { + llc_conn_ev_qlfy_p_flag_eq_f, + NULL +}; + +static llc_conn_action_t llc_busy_actions_19b[] = { + llc_conn_ac_set_vs_nr, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_p_flag, + llc_conn_ac_resend_i_xxx_x_set_0, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_19b = { + llc_conn_ev_rx_rej_rsp_fbit_set_x, + LLC_CONN_STATE_BUSY, + llc_busy_ev_qfyrs_19b, + llc_busy_actions_19b +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_20a[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_busy_actions_20a[] = { + llc_conn_ac_set_vs_nr, + llc_conn_ac_upd_nr_received, + llc_conn_ac_resend_i_xxx_x_set_0, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_20a = { + llc_conn_ev_rx_rej_cmd_pbit_set_0, + LLC_CONN_STATE_BUSY, + llc_busy_ev_qfyrs_20a, + llc_busy_actions_20a +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0 event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_20b[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_busy_actions_20b[] = { + llc_conn_ac_set_vs_nr, + llc_conn_ac_upd_nr_received, + llc_conn_ac_resend_i_xxx_x_set_0, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_20b = { + llc_conn_ev_rx_rej_rsp_fbit_set_0, + LLC_CONN_STATE_BUSY, + llc_busy_ev_qfyrs_20b, + llc_busy_actions_20b +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_busy_actions_21[] = { + llc_conn_ac_set_vs_nr, + llc_conn_ac_upd_nr_received, + llc_conn_ac_send_rnr_rsp_f_set_1, + llc_conn_ac_resend_i_xxx_x_set_0, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_21 = { + llc_conn_ev_rx_rej_cmd_pbit_set_1, + LLC_CONN_STATE_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_busy_actions_21 +}; + +/* State transitions for LLC_CONN_EV_INIT_P_F_CYCLE event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_22[] = { + llc_conn_ev_qlfy_p_flag_eq_0, + NULL +}; + +static llc_conn_action_t llc_busy_actions_22[] = { + llc_conn_ac_send_rnr_cmd_p_set_1, + llc_conn_ac_start_p_timer, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_22 = { + llc_conn_ev_init_p_f_cycle, + LLC_CONN_STATE_BUSY, + llc_busy_ev_qfyrs_22, + llc_busy_actions_22 +}; + +/* State transitions for LLC_CONN_EV_P_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_23[] = { + llc_conn_ev_qlfy_retry_cnt_lt_n2, + NULL +}; + +static llc_conn_action_t llc_busy_actions_23[] = { + llc_conn_ac_send_rnr_cmd_p_set_1, + llc_conn_ac_rst_vs, + llc_conn_ac_start_p_timer, + llc_conn_ac_inc_retry_cnt_by_1, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_23 = { + llc_conn_ev_p_tmr_exp, + LLC_CONN_STATE_AWAIT_BUSY, + llc_busy_ev_qfyrs_23, + llc_busy_actions_23 +}; + +/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_24a[] = { + llc_conn_ev_qlfy_p_flag_eq_0, + llc_conn_ev_qlfy_retry_cnt_lt_n2, + NULL +}; + +static llc_conn_action_t llc_busy_actions_24a[] = { + llc_conn_ac_send_rnr_cmd_p_set_1, + llc_conn_ac_start_p_timer, + llc_conn_ac_inc_retry_cnt_by_1, + llc_conn_ac_rst_vs, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_24a = { + llc_conn_ev_ack_tmr_exp, + LLC_CONN_STATE_AWAIT_BUSY, + llc_busy_ev_qfyrs_24a, + llc_busy_actions_24a +}; + +/* State transitions for LLC_CONN_EV_BUSY_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_24b[] = { + llc_conn_ev_qlfy_p_flag_eq_0, + llc_conn_ev_qlfy_retry_cnt_lt_n2, + NULL +}; + +static llc_conn_action_t llc_busy_actions_24b[] = { + llc_conn_ac_send_rnr_cmd_p_set_1, + llc_conn_ac_start_p_timer, + llc_conn_ac_inc_retry_cnt_by_1, + llc_conn_ac_rst_vs, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_24b = { + llc_conn_ev_busy_tmr_exp, + LLC_CONN_STATE_AWAIT_BUSY, + llc_busy_ev_qfyrs_24b, + llc_busy_actions_24b +}; + +/* State transitions for LLC_CONN_EV_REJ_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_25[] = { + llc_conn_ev_qlfy_p_flag_eq_0, + llc_conn_ev_qlfy_retry_cnt_lt_n2, + NULL +}; + +static llc_conn_action_t llc_busy_actions_25[] = { + llc_conn_ac_send_rnr_cmd_p_set_1, + llc_conn_ac_start_p_timer, + llc_conn_ac_inc_retry_cnt_by_1, + llc_conn_ac_rst_vs, + llc_conn_ac_set_data_flag_1, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_25 = { + llc_conn_ev_rej_tmr_exp, + LLC_CONN_STATE_AWAIT_BUSY, + llc_busy_ev_qfyrs_25, + llc_busy_actions_25 +}; + +/* State transitions for LLC_CONN_EV_REJ_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_26[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + llc_conn_ev_qlfy_retry_cnt_lt_n2, + NULL +}; + +static llc_conn_action_t llc_busy_actions_26[] = { + llc_conn_ac_set_data_flag_1, + NULL +}; + +static struct llc_conn_state_trans llc_busy_state_trans_26 = { + llc_conn_ev_rej_tmr_exp, + LLC_CONN_STATE_BUSY, + llc_busy_ev_qfyrs_26, + llc_busy_actions_26 +}; + +/* + * Array of pointers; + * one to each transition + */ +static struct llc_conn_state_trans *llc_busy_state_transitions[] = { + &llc_common_state_trans_1, /* Request */ + &llc_common_state_trans_2, + &llc_busy_state_trans_1, + &llc_busy_state_trans_2, + &llc_busy_state_trans_2_1, + &llc_common_state_trans_n, + &llc_busy_state_trans_3, /* Local busy */ + &llc_busy_state_trans_4, + &llc_busy_state_trans_5, + &llc_busy_state_trans_6, + &llc_busy_state_trans_7, + &llc_busy_state_trans_8, + &llc_common_state_trans_n, + &llc_busy_state_trans_22, /* Initiate PF cycle */ + &llc_common_state_trans_n, + &llc_common_state_trans_11a, /* Timer */ + &llc_common_state_trans_11b, + &llc_common_state_trans_11c, + &llc_common_state_trans_11d, + &llc_busy_state_trans_23, + &llc_busy_state_trans_24a, + &llc_busy_state_trans_24b, + &llc_busy_state_trans_25, + &llc_busy_state_trans_26, + &llc_common_state_trans_n, + &llc_busy_state_trans_9a, /* Receive frame */ + &llc_busy_state_trans_9b, + &llc_busy_state_trans_10a, + &llc_busy_state_trans_10b, + &llc_busy_state_trans_11, + &llc_busy_state_trans_12, + &llc_busy_state_trans_13a, + &llc_busy_state_trans_13b, + &llc_busy_state_trans_14a, + &llc_busy_state_trans_14b, + &llc_busy_state_trans_15a, + &llc_busy_state_trans_15b, + &llc_busy_state_trans_15c, + &llc_busy_state_trans_16, + &llc_busy_state_trans_17a, + &llc_busy_state_trans_17b, + &llc_busy_state_trans_17c, + &llc_busy_state_trans_18, + &llc_busy_state_trans_19a, + &llc_busy_state_trans_19b, + &llc_busy_state_trans_20a, + &llc_busy_state_trans_20b, + &llc_busy_state_trans_21, + &llc_common_state_trans_3, + &llc_common_state_trans_4, + &llc_common_state_trans_5, + &llc_common_state_trans_6, + &llc_common_state_trans_7a, + &llc_common_state_trans_7b, + &llc_common_state_trans_8a, + &llc_common_state_trans_8b, + &llc_common_state_trans_8c, + &llc_common_state_trans_9, + /* &llc_common_state_trans_10, */ + &llc_common_state_trans_n +}; + +/* -------------------- LLC_CONN_STATE_REJ transitions ------------------ */ +/* State transitions for LLC_CONN_EV_DATA_REQ event */ +static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_1[] = { + llc_conn_ev_qlfy_remote_busy_eq_0, + llc_conn_ev_qlfy_p_flag_eq_0, + NULL +}; + +static llc_conn_action_t llc_reject_actions_1[] = { + llc_conn_ac_send_i_xxx_x_set_0, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_1 = { + llc_conn_ev_data_req, + LLC_CONN_STATE_REJ, + llc_reject_ev_qfyrs_1, + llc_reject_actions_1 +}; + +/* State transitions for LLC_CONN_EV_DATA_REQ event */ +static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_2[] = { + llc_conn_ev_qlfy_remote_busy_eq_0, + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_reject_actions_2[] = { + llc_conn_ac_send_i_xxx_x_set_0, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_2 = { + llc_conn_ev_data_req, + LLC_CONN_STATE_REJ, + llc_reject_ev_qfyrs_2, + llc_reject_actions_2 +}; + +/* State transitions for LLC_CONN_EV_DATA_REQ event */ +static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_2_1[] = { + llc_conn_ev_qlfy_remote_busy_eq_1, + llc_conn_ev_qlfy_set_status_remote_busy, + NULL +}; + +/* just one member, NULL, .bss zeroes it */ +static llc_conn_action_t llc_reject_actions_2_1[1]; + +static struct llc_conn_state_trans llc_reject_state_trans_2_1 = { + llc_conn_ev_data_req, + LLC_CONN_STATE_REJ, + llc_reject_ev_qfyrs_2_1, + llc_reject_actions_2_1 +}; + + +/* State transitions for LLC_CONN_EV_LOCAL_BUSY_DETECTED event */ +static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_3[] = { + llc_conn_ev_qlfy_p_flag_eq_0, + NULL +}; + +static llc_conn_action_t llc_reject_actions_3[] = { + llc_conn_ac_send_rnr_xxx_x_set_0, + llc_conn_ac_set_data_flag_2, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_3 = { + llc_conn_ev_local_busy_detected, + LLC_CONN_STATE_BUSY, + llc_reject_ev_qfyrs_3, + llc_reject_actions_3 +}; + +/* State transitions for LLC_CONN_EV_LOCAL_BUSY_DETECTED event */ +static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_4[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_reject_actions_4[] = { + llc_conn_ac_send_rnr_xxx_x_set_0, + llc_conn_ac_set_data_flag_2, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_4 = { + llc_conn_ev_local_busy_detected, + LLC_CONN_STATE_BUSY, + llc_reject_ev_qfyrs_4, + llc_reject_actions_4 +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns event */ +static llc_conn_action_t llc_reject_actions_5a[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_p_flag, + llc_conn_ac_clear_remote_busy_if_f_eq_1, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_5a = { + llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns, + LLC_CONN_STATE_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_reject_actions_5a +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns event */ +static llc_conn_action_t llc_reject_actions_5b[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_p_flag, + llc_conn_ac_clear_remote_busy_if_f_eq_1, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_5b = { + llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns, + LLC_CONN_STATE_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_reject_actions_5b +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_1_UNEXPD_Ns event */ +static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_5c[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_reject_actions_5c[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_p_flag, + llc_conn_ac_clear_remote_busy_if_f_eq_1, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_5c = { + llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns, + LLC_CONN_STATE_REJ, + llc_reject_ev_qfyrs_5c, + llc_reject_actions_5c +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns event */ +static llc_conn_action_t llc_reject_actions_6[] = { + llc_conn_ac_send_rr_rsp_f_set_1, + llc_conn_ac_upd_nr_received, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_6 = { + llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns, + LLC_CONN_STATE_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_reject_actions_6 +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_X event */ +static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_7a[] = { + llc_conn_ev_qlfy_p_flag_eq_f, + NULL +}; + +static llc_conn_action_t llc_reject_actions_7a[] = { + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_data_ind, + llc_conn_ac_upd_p_flag, + llc_conn_ac_send_ack_xxx_x_set_0, + llc_conn_ac_upd_nr_received, + llc_conn_ac_clear_remote_busy_if_f_eq_1, + llc_conn_ac_stop_rej_timer, + NULL + +}; + +static struct llc_conn_state_trans llc_reject_state_trans_7a = { + llc_conn_ev_rx_i_rsp_fbit_set_x, + LLC_CONN_STATE_NORMAL, + llc_reject_ev_qfyrs_7a, + llc_reject_actions_7a +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */ +static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_7b[] = { + llc_conn_ev_qlfy_p_flag_eq_0, + NULL +}; + +static llc_conn_action_t llc_reject_actions_7b[] = { + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_data_ind, + llc_conn_ac_upd_p_flag, + llc_conn_ac_send_ack_xxx_x_set_0, + llc_conn_ac_upd_nr_received, + llc_conn_ac_clear_remote_busy_if_f_eq_1, + llc_conn_ac_stop_rej_timer, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_7b = { + llc_conn_ev_rx_i_cmd_pbit_set_0, + LLC_CONN_STATE_NORMAL, + llc_reject_ev_qfyrs_7b, + llc_reject_actions_7b +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0 event */ +static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_8a[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_reject_actions_8a[] = { + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_data_ind, + llc_conn_ac_send_ack_xxx_x_set_0, + llc_conn_ac_upd_nr_received, + llc_conn_ac_stop_rej_timer, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_8a = { + llc_conn_ev_rx_i_rsp_fbit_set_0, + LLC_CONN_STATE_NORMAL, + llc_reject_ev_qfyrs_8a, + llc_reject_actions_8a +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */ +static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_8b[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_reject_actions_8b[] = { + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_data_ind, + llc_conn_ac_send_ack_xxx_x_set_0, + llc_conn_ac_upd_nr_received, + llc_conn_ac_stop_rej_timer, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_8b = { + llc_conn_ev_rx_i_cmd_pbit_set_0, + LLC_CONN_STATE_NORMAL, + llc_reject_ev_qfyrs_8b, + llc_reject_actions_8b +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_reject_actions_9[] = { + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_data_ind, + llc_conn_ac_send_ack_rsp_f_set_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_stop_rej_timer, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_9 = { + llc_conn_ev_rx_i_cmd_pbit_set_1, + LLC_CONN_STATE_NORMAL, + LLC_NO_EVENT_QUALIFIERS, + llc_reject_actions_9 +}; + +/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0 event */ +static llc_conn_action_t llc_reject_actions_10a[] = { + llc_conn_ac_upd_p_flag, + llc_conn_ac_upd_nr_received, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_10a = { + llc_conn_ev_rx_rr_cmd_pbit_set_0, + LLC_CONN_STATE_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_reject_actions_10a +}; + +/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0 event */ +static llc_conn_action_t llc_reject_actions_10b[] = { + llc_conn_ac_upd_p_flag, + llc_conn_ac_upd_nr_received, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_10b = { + llc_conn_ev_rx_rr_rsp_fbit_set_0, + LLC_CONN_STATE_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_reject_actions_10b +}; + +/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1 event */ +static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_10c[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_reject_actions_10c[] = { + llc_conn_ac_upd_p_flag, + llc_conn_ac_upd_nr_received, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_10c = { + llc_conn_ev_rx_rr_rsp_fbit_set_1, + LLC_CONN_STATE_REJ, + llc_reject_ev_qfyrs_10c, + llc_reject_actions_10c +}; + +/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_reject_actions_11[] = { + llc_conn_ac_send_ack_rsp_f_set_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_11 = { + llc_conn_ev_rx_rr_cmd_pbit_set_1, + LLC_CONN_STATE_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_reject_actions_11 +}; + +/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0 event */ +static llc_conn_action_t llc_reject_actions_12a[] = { + llc_conn_ac_upd_p_flag, + llc_conn_ac_upd_nr_received, + llc_conn_ac_set_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_12a = { + llc_conn_ev_rx_rnr_cmd_pbit_set_0, + LLC_CONN_STATE_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_reject_actions_12a +}; + +/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0 event */ +static llc_conn_action_t llc_reject_actions_12b[] = { + llc_conn_ac_upd_p_flag, + llc_conn_ac_upd_nr_received, + llc_conn_ac_set_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_12b = { + llc_conn_ev_rx_rnr_rsp_fbit_set_0, + LLC_CONN_STATE_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_reject_actions_12b +}; + +/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1 event */ +static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_12c[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_reject_actions_12c[] = { + llc_conn_ac_upd_p_flag, + llc_conn_ac_upd_nr_received, + llc_conn_ac_set_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_12c = { + llc_conn_ev_rx_rnr_rsp_fbit_set_1, + LLC_CONN_STATE_REJ, + llc_reject_ev_qfyrs_12c, + llc_reject_actions_12c +}; + +/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_reject_actions_13[] = { + llc_conn_ac_send_rr_rsp_f_set_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_set_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_13 = { + llc_conn_ev_rx_rnr_cmd_pbit_set_1, + LLC_CONN_STATE_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_reject_actions_13 +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */ +static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_14a[] = { + llc_conn_ev_qlfy_p_flag_eq_0, + NULL +}; + +static llc_conn_action_t llc_reject_actions_14a[] = { + llc_conn_ac_set_vs_nr, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_p_flag, + llc_conn_ac_resend_i_xxx_x_set_0, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_14a = { + llc_conn_ev_rx_rej_cmd_pbit_set_0, + LLC_CONN_STATE_REJ, + llc_reject_ev_qfyrs_14a, + llc_reject_actions_14a +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_X event */ +static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_14b[] = { + llc_conn_ev_qlfy_p_flag_eq_f, + NULL +}; + +static llc_conn_action_t llc_reject_actions_14b[] = { + llc_conn_ac_set_vs_nr, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_p_flag, + llc_conn_ac_resend_i_xxx_x_set_0, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_14b = { + llc_conn_ev_rx_rej_rsp_fbit_set_x, + LLC_CONN_STATE_REJ, + llc_reject_ev_qfyrs_14b, + llc_reject_actions_14b +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */ +static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_15a[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_reject_actions_15a[] = { + llc_conn_ac_set_vs_nr, + llc_conn_ac_upd_nr_received, + llc_conn_ac_resend_i_xxx_x_set_0, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_15a = { + llc_conn_ev_rx_rej_cmd_pbit_set_0, + LLC_CONN_STATE_REJ, + llc_reject_ev_qfyrs_15a, + llc_reject_actions_15a +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0 event */ +static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_15b[] = { + llc_conn_ev_qlfy_p_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_reject_actions_15b[] = { + llc_conn_ac_set_vs_nr, + llc_conn_ac_upd_nr_received, + llc_conn_ac_resend_i_xxx_x_set_0, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_15b = { + llc_conn_ev_rx_rej_rsp_fbit_set_0, + LLC_CONN_STATE_REJ, + llc_reject_ev_qfyrs_15b, + llc_reject_actions_15b +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_reject_actions_16[] = { + llc_conn_ac_set_vs_nr, + llc_conn_ac_upd_nr_received, + llc_conn_ac_resend_i_rsp_f_set_1, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_16 = { + llc_conn_ev_rx_rej_cmd_pbit_set_1, + LLC_CONN_STATE_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_reject_actions_16 +}; + +/* State transitions for LLC_CONN_EV_INIT_P_F_CYCLE event */ +static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_17[] = { + llc_conn_ev_qlfy_p_flag_eq_0, + NULL +}; + +static llc_conn_action_t llc_reject_actions_17[] = { + llc_conn_ac_send_rr_cmd_p_set_1, + llc_conn_ac_start_p_timer, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_17 = { + llc_conn_ev_init_p_f_cycle, + LLC_CONN_STATE_REJ, + llc_reject_ev_qfyrs_17, + llc_reject_actions_17 +}; + +/* State transitions for LLC_CONN_EV_REJ_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_18[] = { + llc_conn_ev_qlfy_p_flag_eq_0, + llc_conn_ev_qlfy_retry_cnt_lt_n2, + NULL +}; + +static llc_conn_action_t llc_reject_actions_18[] = { + llc_conn_ac_send_rej_cmd_p_set_1, + llc_conn_ac_start_p_timer, + llc_conn_ac_start_rej_timer, + llc_conn_ac_inc_retry_cnt_by_1, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_18 = { + llc_conn_ev_rej_tmr_exp, + LLC_CONN_STATE_REJ, + llc_reject_ev_qfyrs_18, + llc_reject_actions_18 +}; + +/* State transitions for LLC_CONN_EV_P_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_19[] = { + llc_conn_ev_qlfy_retry_cnt_lt_n2, + NULL +}; + +static llc_conn_action_t llc_reject_actions_19[] = { + llc_conn_ac_send_rr_cmd_p_set_1, + llc_conn_ac_start_p_timer, + llc_conn_ac_start_rej_timer, + llc_conn_ac_inc_retry_cnt_by_1, + llc_conn_ac_rst_vs, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_19 = { + llc_conn_ev_p_tmr_exp, + LLC_CONN_STATE_AWAIT_REJ, + llc_reject_ev_qfyrs_19, + llc_reject_actions_19 +}; + +/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_20a[] = { + llc_conn_ev_qlfy_p_flag_eq_0, + llc_conn_ev_qlfy_retry_cnt_lt_n2, + NULL +}; + +static llc_conn_action_t llc_reject_actions_20a[] = { + llc_conn_ac_send_rr_cmd_p_set_1, + llc_conn_ac_start_p_timer, + llc_conn_ac_start_rej_timer, + llc_conn_ac_inc_retry_cnt_by_1, + llc_conn_ac_rst_vs, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_20a = { + llc_conn_ev_ack_tmr_exp, + LLC_CONN_STATE_AWAIT_REJ, + llc_reject_ev_qfyrs_20a, + llc_reject_actions_20a +}; + +/* State transitions for LLC_CONN_EV_BUSY_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_20b[] = { + llc_conn_ev_qlfy_p_flag_eq_0, + llc_conn_ev_qlfy_retry_cnt_lt_n2, + NULL +}; + +static llc_conn_action_t llc_reject_actions_20b[] = { + llc_conn_ac_send_rr_cmd_p_set_1, + llc_conn_ac_start_p_timer, + llc_conn_ac_start_rej_timer, + llc_conn_ac_inc_retry_cnt_by_1, + llc_conn_ac_rst_vs, + NULL +}; + +static struct llc_conn_state_trans llc_reject_state_trans_20b = { + llc_conn_ev_busy_tmr_exp, + LLC_CONN_STATE_AWAIT_REJ, + llc_reject_ev_qfyrs_20b, + llc_reject_actions_20b +}; + +/* + * Array of pointers; + * one to each transition + */ +static struct llc_conn_state_trans *llc_reject_state_transitions[] = { + &llc_common_state_trans_1, /* Request */ + &llc_common_state_trans_2, + &llc_common_state_trans_n, + &llc_reject_state_trans_1, + &llc_reject_state_trans_2, + &llc_reject_state_trans_2_1, + &llc_reject_state_trans_3, /* Local busy */ + &llc_reject_state_trans_4, + &llc_common_state_trans_n, + &llc_reject_state_trans_17, /* Initiate PF cycle */ + &llc_common_state_trans_n, + &llc_common_state_trans_11a, /* Timer */ + &llc_common_state_trans_11b, + &llc_common_state_trans_11c, + &llc_common_state_trans_11d, + &llc_reject_state_trans_18, + &llc_reject_state_trans_19, + &llc_reject_state_trans_20a, + &llc_reject_state_trans_20b, + &llc_common_state_trans_n, + &llc_common_state_trans_3, /* Receive frame */ + &llc_common_state_trans_4, + &llc_common_state_trans_5, + &llc_common_state_trans_6, + &llc_common_state_trans_7a, + &llc_common_state_trans_7b, + &llc_common_state_trans_8a, + &llc_common_state_trans_8b, + &llc_common_state_trans_8c, + &llc_common_state_trans_9, + /* &llc_common_state_trans_10, */ + &llc_reject_state_trans_5a, + &llc_reject_state_trans_5b, + &llc_reject_state_trans_5c, + &llc_reject_state_trans_6, + &llc_reject_state_trans_7a, + &llc_reject_state_trans_7b, + &llc_reject_state_trans_8a, + &llc_reject_state_trans_8b, + &llc_reject_state_trans_9, + &llc_reject_state_trans_10a, + &llc_reject_state_trans_10b, + &llc_reject_state_trans_10c, + &llc_reject_state_trans_11, + &llc_reject_state_trans_12a, + &llc_reject_state_trans_12b, + &llc_reject_state_trans_12c, + &llc_reject_state_trans_13, + &llc_reject_state_trans_14a, + &llc_reject_state_trans_14b, + &llc_reject_state_trans_15a, + &llc_reject_state_trans_15b, + &llc_reject_state_trans_16, + &llc_common_state_trans_n +}; + +/* -------------------- LLC_CONN_STATE_AWAIT transitions ------------------- */ +/* State transitions for LLC_CONN_EV_DATA_REQ event */ +static llc_conn_ev_qfyr_t llc_await_ev_qfyrs_1_0[] = { + llc_conn_ev_qlfy_set_status_refuse, + NULL +}; + +/* just one member, NULL, .bss zeroes it */ +static llc_conn_action_t llc_await_actions_1_0[1]; + +static struct llc_conn_state_trans llc_await_state_trans_1_0 = { + llc_conn_ev_data_req, + LLC_CONN_STATE_AWAIT, + llc_await_ev_qfyrs_1_0, + llc_await_actions_1_0 +}; + +/* State transitions for LLC_CONN_EV_LOCAL_BUSY_DETECTED event */ +static llc_conn_action_t llc_await_actions_1[] = { + llc_conn_ac_send_rnr_xxx_x_set_0, + llc_conn_ac_set_data_flag_0, + NULL +}; + +static struct llc_conn_state_trans llc_await_state_trans_1 = { + llc_conn_ev_local_busy_detected, + LLC_CONN_STATE_AWAIT_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_await_actions_1 +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_1_UNEXPD_Ns event */ +static llc_conn_action_t llc_await_actions_2[] = { + llc_conn_ac_send_rej_xxx_x_set_0, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_stop_p_timer, + llc_conn_ac_resend_i_xxx_x_set_0, + llc_conn_ac_start_rej_timer, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_state_trans_2 = { + llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns, + LLC_CONN_STATE_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_await_actions_2 +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns event */ +static llc_conn_action_t llc_await_actions_3a[] = { + llc_conn_ac_send_rej_xxx_x_set_0, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_start_rej_timer, + NULL +}; + +static struct llc_conn_state_trans llc_await_state_trans_3a = { + llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns, + LLC_CONN_STATE_AWAIT_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_await_actions_3a +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns event */ +static llc_conn_action_t llc_await_actions_3b[] = { + llc_conn_ac_send_rej_xxx_x_set_0, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_start_rej_timer, + NULL +}; + +static struct llc_conn_state_trans llc_await_state_trans_3b = { + llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns, + LLC_CONN_STATE_AWAIT_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_await_actions_3b +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns event */ +static llc_conn_action_t llc_await_actions_4[] = { + llc_conn_ac_send_rej_rsp_f_set_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_start_rej_timer, + llc_conn_ac_start_p_timer, + NULL +}; + +static struct llc_conn_state_trans llc_await_state_trans_4 = { + llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns, + LLC_CONN_STATE_AWAIT_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_await_actions_4 +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_1 event */ +static llc_conn_action_t llc_await_actions_5[] = { + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_data_ind, + llc_conn_ac_stop_p_timer, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_state_trans_5 = { + llc_conn_ev_rx_i_rsp_fbit_set_1, + LLC_CONN_STATE_NORMAL, + LLC_NO_EVENT_QUALIFIERS, + llc_await_actions_5 +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0 event */ +static llc_conn_action_t llc_await_actions_6a[] = { + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_data_ind, + llc_conn_ac_send_rr_xxx_x_set_0, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + NULL +}; + +static struct llc_conn_state_trans llc_await_state_trans_6a = { + llc_conn_ev_rx_i_rsp_fbit_set_0, + LLC_CONN_STATE_AWAIT, + LLC_NO_EVENT_QUALIFIERS, + llc_await_actions_6a +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */ +static llc_conn_action_t llc_await_actions_6b[] = { + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_data_ind, + llc_conn_ac_send_rr_xxx_x_set_0, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + NULL +}; + +static struct llc_conn_state_trans llc_await_state_trans_6b = { + llc_conn_ev_rx_i_cmd_pbit_set_0, + LLC_CONN_STATE_AWAIT, + LLC_NO_EVENT_QUALIFIERS, + llc_await_actions_6b +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_await_actions_7[] = { + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_data_ind, + llc_conn_ac_send_rr_rsp_f_set_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + NULL +}; + +static struct llc_conn_state_trans llc_await_state_trans_7 = { + llc_conn_ev_rx_i_cmd_pbit_set_1, + LLC_CONN_STATE_AWAIT, + LLC_NO_EVENT_QUALIFIERS, + llc_await_actions_7 +}; + +/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1 event */ +static llc_conn_action_t llc_await_actions_8a[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_stop_p_timer, + llc_conn_ac_resend_i_xxx_x_set_0, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_state_trans_8a = { + llc_conn_ev_rx_rr_rsp_fbit_set_1, + LLC_CONN_STATE_NORMAL, + LLC_NO_EVENT_QUALIFIERS, + llc_await_actions_8a +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_1 event */ +static llc_conn_action_t llc_await_actions_8b[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_stop_p_timer, + llc_conn_ac_resend_i_xxx_x_set_0, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_state_trans_8b = { + llc_conn_ev_rx_rej_rsp_fbit_set_1, + LLC_CONN_STATE_NORMAL, + LLC_NO_EVENT_QUALIFIERS, + llc_await_actions_8b +}; + +/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0 event */ +static llc_conn_action_t llc_await_actions_9a[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_state_trans_9a = { + llc_conn_ev_rx_rr_cmd_pbit_set_0, + LLC_CONN_STATE_AWAIT, + LLC_NO_EVENT_QUALIFIERS, + llc_await_actions_9a +}; + +/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0 event */ +static llc_conn_action_t llc_await_actions_9b[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_state_trans_9b = { + llc_conn_ev_rx_rr_rsp_fbit_set_0, + LLC_CONN_STATE_AWAIT, + LLC_NO_EVENT_QUALIFIERS, + llc_await_actions_9b +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */ +static llc_conn_action_t llc_await_actions_9c[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_state_trans_9c = { + llc_conn_ev_rx_rej_cmd_pbit_set_0, + LLC_CONN_STATE_AWAIT, + LLC_NO_EVENT_QUALIFIERS, + llc_await_actions_9c +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0 event */ +static llc_conn_action_t llc_await_actions_9d[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_state_trans_9d = { + llc_conn_ev_rx_rej_rsp_fbit_set_0, + LLC_CONN_STATE_AWAIT, + LLC_NO_EVENT_QUALIFIERS, + llc_await_actions_9d +}; + +/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_await_actions_10a[] = { + llc_conn_ac_send_rr_rsp_f_set_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_state_trans_10a = { + llc_conn_ev_rx_rr_cmd_pbit_set_1, + LLC_CONN_STATE_AWAIT, + LLC_NO_EVENT_QUALIFIERS, + llc_await_actions_10a +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_await_actions_10b[] = { + llc_conn_ac_send_rr_rsp_f_set_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_state_trans_10b = { + llc_conn_ev_rx_rej_cmd_pbit_set_1, + LLC_CONN_STATE_AWAIT, + LLC_NO_EVENT_QUALIFIERS, + llc_await_actions_10b +}; + +/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1 event */ +static llc_conn_action_t llc_await_actions_11[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_stop_p_timer, + llc_conn_ac_set_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_state_trans_11 = { + llc_conn_ev_rx_rnr_rsp_fbit_set_1, + LLC_CONN_STATE_NORMAL, + LLC_NO_EVENT_QUALIFIERS, + llc_await_actions_11 +}; + +/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0 event */ +static llc_conn_action_t llc_await_actions_12a[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_set_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_state_trans_12a = { + llc_conn_ev_rx_rnr_cmd_pbit_set_0, + LLC_CONN_STATE_AWAIT, + LLC_NO_EVENT_QUALIFIERS, + llc_await_actions_12a +}; + +/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0 event */ +static llc_conn_action_t llc_await_actions_12b[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_set_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_state_trans_12b = { + llc_conn_ev_rx_rnr_rsp_fbit_set_0, + LLC_CONN_STATE_AWAIT, + LLC_NO_EVENT_QUALIFIERS, + llc_await_actions_12b +}; + +/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_await_actions_13[] = { + llc_conn_ac_send_rr_rsp_f_set_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_set_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_state_trans_13 = { + llc_conn_ev_rx_rnr_cmd_pbit_set_1, + LLC_CONN_STATE_AWAIT, + LLC_NO_EVENT_QUALIFIERS, + llc_await_actions_13 +}; + +/* State transitions for LLC_CONN_EV_P_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_await_ev_qfyrs_14[] = { + llc_conn_ev_qlfy_retry_cnt_lt_n2, + NULL +}; + +static llc_conn_action_t llc_await_actions_14[] = { + llc_conn_ac_send_rr_cmd_p_set_1, + llc_conn_ac_start_p_timer, + llc_conn_ac_inc_retry_cnt_by_1, + NULL +}; + +static struct llc_conn_state_trans llc_await_state_trans_14 = { + llc_conn_ev_p_tmr_exp, + LLC_CONN_STATE_AWAIT, + llc_await_ev_qfyrs_14, + llc_await_actions_14 +}; + +/* + * Array of pointers; + * one to each transition + */ +static struct llc_conn_state_trans *llc_await_state_transitions[] = { + &llc_common_state_trans_1, /* Request */ + &llc_common_state_trans_2, + &llc_await_state_trans_1_0, + &llc_common_state_trans_n, + &llc_await_state_trans_1, /* Local busy */ + &llc_common_state_trans_n, + &llc_common_state_trans_n, /* Initiate PF Cycle */ + &llc_common_state_trans_11a, /* Timer */ + &llc_common_state_trans_11b, + &llc_common_state_trans_11c, + &llc_common_state_trans_11d, + &llc_await_state_trans_14, + &llc_common_state_trans_n, + &llc_common_state_trans_3, /* Receive frame */ + &llc_common_state_trans_4, + &llc_common_state_trans_5, + &llc_common_state_trans_6, + &llc_common_state_trans_7a, + &llc_common_state_trans_7b, + &llc_common_state_trans_8a, + &llc_common_state_trans_8b, + &llc_common_state_trans_8c, + &llc_common_state_trans_9, + /* &llc_common_state_trans_10, */ + &llc_await_state_trans_2, + &llc_await_state_trans_3a, + &llc_await_state_trans_3b, + &llc_await_state_trans_4, + &llc_await_state_trans_5, + &llc_await_state_trans_6a, + &llc_await_state_trans_6b, + &llc_await_state_trans_7, + &llc_await_state_trans_8a, + &llc_await_state_trans_8b, + &llc_await_state_trans_9a, + &llc_await_state_trans_9b, + &llc_await_state_trans_9c, + &llc_await_state_trans_9d, + &llc_await_state_trans_10a, + &llc_await_state_trans_10b, + &llc_await_state_trans_11, + &llc_await_state_trans_12a, + &llc_await_state_trans_12b, + &llc_await_state_trans_13, + &llc_common_state_trans_n +}; + +/* ------------------ LLC_CONN_STATE_AWAIT_BUSY transitions ---------------- */ +/* State transitions for LLC_CONN_EV_DATA_CONN_REQ event */ +static llc_conn_ev_qfyr_t llc_await_busy_ev_qfyrs_1_0[] = { + llc_conn_ev_qlfy_set_status_refuse, + NULL +}; + +/* just one member, NULL, .bss zeroes it */ +static llc_conn_action_t llc_await_busy_actions_1_0[1]; + +static struct llc_conn_state_trans llc_await_busy_state_trans_1_0 = { + llc_conn_ev_data_req, + LLC_CONN_STATE_AWAIT_BUSY, + llc_await_busy_ev_qfyrs_1_0, + llc_await_busy_actions_1_0 +}; + +/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */ +static llc_conn_ev_qfyr_t llc_await_busy_ev_qfyrs_1[] = { + llc_conn_ev_qlfy_data_flag_eq_1, + NULL +}; + +static llc_conn_action_t llc_await_busy_actions_1[] = { + llc_conn_ac_send_rej_xxx_x_set_0, + llc_conn_ac_start_rej_timer, + NULL +}; + +static struct llc_conn_state_trans llc_await_busy_state_trans_1 = { + llc_conn_ev_local_busy_cleared, + LLC_CONN_STATE_AWAIT_REJ, + llc_await_busy_ev_qfyrs_1, + llc_await_busy_actions_1 +}; + +/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */ +static llc_conn_ev_qfyr_t llc_await_busy_ev_qfyrs_2[] = { + llc_conn_ev_qlfy_data_flag_eq_0, + NULL +}; + +static llc_conn_action_t llc_await_busy_actions_2[] = { + llc_conn_ac_send_rr_xxx_x_set_0, + NULL +}; + +static struct llc_conn_state_trans llc_await_busy_state_trans_2 = { + llc_conn_ev_local_busy_cleared, + LLC_CONN_STATE_AWAIT, + llc_await_busy_ev_qfyrs_2, + llc_await_busy_actions_2 +}; + +/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */ +static llc_conn_ev_qfyr_t llc_await_busy_ev_qfyrs_3[] = { + llc_conn_ev_qlfy_data_flag_eq_2, + NULL +}; + +static llc_conn_action_t llc_await_busy_actions_3[] = { + llc_conn_ac_send_rr_xxx_x_set_0, + NULL +}; + +static struct llc_conn_state_trans llc_await_busy_state_trans_3 = { + llc_conn_ev_local_busy_cleared, + LLC_CONN_STATE_AWAIT_REJ, + llc_await_busy_ev_qfyrs_3, + llc_await_busy_actions_3 +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_1_UNEXPD_Ns event */ +static llc_conn_action_t llc_await_busy_actions_4[] = { + llc_conn_ac_opt_send_rnr_xxx_x_set_0, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_stop_p_timer, + llc_conn_ac_set_data_flag_1, + llc_conn_ac_clear_remote_busy, + llc_conn_ac_resend_i_xxx_x_set_0, + NULL +}; + +static struct llc_conn_state_trans llc_await_busy_state_trans_4 = { + llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns, + LLC_CONN_STATE_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_await_busy_actions_4 +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns event */ +static llc_conn_action_t llc_await_busy_actions_5a[] = { + llc_conn_ac_opt_send_rnr_xxx_x_set_0, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_set_data_flag_1, + NULL +}; + +static struct llc_conn_state_trans llc_await_busy_state_trans_5a = { + llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns, + LLC_CONN_STATE_AWAIT_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_await_busy_actions_5a +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns event */ +static llc_conn_action_t llc_await_busy_actions_5b[] = { + llc_conn_ac_opt_send_rnr_xxx_x_set_0, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_set_data_flag_1, + NULL +}; + +static struct llc_conn_state_trans llc_await_busy_state_trans_5b = { + llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns, + LLC_CONN_STATE_AWAIT_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_await_busy_actions_5b +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns event */ +static llc_conn_action_t llc_await_busy_actions_6[] = { + llc_conn_ac_send_rnr_rsp_f_set_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_set_data_flag_1, + NULL +}; + +static struct llc_conn_state_trans llc_await_busy_state_trans_6 = { + llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns, + LLC_CONN_STATE_AWAIT_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_await_busy_actions_6 +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_1 event */ +static llc_conn_action_t llc_await_busy_actions_7[] = { + llc_conn_ac_opt_send_rnr_xxx_x_set_0, + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_data_ind, + llc_conn_ac_stop_p_timer, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_set_data_flag_0, + llc_conn_ac_clear_remote_busy, + llc_conn_ac_resend_i_xxx_x_set_0, + NULL +}; + +static struct llc_conn_state_trans llc_await_busy_state_trans_7 = { + llc_conn_ev_rx_i_rsp_fbit_set_1, + LLC_CONN_STATE_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_await_busy_actions_7 +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0 event */ +static llc_conn_action_t llc_await_busy_actions_8a[] = { + llc_conn_ac_opt_send_rnr_xxx_x_set_0, + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_data_ind, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_set_data_flag_0, + NULL +}; + +static struct llc_conn_state_trans llc_await_busy_state_trans_8a = { + llc_conn_ev_rx_i_rsp_fbit_set_0, + LLC_CONN_STATE_AWAIT_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_await_busy_actions_8a +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */ +static llc_conn_action_t llc_await_busy_actions_8b[] = { + llc_conn_ac_opt_send_rnr_xxx_x_set_0, + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_data_ind, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_set_data_flag_0, + NULL +}; + +static struct llc_conn_state_trans llc_await_busy_state_trans_8b = { + llc_conn_ev_rx_i_cmd_pbit_set_0, + LLC_CONN_STATE_AWAIT_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_await_busy_actions_8b +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_await_busy_actions_9[] = { + llc_conn_ac_send_rnr_rsp_f_set_1, + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_data_ind, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_set_data_flag_0, + NULL +}; + +static struct llc_conn_state_trans llc_await_busy_state_trans_9 = { + llc_conn_ev_rx_i_cmd_pbit_set_1, + LLC_CONN_STATE_AWAIT_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_await_busy_actions_9 +}; + +/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1 event */ +static llc_conn_action_t llc_await_busy_actions_10a[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_stop_p_timer, + llc_conn_ac_resend_i_xxx_x_set_0, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_busy_state_trans_10a = { + llc_conn_ev_rx_rr_rsp_fbit_set_1, + LLC_CONN_STATE_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_await_busy_actions_10a +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_1 event */ +static llc_conn_action_t llc_await_busy_actions_10b[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_stop_p_timer, + llc_conn_ac_resend_i_xxx_x_set_0, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_busy_state_trans_10b = { + llc_conn_ev_rx_rej_rsp_fbit_set_1, + LLC_CONN_STATE_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_await_busy_actions_10b +}; + +/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0 event */ +static llc_conn_action_t llc_await_busy_actions_11a[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_busy_state_trans_11a = { + llc_conn_ev_rx_rr_cmd_pbit_set_0, + LLC_CONN_STATE_AWAIT_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_await_busy_actions_11a +}; + +/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0 event */ +static llc_conn_action_t llc_await_busy_actions_11b[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_busy_state_trans_11b = { + llc_conn_ev_rx_rr_rsp_fbit_set_0, + LLC_CONN_STATE_AWAIT_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_await_busy_actions_11b +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */ +static llc_conn_action_t llc_await_busy_actions_11c[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_busy_state_trans_11c = { + llc_conn_ev_rx_rej_cmd_pbit_set_0, + LLC_CONN_STATE_AWAIT_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_await_busy_actions_11c +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0 event */ +static llc_conn_action_t llc_await_busy_actions_11d[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_busy_state_trans_11d = { + llc_conn_ev_rx_rej_rsp_fbit_set_0, + LLC_CONN_STATE_AWAIT_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_await_busy_actions_11d +}; + +/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_await_busy_actions_12a[] = { + llc_conn_ac_send_rnr_rsp_f_set_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_busy_state_trans_12a = { + llc_conn_ev_rx_rr_cmd_pbit_set_1, + LLC_CONN_STATE_AWAIT_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_await_busy_actions_12a +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_await_busy_actions_12b[] = { + llc_conn_ac_send_rnr_rsp_f_set_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_busy_state_trans_12b = { + llc_conn_ev_rx_rej_cmd_pbit_set_1, + LLC_CONN_STATE_AWAIT_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_await_busy_actions_12b +}; + +/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1 event */ +static llc_conn_action_t llc_await_busy_actions_13[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_stop_p_timer, + llc_conn_ac_set_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_busy_state_trans_13 = { + llc_conn_ev_rx_rnr_rsp_fbit_set_1, + LLC_CONN_STATE_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_await_busy_actions_13 +}; + +/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0 event */ +static llc_conn_action_t llc_await_busy_actions_14a[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_set_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_busy_state_trans_14a = { + llc_conn_ev_rx_rnr_cmd_pbit_set_0, + LLC_CONN_STATE_AWAIT_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_await_busy_actions_14a +}; + +/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0 event */ +static llc_conn_action_t llc_await_busy_actions_14b[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_set_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_busy_state_trans_14b = { + llc_conn_ev_rx_rnr_rsp_fbit_set_0, + LLC_CONN_STATE_AWAIT_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_await_busy_actions_14b +}; + +/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_await_busy_actions_15[] = { + llc_conn_ac_send_rnr_rsp_f_set_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_set_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_busy_state_trans_15 = { + llc_conn_ev_rx_rnr_cmd_pbit_set_1, + LLC_CONN_STATE_AWAIT_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_await_busy_actions_15 +}; + +/* State transitions for LLC_CONN_EV_P_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_await_busy_ev_qfyrs_16[] = { + llc_conn_ev_qlfy_retry_cnt_lt_n2, + NULL +}; + +static llc_conn_action_t llc_await_busy_actions_16[] = { + llc_conn_ac_send_rnr_cmd_p_set_1, + llc_conn_ac_start_p_timer, + llc_conn_ac_inc_retry_cnt_by_1, + NULL +}; + +static struct llc_conn_state_trans llc_await_busy_state_trans_16 = { + llc_conn_ev_p_tmr_exp, + LLC_CONN_STATE_AWAIT_BUSY, + llc_await_busy_ev_qfyrs_16, + llc_await_busy_actions_16 +}; + +/* + * Array of pointers; + * one to each transition + */ +static struct llc_conn_state_trans *llc_await_busy_state_transitions[] = { + &llc_common_state_trans_1, /* Request */ + &llc_common_state_trans_2, + &llc_await_busy_state_trans_1_0, + &llc_common_state_trans_n, + &llc_await_busy_state_trans_1, /* Local busy */ + &llc_await_busy_state_trans_2, + &llc_await_busy_state_trans_3, + &llc_common_state_trans_n, + &llc_common_state_trans_n, /* Initiate PF cycle */ + &llc_common_state_trans_11a, /* Timer */ + &llc_common_state_trans_11b, + &llc_common_state_trans_11c, + &llc_common_state_trans_11d, + &llc_await_busy_state_trans_16, + &llc_common_state_trans_n, + &llc_await_busy_state_trans_4, /* Receive frame */ + &llc_await_busy_state_trans_5a, + &llc_await_busy_state_trans_5b, + &llc_await_busy_state_trans_6, + &llc_await_busy_state_trans_7, + &llc_await_busy_state_trans_8a, + &llc_await_busy_state_trans_8b, + &llc_await_busy_state_trans_9, + &llc_await_busy_state_trans_10a, + &llc_await_busy_state_trans_10b, + &llc_await_busy_state_trans_11a, + &llc_await_busy_state_trans_11b, + &llc_await_busy_state_trans_11c, + &llc_await_busy_state_trans_11d, + &llc_await_busy_state_trans_12a, + &llc_await_busy_state_trans_12b, + &llc_await_busy_state_trans_13, + &llc_await_busy_state_trans_14a, + &llc_await_busy_state_trans_14b, + &llc_await_busy_state_trans_15, + &llc_common_state_trans_3, + &llc_common_state_trans_4, + &llc_common_state_trans_5, + &llc_common_state_trans_6, + &llc_common_state_trans_7a, + &llc_common_state_trans_7b, + &llc_common_state_trans_8a, + &llc_common_state_trans_8b, + &llc_common_state_trans_8c, + &llc_common_state_trans_9, + /* &llc_common_state_trans_10, */ + &llc_common_state_trans_n +}; + +/* ----------------- LLC_CONN_STATE_AWAIT_REJ transitions --------------- */ +/* State transitions for LLC_CONN_EV_DATA_CONN_REQ event */ +static llc_conn_ev_qfyr_t llc_await_reject_ev_qfyrs_1_0[] = { + llc_conn_ev_qlfy_set_status_refuse, + NULL +}; + +/* just one member, NULL, .bss zeroes it */ +static llc_conn_action_t llc_await_reject_actions_1_0[1]; + +static struct llc_conn_state_trans llc_await_reject_state_trans_1_0 = { + llc_conn_ev_data_req, + LLC_CONN_STATE_AWAIT_REJ, + llc_await_reject_ev_qfyrs_1_0, + llc_await_reject_actions_1_0 +}; + +/* State transitions for LLC_CONN_EV_LOCAL_BUSY_DETECTED event */ +static llc_conn_action_t llc_await_rejct_actions_1[] = { + llc_conn_ac_send_rnr_xxx_x_set_0, + llc_conn_ac_set_data_flag_2, + NULL +}; + +static struct llc_conn_state_trans llc_await_rejct_state_trans_1 = { + llc_conn_ev_local_busy_detected, + LLC_CONN_STATE_AWAIT_BUSY, + LLC_NO_EVENT_QUALIFIERS, + llc_await_rejct_actions_1 +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns event */ +static llc_conn_action_t llc_await_rejct_actions_2a[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + NULL +}; + +static struct llc_conn_state_trans llc_await_rejct_state_trans_2a = { + llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns, + LLC_CONN_STATE_AWAIT_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_await_rejct_actions_2a +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns event */ +static llc_conn_action_t llc_await_rejct_actions_2b[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + NULL +}; + +static struct llc_conn_state_trans llc_await_rejct_state_trans_2b = { + llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns, + LLC_CONN_STATE_AWAIT_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_await_rejct_actions_2b +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns event */ +static llc_conn_action_t llc_await_rejct_actions_3[] = { + llc_conn_ac_send_rr_rsp_f_set_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + NULL +}; + +static struct llc_conn_state_trans llc_await_rejct_state_trans_3 = { + llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns, + LLC_CONN_STATE_AWAIT_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_await_rejct_actions_3 +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_1 event */ +static llc_conn_action_t llc_await_rejct_actions_4[] = { + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_data_ind, + llc_conn_ac_stop_p_timer, + llc_conn_ac_stop_rej_timer, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_rejct_state_trans_4 = { + llc_conn_ev_rx_i_rsp_fbit_set_1, + LLC_CONN_STATE_NORMAL, + LLC_NO_EVENT_QUALIFIERS, + llc_await_rejct_actions_4 +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0 event */ +static llc_conn_action_t llc_await_rejct_actions_5a[] = { + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_data_ind, + llc_conn_ac_send_rr_xxx_x_set_0, + llc_conn_ac_stop_rej_timer, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + NULL +}; + +static struct llc_conn_state_trans llc_await_rejct_state_trans_5a = { + llc_conn_ev_rx_i_rsp_fbit_set_0, + LLC_CONN_STATE_AWAIT, + LLC_NO_EVENT_QUALIFIERS, + llc_await_rejct_actions_5a +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */ +static llc_conn_action_t llc_await_rejct_actions_5b[] = { + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_data_ind, + llc_conn_ac_send_rr_xxx_x_set_0, + llc_conn_ac_stop_rej_timer, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + NULL +}; + +static struct llc_conn_state_trans llc_await_rejct_state_trans_5b = { + llc_conn_ev_rx_i_cmd_pbit_set_0, LLC_CONN_STATE_AWAIT, + LLC_NO_EVENT_QUALIFIERS, llc_await_rejct_actions_5b +}; + +/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_await_rejct_actions_6[] = { + llc_conn_ac_inc_vr_by_1, + llc_conn_ac_data_ind, + llc_conn_ac_send_rr_rsp_f_set_1, + llc_conn_ac_stop_rej_timer, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + NULL +}; + +static struct llc_conn_state_trans llc_await_rejct_state_trans_6 = { + llc_conn_ev_rx_i_cmd_pbit_set_1, + LLC_CONN_STATE_AWAIT, + LLC_NO_EVENT_QUALIFIERS, + llc_await_rejct_actions_6 +}; + +/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1 event */ +static llc_conn_action_t llc_await_rejct_actions_7a[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_stop_p_timer, + llc_conn_ac_resend_i_xxx_x_set_0, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_rejct_state_trans_7a = { + llc_conn_ev_rx_rr_rsp_fbit_set_1, + LLC_CONN_STATE_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_await_rejct_actions_7a +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_1 event */ +static llc_conn_action_t llc_await_rejct_actions_7b[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_stop_p_timer, + llc_conn_ac_resend_i_xxx_x_set_0, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_rejct_state_trans_7b = { + llc_conn_ev_rx_rej_rsp_fbit_set_1, + LLC_CONN_STATE_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_await_rejct_actions_7b +}; + +/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_1_UNEXPD_Ns event */ +static llc_conn_action_t llc_await_rejct_actions_7c[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_stop_p_timer, + llc_conn_ac_resend_i_xxx_x_set_0, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_rejct_state_trans_7c = { + llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns, + LLC_CONN_STATE_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_await_rejct_actions_7c +}; + +/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0 event */ +static llc_conn_action_t llc_await_rejct_actions_8a[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_rejct_state_trans_8a = { + llc_conn_ev_rx_rr_cmd_pbit_set_0, + LLC_CONN_STATE_AWAIT_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_await_rejct_actions_8a +}; + +/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0 event */ +static llc_conn_action_t llc_await_rejct_actions_8b[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_rejct_state_trans_8b = { + llc_conn_ev_rx_rr_rsp_fbit_set_0, + LLC_CONN_STATE_AWAIT_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_await_rejct_actions_8b +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */ +static llc_conn_action_t llc_await_rejct_actions_8c[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_rejct_state_trans_8c = { + llc_conn_ev_rx_rej_cmd_pbit_set_0, + LLC_CONN_STATE_AWAIT_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_await_rejct_actions_8c +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0 event */ +static llc_conn_action_t llc_await_rejct_actions_8d[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_rejct_state_trans_8d = { + llc_conn_ev_rx_rej_rsp_fbit_set_0, + LLC_CONN_STATE_AWAIT_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_await_rejct_actions_8d +}; + +/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_await_rejct_actions_9a[] = { + llc_conn_ac_send_rr_rsp_f_set_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_rejct_state_trans_9a = { + llc_conn_ev_rx_rr_cmd_pbit_set_1, + LLC_CONN_STATE_AWAIT_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_await_rejct_actions_9a +}; + +/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_await_rejct_actions_9b[] = { + llc_conn_ac_send_rr_rsp_f_set_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_clear_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_rejct_state_trans_9b = { + llc_conn_ev_rx_rej_cmd_pbit_set_1, + LLC_CONN_STATE_AWAIT_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_await_rejct_actions_9b +}; + +/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1 event */ +static llc_conn_action_t llc_await_rejct_actions_10[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_stop_p_timer, + llc_conn_ac_set_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_rejct_state_trans_10 = { + llc_conn_ev_rx_rnr_rsp_fbit_set_1, + LLC_CONN_STATE_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_await_rejct_actions_10 +}; + +/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0 event */ +static llc_conn_action_t llc_await_rejct_actions_11a[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_set_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_rejct_state_trans_11a = { + llc_conn_ev_rx_rnr_cmd_pbit_set_0, + LLC_CONN_STATE_AWAIT_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_await_rejct_actions_11a +}; + +/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0 event */ +static llc_conn_action_t llc_await_rejct_actions_11b[] = { + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_set_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_rejct_state_trans_11b = { + llc_conn_ev_rx_rnr_rsp_fbit_set_0, + LLC_CONN_STATE_AWAIT_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_await_rejct_actions_11b +}; + +/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1 event */ +static llc_conn_action_t llc_await_rejct_actions_12[] = { + llc_conn_ac_send_rr_rsp_f_set_1, + llc_conn_ac_upd_nr_received, + llc_conn_ac_upd_vs, + llc_conn_ac_set_remote_busy, + NULL +}; + +static struct llc_conn_state_trans llc_await_rejct_state_trans_12 = { + llc_conn_ev_rx_rnr_cmd_pbit_set_1, + LLC_CONN_STATE_AWAIT_REJ, + LLC_NO_EVENT_QUALIFIERS, + llc_await_rejct_actions_12 +}; + +/* State transitions for LLC_CONN_EV_P_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_await_rejct_ev_qfyrs_13[] = { + llc_conn_ev_qlfy_retry_cnt_lt_n2, + NULL +}; + +static llc_conn_action_t llc_await_rejct_actions_13[] = { + llc_conn_ac_send_rej_cmd_p_set_1, + llc_conn_ac_stop_p_timer, + llc_conn_ac_inc_retry_cnt_by_1, + NULL +}; + +static struct llc_conn_state_trans llc_await_rejct_state_trans_13 = { + llc_conn_ev_p_tmr_exp, + LLC_CONN_STATE_AWAIT_REJ, + llc_await_rejct_ev_qfyrs_13, + llc_await_rejct_actions_13 +}; + +/* + * Array of pointers; + * one to each transition + */ +static struct llc_conn_state_trans *llc_await_rejct_state_transitions[] = { + &llc_await_reject_state_trans_1_0, + &llc_common_state_trans_1, /* requests */ + &llc_common_state_trans_2, + &llc_common_state_trans_n, + &llc_await_rejct_state_trans_1, /* local busy */ + &llc_common_state_trans_n, + &llc_common_state_trans_n, /* Initiate PF cycle */ + &llc_await_rejct_state_trans_13, /* timers */ + &llc_common_state_trans_11a, + &llc_common_state_trans_11b, + &llc_common_state_trans_11c, + &llc_common_state_trans_11d, + &llc_common_state_trans_n, + &llc_await_rejct_state_trans_2a, /* receive frames */ + &llc_await_rejct_state_trans_2b, + &llc_await_rejct_state_trans_3, + &llc_await_rejct_state_trans_4, + &llc_await_rejct_state_trans_5a, + &llc_await_rejct_state_trans_5b, + &llc_await_rejct_state_trans_6, + &llc_await_rejct_state_trans_7a, + &llc_await_rejct_state_trans_7b, + &llc_await_rejct_state_trans_7c, + &llc_await_rejct_state_trans_8a, + &llc_await_rejct_state_trans_8b, + &llc_await_rejct_state_trans_8c, + &llc_await_rejct_state_trans_8d, + &llc_await_rejct_state_trans_9a, + &llc_await_rejct_state_trans_9b, + &llc_await_rejct_state_trans_10, + &llc_await_rejct_state_trans_11a, + &llc_await_rejct_state_trans_11b, + &llc_await_rejct_state_trans_12, + &llc_common_state_trans_3, + &llc_common_state_trans_4, + &llc_common_state_trans_5, + &llc_common_state_trans_6, + &llc_common_state_trans_7a, + &llc_common_state_trans_7b, + &llc_common_state_trans_8a, + &llc_common_state_trans_8b, + &llc_common_state_trans_8c, + &llc_common_state_trans_9, + /* &llc_common_state_trans_10, */ + &llc_common_state_trans_n +}; + +/* -------------------- LLC_CONN_STATE_D_CONN transitions ------------------ */ +/* State transitions for LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X event, + * cause_flag = 1 */ +static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_1[] = { + llc_conn_ev_qlfy_cause_flag_eq_1, + llc_conn_ev_qlfy_set_status_conflict, + NULL +}; + +static llc_conn_action_t llc_d_conn_actions_1[] = { + llc_conn_ac_send_dm_rsp_f_set_p, + llc_conn_ac_stop_ack_timer, + llc_conn_ac_disc_confirm, + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_d_conn_state_trans_1 = { + llc_conn_ev_rx_sabme_cmd_pbit_set_x, + LLC_CONN_STATE_ADM, + llc_d_conn_ev_qfyrs_1, + llc_d_conn_actions_1 +}; + +/* State transitions for LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X event, + * cause_flag = 0 + */ +static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_1_1[] = { + llc_conn_ev_qlfy_cause_flag_eq_0, + llc_conn_ev_qlfy_set_status_conflict, + NULL +}; + +static llc_conn_action_t llc_d_conn_actions_1_1[] = { + llc_conn_ac_send_dm_rsp_f_set_p, + llc_conn_ac_stop_ack_timer, + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_d_conn_state_trans_1_1 = { + llc_conn_ev_rx_sabme_cmd_pbit_set_x, + LLC_CONN_STATE_ADM, + llc_d_conn_ev_qfyrs_1_1, + llc_d_conn_actions_1_1 +}; + +/* State transitions for LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X event, + * cause_flag = 1 */ +static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_2[] = { + llc_conn_ev_qlfy_p_flag_eq_f, + llc_conn_ev_qlfy_cause_flag_eq_1, + llc_conn_ev_qlfy_set_status_disc, + NULL +}; + +static llc_conn_action_t llc_d_conn_actions_2[] = { + llc_conn_ac_stop_ack_timer, + llc_conn_ac_disc_confirm, + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_d_conn_state_trans_2 = { + llc_conn_ev_rx_ua_rsp_fbit_set_x, + LLC_CONN_STATE_ADM, + llc_d_conn_ev_qfyrs_2, + llc_d_conn_actions_2 +}; + +/* State transitions for LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X event, + * cause_flag = 0 */ +static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_2_1[] = { + llc_conn_ev_qlfy_p_flag_eq_f, + llc_conn_ev_qlfy_cause_flag_eq_0, + llc_conn_ev_qlfy_set_status_disc, + NULL +}; + +static llc_conn_action_t llc_d_conn_actions_2_1[] = { + llc_conn_ac_stop_ack_timer, + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_d_conn_state_trans_2_1 = { + llc_conn_ev_rx_ua_rsp_fbit_set_x, + LLC_CONN_STATE_ADM, + llc_d_conn_ev_qfyrs_2_1, + llc_d_conn_actions_2_1 +}; + +/* State transitions for LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X event */ +static llc_conn_action_t llc_d_conn_actions_3[] = { + llc_conn_ac_send_ua_rsp_f_set_p, + NULL +}; + +static struct llc_conn_state_trans llc_d_conn_state_trans_3 = { + llc_conn_ev_rx_disc_cmd_pbit_set_x, + LLC_CONN_STATE_D_CONN, + LLC_NO_EVENT_QUALIFIERS, + llc_d_conn_actions_3 +}; + +/* State transitions for LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X event, + * cause_flag = 1 */ +static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_4[] = { + llc_conn_ev_qlfy_cause_flag_eq_1, + llc_conn_ev_qlfy_set_status_disc, + NULL +}; + +static llc_conn_action_t llc_d_conn_actions_4[] = { + llc_conn_ac_stop_ack_timer, + llc_conn_ac_disc_confirm, + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_d_conn_state_trans_4 = { + llc_conn_ev_rx_dm_rsp_fbit_set_x, + LLC_CONN_STATE_ADM, + llc_d_conn_ev_qfyrs_4, + llc_d_conn_actions_4 +}; + +/* State transitions for LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X event, + * cause_flag = 0 */ +static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_4_1[] = { + llc_conn_ev_qlfy_cause_flag_eq_0, + llc_conn_ev_qlfy_set_status_disc, + NULL +}; + +static llc_conn_action_t llc_d_conn_actions_4_1[] = { + llc_conn_ac_stop_ack_timer, + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_d_conn_state_trans_4_1 = { + llc_conn_ev_rx_dm_rsp_fbit_set_x, + LLC_CONN_STATE_ADM, + llc_d_conn_ev_qfyrs_4_1, + llc_d_conn_actions_4_1 +}; + +/* + * State transition for + * LLC_CONN_EV_DATA_CONN_REQ event + */ +static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_5[] = { + llc_conn_ev_qlfy_set_status_refuse, + NULL +}; + +/* just one member, NULL, .bss zeroes it */ +static llc_conn_action_t llc_d_conn_actions_5[1]; + +static struct llc_conn_state_trans llc_d_conn_state_trans_5 = { + llc_conn_ev_data_req, LLC_CONN_STATE_D_CONN, + llc_d_conn_ev_qfyrs_5, llc_d_conn_actions_5 +}; + +/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_6[] = { + llc_conn_ev_qlfy_retry_cnt_lt_n2, + NULL +}; + +static llc_conn_action_t llc_d_conn_actions_6[] = { + llc_conn_ac_send_disc_cmd_p_set_x, + llc_conn_ac_start_ack_timer, + llc_conn_ac_inc_retry_cnt_by_1, + NULL +}; + +static struct llc_conn_state_trans llc_d_conn_state_trans_6 = { + llc_conn_ev_ack_tmr_exp, + LLC_CONN_STATE_D_CONN, + llc_d_conn_ev_qfyrs_6, + llc_d_conn_actions_6 +}; + +/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event, cause_flag = 1 */ +static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_7[] = { + llc_conn_ev_qlfy_retry_cnt_gte_n2, + llc_conn_ev_qlfy_cause_flag_eq_1, + llc_conn_ev_qlfy_set_status_failed, + NULL +}; + +static llc_conn_action_t llc_d_conn_actions_7[] = { + llc_conn_ac_disc_confirm, + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_d_conn_state_trans_7 = { + llc_conn_ev_ack_tmr_exp, + LLC_CONN_STATE_ADM, + llc_d_conn_ev_qfyrs_7, + llc_d_conn_actions_7 +}; + +/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event, cause_flag = 0 */ +static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_8[] = { + llc_conn_ev_qlfy_retry_cnt_gte_n2, + llc_conn_ev_qlfy_cause_flag_eq_0, + llc_conn_ev_qlfy_set_status_failed, + NULL +}; + +static llc_conn_action_t llc_d_conn_actions_8[] = { + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_d_conn_state_trans_8 = { + llc_conn_ev_ack_tmr_exp, + LLC_CONN_STATE_ADM, + llc_d_conn_ev_qfyrs_8, + llc_d_conn_actions_8 +}; + +/* + * Array of pointers; + * one to each transition + */ +static struct llc_conn_state_trans *llc_d_conn_state_transitions[] = { + &llc_d_conn_state_trans_5, /* Request */ + &llc_common_state_trans_n, + &llc_common_state_trans_n, /* Local busy */ + &llc_common_state_trans_n, /* Initiate PF cycle */ + &llc_d_conn_state_trans_6, /* Timer */ + &llc_d_conn_state_trans_7, + &llc_d_conn_state_trans_8, + &llc_common_state_trans_n, + &llc_d_conn_state_trans_1, /* Receive frame */ + &llc_d_conn_state_trans_1_1, + &llc_d_conn_state_trans_2, + &llc_d_conn_state_trans_2_1, + &llc_d_conn_state_trans_3, + &llc_d_conn_state_trans_4, + &llc_d_conn_state_trans_4_1, + &llc_common_state_trans_n +}; + +/* -------------------- LLC_CONN_STATE_RESET transitions ------------------- */ +/* State transitions for LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X event */ +static llc_conn_action_t llc_rst_actions_1[] = { + llc_conn_ac_set_vs_0, + llc_conn_ac_set_vr_0, + llc_conn_ac_set_s_flag_1, + llc_conn_ac_send_ua_rsp_f_set_p, + NULL +}; + +static struct llc_conn_state_trans llc_rst_state_trans_1 = { + llc_conn_ev_rx_sabme_cmd_pbit_set_x, + LLC_CONN_STATE_RESET, + LLC_NO_EVENT_QUALIFIERS, + llc_rst_actions_1 +}; + +/* State transitions for LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X event, + * cause_flag = 1 */ +static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_2[] = { + llc_conn_ev_qlfy_p_flag_eq_f, + llc_conn_ev_qlfy_cause_flag_eq_1, + llc_conn_ev_qlfy_set_status_conn, + NULL +}; + +static llc_conn_action_t llc_rst_actions_2[] = { + llc_conn_ac_stop_ack_timer, + llc_conn_ac_set_vs_0, + llc_conn_ac_set_vr_0, + llc_conn_ac_upd_p_flag, + llc_conn_ac_rst_confirm, + llc_conn_ac_set_remote_busy_0, + llc_conn_reset, + NULL +}; + +static struct llc_conn_state_trans llc_rst_state_trans_2 = { + llc_conn_ev_rx_ua_rsp_fbit_set_x, + LLC_CONN_STATE_NORMAL, + llc_rst_ev_qfyrs_2, + llc_rst_actions_2 +}; + +/* State transitions for LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X event, + * cause_flag = 0 */ +static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_2_1[] = { + llc_conn_ev_qlfy_p_flag_eq_f, + llc_conn_ev_qlfy_cause_flag_eq_0, + llc_conn_ev_qlfy_set_status_rst_done, + NULL +}; + +static llc_conn_action_t llc_rst_actions_2_1[] = { + llc_conn_ac_stop_ack_timer, + llc_conn_ac_set_vs_0, + llc_conn_ac_set_vr_0, + llc_conn_ac_upd_p_flag, + llc_conn_ac_rst_confirm, + llc_conn_ac_set_remote_busy_0, + llc_conn_reset, + NULL +}; + +static struct llc_conn_state_trans llc_rst_state_trans_2_1 = { + llc_conn_ev_rx_ua_rsp_fbit_set_x, + LLC_CONN_STATE_NORMAL, + llc_rst_ev_qfyrs_2_1, + llc_rst_actions_2_1 +}; + +/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_3[] = { + llc_conn_ev_qlfy_s_flag_eq_1, + llc_conn_ev_qlfy_set_status_rst_done, + NULL +}; + +static llc_conn_action_t llc_rst_actions_3[] = { + llc_conn_ac_set_p_flag_0, + llc_conn_ac_set_remote_busy_0, + NULL +}; + +static struct llc_conn_state_trans llc_rst_state_trans_3 = { + llc_conn_ev_ack_tmr_exp, + LLC_CONN_STATE_NORMAL, + llc_rst_ev_qfyrs_3, + llc_rst_actions_3 +}; + +/* State transitions for LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X event, + * cause_flag = 1 */ +static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_4[] = { + llc_conn_ev_qlfy_cause_flag_eq_1, + llc_conn_ev_qlfy_set_status_disc, + NULL +}; +static llc_conn_action_t llc_rst_actions_4[] = { + llc_conn_ac_send_dm_rsp_f_set_p, + llc_conn_ac_disc_ind, + llc_conn_ac_stop_ack_timer, + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_rst_state_trans_4 = { + llc_conn_ev_rx_disc_cmd_pbit_set_x, + LLC_CONN_STATE_ADM, + llc_rst_ev_qfyrs_4, + llc_rst_actions_4 +}; + +/* State transitions for LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X event, + * cause_flag = 0 */ +static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_4_1[] = { + llc_conn_ev_qlfy_cause_flag_eq_0, + llc_conn_ev_qlfy_set_status_refuse, + NULL +}; + +static llc_conn_action_t llc_rst_actions_4_1[] = { + llc_conn_ac_send_dm_rsp_f_set_p, + llc_conn_ac_stop_ack_timer, + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_rst_state_trans_4_1 = { + llc_conn_ev_rx_disc_cmd_pbit_set_x, + LLC_CONN_STATE_ADM, + llc_rst_ev_qfyrs_4_1, + llc_rst_actions_4_1 +}; + +/* State transitions for LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X event, + * cause_flag = 1 */ +static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_5[] = { + llc_conn_ev_qlfy_cause_flag_eq_1, + llc_conn_ev_qlfy_set_status_disc, + NULL +}; + +static llc_conn_action_t llc_rst_actions_5[] = { + llc_conn_ac_disc_ind, + llc_conn_ac_stop_ack_timer, + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_rst_state_trans_5 = { + llc_conn_ev_rx_dm_rsp_fbit_set_x, + LLC_CONN_STATE_ADM, + llc_rst_ev_qfyrs_5, + llc_rst_actions_5 +}; + +/* State transitions for LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X event, + * cause_flag = 0 */ +static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_5_1[] = { + llc_conn_ev_qlfy_cause_flag_eq_0, + llc_conn_ev_qlfy_set_status_refuse, + NULL +}; + +static llc_conn_action_t llc_rst_actions_5_1[] = { + llc_conn_ac_stop_ack_timer, + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_rst_state_trans_5_1 = { + llc_conn_ev_rx_dm_rsp_fbit_set_x, + LLC_CONN_STATE_ADM, + llc_rst_ev_qfyrs_5_1, + llc_rst_actions_5_1 +}; + +/* State transitions for DATA_CONN_REQ event */ +static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_6[] = { + llc_conn_ev_qlfy_set_status_refuse, + NULL +}; + +/* just one member, NULL, .bss zeroes it */ +static llc_conn_action_t llc_rst_actions_6[1]; + +static struct llc_conn_state_trans llc_rst_state_trans_6 = { + llc_conn_ev_data_req, + LLC_CONN_STATE_RESET, + llc_rst_ev_qfyrs_6, + llc_rst_actions_6 +}; + +/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_7[] = { + llc_conn_ev_qlfy_retry_cnt_lt_n2, + llc_conn_ev_qlfy_s_flag_eq_0, + NULL +}; + +static llc_conn_action_t llc_rst_actions_7[] = { + llc_conn_ac_send_sabme_cmd_p_set_x, + llc_conn_ac_start_ack_timer, + llc_conn_ac_inc_retry_cnt_by_1, + NULL +}; + +static struct llc_conn_state_trans llc_rst_state_trans_7 = { + llc_conn_ev_ack_tmr_exp, + LLC_CONN_STATE_RESET, + llc_rst_ev_qfyrs_7, + llc_rst_actions_7 +}; + +/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_8[] = { + llc_conn_ev_qlfy_retry_cnt_gte_n2, + llc_conn_ev_qlfy_s_flag_eq_0, + llc_conn_ev_qlfy_cause_flag_eq_1, + llc_conn_ev_qlfy_set_status_failed, + NULL +}; +static llc_conn_action_t llc_rst_actions_8[] = { + llc_conn_ac_disc_ind, + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_rst_state_trans_8 = { + llc_conn_ev_ack_tmr_exp, + LLC_CONN_STATE_ADM, + llc_rst_ev_qfyrs_8, + llc_rst_actions_8 +}; + +/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_8_1[] = { + llc_conn_ev_qlfy_retry_cnt_gte_n2, + llc_conn_ev_qlfy_s_flag_eq_0, + llc_conn_ev_qlfy_cause_flag_eq_0, + llc_conn_ev_qlfy_set_status_failed, + NULL +}; +static llc_conn_action_t llc_rst_actions_8_1[] = { + llc_conn_ac_disc_ind, + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_rst_state_trans_8_1 = { + llc_conn_ev_ack_tmr_exp, + LLC_CONN_STATE_ADM, + llc_rst_ev_qfyrs_8_1, + llc_rst_actions_8_1 +}; + +/* + * Array of pointers; + * one to each transition + */ +static struct llc_conn_state_trans *llc_rst_state_transitions[] = { + &llc_rst_state_trans_6, /* Request */ + &llc_common_state_trans_n, + &llc_common_state_trans_n, /* Local busy */ + &llc_common_state_trans_n, /* Initiate PF cycle */ + &llc_rst_state_trans_3, /* Timer */ + &llc_rst_state_trans_7, + &llc_rst_state_trans_8, + &llc_rst_state_trans_8_1, + &llc_common_state_trans_n, + &llc_rst_state_trans_1, /* Receive frame */ + &llc_rst_state_trans_2, + &llc_rst_state_trans_2_1, + &llc_rst_state_trans_4, + &llc_rst_state_trans_4_1, + &llc_rst_state_trans_5, + &llc_rst_state_trans_5_1, + &llc_common_state_trans_n +}; + +/* -------------------- LLC_CONN_STATE_ERROR transitions ------------------- */ +/* State transitions for LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X event */ +static llc_conn_action_t llc_error_actions_1[] = { + llc_conn_ac_set_vs_0, + llc_conn_ac_set_vr_0, + llc_conn_ac_send_ua_rsp_f_set_p, + llc_conn_ac_rst_ind, + llc_conn_ac_set_p_flag_0, + llc_conn_ac_set_remote_busy_0, + llc_conn_ac_stop_ack_timer, + llc_conn_reset, + NULL +}; + +static struct llc_conn_state_trans llc_error_state_trans_1 = { + llc_conn_ev_rx_sabme_cmd_pbit_set_x, + LLC_CONN_STATE_NORMAL, + LLC_NO_EVENT_QUALIFIERS, + llc_error_actions_1 +}; + +/* State transitions for LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X event */ +static llc_conn_action_t llc_error_actions_2[] = { + llc_conn_ac_send_ua_rsp_f_set_p, + llc_conn_ac_disc_ind, + llc_conn_ac_stop_ack_timer, + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_error_state_trans_2 = { + llc_conn_ev_rx_disc_cmd_pbit_set_x, + LLC_CONN_STATE_ADM, + LLC_NO_EVENT_QUALIFIERS, + llc_error_actions_2 +}; + +/* State transitions for LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X event */ +static llc_conn_action_t llc_error_actions_3[] = { + llc_conn_ac_disc_ind, + llc_conn_ac_stop_ack_timer, + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_error_state_trans_3 = { + llc_conn_ev_rx_dm_rsp_fbit_set_x, + LLC_CONN_STATE_ADM, + LLC_NO_EVENT_QUALIFIERS, + llc_error_actions_3 +}; + +/* State transitions for LLC_CONN_EV_RX_FRMR_RSP_Fbit_SET_X event */ +static llc_conn_action_t llc_error_actions_4[] = { + llc_conn_ac_send_sabme_cmd_p_set_x, + llc_conn_ac_start_ack_timer, + llc_conn_ac_set_retry_cnt_0, + llc_conn_ac_set_cause_flag_0, + NULL +}; + +static struct llc_conn_state_trans llc_error_state_trans_4 = { + llc_conn_ev_rx_frmr_rsp_fbit_set_x, + LLC_CONN_STATE_RESET, + LLC_NO_EVENT_QUALIFIERS, + llc_error_actions_4 +}; + +/* State transitions for LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_X event */ +static llc_conn_action_t llc_error_actions_5[] = { + llc_conn_ac_resend_frmr_rsp_f_set_p, + NULL +}; + +static struct llc_conn_state_trans llc_error_state_trans_5 = { + llc_conn_ev_rx_xxx_cmd_pbit_set_x, + LLC_CONN_STATE_ERROR, + LLC_NO_EVENT_QUALIFIERS, + llc_error_actions_5 +}; + +/* State transitions for LLC_CONN_EV_RX_XXX_RSP_Fbit_SET_X event */ +static struct llc_conn_state_trans llc_error_state_trans_6 = { + llc_conn_ev_rx_xxx_rsp_fbit_set_x, + LLC_CONN_STATE_ERROR, + LLC_NO_EVENT_QUALIFIERS, + LLC_NO_TRANSITION_ACTIONS +}; + +/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_error_ev_qfyrs_7[] = { + llc_conn_ev_qlfy_retry_cnt_lt_n2, + NULL +}; + +static llc_conn_action_t llc_error_actions_7[] = { + llc_conn_ac_resend_frmr_rsp_f_set_0, + llc_conn_ac_start_ack_timer, + llc_conn_ac_inc_retry_cnt_by_1, + NULL +}; + +static struct llc_conn_state_trans llc_error_state_trans_7 = { + llc_conn_ev_ack_tmr_exp, + LLC_CONN_STATE_ERROR, + llc_error_ev_qfyrs_7, + llc_error_actions_7 +}; + +/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */ +static llc_conn_ev_qfyr_t llc_error_ev_qfyrs_8[] = { + llc_conn_ev_qlfy_retry_cnt_gte_n2, + NULL +}; + +static llc_conn_action_t llc_error_actions_8[] = { + llc_conn_ac_send_sabme_cmd_p_set_x, + llc_conn_ac_set_s_flag_0, + llc_conn_ac_start_ack_timer, + llc_conn_ac_set_retry_cnt_0, + llc_conn_ac_set_cause_flag_0, + NULL +}; + +static struct llc_conn_state_trans llc_error_state_trans_8 = { + llc_conn_ev_ack_tmr_exp, + LLC_CONN_STATE_RESET, + llc_error_ev_qfyrs_8, + llc_error_actions_8 +}; + +/* State transitions for LLC_CONN_EV_DATA_CONN_REQ event */ +static llc_conn_ev_qfyr_t llc_error_ev_qfyrs_9[] = { + llc_conn_ev_qlfy_set_status_refuse, + NULL +}; + +/* just one member, NULL, .bss zeroes it */ +static llc_conn_action_t llc_error_actions_9[1]; + +static struct llc_conn_state_trans llc_error_state_trans_9 = { + llc_conn_ev_data_req, + LLC_CONN_STATE_ERROR, + llc_error_ev_qfyrs_9, + llc_error_actions_9 +}; + +/* + * Array of pointers; + * one to each transition + */ +static struct llc_conn_state_trans *llc_error_state_transitions[] = { + &llc_error_state_trans_9, /* Request */ + &llc_common_state_trans_n, + &llc_common_state_trans_n, /* Local busy */ + &llc_common_state_trans_n, /* Initiate PF cycle */ + &llc_error_state_trans_7, /* Timer */ + &llc_error_state_trans_8, + &llc_common_state_trans_n, + &llc_error_state_trans_1, /* Receive frame */ + &llc_error_state_trans_2, + &llc_error_state_trans_3, + &llc_error_state_trans_4, + &llc_error_state_trans_5, + &llc_error_state_trans_6, + &llc_common_state_trans_n +}; + +/* ------------------- LLC_CONN_STATE_TEMP transitions ----------------- */ +/* State transitions for LLC_CONN_EV_DISC_REQ event */ +static llc_conn_action_t llc_temp_actions_1[] = { + llc_conn_ac_stop_all_timers, + llc_conn_ac_send_disc_cmd_p_set_x, + llc_conn_disc, + NULL +}; + +static struct llc_conn_state_trans llc_temp_state_trans_1 = { + llc_conn_ev_disc_req, + LLC_CONN_STATE_ADM, + LLC_NO_EVENT_QUALIFIERS, + llc_temp_actions_1 +}; + +/* + * Array of pointers; + * one to each transition + */ +static struct llc_conn_state_trans *llc_temp_state_transitions[] = { + &llc_temp_state_trans_1, /* requests */ + &llc_common_state_trans_n, + &llc_common_state_trans_n, /* local busy */ + &llc_common_state_trans_n, /* init_pf_cycle */ + &llc_common_state_trans_n, /* timer */ + &llc_common_state_trans_n /* recieve */ +}; + +/* Connection State Transition Table */ +struct llc_conn_state llc_conn_state_table[] = { + { LLC_CONN_STATE_ADM, llc_adm_state_transitions }, + { LLC_CONN_STATE_SETUP, llc_setup_state_transitions }, + { LLC_CONN_STATE_NORMAL, llc_normal_state_transitions }, + { LLC_CONN_STATE_BUSY, llc_busy_state_transitions }, + { LLC_CONN_STATE_REJ, llc_reject_state_transitions }, + { LLC_CONN_STATE_AWAIT, llc_await_state_transitions }, + { LLC_CONN_STATE_AWAIT_BUSY, llc_await_busy_state_transitions }, + { LLC_CONN_STATE_AWAIT_REJ, llc_await_rejct_state_transitions }, + { LLC_CONN_STATE_D_CONN, llc_d_conn_state_transitions }, + { LLC_CONN_STATE_RESET, llc_rst_state_transitions }, + { LLC_CONN_STATE_ERROR, llc_error_state_transitions }, + { LLC_CONN_STATE_TEMP, llc_temp_state_transitions } +}; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_conn.c linux.19pre5-ac1/net/llc/llc_conn.c --- linux.19p5/net/llc/llc_conn.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/net/llc/llc_conn.c Tue Mar 19 19:15:34 2002 @@ -0,0 +1,520 @@ +/* + * llc_conn.c - Driver routines for connection component. + * + * Copyright (c) 1997 by Procom Technology, Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int llc_find_offset(int state, int ev_type); +static void llc_conn_send_pdus(struct sock *sk); +static int llc_conn_service(struct sock *sk, struct llc_conn_state_ev *ev); +static int llc_exec_conn_trans_actions(struct sock *sk, + struct llc_conn_state_trans *trans, + struct llc_conn_state_ev *ev); +static struct llc_conn_state_trans * + llc_qualify_conn_ev(struct sock *sk, struct llc_conn_state_ev *ev); + +/* Offset table on connection states transition diagram */ +static int llc_offset_table[NBR_CONN_STATES][NBR_CONN_EV]; + +/** + * llc_conn_alloc_event: allocates an event + * @sk: socket that event is associated + * + * Returns pointer to allocated connection on success, %NULL on failure. + */ +struct llc_conn_state_ev *llc_conn_alloc_ev(struct sock *sk) +{ + struct llc_conn_state_ev *ev = NULL; + + /* verify connection is valid, active and open */ + if (llc_sk(sk)->state != LLC_CONN_OUT_OF_SVC) { + /* get event structure to build a station event */ + ev = kmalloc(sizeof(*ev), GFP_ATOMIC); + if (ev) + memset(ev, 0, sizeof(*ev)); + } + return ev; +} + +/** + * llc_conn_send_event - sends event to connection state machine + * @sk: connection + * @ev: occurred event + * + * Sends an event to connection state machine. after processing event + * (executing it's actions and changing state), upper layer will be + * indicated or confirmed, if needed. Returns 0 for success, 1 for + * failure. The socket lock has to be held before calling this function. + */ +int llc_conn_send_ev(struct sock *sk, struct llc_conn_state_ev *ev) +{ + /* sending event to state machine */ + int rc = llc_conn_service(sk, ev); + struct llc_opt *llc = llc_sk(sk); + u8 flag = ev->flag; + struct llc_prim_if_block *ind_prim = ev->ind_prim; + struct llc_prim_if_block *cfm_prim = ev->cfm_prim; + + llc_conn_free_ev(ev); +#ifdef THIS_BREAKS_DISCONNECT_NOTIFICATION_BADLY + /* check if the connection was freed by the state machine by + * means of llc_conn_disc */ + if (rc == 2) { + printk(KERN_INFO __FUNCTION__ ": rc == 2\n"); + rc = -ECONNABORTED; + goto out; + } +#endif /* THIS_BREAKS_DISCONNECT_NOTIFICATION_BADLY */ + if (!flag) /* indicate or confirm not required */ + goto out; + rc = 0; + if (ind_prim) /* indication required */ + llc->sap->ind(ind_prim); + if (!cfm_prim) /* confirmation not required */ + goto out; + /* data confirm has preconditions */ + if (cfm_prim->prim != LLC_DATA_PRIM) { + llc->sap->conf(cfm_prim); + goto out; + } + if (!llc_data_accept_state(llc->state)) { + /* In this state, we can send I pdu */ + /* FIXME: check if we don't need to see if sk->lock.users != 0 + * is needed here */ + rc = llc->sap->conf(cfm_prim); + if (rc) /* confirmation didn't accept by upper layer */ + llc->failed_data_req = 1; + } else + llc->failed_data_req = 1; +out: return rc; +} + +void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb) +{ + llc_sock_assert(sk); + /* queue PDU to send to MAC layer */ + skb_queue_tail(&sk->write_queue, skb); + llc_conn_send_pdus(sk); +} + +/** + * llc_conn_rtn_pdu - sends received data pdu to upper layer + * @sk: Active connection + * @skb: Received data frame + * @ev: Occurred event + * + * Sends received data pdu to upper layer (by using indicate function). + * Prepares service parameters (prim and prim_data). calling indication + * function will be done in llc_conn_send_ev. + */ +void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb, + struct llc_conn_state_ev *ev) +{ + struct llc_prim_if_block *prim = &llc_ind_prim; + union llc_u_prim_data *prim_data = llc_ind_prim.data; + + prim_data->data.sk = sk; + prim_data->data.pri = 0; + prim_data->data.skb = skb; + prim_data->data.link = llc_sk(sk)->link; + prim->data = prim_data; + prim->prim = LLC_DATA_PRIM; + prim->sap = llc_sk(sk)->sap; + ev->flag = 1; + /* saving prepd prim in event for future use in llc_conn_send_ev */ + ev->ind_prim = prim; +} + +/** + * llc_conn_resend_i_pdu_as_cmd - resend all all unacknowledged I PDUs + * @sk: active connection + * @nr: NR + * @first_p_bit: p_bit value of first pdu + * + * Resend all unacknowledged I PDUs, starting with the NR; send first as + * command PDU with P bit equal first_p_bit; if more than one send + * subsequent as command PDUs with P bit equal zero (0). + */ +void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr, u8 first_p_bit) +{ + struct sk_buff *skb; + llc_pdu_sn_t *pdu; + u16 nbr_unack_pdus; + u8 howmany_resend = 0; + + llc_conn_remove_acked_pdus(sk, nr, &nbr_unack_pdus); + if (!nbr_unack_pdus) + goto out; + /* process unack PDUs only if unack queue is not empty; remove + * appropriate PDUs, fix them up, and put them on mac_pdu_q. */ + while ((skb = skb_dequeue(&llc_sk(sk)->pdu_unack_q)) != NULL) { + pdu = (llc_pdu_sn_t *)skb->nh.raw; + llc_pdu_set_cmd_rsp(skb, LLC_PDU_CMD); + llc_pdu_set_pf_bit(skb, first_p_bit); + skb_queue_tail(&sk->write_queue, skb); + first_p_bit = 0; + llc_sk(sk)->vS = LLC_I_GET_NS(pdu); + howmany_resend++; + } + if (howmany_resend > 0) + llc_sk(sk)->vS = (llc_sk(sk)->vS + 1) % LLC_2_SEQ_NBR_MODULO; + /* any PDUs to re-send are queued up; start sending to MAC */ + llc_conn_send_pdus(sk); +out:; +} + +/** + * llc_conn_resend_i_pdu_as_rsp - Resend all unacknowledged I PDUs + * @sk: active connection. + * @nr: NR + * @first_f_bit: f_bit value of first pdu. + * + * Resend all unacknowledged I PDUs, starting with the NR; send first as + * response PDU with F bit equal first_f_bit; if more than one send + * subsequent as response PDUs with F bit equal zero (0). + */ +void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, u8 first_f_bit) +{ + struct sk_buff *skb; + llc_pdu_sn_t *pdu; + u16 nbr_unack_pdus; + u8 howmany_resend = 0; + + llc_conn_remove_acked_pdus(sk, nr, &nbr_unack_pdus); + if (!nbr_unack_pdus) + goto out; + /* process unack PDUs only if unack queue is not empty; remove + * appropriate PDUs, fix them up, and put them on mac_pdu_q */ + while ((skb = skb_dequeue(&llc_sk(sk)->pdu_unack_q)) != NULL) { + pdu = (llc_pdu_sn_t *)skb->nh.raw; + llc_pdu_set_cmd_rsp(skb, LLC_PDU_RSP); + llc_pdu_set_pf_bit(skb, first_f_bit); + skb_queue_tail(&sk->write_queue, skb); + first_f_bit = 0; + llc_sk(sk)->vS = LLC_I_GET_NS(pdu); + howmany_resend++; + } + if (howmany_resend > 0) + llc_sk(sk)->vS = (llc_sk(sk)->vS + 1) % LLC_2_SEQ_NBR_MODULO; + /* any PDUs to re-send are queued up; start sending to MAC */ + llc_conn_send_pdus(sk); +out:; +} + +/** + * llc_conn_remove_acked_pdus - Removes acknowledged pdus from tx queue + * @sk: active connection + * nr: NR + * how_many_unacked: size of pdu_unack_q after removing acked pdus + * + * Removes acknowledged pdus from transmit queue (pdu_unack_q). Returns + * the number of pdus that removed from queue. + */ +int llc_conn_remove_acked_pdus(struct sock *sk, u8 nr, u16 *how_many_unacked) +{ + int pdu_pos, i; + struct sk_buff *skb; + llc_pdu_sn_t *pdu; + int nbr_acked = 0; + int q_len = skb_queue_len(&llc_sk(sk)->pdu_unack_q); + + if (!q_len) + goto out; + skb = skb_peek(&llc_sk(sk)->pdu_unack_q); + pdu = (llc_pdu_sn_t *)skb->nh.raw; + + /* finding position of last acked pdu in queue */ + pdu_pos = ((int)LLC_2_SEQ_NBR_MODULO + (int)nr - + (int)LLC_I_GET_NS(pdu)) % LLC_2_SEQ_NBR_MODULO; + + for (i = 0; i < pdu_pos && i < q_len; i++) { + skb = skb_dequeue(&llc_sk(sk)->pdu_unack_q); + if (skb) + kfree_skb(skb); + nbr_acked++; + } +out: *how_many_unacked = skb_queue_len(&llc_sk(sk)->pdu_unack_q); + return nbr_acked; +} + +/** + * llc_conn_send_pdus - Sends queued PDUs + * @sk: active connection + * + * Sends queued pdus to MAC layer for transmition. + */ +static void llc_conn_send_pdus(struct sock *sk) +{ + struct sk_buff *skb; + + while ((skb = skb_dequeue(&sk->write_queue)) != NULL) { + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw; + + if (!LLC_PDU_TYPE_IS_I(pdu) && + !(skb->dev->flags & IFF_LOOPBACK)) + skb_queue_tail(&llc_sk(sk)->pdu_unack_q, skb); + mac_send_pdu(skb); + if (LLC_PDU_TYPE_IS_I(pdu) || + (skb->dev && skb->dev->flags & IFF_LOOPBACK)) + kfree_skb(skb); + } +} + +/** + * llc_conn_free_ev - free event + * @ev: event to free + * + * Free allocated event. + */ +void llc_conn_free_ev(struct llc_conn_state_ev *ev) +{ + if (ev->type == LLC_CONN_EV_TYPE_PDU) { + /* free the frame that binded to this event */ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw; + + if (LLC_PDU_TYPE_IS_I(pdu) || !ev->flag || !ev->ind_prim) + kfree_skb(ev->data.pdu.skb); + } + /* free event structure to free list of the same */ + kfree(ev); +} + +/** + * llc_conn_service - finds transition and changes state of connection + * @sk: connection + * @ev: happened event + * + * This function finds transition that matches with happened event, then + * executes related actions and finally changes state of connection. + * Returns 0 for success, 1 for failure. + */ +static int llc_conn_service(struct sock *sk, struct llc_conn_state_ev *ev) +{ + int rc = 1; + struct llc_conn_state_trans *trans; + + if (llc_sk(sk)->state > NBR_CONN_STATES) + goto out; + rc = 0; + trans = llc_qualify_conn_ev(sk, ev); + if (trans) { + rc = llc_exec_conn_trans_actions(sk, trans, ev); + if (!rc && trans->next_state != NO_STATE_CHANGE) + llc_sk(sk)->state = trans->next_state; + } +out: return rc; +} + +/** + * llc_qualify_conn_ev - finds transition for event + * @sk: connection + * @ev: happened event + * + * This function finds transition that matches with happened event. + * Returns pointer to found transition on success, %NULL otherwise. + */ +static struct llc_conn_state_trans * + llc_qualify_conn_ev(struct sock *sk, struct llc_conn_state_ev *ev) +{ + struct llc_conn_state_trans **next_trans; + llc_conn_ev_qfyr_t *next_qualifier; + struct llc_conn_state *curr_state = + &llc_conn_state_table[llc_sk(sk)->state - 1]; + + /* search thru events for this state until list exhausted or until + no more */ + for (next_trans = curr_state->transitions + + llc_find_offset(llc_sk(sk)->state - 1, ev->type); + (*next_trans)->ev; next_trans++) { + if (!((*next_trans)->ev)(sk, ev)) { + /* got POSSIBLE event match; the event may require + * qualification based on the values of a number of + * state flags; if all qualifications are met (i.e., + * if all qualifying functions return success, or 0, + * then this is THE event we're looking for */ + for (next_qualifier = (*next_trans)->ev_qualifiers; + next_qualifier && *next_qualifier && + !(*next_qualifier)(sk, ev); next_qualifier++) + /* nothing */; + if (!next_qualifier || !*next_qualifier) + /* all qualifiers executed successfully; this is + * our transition; return it so we can perform + * the associated actions & change the state */ + return *next_trans; + } + } + return NULL; +} + +/** + * llc_exec_conn_trans_actions - executes related actions + * @sk: connection + * @trans: transition that it's actions must be performed + * @ev: happened event + * + * Executes actions that is related to happened event. Returns 0 for + * success, 1 to indicate failure of at least one action or 2 if the + * connection was freed (llc_conn_disc was called) + */ +static int llc_exec_conn_trans_actions(struct sock *sk, + struct llc_conn_state_trans *trans, + struct llc_conn_state_ev *ev) +{ + int rc = 0; + llc_conn_action_t *next_action; + + for (next_action = trans->ev_actions; + next_action && *next_action; next_action++) { + int rc2 = (*next_action)(sk, ev); + + if (rc2 == 2) { + rc = rc2; + break; + } else if (rc2) + rc = 1; + } + return rc; +} + +/** + * llc_find_sock - Finds connection in sap for the remote/local sap/mac + * @sap: SAP + * @daddr: address of remote LLC (MAC + SAP) + * @laddr: address of local LLC (MAC + SAP) + * + * Search connection list of the SAP and finds connection using the remote + * mac, remote sap, local mac, and local sap. Returns pointer for + * connection found, %NULL otherwise. + */ +struct sock *llc_find_sock(struct llc_sap *sap, struct llc_addr *daddr, + struct llc_addr *laddr) +{ + struct sock *rc = NULL; + struct list_head *entry; + + spin_lock_bh(&sap->sk_list.lock); + if (list_empty(&sap->sk_list.list)) + goto out; + list_for_each(entry, &sap->sk_list.list) { + struct llc_opt *llc = list_entry(entry, struct llc_opt, node); + + if (llc->laddr.lsap == laddr->lsap && + llc->daddr.lsap == daddr->lsap && + !memcmp(llc->laddr.mac, laddr->mac, ETH_ALEN) && + !memcmp(llc->daddr.mac, daddr->mac, ETH_ALEN)) { + rc = llc->sk; + break; + } + } + if (rc) + sock_hold(rc); +out: spin_unlock_bh(&sap->sk_list.lock); + return rc; +} + +/** + * llc_data_accept_state - designates if in this state data can be sent. + * @state: state of connection. + * + * Returns 0 if data can be sent, 1 otherwise. + */ +u8 llc_data_accept_state(u8 state) +{ + if (state != LLC_CONN_STATE_NORMAL && state != LLC_CONN_STATE_BUSY && + state != LLC_CONN_STATE_REJ) + return 1; /* data_conn_refuse */ + return 0; +} + +/** + * find_next_offset - finds offset for next category of transitions + * @state: state table. + * @offset: start offset. + * + * Finds offset of next category of transitions in transition table. + * Returns the start index of next category. + */ +u16 find_next_offset(struct llc_conn_state *state, u16 offset) +{ + u16 cnt = 0; + struct llc_conn_state_trans **next_trans; + + for (next_trans = state->transitions + offset; + (*next_trans)->ev; next_trans++) + ++cnt; + return cnt; +} + +/** + * llc_build_offset_table - builds offset table of connection + * + * Fills offset table of connection state transition table + * (llc_offset_table). + */ +void __init llc_build_offset_table(void) +{ + struct llc_conn_state *curr_state; + int state, ev_type, next_offset; + + memset(llc_offset_table, 0, sizeof(llc_offset_table)); + for (state = 0; state < NBR_CONN_STATES; state++) { + curr_state = &llc_conn_state_table[state]; + next_offset = 0; + for (ev_type = 0; ev_type < NBR_CONN_EV; ev_type++) { + llc_offset_table[state][ev_type] = next_offset; + next_offset += find_next_offset(curr_state, + next_offset) + 1; + } + } +} + +/** + * llc_find_offset - finds start offset of category of transitions + * @state: state of connection + * @ev_type: type of happened event + * + * Finds start offset of desired category of transitions. Returns the + * desired start offset. + */ +static int llc_find_offset(int state, int ev_type) +{ + int rc = 0; + /* at this stage, llc_offset_table[..][2] is not important. it is for + * init_pf_cycle and I don't know what is it. */ + switch (ev_type) { + case LLC_CONN_EV_TYPE_PRIM: + rc = llc_offset_table[state][0]; break; + case LLC_CONN_EV_TYPE_PDU: + rc = llc_offset_table[state][4]; break; + case LLC_CONN_EV_TYPE_SIMPLE: + rc = llc_offset_table[state][1]; break; + case LLC_CONN_EV_TYPE_P_TMR: + case LLC_CONN_EV_TYPE_ACK_TMR: + case LLC_CONN_EV_TYPE_REJ_TMR: + case LLC_CONN_EV_TYPE_BUSY_TMR: + rc = llc_offset_table[state][3]; break; + } + return rc; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_evnt.c linux.19pre5-ac1/net/llc/llc_evnt.c --- linux.19p5/net/llc/llc_evnt.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/net/llc/llc_evnt.c Tue Mar 19 19:15:34 2002 @@ -0,0 +1,112 @@ +/* + * llc_evnt.c - LLC station component event match functions + * Description : + * Functions in this module are implementation of station component events. + * Details of events can be found in IEEE-802.2 standard document. + * All functions have one station and one event as input argument. All of + * them return 0 On success and 1 otherwise. + * + * Copyright (c) 1997 by Procom Technology, Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include + +int llc_stat_ev_enable_with_dup_addr_check(struct llc_station *station, + struct llc_station_state_ev *ev) +{ + return ev->type == LLC_STATION_EV_TYPE_SIMPLE && + ev->data.a.ev == + LLC_STATION_EV_ENABLE_WITH_DUP_ADDR_CHECK ? 0 : 1; +} + +int llc_stat_ev_enable_without_dup_addr_check(struct llc_station *station, + struct llc_station_state_ev *ev) +{ + return ev->type == LLC_STATION_EV_TYPE_SIMPLE && + ev->data.a.ev == + LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK ? 0 : 1; +} + +int llc_stat_ev_ack_tmr_exp_lt_retry_cnt_max_retry(struct llc_station *station, + struct llc_station_state_ev *ev) +{ + return ev->type == LLC_STATION_EV_TYPE_ACK_TMR && + station->retry_count < station->maximum_retry ? 0 : 1; +} + +int llc_stat_ev_ack_tmr_exp_eq_retry_cnt_max_retry(struct llc_station *station, + struct llc_station_state_ev *ev) +{ + return ev->type == LLC_STATION_EV_TYPE_ACK_TMR && + station->retry_count == station->maximum_retry ? 0 : 1; +} + +int llc_stat_ev_rx_null_dsap_xid_c(struct llc_station *station, + struct llc_station_state_ev *ev) +{ + llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw; + + return ev->type == LLC_STATION_EV_TYPE_PDU && + !LLC_PDU_IS_CMD(pdu) && /* command PDU */ + !LLC_PDU_TYPE_IS_U(pdu) && /* U type PDU */ + LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_XID && + !pdu->dsap ? 0 : 1; /* NULL DSAP value */ +} + +int llc_stat_ev_rx_null_dsap_0_xid_r_xid_r_cnt_eq(struct llc_station *station, + struct llc_station_state_ev *ev) +{ + llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw; + + return ev->type == LLC_STATION_EV_TYPE_PDU && + !LLC_PDU_IS_RSP(pdu) && /* response PDU */ + !LLC_PDU_TYPE_IS_U(pdu) && /* U type PDU */ + LLC_U_PDU_RSP(pdu) == LLC_1_PDU_CMD_XID && + !pdu->dsap && /* NULL DSAP value */ + !station->xid_r_count ? 0 : 1; +} + +int llc_stat_ev_rx_null_dsap_1_xid_r_xid_r_cnt_eq(struct llc_station *station, + struct llc_station_state_ev *ev) +{ + llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw; + + return ev->type == LLC_STATION_EV_TYPE_PDU && + !LLC_PDU_IS_RSP(pdu) && /* response PDU */ + !LLC_PDU_TYPE_IS_U(pdu) && /* U type PDU */ + LLC_U_PDU_RSP(pdu) == LLC_1_PDU_CMD_XID && + !pdu->dsap && /* NULL DSAP value */ + station->xid_r_count == 1 ? 0 : 1; +} + +int llc_stat_ev_rx_null_dsap_test_c(struct llc_station *station, + struct llc_station_state_ev *ev) +{ + llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw; + + return ev->type == LLC_STATION_EV_TYPE_PDU && + !LLC_PDU_IS_CMD(pdu) && /* command PDU */ + !LLC_PDU_TYPE_IS_U(pdu) && /* U type PDU */ + LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_TEST && + !pdu->dsap ? 0 : 1; /* NULL DSAP */ +} + +int llc_stat_ev_disable_req(struct llc_station *station, + struct llc_station_state_ev *ev) +{ + return ev->type == LLC_STATION_EV_TYPE_PRIM && + ev->data.prim.prim == LLC_DISABLE_PRIM && + ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_if.c linux.19pre5-ac1/net/llc/llc_if.c --- linux.19p5/net/llc/llc_if.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/net/llc/llc_if.c Tue Mar 19 19:15:34 2002 @@ -0,0 +1,514 @@ +/* + * llc_if.c - Defines LLC interface to upper layer + * + * Copyright (c) 1997 by Procom Technology, Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int llc_sap_req(struct llc_prim_if_block *prim); +static int llc_unitdata_req_handler(struct llc_prim_if_block *prim); +static int llc_test_req_handler(struct llc_prim_if_block *prim); +static int llc_xid_req_handler(struct llc_prim_if_block *prim); +static int llc_data_req_handler(struct llc_prim_if_block *prim); +static int llc_conn_req_handler(struct llc_prim_if_block *prim); +static int llc_disc_req_handler(struct llc_prim_if_block *prim); +static int llc_rst_req_handler(struct llc_prim_if_block *prim); +static int llc_flowcontrol_req_handler(struct llc_prim_if_block *prim); +static int llc_sap_resp(struct llc_prim_if_block *prim); +static int llc_conn_rsp_handler(struct llc_prim_if_block *prim); +static int llc_rst_rsp_handler(struct llc_prim_if_block *prim); +static int llc_no_rsp_handler(struct llc_prim_if_block *prim); + +extern void llc_register_sap(unsigned char sap, + int (*rcvfunc)(struct sk_buff *skb, + struct net_device *dev, + struct packet_type *pt)); +extern void llc_unregister_sap(unsigned char sap); + +/* table of request handler functions */ +static llc_prim_call_t llc_req_prim[LLC_NBR_PRIMITIVES] = { + llc_unitdata_req_handler, /* order of functions must not change */ + llc_conn_req_handler, + llc_data_req_handler, + llc_disc_req_handler, + llc_rst_req_handler, + llc_flowcontrol_req_handler, + NULL, + llc_xid_req_handler, + llc_test_req_handler, +}; + +/* table of response handler functions */ +static llc_prim_call_t llc_resp_prim[LLC_NBR_PRIMITIVES] = { + llc_no_rsp_handler, /* order of functions must not change */ + llc_conn_rsp_handler, + llc_no_rsp_handler, + llc_no_rsp_handler, + llc_rst_rsp_handler, + llc_no_rsp_handler, +}; + +/** + * llc_sap_open - open interface to the upper layers. + * @nw_indicate: pointer to indicate function of upper layer. + * @nw_confirm: pointer to confirm function of upper layer. + * @lsap: SAP number. + * @sap: pointer to allocated SAP (output argument). + * + * Interface function to upper layer. each one who wants to get a SAP + * (for example NetBEUI) should call this function. Returns 0 for + * success, 1 for failure. + */ +struct llc_sap *llc_sap_open(llc_prim_call_t nw_indicate, + llc_prim_call_t nw_confirm, u8 lsap) +{ + /* verify this SAP is not already open; if so, return error */ + struct llc_sap *sap; + + MOD_INC_USE_COUNT; + sap = llc_sap_find(lsap); + if (sap) { /* SAP already exists */ + sap = NULL; + goto err; + } + /* sap requested does not yet exist */ + sap = llc_sap_alloc(); + if (!sap) + goto err; + /* allocated a SAP; initialize it and clear out its memory pool */ + sap->laddr.lsap = lsap; + sap->req = llc_sap_req; + sap->resp = llc_sap_resp; + sap->ind = nw_indicate; + sap->conf = nw_confirm; + sap->parent_station = llc_station_get(); + /* initialized SAP; add it to list of SAPs this station manages */ + llc_sap_save(sap); + llc_register_sap(lsap, mac_indicate); +out: return sap; +err: MOD_DEC_USE_COUNT; + goto out; +} + +/** + * llc_sap_close - close interface for upper layers. + * @sap: SAP to be closed. + * + * Close interface function to upper layer. each one who wants to + * close an open SAP (for example NetBEUI) should call this function. + */ +void llc_sap_close(struct llc_sap *sap) +{ + llc_unregister_sap(sap->laddr.lsap); + llc_free_sap(sap); + MOD_DEC_USE_COUNT; +} + +/** + * llc_sap_req - Request interface for upper layers + * @prim: pointer to structure that contains service parameters. + * + * Request interface function to upper layer. each one who wants to + * request a service from LLC, must call this function. details of + * requested service is defined in input argument(prim). Returns 0 for + * success, 1 otherwise. + */ +static int llc_sap_req(struct llc_prim_if_block *prim) +{ + int rc = 1; + + if (prim->prim > 8 || prim->prim == 6) { + printk(KERN_ERR __FUNCTION__ ": invalid primitive %d\n", + prim->prim); + goto out; + } + /* receive REQUEST primitive from network layer; call the appropriate + * primitive handler which then packages it up as an event and sends it + * to the SAP or CONNECTION event handler */ + if (prim->prim < LLC_NBR_PRIMITIVES) + /* valid primitive; call the function to handle it */ + rc = llc_req_prim[prim->prim](prim); +out: return rc; +} + +/** + * llc_unitdata_req_handler - unitdata request interface for upper layers + * @prim: pointer to structure that contains service parameters + * + * Upper layers calls this function when upper layer wants to send data + * using connection-less mode communication (UI pdu). Returns 0 for + * success, 1 otherwise. + */ +static int llc_unitdata_req_handler(struct llc_prim_if_block *prim) +{ + int rc = 1; + struct llc_sap_state_ev *ev; + /* accept data frame from network layer to be sent using connection- + * less mode communication; timeout/retries handled by network layer; + * package primitive as an event and send to SAP event handler */ + struct llc_sap *sap = llc_sap_find(prim->data->udata.saddr.lsap); + + if (!sap) + goto out; + ev = llc_sap_alloc_ev(sap); + if (!ev) + goto out; + ev->type = LLC_SAP_EV_TYPE_PRIM; + ev->data.prim.prim = LLC_DATAUNIT_PRIM; + ev->data.prim.type = LLC_PRIM_TYPE_REQ; + ev->data.prim.data = prim; + rc = 0; + llc_sap_send_ev(sap, ev); +out: return rc; +} + +/** + * llc_test_req_handler - TEST interface for upper layers. + * @prim: pointer to structure that contains service parameters. + * + * This function is called when upper layer wants to send a TEST pdu. + * Returns 0 for success, 1 otherwise. + */ +static int llc_test_req_handler(struct llc_prim_if_block *prim) +{ + int rc = 1; + struct llc_sap_state_ev *ev; + /* package primitive as an event and send to SAP event handler */ + struct llc_sap *sap = llc_sap_find(prim->data->udata.saddr.lsap); + if (!sap) + goto out; + ev = llc_sap_alloc_ev(sap); + if (!ev) + goto out; + ev->type = LLC_SAP_EV_TYPE_PRIM; + ev->data.prim.prim = LLC_TEST_PRIM; + ev->data.prim.type = LLC_PRIM_TYPE_REQ; + ev->data.prim.data = prim; + rc = 0; + llc_sap_send_ev(sap, ev); +out: return rc; +} + +/** + * llc_xid_req_handler - XID interface for upper layers + * @prim: pointer to structure that contains service parameters. + * + * This function is called when upper layer wants to send a XID pdu. + * Returns 0 for success, 1 otherwise. + */ +static int llc_xid_req_handler(struct llc_prim_if_block *prim) +{ + int rc = 1; + struct llc_sap_state_ev *ev; + /* package primitive as an event and send to SAP event handler */ + struct llc_sap *sap = llc_sap_find(prim->data->udata.saddr.lsap); + + if (!sap) + goto out; + ev = llc_sap_alloc_ev(sap); + if (!ev) + goto out; + ev->type = LLC_SAP_EV_TYPE_PRIM; + ev->data.prim.prim = LLC_XID_PRIM; + ev->data.prim.type = LLC_PRIM_TYPE_REQ; + ev->data.prim.data = prim; + rc = 0; + llc_sap_send_ev(sap, ev); +out: return rc; +} + +/** + * llc_data_req_handler - Connection data sending for upper layers. + * @prim: pointer to structure that contains service parameters + * + * This function is called when upper layer wants to send data using + * connection oriented communication mode. during sending data, connection + * will be locked and received frames and expired timers will be queued. + * Returns 0 for success, -ECONNABORTED when the connection already + * closed. and -EBUSY when sending data is not permitted in this state or + * LLC has send an I pdu with p bit set to 1 and is waiting for it's + * response. + */ +static int llc_data_req_handler(struct llc_prim_if_block *prim) +{ + struct llc_conn_state_ev *ev; + int rc = -ECONNABORTED; + /* accept data frame from network layer to be sent using connection + * mode communication; timeout/retries handled by this layer; + * package primitive as an event and send to connection event handler */ + struct sock *sk = prim->data->data.sk; + struct llc_opt *llc = llc_sk(sk); + + lock_sock(sk); + if (llc->state == LLC_CONN_STATE_ADM) + goto out; + rc = -EBUSY; + if (llc_data_accept_state(llc->state)) { /* data_conn_refuse */ + llc->failed_data_req = 1; + goto out; + } + if (llc->p_flag) { + llc->failed_data_req = 1; + goto out; + } + rc = -ENOMEM; + ev = llc_conn_alloc_ev(sk); + if (ev) { + ev->type = LLC_CONN_EV_TYPE_PRIM; + ev->data.prim.prim = LLC_DATA_PRIM; + ev->data.prim.type = LLC_PRIM_TYPE_REQ; + ev->data.prim.data = prim; + prim->data->data.skb->dev = llc->dev; + rc = llc_conn_send_ev(sk, ev); + } +out: release_sock(sk); + return rc; +} + +/** + * confirm_impossible - Informs upper layer about failed connection + * @prim: pointer to structure that contains confirmation data. + * + * Informs upper layer about failing in connection establishment. This + * function is called by llc_conn_req_handler. + */ +static void confirm_impossible(struct llc_prim_if_block *prim) +{ + prim->data->conn.status = LLC_STATUS_IMPOSSIBLE; + prim->sap->conf(prim); +} + +/** + * llc_conn_req_handler - Called by upper layer to establish a conn + * @prim: pointer to structure that contains service parameters. + * + * Upper layer calls this to establish an LLC connection with a remote + * machine. this function packages a proper event and sends it connection + * component state machine. Success or failure of connection + * establishment will inform to upper layer via calling it's confirm + * function and passing proper information. + */ +static int llc_conn_req_handler(struct llc_prim_if_block *prim) +{ + int rc = -EBUSY; + struct llc_opt *llc; + struct llc_sap *sap = prim->sap; + struct llc_conn_state_ev *ev; + struct net_device *ddev = mac_dev_peer(prim->data->conn.dev, + prim->data->conn.dev->type, + prim->data->conn.daddr.mac), + *sdev = (ddev->flags & IFF_LOOPBACK) ? + ddev : prim->data->conn.dev; + struct llc_addr laddr, daddr; + /* network layer supplies addressing required to establish connection; + * package as an event and send it to the connection event handler */ + struct sock *sk; + + memcpy(laddr.mac, sdev->dev_addr, sizeof(laddr.mac)); + laddr.lsap = prim->data->conn.saddr.lsap; + memcpy(daddr.mac, ddev->dev_addr, sizeof(daddr.mac)); + daddr.lsap = prim->data->conn.daddr.lsap; + sk = llc_find_sock(sap, &daddr, &laddr); + if (sk) { + confirm_impossible(prim); + goto out_put; + } + rc = -ENOMEM; + if (prim->data->conn.sk) { + sk = prim->data->conn.sk; + if (llc_sock_init(sk)) + goto out; + } else { + sk = llc_sock_alloc(); + if (!sk) { + confirm_impossible(prim); + goto out; + } + prim->data->conn.sk = sk; + } + sock_hold(sk); + lock_sock(sk); + /* assign new connection to it's SAP */ + llc_sap_assign_sock(sap, sk); + llc = llc_sk(sk); + memcpy(&llc->daddr, &daddr, sizeof(llc->daddr)); + memcpy(&llc->laddr, &laddr, sizeof(llc->laddr)); + llc->dev = ddev; + llc->link = prim->data->conn.link; + llc->handler = prim->data->conn.handler; + ev = llc_conn_alloc_ev(sk); + if (ev) { + ev->type = LLC_CONN_EV_TYPE_PRIM; + ev->data.prim.prim = LLC_CONN_PRIM; + ev->data.prim.type = LLC_PRIM_TYPE_REQ; + ev->data.prim.data = prim; + rc = llc_conn_send_ev(sk, ev); + } + if (rc) { + llc_sap_unassign_sock(sap, sk); + llc_sock_free(sk); + confirm_impossible(prim); + } + release_sock(sk); +out_put: + sock_put(sk); +out: return rc; +} + +/** + * llc_disc_req_handler - Called by upper layer to close a connection + * @prim: pointer to structure that contains service parameters. + * + * Upper layer calls this when it wants to close an established LLC + * connection with a remote machine. this function packages a proper event + * and sends it to connection component state machine. Returns 0 for + * success, 1 otherwise. + */ +static int llc_disc_req_handler(struct llc_prim_if_block *prim) +{ + u16 rc = 1; + struct llc_conn_state_ev *ev; + struct sock* sk = prim->data->disc.sk; + + sock_hold(sk); + lock_sock(sk); + if (llc_sk(sk)->state == LLC_CONN_STATE_ADM || + llc_sk(sk)->state == LLC_CONN_OUT_OF_SVC) + goto out; + /* postpone unassigning the connection from its SAP and returning the + * connection until all ACTIONs have been completely executed */ + ev = llc_conn_alloc_ev(sk); + if (!ev) + goto out; + ev->type = LLC_CONN_EV_TYPE_PRIM; + ev->data.prim.prim = LLC_DISC_PRIM; + ev->data.prim.type = LLC_PRIM_TYPE_REQ; + ev->data.prim.data = prim; + rc = llc_conn_send_ev(sk, ev); +out: release_sock(sk); + sock_put(sk); + return rc; +} + +/** + * llc_rst_req_handler - Resets an established LLC connection + * @prim: pointer to structure that contains service parameters. + * + * Called when upper layer wants to reset an established LLC connection + * with a remote machine. this function packages a proper event and sends + * it to connection component state machine. Returns 0 for success, 1 + * otherwise. + */ +static int llc_rst_req_handler(struct llc_prim_if_block *prim) +{ + int rc = 1; + struct sock *sk = prim->data->res.sk; + struct llc_conn_state_ev *ev; + + lock_sock(sk); + ev = llc_conn_alloc_ev(sk); + if (ev) { + ev->type = LLC_CONN_EV_TYPE_PRIM; + ev->data.prim.prim = LLC_RESET_PRIM; + ev->data.prim.type = LLC_PRIM_TYPE_REQ; + ev->data.prim.data = prim; + rc = llc_conn_send_ev(sk, ev); + } + release_sock(sk); + return rc; +} + +/* We don't support flow control. The original code from procom has + * some bits, but for now I'm cleaning this */ +static int llc_flowcontrol_req_handler(struct llc_prim_if_block *prim) +{ + return 1; +} + +/** + * llc_sap_resp - Sends response to peer + * @prim: pointer to structure that contains service parameters + * + * This function is a interface function to upper layer. each one who + * wants to response to an indicate can call this function via calling + * sap_resp with proper service parameters. Returns 0 for success, 1 + * otherwise. + */ +static int llc_sap_resp(struct llc_prim_if_block *prim) +{ + u16 rc = 1; + /* network layer RESPONSE primitive received; package primitive + * as an event and send it to the connection event handler */ + if (prim->prim < LLC_NBR_PRIMITIVES) + /* valid primitive; call the function to handle it */ + rc = llc_resp_prim[prim->prim](prim); + return rc; +} + +/** + * llc_conn_rsp_handler - Response to connect indication + * @prim: pointer to structure that contains response info. + * + * Response to connect indication. + */ +static int llc_conn_rsp_handler(struct llc_prim_if_block *prim) +{ + struct sock *sk = prim->data->conn.sk; + + llc_sk(sk)->link = prim->data->conn.link; + return 0; +} + +/** + * llc_rst_rsp_handler - Response to RESET indication + * @prim: pointer to structure that contains response info + * + * Returns 0 for success, 1 otherwise + */ +static int llc_rst_rsp_handler(struct llc_prim_if_block *prim) +{ + int rc = 1; + /* network layer supplies connection handle; map it to a connection; + * package as event and send it to connection event handler */ + struct sock *sk = prim->data->res.sk; + struct llc_conn_state_ev *ev = llc_conn_alloc_ev(sk); + + if (ev) { + ev->type = LLC_CONN_EV_TYPE_PRIM; + ev->data.prim.prim = LLC_RESET_PRIM; + ev->data.prim.type = LLC_PRIM_TYPE_RESP; + ev->data.prim.data = prim; + rc = llc_conn_send_ev(sk, ev); + } + return rc; +} + +static int llc_no_rsp_handler(struct llc_prim_if_block *prim) +{ + return 0; +} + +EXPORT_SYMBOL(llc_sap_open); +EXPORT_SYMBOL(llc_sap_close); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_mac.c linux.19pre5-ac1/net/llc/llc_mac.c --- linux.19p5/net/llc/llc_mac.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/net/llc/llc_mac.c Tue Mar 19 19:15:34 2002 @@ -0,0 +1,311 @@ +/* + * llc_mac.c - Manages interface between LLC and MAC + * + * Copyright (c) 1997 by Procom Technology, Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_TR +extern void tr_source_route(struct sk_buff *skb, struct trh_hdr *trh, + struct net_device *dev); +#endif +/* function prototypes */ +static void fix_up_incoming_skb(struct sk_buff *skb); + +/** + * mac_send_pdu - Sends PDU to specific device. + * @skb: pdu which must be sent + * + * If module is not initialized then returns failure, else figures out + * where to direct this PDU. Sends PDU to specific device, at this point a + * device must has been assigned to the PDU; If not, can't transmit the + * PDU. PDU sent to MAC layer, is free to re-send at a later time. Returns + * 0 on success, 1 for failure. + */ +int mac_send_pdu(struct sk_buff *skb) +{ + struct sk_buff *skb2; + int pri = GFP_ATOMIC, rc = -1; + + if (!skb->dev) { + printk(KERN_ERR __FUNCTION__ ": skb->dev == NULL!"); + goto out; + } + if (skb->sk) + pri = (int)skb->sk->priority; + skb2 = skb_clone(skb, pri); + if (!skb2) + goto out; + rc = 0; + dev_queue_xmit(skb2); +out: return rc; +} + +/** + * mac_indicate - 802.2 entry point from net lower layers + * @skb: received pdu + * @dev: device that receive pdu + * @pt: packet type + * + * When the system receives a 802.2 frame this function is called. It + * checks SAP and connection of received pdu and passes frame to + * llc_pdu_router for sending to proper state machine. If frame is + * related to a busy connection (a connection is sending data now), + * function queues this frame in connection's backlog. + */ +int mac_indicate(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt) +{ + struct llc_sap *sap; + llc_pdu_sn_t *pdu; + u8 dest; + + /* When the interface is in promisc. mode, drop all the crap that it + receives, do not try to analyse it. */ + if (skb->pkt_type == PACKET_OTHERHOST) { + printk(KERN_INFO __FUNCTION__ ": PACKET_OTHERHOST\n"); + goto drop; + } + skb = skb_share_check(skb, GFP_ATOMIC); + if (!skb) + goto out; + fix_up_incoming_skb(skb); + pdu = (llc_pdu_sn_t *)skb->nh.raw; + if (!pdu->dsap) { /* NULL DSAP, refer to station */ + llc_pdu_router(NULL, NULL, skb, 0); + goto out; + } + sap = llc_sap_find(pdu->dsap); + if (!sap) /* unknown SAP */ + goto drop; + llc_decode_pdu_type(skb, &dest); + if (dest == LLC_DEST_SAP) /* type 1 services */ + llc_pdu_router(sap, NULL, skb, LLC_TYPE_1); + else if (dest == LLC_DEST_CONN) { + struct llc_addr saddr, daddr; + struct sock *sk; + + llc_pdu_decode_sa(skb, saddr.mac); + llc_pdu_decode_ssap(skb, &saddr.lsap); + llc_pdu_decode_da(skb, daddr.mac); + llc_pdu_decode_dsap(skb, &daddr.lsap); + + sk = llc_find_sock(sap, &saddr, &daddr); + if (!sk) { /* didn't find an active connection; allocate a + connection to use; associate it with this SAP */ + sk = llc_sock_alloc(); + if (!sk) + goto drop; + memcpy(&llc_sk(sk)->daddr, &saddr, sizeof(saddr)); + llc_sap_assign_sock(sap, sk); + sock_hold(sk); + } + bh_lock_sock(sk); + if (!sk->lock.users) { + /* FIXME: Check this on SMP as it is now calling + * llc_pdu_router _with_ the lock held. + * Old comment: + * With the current code one can't call + * llc_pdu_router with the socket lock held, cause + * it'll route the pdu to the upper layers and it can + * reenter llc and in llc_req_prim will try to grab + * the same lock, maybe we should use spin_trylock_bh + * in the llc_req_prim (llc_data_req_handler, etc) and + * add the request to the backlog, well see... */ + llc_pdu_router(llc_sk(sk)->sap, sk, skb, LLC_TYPE_2); + bh_unlock_sock(sk); + } else { + skb->cb[0] = LLC_PACKET; + sk_add_backlog(sk, skb); + bh_unlock_sock(sk); + } + sock_put(sk); + } else /* unknown or not supported pdu */ + goto drop; +out: return 0; +drop: kfree_skb(skb); + goto out; +} + +/** + * fix_up_incoming_skb - initializes skb pointers + * @skb: This argument points to incoming skb + * + * Initializes internal skb pointer to start of network layer by deriving + * length of LLC header; finds length of LLC control field in LLC header + * by looking at the two lowest-order bits of the first control field + * byte; field is either 3 or 4 bytes long. + */ +static void fix_up_incoming_skb(struct sk_buff *skb) +{ + u8 llc_len = 2; + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->data; + + if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) == LLC_PDU_TYPE_U) + llc_len = 1; + llc_len += 2; + skb_pull(skb, llc_len); + if (skb->protocol == htons(ETH_P_802_2)) { + u16 pdulen = ((struct ethhdr *)skb->mac.raw)->h_proto, + data_size = ntohs(pdulen) - llc_len; + + skb_trim(skb, data_size); + } +} + +/** + * llc_pdu_router - routes received pdus to the upper layers + * @sap: current sap component structure. + * @sk: current connection structure. + * @frame: received frame. + * @type: type of received frame, that is LLC_TYPE_1 or LLC_TYPE_2 + * + * Queues received PDUs from LLC_MAC PDU receive queue until queue is + * empty; examines LLC header to determine the destination of PDU, if DSAP + * is NULL then data unit destined for station else frame destined for SAP + * or connection; finds a matching open SAP, if one, forwards the packet + * to it; if no matching SAP, drops the packet. Returns 0 or the return of + * llc_conn_send_ev (that may well result in the connection being + * destroyed) + */ +int llc_pdu_router(struct llc_sap *sap, struct sock* sk, + struct sk_buff *skb, u8 type) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw; + int rc = 0; + + if (!pdu->dsap) { + struct llc_station *station = llc_station_get(); + struct llc_station_state_ev *stat_ev = + llc_station_alloc_ev(station); + if (stat_ev) { + stat_ev->type = LLC_STATION_EV_TYPE_PDU; + stat_ev->data.pdu.skb = skb; + stat_ev->data.pdu.reason = 0; + llc_station_send_ev(station, stat_ev); + } + } else if (type == LLC_TYPE_1) { + struct llc_sap_state_ev *sap_ev = llc_sap_alloc_ev(sap); + + if (sap_ev) { + sap_ev->type = LLC_SAP_EV_TYPE_PDU; + sap_ev->data.pdu.skb = skb; + sap_ev->data.pdu.reason = 0; + llc_sap_send_ev(sap, sap_ev); + } + } else if (type == LLC_TYPE_2) { + struct llc_conn_state_ev *conn_ev = llc_conn_alloc_ev(sk); + struct llc_opt *llc = llc_sk(sk); + + if (!llc->dev) + llc->dev = skb->dev; + if (conn_ev) { + conn_ev->type = LLC_CONN_EV_TYPE_PDU; + conn_ev->data.pdu.skb = skb; + conn_ev->data.pdu.reason = 0; + rc = llc_conn_send_ev(sk, conn_ev); + } + } + return rc; +} + +/** + * lan_hdrs_init - fills MAC header fields + * @skb: Address of the frame to initialize its MAC header + * @sa: The MAC source address + * @da: The MAC destination address + * + * Fills MAC header fields, depending on MAC type. Returns 0, If MAC type + * is a valid type and initialization completes correctly 1, otherwise. + */ +u16 lan_hdrs_init(struct sk_buff *skb, u8 *sa, u8 *da) +{ + u8 *saddr; + u8 *daddr; + u16 rc = 0; + + switch (skb->dev->type) { +#ifdef CONFIG_TR + case ARPHRD_IEEE802_TR: { + struct trh_hdr *trh = (struct trh_hdr *) + skb_push(skb, sizeof(*trh)); + struct net_device *dev = skb->dev; + + trh->ac = AC; + trh->fc = LLC_FRAME; + if (sa) + memcpy(trh->saddr, sa, dev->addr_len); + else + memset(trh->saddr, 0, dev->addr_len); + if (da) { + memcpy(trh->daddr, da, dev->addr_len); + tr_source_route(skb, trh, dev); + } + skb->mac.raw = skb->data; + break; + } +#endif + case ARPHRD_ETHER: + case ARPHRD_LOOPBACK: { + unsigned short len = skb->len; + + skb->mac.raw = skb_push(skb, sizeof(struct ethhdr)); + memset(skb->mac.raw, 0, sizeof(struct ethhdr)); + ((struct ethhdr *)skb->mac.raw)->h_proto = htons(len); + daddr = ((struct ethhdr *)skb->mac.raw)->h_dest; + saddr = ((struct ethhdr *)skb->mac.raw)->h_source; + memcpy(daddr, da, ETH_ALEN); + memcpy(saddr, sa, ETH_ALEN); + break; + } + default: + printk(KERN_WARNING "Unknown DEVICE type : %d\n", + skb->dev->type); + rc = 1; + } + return rc; +} + +/** + * mac_dev_peer - search the appropriate dev to send packets to peer + * @current_dev - Current device suggested by upper layer + * @type - hardware type + * @mac - mac address + * + * Check if the we should use loopback to send packets, i.e., if the + * dmac belongs to one of the local interfaces, returning the pointer + * to the loopback &net_device struct or the current_dev if it is not + * local. + */ +struct net_device *mac_dev_peer(struct net_device *current_dev, int type, + u8 *mac) +{ + struct net_device *dev; + + rtnl_lock(); + dev = dev_getbyhwaddr(type, mac); + if (dev) + dev = __dev_get_by_name("lo"); + rtnl_unlock(); + return dev ? : current_dev; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_main.c linux.19pre5-ac1/net/llc/llc_main.c --- linux.19p5/net/llc/llc_main.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/net/llc/llc_main.c Tue Mar 26 16:57:25 2002 @@ -0,0 +1,629 @@ +/* + * llc_main.c - This module contains main functions to manage station, saps + * and connections of the LLC. + * + * Copyright (c) 1997 by Procom Technology, Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* static function prototypes */ +static void llc_station_service_events(struct llc_station *station); +static void llc_station_free_ev(struct llc_station *station, + struct llc_station_state_ev *ev); +static void llc_station_send_pdus(struct llc_station *station); +static u16 llc_station_next_state(struct llc_station *station, + struct llc_station_state_ev *ev); +static u16 llc_exec_station_trans_actions(struct llc_station *station, + struct llc_station_state_trans *trans, + struct llc_station_state_ev *ev); +static struct llc_station_state_trans * + llc_find_station_trans(struct llc_station *station, + struct llc_station_state_ev *ev); +static int llc_rtn_all_conns(struct llc_sap *sap); + +extern void llc_register_sap(unsigned char sap, + int (*rcvfunc)(struct sk_buff *skb, + struct net_device *dev, + struct packet_type *pt)); +extern void llc_unregister_sap(unsigned char sap); + +static struct llc_station llc_main_station; /* only one of its kind */ +struct llc_prim_if_block llc_ind_prim, llc_cfm_prim; +static union llc_u_prim_data llc_ind_data_prim, llc_cfm_data_prim; + +/** + * llc_sap_alloc - allocates and initializes sap. + * + * Allocates and initializes sap. + */ +struct llc_sap *llc_sap_alloc(void) +{ + struct llc_sap *sap = kmalloc(sizeof(*sap), GFP_ATOMIC); + + if (sap) { + memset(sap, 0, sizeof(*sap)); + sap->state = LLC_SAP_STATE_ACTIVE; + memcpy(sap->laddr.mac, llc_main_station.mac_sa, ETH_ALEN); + spin_lock_init(&sap->sk_list.lock); + INIT_LIST_HEAD(&sap->sk_list.list); + skb_queue_head_init(&sap->mac_pdu_q); + } + return sap; +} + +/** + * llc_free_sap - frees a sap + * @sap: Address of the sap + * + * Frees all associated connections (if any), removes this sap from + * the list of saps in te station and them frees the memory for this sap. + */ +void llc_free_sap(struct llc_sap *sap) +{ + struct llc_station *station = sap->parent_station; + + llc_rtn_all_conns(sap); + spin_lock_bh(&station->sap_list.lock); + list_del(&sap->node); + spin_unlock_bh(&station->sap_list.lock); + kfree(sap); +} + +/** + * llc_sap_save - add sap to station list + * @sap: Address of the sap + * + * Adds a sap to the LLC's station sap list. + */ +void llc_sap_save(struct llc_sap *sap) +{ + spin_lock_bh(&llc_main_station.sap_list.lock); + list_add_tail(&sap->node, &llc_main_station.sap_list.list); + spin_unlock_bh(&llc_main_station.sap_list.lock); +} + +/** + * llc_sap_find - searchs a SAP in station + * @sap_value: sap to be found + * + * Searchs for a sap in the sap list of the LLC's station upon the sap ID. + * Returns the sap or %NULL if not found. + */ +struct llc_sap *llc_sap_find(u8 sap_value) +{ + struct llc_sap* sap = NULL; + struct list_head *entry; + + spin_lock_bh(&llc_main_station.sap_list.lock); + list_for_each(entry, &llc_main_station.sap_list.list) { + sap = list_entry(entry, struct llc_sap, node); + if (sap->laddr.lsap == sap_value) + break; + } + if (entry == &llc_main_station.sap_list.list) /* not found */ + sap = NULL; + spin_unlock_bh(&llc_main_station.sap_list.lock); + return sap; +} + +/** + * llc_backlog_rcv - Processes rx frames and expired timers. + * @sk: LLC sock (p8022 connection) + * @skb: queued rx frame or event + * + * This function processes frames that has received and timers that has + * expired during sending an I pdu (refer to data_req_handler). frames + * queue by mac_indicate function (llc_mac.c) and timers queue by timer + * callback functions(llc_c_ac.c). + */ +static int llc_backlog_rcv(struct sock *sk, struct sk_buff *skb) +{ + int rc = 0; + struct llc_opt *llc = llc_sk(sk); + + if (skb->cb[0] == LLC_PACKET) { + if (llc->state > 1) /* not closed */ + rc = llc_pdu_router(llc->sap, sk, skb, LLC_TYPE_2); + else + kfree_skb(skb); + } else if (skb->cb[0] == LLC_EVENT) { + struct llc_conn_state_ev *ev = + (struct llc_conn_state_ev *)skb->data; + /* timer expiration event */ + if (llc->state > 1) /* not closed */ + rc = llc_conn_send_ev(sk, ev); + else + llc_conn_free_ev(ev); + kfree_skb(skb); + } + return rc; +} + +/** + * llc_sock_init - Initialize a socket with default llc values. + * @sk: socket to intiailize. + */ +int llc_sock_init(struct sock* sk) +{ + struct llc_opt *llc = kmalloc(sizeof(*llc), GFP_ATOMIC); + int rc = -ENOMEM; + + if (!llc) + goto out; + memset(llc, 0, sizeof(*llc)); + rc = 0; + llc->sk = sk; + llc->state = LLC_CONN_STATE_ADM; + llc->inc_cntr = llc->dec_cntr = 2; + llc->dec_step = llc->connect_step = 1; + llc->ack_timer.expire = LLC_ACK_TIME; + llc->pf_cycle_timer.expire = LLC_P_TIME; + llc->rej_sent_timer.expire = LLC_REJ_TIME; + llc->busy_state_timer.expire = LLC_BUSY_TIME; + llc->n2 = 2; /* max retransmit */ + llc->k = 2; /* tx win size, will adjust dynam */ + llc->rw = 128; /* rx win size (opt and equal to + tx_win of remote LLC) */ + skb_queue_head_init(&llc->pdu_unack_q); + sk->backlog_rcv = llc_backlog_rcv; + llc_sk(sk) = llc; +out: return rc; +} + +/** + * __llc_sock_alloc - Allocates LLC sock + * + * Allocates a LLC sock and initializes it. Returns the new LLC sock + * or %NULL if there's no memory available for one + */ +struct sock *__llc_sock_alloc(void) +{ + struct sock *sk = sk_alloc(PF_LLC, GFP_ATOMIC, 1); + + if (!sk) + goto out; + if (llc_sock_init(sk)) + goto outsk; + sock_init_data(NULL, sk); +out: return sk; +outsk: sk_free(sk); + sk = NULL; + goto out; +} + +/** + * __llc_sock_free - Frees a LLC socket + * @sk - socket to free + * + * Frees a LLC socket + */ +void __llc_sock_free(struct sock *sk, u8 free) +{ + struct llc_opt *llc = llc_sk(sk); + + llc->state = LLC_CONN_OUT_OF_SVC; + /* stop all (possibly) running timers */ + llc_conn_ac_stop_all_timers(sk, NULL); + /* handle return of frames on lists */ + printk(KERN_INFO __FUNCTION__ ": unackq=%d, txq=%d\n", + skb_queue_len(&llc->pdu_unack_q), + skb_queue_len(&sk->write_queue)); + skb_queue_purge(&sk->write_queue); + skb_queue_purge(&llc->pdu_unack_q); + if (free) + sock_put(sk); +} + +/** + * llc_sock_reset - resets a connection + * @sk: LLC socket to reset + * + * Resets a connection to the out of service state. Stops its timers + * and frees any frames in the queues of the connection. + */ +void llc_sock_reset(struct sock *sk) +{ + struct llc_opt *llc = llc_sk(sk); + + llc_conn_ac_stop_all_timers(sk, NULL); + skb_queue_purge(&sk->write_queue); + skb_queue_purge(&llc->pdu_unack_q); + llc->remote_busy_flag = 0; + llc->cause_flag = 0; + llc->retry_count = 0; + llc->p_flag = 0; + llc->f_flag = 0; + llc->s_flag = 0; + llc->ack_pf = 0; + llc->first_pdu_Ns = 0; + llc->ack_must_be_send = 0; + llc->dec_step = 1; + llc->inc_cntr = 2; + llc->dec_cntr = 2; + llc->X = 0; + llc->failed_data_req = 0 ; + llc->last_nr = 0; +} + +/** + * llc_rtn_all_conns - Closes all connections of a sap + * @sap: sap to close its connections + * + * Closes all connections of a sap. Returns 0 if all actions complete + * successfully, nonzero otherwise + */ +static int llc_rtn_all_conns(struct llc_sap *sap) +{ + int rc = 0; + union llc_u_prim_data prim_data; + struct llc_prim_if_block prim; + struct list_head *entry, *tmp; + + spin_lock_bh(&sap->sk_list.lock); + if (list_empty(&sap->sk_list.list)) + goto out; + list_for_each_safe(entry, tmp, &sap->sk_list.list) { + struct llc_opt *llc = list_entry(entry, struct llc_opt, node); + + prim.sap = sap; + prim_data.disc.sk = llc->sk; + prim.prim = LLC_DISC_PRIM; + prim.data = &prim_data; + llc->state = LLC_CONN_STATE_TEMP; + if (sap->req(&prim)) + rc = 1; + } +out: spin_unlock_bh(&sap->sk_list.lock); + return rc; +} + +/** + * llc_station_get - get addr of global station. + * + * Returns address of a place to copy the global station to it. + */ +struct llc_station *llc_station_get(void) +{ + return &llc_main_station; +} + +/** + * llc_station_alloc_ev - allocates an event + * @station: Address of the station + * + * Allocates an event in this station. Returns the allocated event on + * success, %NULL otherwise. + */ +struct llc_station_state_ev *llc_station_alloc_ev(struct llc_station *station) +{ + struct llc_station_state_ev *ev = kmalloc(sizeof(*ev), GFP_ATOMIC); + + if (ev) + memset(ev, 0, sizeof(*ev)); + return ev; +} + +/** + * llc_station_send_ev: queue event and try to process queue. + * @station: Address of the station + * @ev: Address of the event + * + * Queues an event (on the station event queue) for handling by the + * station state machine and attempts to process any queued-up events. + */ +void llc_station_send_ev(struct llc_station *station, + struct llc_station_state_ev *ev) +{ + spin_lock_bh(&station->ev_q.lock); + list_add_tail(&ev->node, &station->ev_q.list); + llc_station_service_events(station); + spin_unlock_bh(&station->ev_q.lock); +} + +/** + * llc_station_send_pdu - queues PDU to send + * @station: Address of the station + * @skb: Address of the PDU + * + * Queues a PDU to send to the MAC layer. + */ +void llc_station_send_pdu(struct llc_station *station, struct sk_buff *skb) +{ + skb_queue_tail(&station->mac_pdu_q, skb); + llc_station_send_pdus(station); +} + +/** + * llc_station_send_pdus - tries to send queued PDUs + * @station: Address of the station + * + * Tries to send any PDUs queued in the station mac_pdu_q to the MAC + * layer. + */ +static void llc_station_send_pdus(struct llc_station *station) +{ + struct sk_buff *skb; + + while ((skb = skb_dequeue(&station->mac_pdu_q)) != NULL) { + int rc = mac_send_pdu(skb); + + kfree_skb(skb); + if (rc) + break; + } +} + +/** + * llc_station_free_ev - frees an event + * @station: Address of the station + * @event: Address of the event + * + * Frees an event. + */ +static void llc_station_free_ev(struct llc_station *station, + struct llc_station_state_ev *ev) +{ + struct sk_buff *skb = ev->data.pdu.skb; + + if (ev->type == LLC_STATION_EV_TYPE_PDU) + kfree_skb(skb); + kfree(ev); +} + +/** + * llc_station_service_events - service events in the queue + * @station: Address of the station + * + * Get an event from the station event queue (if any); attempt to service + * the event; if event serviced, get the next event (if any) on the event + * queue; if event not service, re-queue the event on the event queue and + * attempt to service the next event; when serviced all events in queue, + * finished; if don't transition to different state, just service all + * events once; if transition to new state, service all events again. + * Caller must hold station->ev_q.lock. + */ +static void llc_station_service_events(struct llc_station *station) +{ + struct llc_station_state_ev *ev; + struct list_head *entry, *tmp; + + list_for_each_safe(entry, tmp, &station->ev_q.list) { + ev = list_entry(entry, struct llc_station_state_ev, node); + list_del(&ev->node); + llc_station_next_state(station, ev); + } +} + +/** + * llc_station_next_state - processes event and goes to the next state + * @station: Address of the station + * @ev: Address of the event + * + * Processes an event, executes any transitions related to that event and + * updates the state of the station. + */ +static u16 llc_station_next_state(struct llc_station *station, + struct llc_station_state_ev *ev) +{ + u16 rc = 1; + struct llc_station_state_trans *trans; + + if (station->state > LLC_NBR_STATION_STATES) + goto out; + trans = llc_find_station_trans(station, ev); + if (trans) { + /* got the state to which we next transition; perform the + * actions associated with this transition before actually + * transitioning to the next state */ + rc = llc_exec_station_trans_actions(station, trans, ev); + if (!rc) + /* transition station to next state if all actions + * execute successfully; done; wait for next event */ + station->state = trans->next_state; + } else + /* event not recognized in current state; re-queue it for + * processing again at a later time; return failure */ + rc = 0; +out: llc_station_free_ev(station, ev); + return rc; +} + +/** + * llc_find_station_trans - finds transition for this event + * @station: Address of the station + * @ev: Address of the event + * + * Search thru events of the current state of the station until list + * exhausted or it's obvious that the event is not valid for the current + * state. Returns the address of the transition if cound, %NULL otherwise. + */ +static struct llc_station_state_trans * + llc_find_station_trans(struct llc_station *station, + struct llc_station_state_ev *ev) +{ + int i = 0; + struct llc_station_state_trans *rc = NULL; + struct llc_station_state_trans **next_trans; + struct llc_station_state *curr_state = + &llc_station_state_table[station->state - 1]; + + for (next_trans = curr_state->transitions; next_trans[i]->ev; i++) + if (!next_trans[i]->ev(station, ev)) { + rc = next_trans[i]; + break; + } + return rc; +} + +/** + * llc_exec_station_trans_actions - executes actions for transition + * @station: Address of the station + * @trans: Address of the transition + * @ev: Address of the event that caused the transition + * + * Executes actions of a transition of the station state machine. Returns + * 0 if all actions complete successfully, nonzero otherwise. + */ +static u16 llc_exec_station_trans_actions(struct llc_station *station, + struct llc_station_state_trans *trans, + struct llc_station_state_ev *ev) +{ + u16 rc = 0; + llc_station_action_t *next_action; + + for (next_action = trans->ev_actions; + next_action && *next_action; next_action++) + if ((*next_action)(station, ev)) + rc = 1; + return rc; +} + +/** + * llc_alloc_frame - allocates sk_buff for frame + * + * Allocates an sk_buff for frame and initializes sk_buff fields. + * Returns allocated skb or %NULL when out of memory. + */ +struct sk_buff *llc_alloc_frame(void) +{ + struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC); + + if (skb) { + skb_reserve(skb, 50); + skb->nh.raw = skb->h.raw = skb->data; + skb->protocol = htons(ETH_P_802_2); + skb->dev = dev_base->next; + skb->mac.raw = skb->head; + } + return skb; +} + +static int llc_proc_get_info(char *bf, char **start, off_t offset, int length) +{ + struct llc_opt *llc; + struct list_head *sap_entry, *llc_entry; + off_t begin = 0, pos = 0; + int len = 0; + + spin_lock_bh(&llc_main_station.sap_list.lock); + list_for_each(sap_entry, &llc_main_station.sap_list.list) { + struct llc_sap *sap = list_entry(sap_entry, struct llc_sap, + node); + + len += sprintf(bf + len, "lsap=%d\n", sap->laddr.lsap); + spin_lock_bh(&sap->sk_list.lock); + if (list_empty(&sap->sk_list.list)) { + len += sprintf(bf + len, "no connections\n"); + goto unlock; + } + len += sprintf(bf + len, + "connection list:\nstate retr txwin rxwin\n"); + list_for_each(llc_entry, &sap->sk_list.list) { + llc = list_entry(llc_entry, struct llc_opt, node); + len += sprintf(bf + len, " %-5d%-5d%-6d%-5d\n", + llc->state, llc->retry_count, llc->k, + llc->rw); + } +unlock: spin_unlock_bh(&sap->sk_list.lock); + pos = begin + len; + if (pos < offset) { + len = 0; /* Keep dumping into the buffer start */ + begin = pos; + } + if (pos > offset + length) /* We have dumped enough */ + break; + } + spin_unlock_bh(&llc_main_station.sap_list.lock); + + /* The data in question runs from begin to begin + len */ + *start = bf + (offset - begin); /* Start of wanted data */ + len -= (offset - begin); /* Remove unwanted header data from length */ + return len; +} + +static char llc_banner[] __initdata = + KERN_INFO "LLC 2.0 by Procom, 1997, Arnaldo C. Melo, 2001\n" + KERN_INFO "NET4.0 IEEE 802.2 extended support\n"; +static char llc_error_msg[] __initdata = + KERN_ERR "LLC install NOT successful.\n"; + +static int __init llc_init(void) +{ + u16 rc = 0; + struct llc_station_state_ev *ev; + + printk(llc_banner); + INIT_LIST_HEAD(&llc_main_station.ev_q.list); + spin_lock_init(&llc_main_station.ev_q.lock); + INIT_LIST_HEAD(&llc_main_station.sap_list.list); + spin_lock_init(&llc_main_station.sap_list.lock); + skb_queue_head_init(&llc_main_station.mac_pdu_q); + ev = kmalloc(sizeof(*ev), GFP_ATOMIC); + if (!ev) + goto err; + memset(ev, 0, sizeof(*ev)); + if(dev_base->next) + memcpy(llc_main_station.mac_sa, dev_base->next->dev_addr, ETH_ALEN); + else + memset(llc_main_station.mac_sa, 0, ETH_ALEN); + llc_main_station.ack_timer.expires = jiffies + 3 * HZ; + /* initialize the station component */ + llc_register_sap(0, mac_indicate); + llc_main_station.maximum_retry = 1; + llc_main_station.state = LLC_STATION_STATE_DOWN; + ev->type = LLC_STATION_EV_TYPE_SIMPLE; + ev->data.a.ev = LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK; + rc = llc_station_next_state(&llc_main_station, ev); + llc_build_offset_table(); + llc_ind_prim.data = &llc_ind_data_prim; + llc_cfm_prim.data = &llc_cfm_data_prim; + proc_net_create("802.2", 0, llc_proc_get_info); + llc_ui_init(); +out: return rc; +err: printk(llc_error_msg); + rc = 1; + goto out; +} + +static void __exit llc_exit(void) +{ + llc_ui_exit(); + llc_unregister_sap(0); + proc_net_remove("802.2"); +} + +module_init(llc_init); +module_exit(llc_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Procom, 1997, Arnaldo C. Melo, Jay Schullist, 2001"); +MODULE_DESCRIPTION("LLC 2.0, NET4.0 IEEE 802.2 extended support"); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_pdu.c linux.19pre5-ac1/net/llc/llc_pdu.c --- linux.19p5/net/llc/llc_pdu.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/net/llc/llc_pdu.c Tue Mar 19 19:15:34 2002 @@ -0,0 +1,652 @@ +/* + * llc_pdu.c - access to PDU internals + * + * Copyright (c) 1997 by Procom Technology, Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include + +static int llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type); +static int llc_get_llc_hdr_length(u8 pdu_type); +static u8 llc_pdu_get_pf_bit(llc_pdu_sn_t *pdu); + +/** + * llc_pdu_header_init - initializes pdu header + * @skb: input skb that header must be set into it. + * @pdu_type: type of PDU (U, I or S). + * @ssap: source sap. + * @dsap: destination sap. + * @cr: command/response bit (0 or 1). + * + * This function sets DSAP, SSAP and command/Response bit in LLC header. + */ +void llc_pdu_header_init(struct sk_buff *skb, u8 pdu_type, u8 ssap, + u8 dsap, u8 cr) +{ + llc_pdu_un_t *p; + + skb->nh.raw = skb_push(skb, llc_get_llc_hdr_length(pdu_type)); + p = (llc_pdu_un_t *)skb->nh.raw; + p->dsap = dsap; + p->ssap = ssap; + p->ssap |= cr; +} + +void llc_pdu_set_cmd_rsp(struct sk_buff *skb, u8 pdu_type) +{ + ((llc_pdu_un_t *)skb->nh.raw)->ssap |= pdu_type; +} + +/** + * pdu_set_pf_bit - sets poll/final bit in LLC header + * @pdu_frame: input frame that p/f bit must be set into it. + * @bit_value: poll/final bit (0 or 1). + * + * This function sets poll/final bit in LLC header (based on type of PDU). + * in I or S pdus, p/f bit is right bit of fourth byte in header. in U + * pdus p/f bit is fifth bit of third byte. + */ +void llc_pdu_set_pf_bit(struct sk_buff *skb, u8 bit_value) +{ + u8 pdu_type; + + if (llc_pdu_decode_pdu_type(skb, &pdu_type)) + goto out; + switch (pdu_type) { + case LLC_PDU_TYPE_I: + case LLC_PDU_TYPE_S: + ((llc_pdu_sn_t *)skb->nh.raw)->ctrl_2 = + (((llc_pdu_sn_t *)skb->nh.raw)->ctrl_2 & 0xFE) | + bit_value; + break; + case LLC_PDU_TYPE_U: + ((llc_pdu_un_t *)skb->nh.raw)->ctrl_1 |= + (((llc_pdu_un_t *)skb->nh.raw)->ctrl_1 & 0xEF) | + (bit_value << 4); + break; + } +out:; +} + +/** + * llc_pdu_decode_pf_bit - extracs poll/final bit from LLC header + * @skb: input skb that p/f bit must be extracted from it + * @pf_bit: poll/final bit (0 or 1) + * + * This function extracts poll/final bit from LLC header (based on type of + * PDU). In I or S pdus, p/f bit is right bit of fourth byte in header. In + * U pdus p/f bit is fifth bit of third byte. + */ +int llc_pdu_decode_pf_bit(struct sk_buff *skb, u8 *pf_bit) +{ + u8 pdu_type; + int rc = llc_pdu_decode_pdu_type(skb, &pdu_type); + + if (rc) + goto out; + switch (pdu_type) { + case LLC_PDU_TYPE_I: + case LLC_PDU_TYPE_S: + *pf_bit = ((llc_pdu_sn_t *)skb->nh.raw)->ctrl_2 & + LLC_S_PF_BIT_MASK; + break; + case LLC_PDU_TYPE_U: + *pf_bit = (((llc_pdu_un_t *)skb->nh.raw)->ctrl_1 & + LLC_U_PF_BIT_MASK) >> 4; + break; + } +out: return 0; +} + +/** + * llc_pdu_decode_cr_bit - extracs command response bit from LLC header + * @skb: input skb that c/r bit must be extracted from it. + * @cr_bit: command/response bit (0 or 1). + * + * This function extracts command/response bit from LLC header. this bit + * is right bit of source SAP. + */ +int llc_pdu_decode_cr_bit(struct sk_buff *skb, u8 *cr_bit) +{ + *cr_bit = ((llc_pdu_un_t *)skb->nh.raw)->ssap & LLC_PDU_CMD_RSP_MASK; + return 0; +} + +/** + * llc_pdu_decode_sa - extracs source address (MAC) of input frame + * @skb: input skb that source address must be extracted from it. + * @sa: pointer to source address (6 byte array). + * + * This function extracts source address(MAC) of input frame. + */ +int llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa) +{ + if (skb->protocol == ntohs(ETH_P_802_2)) + memcpy(sa, ((struct ethhdr *)skb->mac.raw)->h_source, ETH_ALEN); + else if (skb->protocol == ntohs(ETH_P_TR_802_2)) + memcpy(sa, ((struct trh_hdr *)skb->mac.raw)->saddr, ETH_ALEN); + return 0; +} + +/** + * llc_pdu_decode_da - extracts dest address of input frame + * @skb: input skb that destination address must be extracted from it + * @sa: pointer to destination address (6 byte array). + * + * This function extracts destination address(MAC) of input frame. + */ +int llc_pdu_decode_da(struct sk_buff *skb, u8 *da) +{ + if (skb->protocol == ntohs(ETH_P_802_2)) + memcpy(da, ((struct ethhdr *)skb->mac.raw)->h_dest, ETH_ALEN); + else if (skb->protocol == ntohs(ETH_P_TR_802_2)) + memcpy(da, ((struct trh_hdr *)skb->mac.raw)->daddr, ETH_ALEN); + return 0; +} + +/** + * llc_pdu_decode_dsap - extracts dest SAP of input frame + * @skb: input skb that destination SAP must be extracted from it. + * @dsap: destination SAP (output argument). + * + * This function extracts destination SAP of input frame. right bit of + * DSAP designates individual/group SAP. + */ +int llc_pdu_decode_dsap(struct sk_buff *skb, u8 *dsap) +{ + *dsap = ((llc_pdu_un_t *)skb->nh.raw)->dsap & 0xFE; + return 0; +} + +/** + * llc_pdu_decode_ssap - extracts source SAP of input frame + * @skb: input skb that source SAP must be extracted from it. + * @ssap: source SAP (output argument). + * + * This function extracts source SAP of input frame. right bit of SSAP is + * command/response bit. + */ +int llc_pdu_decode_ssap(struct sk_buff *skb, u8 *ssap) +{ + *ssap = ((llc_pdu_un_t *)skb->nh.raw)->ssap & 0xFE; + return 0; +} + +/** + * llc_pdu_init_as_ui_cmd - sets LLC header as UI PDU + * @skb: input skb that header must be set into it. + * + * This function sets third byte of LLC header as a UI PDU. + */ +int llc_pdu_init_as_ui_cmd(struct sk_buff *skb) +{ + llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw; + + pdu->ctrl_1 = LLC_PDU_TYPE_U; + pdu->ctrl_1 |= LLC_1_PDU_CMD_UI; + return 0; +} + +/** + * llc_pdu_init_as_xid_cmd - sets bytes 3, 4 & 5 of LLC header as XID + * @skb: input skb that header must be set into it. + * + * This function sets third,fourth,fifth and sixth bytes of LLC header as + * a XID PDU. + */ +int llc_pdu_init_as_xid_cmd(struct sk_buff *skb, u8 svcs_supported, + u8 rx_window) +{ + llc_xid_info_t *xid_info; + llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw; + + pdu->ctrl_1 = LLC_PDU_TYPE_U; + pdu->ctrl_1 |= LLC_1_PDU_CMD_XID; + pdu->ctrl_1 |= LLC_U_PF_BIT_MASK; + xid_info = (llc_xid_info_t *)(((u8 *)&pdu->ctrl_1) + 1); + xid_info->fmt_id = LLC_XID_FMT_ID; /* 0x81*/ + xid_info->type = svcs_supported; + xid_info->rw = (rx_window << 1); /* size of recieve window */ + skb_put(skb, 3); + return 0; +} + +/** + * llc_pdu_init_as_test_cmd - sets PDU as TEST + * @skb - Address of the skb to build + * + * Sets a PDU as TEST + */ +int llc_pdu_init_as_test_cmd(struct sk_buff *skb) +{ + llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw; + + pdu->ctrl_1 = LLC_PDU_TYPE_U; + pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST; + pdu->ctrl_1 |= LLC_U_PF_BIT_MASK; + return 0; +} + +/** + * llc_pdu_init_as_disc_cmd - Builds DISC PDU + * @skb: Address of the skb to build + * @p_bit: The P bit to set in the PDU + * + * Builds a pdu frame as a DISC command. + */ +int llc_pdu_init_as_disc_cmd(struct sk_buff *skb, u8 p_bit) +{ + llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw; + + pdu->ctrl_1 = LLC_PDU_TYPE_U; + pdu->ctrl_1 |= LLC_2_PDU_CMD_DISC; + pdu->ctrl_1 |= (((p_bit & 1) << 4) & LLC_U_PF_BIT_MASK); + return 0; +} + +/** + * pdu_init_as_i_cmd - builds I pdu + * @skb: Address of the skb to build + * @p_bit: The P bit to set in the PDU + * @ns: The sequence number of the data PDU + * @nr: The seq. number of the expected I PDU from the remote + * + * Builds a pdu frame as an I command. + */ +int llc_pdu_init_as_i_cmd(struct sk_buff *skb, u8 p_bit, u8 ns, u8 nr) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw; + + pdu->ctrl_1 = LLC_PDU_TYPE_I; + pdu->ctrl_2 = 0; + pdu->ctrl_2 |= (p_bit & LLC_I_PF_BIT_MASK); /* p/f bit */ + pdu->ctrl_1 |= ((ns << 1) & 0xFE); /* set N(S) in bits 2..8 */ + pdu->ctrl_2 |= ((nr << 1) & 0xFE); /* set N(R) in bits 10..16 */ + return 0; +} + +/** + * pdu_init_as_rej_cmd - builds REJ PDU + * @skb: Address of the skb to build + * @p_bit: The P bit to set in the PDU + * @nr: The seq. number of the expected I PDU from the remote + * + * Builds a pdu frame as a REJ command. + */ +int llc_pdu_init_as_rej_cmd(struct sk_buff *skb, u8 p_bit, u8 nr) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw; + + pdu->ctrl_1 = LLC_PDU_TYPE_S; + pdu->ctrl_1 |= LLC_2_PDU_CMD_REJ; + pdu->ctrl_2 = 0; + pdu->ctrl_2 |= (p_bit & LLC_S_PF_BIT_MASK); + pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */ + pdu->ctrl_2 |= ((nr << 1) & 0xFE); /* set N(R) in bits 10..16 */ + return 0; +} + +/** + * pdu_init_as_rnr_cmd - builds RNR pdu + * @skb: Address of the skb to build + * @p_bit: The P bit to set in the PDU + * @nr: The seq. number of the expected I PDU from the remote + * + * Builds a pdu frame as an RNR command. + */ +int llc_pdu_init_as_rnr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw; + + pdu->ctrl_1 = LLC_PDU_TYPE_S; + pdu->ctrl_1 |= LLC_2_PDU_CMD_RNR; + pdu->ctrl_2 = 0; + pdu->ctrl_2 |= (p_bit & LLC_S_PF_BIT_MASK); + pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */ + pdu->ctrl_2 |= ((nr << 1) & 0xFE); /* set N(R) in bits 10..16 */ + return 0; +} + +/** + * pdu_init_as_rr_cmd - Builds RR pdu + * @skb: Address of the skb to build + * @p_bit: The P bit to set in the PDU + * @nr: The seq. number of the expected I PDU from the remote + * + * Builds a pdu frame as an RR command. + */ +int llc_pdu_init_as_rr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw; + + pdu->ctrl_1 = LLC_PDU_TYPE_S; + pdu->ctrl_1 |= LLC_2_PDU_CMD_RR; + pdu->ctrl_2 = (p_bit & LLC_S_PF_BIT_MASK); + pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */ + pdu->ctrl_2 |= ((nr << 1) & 0xFE); /* set N(R) in bits 10..16 */ + return 0; +} + +/** + * pdu_init_as_sabme_cmd - builds SABME pdu + * @skb: Address of the skb to build + * @p_bit: The P bit to set in the PDU + * + * Builds a pdu frame as an SABME command. + */ +int llc_pdu_init_as_sabme_cmd(struct sk_buff *skb, u8 p_bit) +{ + llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw; + + pdu->ctrl_1 = LLC_PDU_TYPE_U; + pdu->ctrl_1 |= LLC_2_PDU_CMD_SABME; + pdu->ctrl_1 |= (((p_bit & 1) << 4) & LLC_U_PF_BIT_MASK); + return 0; +} + +/** + * pdu_init_as_dm_rsp - builds DM response pdu + * @skb: Address of the skb to build + * @f_bit: The F bit to set in the PDU + * + * Builds a pdu frame as a DM response. + */ +int llc_pdu_init_as_dm_rsp(struct sk_buff *skb, u8 f_bit) +{ + llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw; + + pdu->ctrl_1 = LLC_PDU_TYPE_U; + pdu->ctrl_1 |= LLC_2_PDU_RSP_DM; + pdu->ctrl_1 |= (((f_bit & 1) << 4) & LLC_U_PF_BIT_MASK); + return 0; +} + +/** + * pdu_init_as_xid_rsp - builds XID response PDU + * @skb: Address of the skb to build + * @svcs_supported: The class of the LLC (I or II) + * @rx_window: The size of the receive window of the LLC + * + * Builds a pdu frame as an XID response. + */ +int llc_pdu_init_as_xid_rsp(struct sk_buff *skb, u8 svcs_supported, + u8 rx_window) +{ + llc_xid_info_t *xid_info; + llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw; + + pdu->ctrl_1 = LLC_PDU_TYPE_U; + pdu->ctrl_1 |= LLC_1_PDU_CMD_XID; + pdu->ctrl_1 |= LLC_U_PF_BIT_MASK; + + xid_info = (llc_xid_info_t *)(((u8 *)&pdu->ctrl_1) + 1); + xid_info->fmt_id = LLC_XID_FMT_ID; + xid_info->type = svcs_supported; + xid_info->rw = rx_window << 1; + skb_put(skb, 3); + return 0; +} + +/** + * pdu_init_as_test_rsp - build TEST response PDU + * @skb: Address of the skb to build + * @ev_skb: The received TEST command PDU frame + * + * Builds a pdu frame as a TEST response. + */ +int llc_pdu_init_as_test_rsp(struct sk_buff *skb, struct sk_buff *ev_skb) +{ + int dsize; + llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw; + + pdu->ctrl_1 = LLC_PDU_TYPE_U; + pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST; + pdu->ctrl_1 |= LLC_U_PF_BIT_MASK; + if (ev_skb->protocol == ntohs(ETH_P_802_2)) { + dsize = ntohs(((struct ethhdr *)ev_skb->mac.raw)->h_proto) - 3; + memcpy(((u8 *)skb->nh.raw) + 3, + ((u8 *)ev_skb->nh.raw) + 3, dsize); + skb_put(skb, dsize); + } + return 0; +} + +/** + * pdu_init_as_frmr_rsp - builds FRMR response PDU + * @pdu_frame: Address of the frame to build + * @prev_pdu: The rejected PDU frame + * @f_bit: The F bit to set in the PDU + * @vs: tx state vari value for the data link conn at the rejecting LLC + * @vr: rx state var value for the data link conn at the rejecting LLC + * @vzyxw: completely described in the IEEE Std 802.2 document (Pg 55) + * + * Builds a pdu frame as a FRMR response. + */ +int llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, llc_pdu_sn_t *prev_pdu, + u8 f_bit, u8 vs, u8 vr, u8 vzyxw) +{ + llc_frmr_info_t *frmr_info; + u8 prev_pf = 0; + u8 *ctrl; + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw; + + pdu->ctrl_1 = LLC_PDU_TYPE_U; + pdu->ctrl_1 |= LLC_2_PDU_RSP_FRMR; + pdu->ctrl_1 |= ((f_bit & 1) << 4) & LLC_U_PF_BIT_MASK; + + frmr_info = (llc_frmr_info_t *)&pdu->ctrl_2; + ctrl = (u8 *)&prev_pdu->ctrl_1; + FRMR_INFO_SET_REJ_CNTRL(frmr_info,ctrl); + FRMR_INFO_SET_Vs(frmr_info, vs); + FRMR_INFO_SET_Vr(frmr_info, vr); + prev_pf = llc_pdu_get_pf_bit(prev_pdu); + FRMR_INFO_SET_C_R_BIT(frmr_info, prev_pf); + FRMR_INFO_SET_INVALID_PDU_CTRL_IND(frmr_info, vzyxw); + FRMR_INFO_SET_INVALID_PDU_INFO_IND(frmr_info, vzyxw); + FRMR_INFO_SET_PDU_INFO_2LONG_IND(frmr_info, vzyxw); + FRMR_INFO_SET_PDU_INVALID_Nr_IND(frmr_info, vzyxw); + FRMR_INFO_SET_PDU_INVALID_Ns_IND(frmr_info, vzyxw); + skb_put(skb, 5); + return 0; +} + +/** + * pdu_init_as_rr_rsp - builds RR response pdu + * @skb: Address of the skb to build + * @f_bit: The F bit to set in the PDU + * @nr: The seq. number of the expected data PDU from the remote + * + * Builds a pdu frame as an RR response. + */ +int llc_pdu_init_as_rr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw; + + pdu->ctrl_1 = LLC_PDU_TYPE_S; + pdu->ctrl_1 |= LLC_2_PDU_RSP_RR; + pdu->ctrl_2 = 0; + pdu->ctrl_2 |= (f_bit & LLC_S_PF_BIT_MASK); + pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */ + pdu->ctrl_2 |= ((nr << 1) & 0xFE); /* set N(R) in bits 10..16 */ + return 0; +} + +/** + * pdu_init_as_rej_rsp - builds REJ response pdu + * @skb: Address of the skb to build + * @f_bit: The F bit to set in the PDU + * @nr: The seq. number of the expected data PDU from the remote + * + * Builds a pdu frame as a REJ response. + */ +int llc_pdu_init_as_rej_rsp(struct sk_buff *skb, u8 f_bit, u8 nr) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw; + + pdu->ctrl_1 = LLC_PDU_TYPE_S; + pdu->ctrl_1 |= LLC_2_PDU_RSP_REJ; + pdu->ctrl_2 = 0; + pdu->ctrl_2 |= (f_bit & LLC_S_PF_BIT_MASK); + pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */ + pdu->ctrl_2 |= ((nr << 1) & 0xFE); /* set N(R) in bits 10..16 */ + return 0; +} + +/** + * pdu_init_as_rnr_rsp - builds RNR response pdu + * @pdu_frame: Address of the frame to build + * @f_bit: The F bit to set in the PDU + * @nr: The seq. number of the expected data PDU from the remote + * + * Builds a pdu frame as an RNR response. + */ +int llc_pdu_init_as_rnr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr) +{ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw; + + pdu->ctrl_1 = LLC_PDU_TYPE_S; + pdu->ctrl_1 |= LLC_2_PDU_RSP_RNR; + pdu->ctrl_2 = 0; + pdu->ctrl_2 |= (f_bit & LLC_S_PF_BIT_MASK); + pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */ + pdu->ctrl_2 |= ((nr << 1) & 0xFE); /* set N(R) in bits 10..16 */ + return 0; +} + +/** + * pdu_init_as_ua_rsp - builds UA response pdu + * @skb: Address of the frame to build + * @f_bit: The F bit to set in the PDU + * + * Builds a pdu frame as a UA response. + */ +int llc_pdu_init_as_ua_rsp(struct sk_buff *skb, u8 f_bit) +{ + llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw; + + pdu->ctrl_1 = LLC_PDU_TYPE_U; + pdu->ctrl_1 |= LLC_2_PDU_RSP_UA; + pdu->ctrl_1 |= (((f_bit & 1) << 4) & LLC_U_PF_BIT_MASK); + return 0; +} + +/** + * llc_pdu_decode_pdu_type - designates PDU type + * @skb: input skb that type of it must be designated. + * @type: type of PDU (output argument). + * + * This function designates type of PDU (I,S or U). + */ +static int llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type) +{ + llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw; + + if (pdu->ctrl_1 & 1) { + if ((pdu->ctrl_1 & LLC_PDU_TYPE_U) == LLC_PDU_TYPE_U) + *type = LLC_PDU_TYPE_U; + else + *type = LLC_PDU_TYPE_S; + } else + *type = LLC_PDU_TYPE_I; + return 0; +} + +/** + * llc_decode_pdu_type - designates component LLC must handle for PDU + * @skb: input skb + * @dest: destination component + * + * This function designates which component of LLC must handle this PDU. + */ +int llc_decode_pdu_type(struct sk_buff *skb, u8 *dest) +{ + u8 type = LLC_DEST_CONN; /* I-PDU or S-PDU type */ + llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw; + + if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) != LLC_PDU_TYPE_U) + goto out; + switch (LLC_U_PDU_CMD(pdu)) { + case LLC_1_PDU_CMD_XID: + case LLC_1_PDU_CMD_UI: + case LLC_1_PDU_CMD_TEST: + type = LLC_DEST_SAP; + break; + case LLC_2_PDU_CMD_SABME: + case LLC_2_PDU_CMD_DISC: + case LLC_2_PDU_RSP_UA: + case LLC_2_PDU_RSP_DM: + case LLC_2_PDU_RSP_FRMR: + break; + default: + type = LLC_DEST_INVALID; + break; + } +out: *dest = type; + return 0; +} + +/** + * get_llc_hdr_len - designates LLC header length + * @pdu_type: type of PDU. + * + * This function designates LLC header length of PDU. header length for I + * and S PDU is 4 and for U is 3 bytes. Returns the length of header. + */ +static int llc_get_llc_hdr_length(u8 pdu_type) +{ + int rtn_val = 0; + + switch (pdu_type) { + case LLC_PDU_TYPE_I: + case LLC_PDU_TYPE_S: + rtn_val = 4; + break; + case LLC_PDU_TYPE_U: + rtn_val = 3; + break; + } + return rtn_val; +} + +/** + * llc_pdu_get_pf_bit - extracts p/f bit of input PDU + * @pdu: pointer to LLC header. + * + * This function extracts p/f bit of input PDU. at first examines type of + * PDU and then extracts p/f bit. Returns the p/f bit. + */ +static u8 llc_pdu_get_pf_bit(llc_pdu_sn_t *pdu) +{ + u8 pdu_type; + u8 pf_bit = 0; + + if (pdu->ctrl_1 & 1) { + if ((pdu->ctrl_1 & LLC_PDU_TYPE_U) == LLC_PDU_TYPE_U) + pdu_type = LLC_PDU_TYPE_U; + else + pdu_type = LLC_PDU_TYPE_S; + } else + pdu_type = LLC_PDU_TYPE_I; + switch (pdu_type) { + case LLC_PDU_TYPE_I: + case LLC_PDU_TYPE_S: + pf_bit = pdu->ctrl_2 & LLC_S_PF_BIT_MASK; + break; + case LLC_PDU_TYPE_U: + pf_bit = (pdu->ctrl_1 & LLC_U_PF_BIT_MASK) >> 4; + break; + } + return pf_bit; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_s_ac.c linux.19pre5-ac1/net/llc/llc_s_ac.c --- linux.19p5/net/llc/llc_s_ac.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/net/llc/llc_s_ac.c Tue Mar 19 19:15:34 2002 @@ -0,0 +1,222 @@ +/* + * llc_s_ac.c - actions performed during sap state transition. + * + * Description : + * Functions in this module are implementation of sap component actions. + * Details of actions can be found in IEEE-802.2 standard document. + * All functions have one sap and one event as input argument. All of + * them return 0 On success and 1 otherwise. + * + * Copyright (c) 1997 by Procom Technology, Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include + +/** + * llc_sap_action_unit_data_ind - forward UI PDU to network layer + * @sap: SAP + * @ev: the event to forward + * + * Received a UI PDU from MAC layer; forward to network layer as a + * UNITDATA INDICATION; verify our event is the kind we expect + */ +int llc_sap_action_unitdata_ind(struct llc_sap *sap, + struct llc_sap_state_ev *ev) +{ + llc_sap_rtn_pdu(sap, ev->data.pdu.skb, ev); + return 0; +} + +/** + * llc_sap_action_send_ui - sends UI PDU resp to UNITDATA REQ to MAC layer + * @sap: SAP + * @ev: the event to send + * + * Sends a UI PDU to the MAC layer in response to a UNITDATA REQUEST + * primitive from the network layer. Verifies event is a primitive type of + * event. Verify the primitive is a UNITDATA REQUEST. + */ +int llc_sap_action_send_ui(struct llc_sap *sap, struct llc_sap_state_ev *ev) +{ + struct llc_prim_if_block *prim = ev->data.prim.data; + struct llc_prim_unit_data *prim_data = &prim->data->udata; + struct sk_buff *skb = prim->data->udata.skb; + int rc; + + llc_pdu_header_init(skb, LLC_PDU_TYPE_U, prim_data->saddr.lsap, + prim_data->daddr.lsap, LLC_PDU_CMD); + rc = llc_pdu_init_as_ui_cmd(skb); + if (rc) + goto out; + rc = lan_hdrs_init(skb, prim_data->saddr.mac, prim_data->daddr.mac); + if (!rc) + llc_sap_send_pdu(sap, skb); +out: return rc; +} + +/** + * llc_sap_action_send_xid_c - send XID PDU as response to XID REQ + * @sap: SAP + * @ev: the event to send + * + * Send a XID command PDU to MAC layer in response to a XID REQUEST + * primitive from the network layer. Verify event is a primitive type + * event. Verify the primitive is a XID REQUEST. + */ +int llc_sap_action_send_xid_c(struct llc_sap *sap, struct llc_sap_state_ev *ev) +{ + struct llc_prim_if_block *prim = ev->data.prim.data; + struct llc_prim_xid *prim_data = &prim->data->xid; + struct sk_buff *skb = prim_data->skb; + int rc; + + llc_pdu_header_init(skb, LLC_PDU_TYPE_U, prim_data->saddr.lsap, + prim_data->daddr.lsap, LLC_PDU_CMD); + rc = llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 0); + if (rc) + goto out; + rc = lan_hdrs_init(skb, prim_data->saddr.mac, prim_data->daddr.mac); + if (!rc) + llc_sap_send_pdu(sap, skb); +out: return rc; +} + +/** + * llc_sap_action_send_xid_r - send XID PDU resp to MAC for received XID + * @sap: SAP + * @ev: the event to send + * + * Send XID response PDU to MAC in response to an earlier received XID + * command PDU. Verify event is a PDU type event + */ +int llc_sap_action_send_xid_r(struct llc_sap *sap, struct llc_sap_state_ev *ev) +{ + u8 mac_da[ETH_ALEN], mac_sa[ETH_ALEN], dsap; + int rc = 1; + struct sk_buff *ev_skb = ev->data.pdu.skb; + struct sk_buff *skb; + + llc_pdu_decode_sa(ev_skb, mac_da); + llc_pdu_decode_da(ev_skb, mac_sa); + llc_pdu_decode_ssap(ev_skb, &dsap); + skb = llc_alloc_frame(); + if (!skb) + goto out; + skb->dev = ev_skb->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap, + LLC_PDU_RSP); + rc = llc_pdu_init_as_xid_rsp(skb, LLC_XID_NULL_CLASS_2, 0); + if (rc) + goto out; + rc = lan_hdrs_init(skb, mac_sa, mac_da); + if (!rc) + llc_sap_send_pdu(sap, skb); +out: return rc; +} + +/** + * llc_sap_action_send_test_c - send TEST PDU to MAC in resp to TEST REQ + * @sap: SAP + * @ev: the event to send + * + * Send a TEST command PDU to the MAC layer in response to a TEST REQUEST + * primitive from the network layer. Verify event is a primitive type + * event; verify the primitive is a TEST REQUEST. + */ +int llc_sap_action_send_test_c(struct llc_sap *sap, struct llc_sap_state_ev *ev) +{ + struct llc_prim_if_block *prim = ev->data.prim.data; + struct llc_prim_test *prim_data = &prim->data->test; + struct sk_buff *skb = prim_data->skb; + int rc; + + llc_pdu_header_init(skb, LLC_PDU_TYPE_U, prim_data->saddr.lsap, + prim_data->daddr.lsap, LLC_PDU_CMD); + rc = llc_pdu_init_as_test_cmd(skb); + if (rc) + goto out; + rc = lan_hdrs_init(skb, prim_data->saddr.mac, prim_data->daddr.mac); + if (!rc) + llc_sap_send_pdu(sap, skb); +out: return rc; +} + +int llc_sap_action_send_test_r(struct llc_sap *sap, struct llc_sap_state_ev *ev) +{ + u8 mac_da[ETH_ALEN], mac_sa[ETH_ALEN], dsap; + int rc = 1; + struct sk_buff *ev_skb = ev->data.pdu.skb; + struct sk_buff *skb; + + llc_pdu_decode_sa(ev_skb, mac_da); + llc_pdu_decode_da(ev_skb, mac_sa); + llc_pdu_decode_ssap(ev_skb, &dsap); + skb = llc_alloc_frame(); + if (!skb) + goto out; + skb->dev = ev_skb->dev; + llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap, + LLC_PDU_RSP); + rc = llc_pdu_init_as_test_rsp(skb, ev_skb); + if (rc) + goto out; + rc = lan_hdrs_init(skb, mac_sa, mac_da); + if (!rc) + llc_sap_send_pdu(sap, skb); +out: return rc; +} + +/** + * llc_sap_action_report_status - report data link status to layer mgmt + * @sap: SAP + * @ev: the event to send + * + * Report data link status to layer management. Verify our event is the + * kind we expect. + */ +int llc_sap_action_report_status(struct llc_sap *sap, + struct llc_sap_state_ev *ev) +{ + return 0; +} + +/** + * llc_sap_action_xid_ind - send XID PDU resp to net layer via XID IND + * @sap: SAP + * @ev: the event to send + * + * Send a XID response PDU to the network layer via a XID INDICATION + * primitive. + */ +int llc_sap_action_xid_ind(struct llc_sap *sap, struct llc_sap_state_ev *ev) +{ + llc_sap_rtn_pdu(sap, ev->data.pdu.skb, ev); + return 0; +} + +/** + * llc_sap_action_test_ind - send TEST PDU to net layer via TEST IND + * @sap: SAP + * @ev: the event to send + * + * Send a TEST response PDU to the network layer via a TEST INDICATION + * primitive. Verify our event is a PDU type event. + */ +int llc_sap_action_test_ind(struct llc_sap *sap, struct llc_sap_state_ev *ev) +{ + llc_sap_rtn_pdu(sap, ev->data.pdu.skb, ev); + return 0; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_s_ev.c linux.19pre5-ac1/net/llc/llc_s_ev.c --- linux.19p5/net/llc/llc_s_ev.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/net/llc/llc_s_ev.c Tue Mar 19 19:15:34 2002 @@ -0,0 +1,101 @@ +/* + * llc_s_ev.c - Defines SAP component events + * + * The followed event functions are SAP component events which are described + * in 802.2 LLC protocol standard document. + * + * Copyright (c) 1997 by Procom Technology, Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +#include +#include +#include +#include +#include + +int llc_sap_ev_activation_req(struct llc_sap *sap, struct llc_sap_state_ev *ev) +{ + return ev->type == LLC_SAP_EV_TYPE_SIMPLE && + ev->data.a.ev == LLC_SAP_EV_ACTIVATION_REQ ? 0 : 1; +} + +int llc_sap_ev_rx_ui(struct llc_sap *sap, struct llc_sap_state_ev *ev) +{ + llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw; + + return ev->type == LLC_SAP_EV_TYPE_PDU && !LLC_PDU_IS_CMD(pdu) && + !LLC_PDU_TYPE_IS_U(pdu) && + LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_UI ? 0 : 1; +} + +int llc_sap_ev_unitdata_req(struct llc_sap *sap, struct llc_sap_state_ev *ev) +{ + return ev->type == LLC_SAP_EV_TYPE_PRIM && + ev->data.prim.prim == LLC_DATAUNIT_PRIM && + ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1; + +} + +int llc_sap_ev_xid_req(struct llc_sap *sap, struct llc_sap_state_ev *ev) +{ + return ev->type == LLC_SAP_EV_TYPE_PRIM && + ev->data.prim.prim == LLC_XID_PRIM && + ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1; +} + +int llc_sap_ev_rx_xid_c(struct llc_sap *sap, struct llc_sap_state_ev *ev) +{ + llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw; + + return ev->type == LLC_SAP_EV_TYPE_PDU && !LLC_PDU_IS_CMD(pdu) && + !LLC_PDU_TYPE_IS_U(pdu) && + LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_XID ? 0 : 1; +} + +int llc_sap_ev_rx_xid_r(struct llc_sap *sap, struct llc_sap_state_ev *ev) +{ + llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw; + + return ev->type == LLC_SAP_EV_TYPE_PDU && !LLC_PDU_IS_RSP(pdu) && + !LLC_PDU_TYPE_IS_U(pdu) && + LLC_U_PDU_RSP(pdu) == LLC_1_PDU_CMD_XID ? 0 : 1; +} + +int llc_sap_ev_test_req(struct llc_sap *sap, struct llc_sap_state_ev *ev) +{ + return ev->type == LLC_SAP_EV_TYPE_PRIM && + ev->data.prim.prim == LLC_TEST_PRIM && + ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1; +} + +int llc_sap_ev_rx_test_c(struct llc_sap *sap, struct llc_sap_state_ev *ev) +{ + llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw; + + return ev->type == LLC_SAP_EV_TYPE_PDU && !LLC_PDU_IS_CMD(pdu) && + !LLC_PDU_TYPE_IS_U(pdu) && + LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_TEST ? 0 : 1; +} + +int llc_sap_ev_rx_test_r(struct llc_sap *sap, struct llc_sap_state_ev *ev) +{ + llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw; + + return ev->type == LLC_SAP_EV_TYPE_PDU && !LLC_PDU_IS_RSP(pdu) && + !LLC_PDU_TYPE_IS_U(pdu) && + LLC_U_PDU_RSP(pdu) == LLC_1_PDU_CMD_TEST ? 0 : 1; +} + +int llc_sap_ev_deactivation_req(struct llc_sap *sap, + struct llc_sap_state_ev *ev) +{ + return ev->type == LLC_SAP_EV_TYPE_SIMPLE && + ev->data.a.ev == LLC_SAP_EV_DEACTIVATION_REQ ? 0 : 1; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_s_st.c linux.19pre5-ac1/net/llc/llc_s_st.c --- linux.19p5/net/llc/llc_s_st.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/net/llc/llc_s_st.c Tue Mar 19 19:15:34 2002 @@ -0,0 +1,163 @@ +/* + * llc_s_st.c - Defines SAP component state machine transitions. + * + * The followed transitions are SAP component state machine transitions + * which are described in 802.2 LLC protocol standard document. + * + * Copyright (c) 1997 by Procom Technology, Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +#include +#include +#include +#include +#include + +/* dummy last-transition indicator; common to all state transition groups */ +/* last entry for this state */ +/* all members are zeros, .bss zeroes it */ +static struct llc_sap_state_trans llc_sap_state_trans_n; + +/* state LLC_SAP_STATE_INACTIVE transition for LLC_SAP_EV_ACTIVATION_REQ event */ +static llc_sap_action_t llc_sap_inactive_state_actions_1[] = { + llc_sap_action_report_status, + NULL +}; + +static struct llc_sap_state_trans llc_sap_inactive_state_trans_1 = { + llc_sap_ev_activation_req, LLC_SAP_STATE_ACTIVE, + llc_sap_inactive_state_actions_1 +}; + +/* array of pointers; one to each transition */ +static struct llc_sap_state_trans *llc_sap_inactive_state_transitions[] = { + &llc_sap_inactive_state_trans_1, + &llc_sap_state_trans_n +}; + +/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_RX_UI event */ +static llc_sap_action_t llc_sap_active_state_actions_1[] = { + llc_sap_action_unitdata_ind, + NULL +}; + +static struct llc_sap_state_trans llc_sap_active_state_trans_1 = { + llc_sap_ev_rx_ui, LLC_SAP_STATE_ACTIVE, + llc_sap_active_state_actions_1 +}; + +/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_UNITDATA_REQ event */ +static llc_sap_action_t llc_sap_active_state_actions_2[] = { + llc_sap_action_send_ui, + NULL +}; + +static struct llc_sap_state_trans llc_sap_active_state_trans_2 = { + llc_sap_ev_unitdata_req, LLC_SAP_STATE_ACTIVE, + llc_sap_active_state_actions_2 +}; + + +/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_XID_REQ event */ +static llc_sap_action_t llc_sap_active_state_actions_3[] = { + llc_sap_action_send_xid_c, + NULL +}; + +static struct llc_sap_state_trans llc_sap_active_state_trans_3 = { + llc_sap_ev_xid_req, LLC_SAP_STATE_ACTIVE, + llc_sap_active_state_actions_3 +}; + +/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_RX_XID_C event */ +static llc_sap_action_t llc_sap_active_state_actions_4[] = { + llc_sap_action_send_xid_r, + NULL +}; + +static struct llc_sap_state_trans llc_sap_active_state_trans_4 = { + llc_sap_ev_rx_xid_c, LLC_SAP_STATE_ACTIVE, + llc_sap_active_state_actions_4 +}; + +/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_RX_XID_R event */ +static llc_sap_action_t llc_sap_active_state_actions_5[] = { + llc_sap_action_xid_ind, + NULL +}; + +static struct llc_sap_state_trans llc_sap_active_state_trans_5 = { + llc_sap_ev_rx_xid_r, LLC_SAP_STATE_ACTIVE, + llc_sap_active_state_actions_5 +}; + +/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_TEST_REQ event */ +static llc_sap_action_t llc_sap_active_state_actions_6[] = { + llc_sap_action_send_test_c, + NULL +}; + +static struct llc_sap_state_trans llc_sap_active_state_trans_6 = { + llc_sap_ev_test_req, LLC_SAP_STATE_ACTIVE, + llc_sap_active_state_actions_6 +}; + +/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_RX_TEST_C event */ +static llc_sap_action_t llc_sap_active_state_actions_7[] = { + llc_sap_action_send_test_r, + NULL +}; + +static struct llc_sap_state_trans llc_sap_active_state_trans_7 = { + llc_sap_ev_rx_test_c, LLC_SAP_STATE_ACTIVE, + llc_sap_active_state_actions_7 +}; + +/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_RX_TEST_R event */ +static llc_sap_action_t llc_sap_active_state_actions_8[] = { + llc_sap_action_test_ind, + NULL +}; + +static struct llc_sap_state_trans llc_sap_active_state_trans_8 = { + llc_sap_ev_rx_test_r, LLC_SAP_STATE_ACTIVE, + llc_sap_active_state_actions_8 +}; + +/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_DEACTIVATION_REQ event */ +static llc_sap_action_t llc_sap_active_state_actions_9[] = { + llc_sap_action_report_status, + NULL +}; + +static struct llc_sap_state_trans llc_sap_active_state_trans_9 = { + llc_sap_ev_deactivation_req, LLC_SAP_STATE_INACTIVE, + llc_sap_active_state_actions_9 +}; + +/* array of pointers; one to each transition */ +static struct llc_sap_state_trans *llc_sap_active_state_transitions[] = { + &llc_sap_active_state_trans_2, + &llc_sap_active_state_trans_1, + &llc_sap_active_state_trans_3, + &llc_sap_active_state_trans_4, + &llc_sap_active_state_trans_5, + &llc_sap_active_state_trans_6, + &llc_sap_active_state_trans_7, + &llc_sap_active_state_trans_8, + &llc_sap_active_state_trans_9, + &llc_sap_state_trans_n +}; + +/* SAP state transition table */ +struct llc_sap_state llc_sap_state_table[] = { + { LLC_SAP_STATE_INACTIVE, llc_sap_inactive_state_transitions }, + { LLC_SAP_STATE_ACTIVE, llc_sap_active_state_transitions } +}; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_sap.c linux.19pre5-ac1/net/llc/llc_sap.c --- linux.19p5/net/llc/llc_sap.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/net/llc/llc_sap.c Tue Mar 19 19:15:34 2002 @@ -0,0 +1,259 @@ +/* + * llc_sap.c - driver routines for SAP component. + * + * Copyright (c) 1997 by Procom Technology, Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void llc_sap_free_ev(struct llc_sap *sap, struct llc_sap_state_ev *ev); +static int llc_sap_next_state(struct llc_sap *sap, struct llc_sap_state_ev *ev); +static int llc_exec_sap_trans_actions(struct llc_sap *sap, + struct llc_sap_state_trans *trans, + struct llc_sap_state_ev *ev); +static struct llc_sap_state_trans *llc_find_sap_trans(struct llc_sap *sap, + struct llc_sap_state_ev *ev); + +/** + * llc_sap_assign_sock - adds a connection to a SAP + * @sap: pointer to SAP. + * @conn: pointer to connection. + * + * This function adds a connection to connection_list of a SAP. + */ +void llc_sap_assign_sock(struct llc_sap *sap, struct sock *sk) +{ + spin_lock_bh(&sap->sk_list.lock); + llc_sk(sk)->sap = sap; + list_add_tail(&llc_sk(sk)->node, &sap->sk_list.list); + sock_hold(sk); + spin_unlock_bh(&sap->sk_list.lock); +} + +/** + * llc_sap_unassign_sock - removes a connection from SAP + * @sap: SAP + * @sk: pointer to connection + * + * This function removes a connection from connection_list of a SAP. + * List locking is performed by caller (rtn_all_conns). + */ +void llc_sap_unassign_sock(struct llc_sap *sap, struct sock *sk) +{ + spin_lock_bh(&sap->sk_list.lock); + list_del(&llc_sk(sk)->node); + sock_put(sk); + spin_unlock_bh(&sap->sk_list.lock); +} + +/** + * llc_sap_alloc_ev - allocates sap event + * @sap: pointer to SAP + * @ev: allocated event (output argument) + * + * Returns the allocated sap event or %NULL when out of memory. + */ +struct llc_sap_state_ev *llc_sap_alloc_ev(struct llc_sap *sap) +{ + struct llc_sap_state_ev *ev = kmalloc(sizeof(*ev), GFP_ATOMIC); + + if (ev) + memset(ev, 0, sizeof(*ev)); + return ev; +} + +/** + * llc_sap_send_ev - sends event to SAP state machine + * @sap: pointer to SAP + * @ev: pointer to occurred event + * + * After executing actions of the event, upper layer will be indicated + * if needed(on receiving an UI frame). + */ +void llc_sap_send_ev(struct llc_sap *sap, struct llc_sap_state_ev *ev) +{ + struct llc_prim_if_block *prim; + u8 flag; + + llc_sap_next_state(sap, ev); + flag = ev->ind_cfm_flag; + prim = ev->prim; + if (flag == LLC_IND) { + skb_get(ev->data.pdu.skb); + sap->ind(prim); + } + llc_sap_free_ev(sap, ev); +} + +/** + * llc_sap_rtn_pdu - Informs upper layer on rx of an UI, XID or TEST pdu. + * @sap: pointer to SAP + * @skb: received pdu + * @ev: pointer to occurred event + */ +void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb, + struct llc_sap_state_ev *ev) +{ + llc_pdu_un_t *pdu; + struct llc_prim_if_block *prim = &llc_ind_prim; + union llc_u_prim_data *prim_data = llc_ind_prim.data; + u8 lfb; + + llc_pdu_decode_sa(skb, prim_data->udata.saddr.mac); + llc_pdu_decode_da(skb, prim_data->udata.daddr.mac); + llc_pdu_decode_dsap(skb, &prim_data->udata.daddr.lsap); + llc_pdu_decode_ssap(skb, &prim_data->udata.saddr.lsap); + prim_data->udata.pri = 0; + prim_data->udata.skb = skb; + pdu = (llc_pdu_un_t *)skb->nh.raw; + switch (LLC_U_PDU_RSP(pdu)) { + case LLC_1_PDU_CMD_TEST: + prim->prim = LLC_TEST_PRIM; + break; + case LLC_1_PDU_CMD_XID: + prim->prim = LLC_XID_PRIM; + break; + case LLC_1_PDU_CMD_UI: + if (skb->protocol == ntohs(ETH_P_TR_802_2)) { + if (((struct trh_hdr *)skb->mac.raw)->rcf) { + lfb = ntohs(((struct trh_hdr *) + skb->mac.raw)->rcf) & + 0x0070; + prim_data->udata.lfb = lfb >> 4; + } else { + lfb = 0xFF; + prim_data->udata.lfb = 0xFF; + } + } + prim->prim = LLC_DATAUNIT_PRIM; + break; + } + prim->data = prim_data; + prim->sap = sap; + ev->ind_cfm_flag = LLC_IND; + ev->prim = prim; +} + +/** + * llc_sap_send_pdu - Sends a frame to MAC layer for transmition + * @sap: pointer to SAP + * @skb: pdu that must be sent + */ +void llc_sap_send_pdu(struct llc_sap *sap, struct sk_buff *skb) +{ + mac_send_pdu(skb); + kfree_skb(skb); +} + +/** + * llc_sap_free_ev - frees an sap event + * @sap: pointer to SAP + * @ev: released event + */ +static void llc_sap_free_ev(struct llc_sap *sap, struct llc_sap_state_ev *ev) +{ + if (ev->type == LLC_SAP_EV_TYPE_PDU) { + llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw; + + if (LLC_U_PDU_CMD(pdu) != LLC_1_PDU_CMD_UI) + kfree_skb(ev->data.pdu.skb); + } + kfree(ev); +} + +/** + * llc_sap_next_state - finds transition, execs actions & change SAP state + * @sap: pointer to SAP + * @ev: happened event + * + * This function finds transition that matches with happened event, then + * executes related actions and finally changes state of SAP. It returns + * 0 on success and 1 for failure. + */ +static int llc_sap_next_state(struct llc_sap *sap, struct llc_sap_state_ev *ev) +{ + int rc = 1; + struct llc_sap_state_trans *trans; + + if (sap->state <= LLC_NBR_SAP_STATES) { + trans = llc_find_sap_trans(sap, ev); + if (trans) { + /* got the state to which we next transition; perform + * the actions associated with this transition before + * actually transitioning to the next state */ + rc = llc_exec_sap_trans_actions(sap, trans, ev); + if (!rc) + /* transition SAP to next state if all actions + execute successfully */ + sap->state = trans->next_state; + } + } + return rc; +} + +/** + * llc_find_sap_trans - finds transition for event + * @sap: pointer to SAP + * @ev: happened event + * + * This function finds transition that matches with happened event. + * Returns the pointer to found transition on success or %NULL for + * failure. + */ +static struct llc_sap_state_trans *llc_find_sap_trans(struct llc_sap *sap, + struct llc_sap_state_ev* ev) +{ + int i = 0; + struct llc_sap_state_trans *rc = NULL; + struct llc_sap_state_trans **next_trans; + struct llc_sap_state *curr_state = &llc_sap_state_table[sap->state - 1]; + /* search thru events for this state until list exhausted or until + * its obvious the event is not valid for the current state */ + for (next_trans = curr_state->transitions; next_trans [i]->ev; i++) + if (!next_trans[i]->ev(sap, ev)) { + /* got event match; return it */ + rc = next_trans[i]; + break; + } + return rc; +} + +/** + * llc_exec_sap_trans_actions - execute actions related to event + * @sap: pointer to SAP + * @trans: pointer to transition that it's actions must be performed + * @ev: happened event. + * + * This function executes actions that is related to happened event. + * Returns 0 for success and 1 for failure of at least one action. + */ +static int llc_exec_sap_trans_actions(struct llc_sap *sap, + struct llc_sap_state_trans *trans, + struct llc_sap_state_ev *ev) +{ + int rc = 0; + llc_sap_action_t *next_action; + + for (next_action = trans->ev_actions; + next_action && *next_action; next_action++) + if ((*next_action)(sap, ev)) + rc = 1; + return rc; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_sock.c linux.19pre5-ac1/net/llc/llc_sock.c --- linux.19p5/net/llc/llc_sock.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/net/llc/llc_sock.c Tue Mar 19 19:15:34 2002 @@ -0,0 +1,1755 @@ +/* + * llc_sock.c - LLC User Interface SAPs + * Description: + * Functions in this module are implementation of socket based llc + * communications for the Linux operating system. Support of llc class + * one and class two is provided via SOCK_DGRAM and SOCK_STREAM + * respectively. + * + * An llc2 connection is (mac + sap), only one llc2 sap connection + * is allowed per mac. Though one sap may have multiple mac + sap + * connections. + * + * Copyright (c) 2001 by Jay Schulist + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define dprintk(format, a...) printk(KERN_INFO __FUNCTION__ ": " format, ##a) + +/* remember: uninitialized global data is zeroed because its in .bss */ +static u16 llc_ui_sap_last_autoport = LLC_SAP_DYN_START; +static u16 llc_ui_sap_link_no_max[256]; +static u8 llc_ui_addrany[IFHWADDRLEN]; +static struct sockaddr_llc llc_ui_addrnull; +static struct proto_ops llc_ui_ops; +static struct sock *llc_ui_sockets; +static rwlock_t llc_ui_sockets_lock = RW_LOCK_UNLOCKED; + +static int llc_ui_indicate(struct llc_prim_if_block *prim); +static int llc_ui_confirm(struct llc_prim_if_block *prim); +static int llc_ui_wait_for_conn(struct sock *sk, int seconds); +static int llc_ui_wait_for_disc(struct sock *sk, int seconds); + +/** + * llc_ui_next_link_no - return the next unused link number for a sap + * @sap: Address of sap to get link number from. + * + * Return the next unused link number for a given sap. + */ +static inline u16 llc_ui_next_link_no(int sap) +{ + return llc_ui_sap_link_no_max[sap]++; +} + +/** + * llc_ui_mac_match - determines if two mac addresses are the same + * @mac1: First mac address to compare. + * @mac2: Second mac address to compare. + * + * Determines if two given mac address are the same. Returns 0 if there + * is not a complete match up to len, 1 if a complete match up to len is + * found. + */ +static inline u8 llc_ui_mac_match(u8 *mac1, u8 *mac2) +{ + return !memcmp(mac1, mac2, IFHWADDRLEN); +} + +/** + * llc_ui_mac_null - determines if a address is a null mac address + * @mac: Mac address to test if null. + * + * Determines if a given address is a null mac address. Returns 0 if the + * address is not a null mac, 1 if the address is a null mac. + */ +static inline u8 llc_ui_mac_null(u8 *mac) +{ + return !memcmp(mac, llc_ui_addrany, IFHWADDRLEN); +} + +/** + * llc_ui_addr_null - determines if a address structure is null + * @addr: Address to test if null. + */ +static inline u8 llc_ui_addr_null(struct sockaddr_llc *addr) +{ + return !memcmp(addr, &llc_ui_addrnull, sizeof(*addr)); +} + +/** + * llc_ui_protocol_type - return eth protocol for ARP header type + * @arphrd: ARP header type. + * + * Given an ARP header type return the corresponding ethernet protocol. + * Returns 0 if ARP header type not supported or the corresponding + * ethernet protocol type. + */ +static inline u16 llc_ui_protocol_type(u16 arphrd) +{ + u16 rc = htons(ETH_P_802_2); + + if (arphrd == ARPHRD_IEEE802_TR) + rc = htons(ETH_P_TR_802_2); + return rc; +} + +/** + * llc_ui_header_len - return length of llc header based on operation + * @sk: Socket which contains a valid llc socket type. + * @addr: Complete sockaddr_llc structure received from the user. + * + * Provide the length of the llc header depending on what kind of + * operation the user would like to perform and the type of socket. + * Returns the correct llc header length. + */ +static inline u8 llc_ui_header_len(struct sock *sk, struct sockaddr_llc *addr) +{ + u8 rc = LLC_PDU_LEN_U; + + if (addr->sllc_test || addr->sllc_xid) + rc = LLC_PDU_LEN_U; + else if (sk->type == SOCK_STREAM) + rc = LLC_PDU_LEN_I; + return rc; +} + +/** + * llc_ui_send_conn - send connect command for new llc2 connection + * @sap : Sap the socket is bound to. + * @addr: Source and destination fields provided by the user. + * @dev : Device which this connection should use. + * @link: Link number to assign to this connection. + * + * Send a connect command to the llc layer for a new llc2 connection. + * Returns 0 upon success, non-zero if action didn't succeed. + */ +static int llc_ui_send_conn(struct sock *sk, struct llc_sap *sap, + struct sockaddr_llc *addr, + struct net_device *dev, int link) +{ + struct llc_ui_opt *llc_ui = llc_ui_sk(sk); + union llc_u_prim_data prim_data; + struct llc_prim_if_block prim; + + prim.data = &prim_data; + prim.sap = sap; + prim.prim = LLC_CONN_PRIM; + prim_data.conn.dev = dev; + prim_data.conn.link = link; + prim_data.conn.sk = NULL; + prim_data.conn.handler = sk; + prim_data.conn.pri = 0; + prim_data.conn.saddr.lsap = llc_ui->addr.sllc_ssap; + prim_data.conn.daddr.lsap = addr->sllc_dsap; + memcpy(prim_data.conn.saddr.mac, dev->dev_addr, IFHWADDRLEN); + memcpy(prim_data.conn.daddr.mac, addr->sllc_dmac, IFHWADDRLEN); + return sap->req(&prim); +} + +/** + * llc_ui_send_disc - send disc command to llc layer + * @sk: Socket with valid llc information. + * + * Send a disconnect command to the llc layer for an established + * llc2 connection. + * Returns 0 upon success, non-zero if action did not succeed. + */ +static int llc_ui_send_disc(struct sock *sk) +{ + struct llc_ui_opt *llc_ui = llc_ui_sk(sk); + union llc_u_prim_data prim_data; + struct llc_prim_if_block prim; + int rc = 0; + + if (sk->type != SOCK_STREAM || sk->state != TCP_ESTABLISHED) + goto out; + sk->state = TCP_CLOSING; + prim.data = &prim_data; + prim.sap = llc_ui->sap; + prim.prim = LLC_DISC_PRIM; + prim_data.disc.sk = llc_ui->core_sk; + prim_data.disc.link = llc_ui->link; + rc = llc_ui->sap->req(&prim); +out: return rc; +} + +/** + * llc_ui_send_data - send data via reliable llc2 connection + * @sap: Sap the socket is bound to. + * @sk: Connection the socket is using. + * @skb: Data the user wishes to send. + * @addr: Source and destination fields provided by the user. + * + * Send data via reliable llc2 connection. + * Returns 0 upon success, non-zero if action did not succeed. + */ +static int llc_ui_send_data(struct llc_sap *sap, struct sock* sk, + struct sk_buff *skb, struct sockaddr_llc *addr) +{ + union llc_u_prim_data prim_data; + struct llc_prim_if_block prim; + struct llc_ui_opt* llc_ui = llc_ui_sk(sk); + struct llc_opt* llc_core = llc_sk(llc_ui->core_sk); + int rc; + + prim.data = &prim_data; + prim.sap = sap; + prim.prim = LLC_DATA_PRIM; + prim_data.data.skb = skb; + prim_data.data.pri = 0; + prim_data.data.sk = llc_ui->core_sk; + skb->protocol = llc_ui_protocol_type(addr->sllc_arphrd); + sock_hold(sk); +try: rc = sap->req(&prim); + if (rc != -EBUSY) + goto out; + rc = wait_event_interruptible(sk->socket->wait, !llc_ui->core_sk || + !llc_core->failed_data_req); + if (!rc) + goto try; + if (!llc_ui->core_sk) + rc = -ENOTCONN; +out: sock_put(sk); + return rc; +} + +/** + * llc_ui_send_llc1 - send llc1 prim data block to llc layer. + * @sap : Sap the socket is bound to. + * @skb : Data the user wishes to send. + * @addr : Source and destination fields provided by the user. + * @primitive: Action the llc layer should perform. + * + * Send an llc1 primitive data block to the llc layer for processing. + * This function is used for test, xid and unit_data messages. + * Returns 0 upon success, non-zero if action did not succeed. + */ +static int llc_ui_send_llc1(struct llc_sap *sap, struct sk_buff *skb, + struct sockaddr_llc *addr, int primitive) +{ + union llc_u_prim_data prim_data; + struct llc_prim_if_block prim; + + prim.data = &prim_data; + prim.sap = sap; + prim.prim = primitive; + prim_data.test.skb = skb; + prim_data.test.saddr.lsap = sap->laddr.lsap; + prim_data.test.daddr.lsap = addr->sllc_dsap; + skb->protocol = llc_ui_protocol_type(addr->sllc_arphrd); + memcpy(prim_data.test.saddr.mac, skb->dev->dev_addr, IFHWADDRLEN); + memcpy(prim_data.test.daddr.mac, addr->sllc_dmac, IFHWADDRLEN); + return sap->req(&prim); +} + +/** + * llc_ui_find_sap - returns sap struct that matches sap number specified + * @sap: Sap number to search for. + * + * Search the local socket list and return the first instance of the sap + * structure which matches the sap number the user specified. + * Returns llc_sap upon match, %NULL otherwise. + */ +static inline struct llc_sap *llc_ui_find_sap(u8 sap) +{ + struct sock *sk; + struct llc_sap *s = NULL; + + read_lock_bh(&llc_ui_sockets_lock); + for (sk = llc_ui_sockets; sk; sk = sk->next) { + struct llc_ui_opt *llc_ui = llc_ui_sk(sk); + + if (!llc_ui->sap) + continue; + if (llc_ui->sap->laddr.lsap == sap) { + s = llc_ui->sap; + break; + } + } + read_unlock_bh(&llc_ui_sockets_lock); + return s; +} + +static struct sock *__llc_ui_find_sk_by_exact(struct llc_addr *laddr, + struct llc_addr *daddr) +{ + struct sock *sk; + + for (sk = llc_ui_sockets; sk; sk = sk->next) { + struct llc_ui_opt *llc_ui = llc_ui_sk(sk); + + if (llc_ui->addr.sllc_ssap == laddr->lsap && + llc_ui->addr.sllc_dsap == daddr->lsap && + llc_ui_mac_null(llc_ui->addr.sllc_mmac) && + llc_ui_mac_match(llc_ui->addr.sllc_smac, laddr->mac) && + llc_ui_mac_match(llc_ui->addr.sllc_dmac, daddr->mac)) + break; + } + return sk; +} + +/** + * __llc_ui_find_sk_by_addr - return socket matching local mac + sap. + * @addr: Local address to match. + * + * Search the local socket list and return the socket which has a matching + * local (mac + sap) address (allows null mac). This search will work on + * unconnected and connected sockets, though find_by_link_no is recommend + * for connected sockets. + * Returns sock upon match, %NULL otherwise. + */ +static struct sock *__llc_ui_find_sk_by_addr(struct llc_addr *laddr, + struct llc_addr *daddr, + struct net_device *dev) +{ + struct sock *sk, *tmp_sk; + + for (sk = llc_ui_sockets; sk; sk = sk->next) { + struct llc_ui_opt *llc_ui = llc_ui_sk(sk); + + if (llc_ui->addr.sllc_ssap != laddr->lsap) + continue; + if (llc_ui_mac_null(llc_ui->addr.sllc_smac)) { + if (!llc_ui_mac_null(llc_ui->addr.sllc_mmac) && + !llc_ui_mac_match(llc_ui->addr.sllc_mmac, laddr->mac)) + continue; + break; + } + if (dev && !llc_ui_mac_null(llc_ui->addr.sllc_mmac) && + llc_ui_mac_match(llc_ui->addr.sllc_mmac, laddr->mac) && + llc_ui_mac_match(llc_ui->addr.sllc_smac, dev->dev_addr)) + break; + if (dev->flags & IFF_LOOPBACK) + break; + if (!llc_ui_mac_match(llc_ui->addr.sllc_smac, laddr->mac)) + continue; + tmp_sk = __llc_ui_find_sk_by_exact(laddr, daddr); + if (tmp_sk) { + sk = tmp_sk; + break; + } + if (llc_ui_mac_null(llc_ui->addr.sllc_dmac)) + break; + } + return sk; +} + +static struct sock *llc_ui_find_sk_by_addr(struct llc_addr *addr, + struct llc_addr *daddr, + struct net_device *dev) +{ + struct sock *sk; + + read_lock(&llc_ui_sockets_lock); + sk = __llc_ui_find_sk_by_addr(addr, daddr, dev); + if (sk) + sock_hold(sk); + read_unlock(&llc_ui_sockets_lock); + return sk; +} + +static struct sock *llc_ui_bh_find_sk_by_addr(struct llc_addr *addr, + struct llc_addr *daddr, + struct net_device *dev) +{ + struct sock *sk; + + read_lock_bh(&llc_ui_sockets_lock); + sk = __llc_ui_find_sk_by_addr(addr, daddr, dev); + if (sk) + sock_hold(sk); + read_unlock_bh(&llc_ui_sockets_lock); + return sk; +} + +/** + * llc_ui_insert_socket - insert socket into list + * @sk: Socket to insert. + * + * Insert a socket into the local llc socket list. + */ +static inline void llc_ui_insert_socket(struct sock *sk) +{ + write_lock_bh(&llc_ui_sockets_lock); + sk->next = llc_ui_sockets; + if (sk->next) + llc_ui_sockets->pprev = &sk->next; + llc_ui_sockets = sk; + sk->pprev = &llc_ui_sockets; + sock_hold(sk); + write_unlock_bh(&llc_ui_sockets_lock); +} + +/** + * llc_ui_remove_socket - remove socket from list + * @sk: Socket to remove. + * + * Remove a socket from the local llc socket list. + */ +static inline void llc_ui_remove_socket(struct sock *sk) +{ + write_lock_bh(&llc_ui_sockets_lock); + if (sk->pprev) { + if (sk->next) + sk->next->pprev = sk->pprev; + *sk->pprev = sk->next; + sk->pprev = NULL; + /* this only makes sense if the socket was inserted on the + * list, if sk->pprev is NULL it wasn't */ + sock_put(sk); + } + write_unlock_bh(&llc_ui_sockets_lock); +} + +/** + * llc_ui_destroy_sk - destroy socket + * @data: Socket which is to be destroyed. + * + * Really destroy the socket. + */ +static void llc_ui_destroy_sk(struct sock *sk) +{ + skb_queue_purge(&sk->receive_queue); + skb_queue_purge(&sk->write_queue); + sock_put(sk); + MOD_DEC_USE_COUNT; +} + +/** + * llc_ui_destroy_timer - try to destroy socket again + * @data: Socket which is to be destroyed. + * + * Attempt to destroy a socket which was previously destroyed but + * was still in use at the time. + */ +static void llc_ui_destroy_timer(unsigned long data) +{ + struct sock *sk = (struct sock *)data; + + if (!atomic_read(&sk->wmem_alloc) && + !atomic_read(&sk->rmem_alloc) && sk->dead) + llc_ui_destroy_sk(sk); + else { + sk->timer.expires = jiffies + SOCK_DESTROY_TIME; + add_timer(&sk->timer); + } +} + +/** + * llc_ui_create - alloc and init a new llc_ui socket + * @sock: Socket to initialize and attach allocated sk to. + * @protocol: Unused. + * + * Allocate and initialize a new llc_ui socket, validate the user wants a + * socket type we have available. + * Returns 0 upon success, negative upon failure. + */ +static int llc_ui_create(struct socket *sock, int protocol) +{ + struct sock *sk; + struct llc_ui_opt *llc_ui; + int rc = -ESOCKTNOSUPPORT; + + MOD_INC_USE_COUNT; + if (sock->type != SOCK_DGRAM && sock->type != SOCK_STREAM) + goto decmod; + rc = -ENOMEM; + sk = sk_alloc(PF_LLC, GFP_KERNEL, 1); + if (!sk) + goto decmod; + llc_ui = kmalloc(sizeof(*llc_ui), GFP_KERNEL); + if (!llc_ui) + goto outsk; + memset(llc_ui, 0, sizeof(*llc_ui)); + rc = 0; + sock_init_data(sock, sk); + llc_ui_sk(sk) = llc_ui; + sock->ops = &llc_ui_ops; +out: return rc; +outsk: sk_free(sk); +decmod: MOD_DEC_USE_COUNT; + goto out; +} + +/** + * llc_ui_release - shutdown socket + * @sock: Socket to release. + * + * Shutdown and deallocate an existing socket. + */ +static int llc_ui_release(struct socket *sock) +{ + struct sock *sk = sock->sk; + struct llc_ui_opt *llc_ui; + + if (!sk) + goto out; + llc_ui = llc_ui_sk(sk); + if (llc_ui->core_sk && !llc_ui_send_disc(sk)) + llc_ui_wait_for_disc(sk, 255); + llc_ui_remove_socket(sk); + if (llc_ui->sap && !llc_ui_find_sap(llc_ui->sap->laddr.lsap)) + llc_sap_close(llc_ui->sap); + dprintk("rxq=%d, txq=%d\n", skb_queue_len(&sk->receive_queue), + skb_queue_len(&sk->write_queue)); + sock_orphan(sk); + sock->sk = NULL; + if (!atomic_read(&sk->wmem_alloc) && + !atomic_read(&sk->rmem_alloc) && sk->dead) + llc_ui_destroy_sk(sk); + else { + init_timer(&sk->timer); + sk->timer.expires = jiffies + SOCK_DESTROY_TIME; + sk->timer.function = llc_ui_destroy_timer; + sk->timer.data = (unsigned long)sk; + add_timer(&sk->timer); + } +out: return 0; +} + +/** + * llc_ui_autoport - provide dynamicly allocate SAP number + * + * Provide the caller with a dynamicly allocated SAP number according + * to the rules that are set in this function. Returns: 0, upon failure, + * SAP number otherwise. + */ +static int llc_ui_autoport(void) +{ + struct llc_sap *sap; + int i, tries = 0; + + while (tries < LLC_SAP_DYN_TRIES) { + for (i = llc_ui_sap_last_autoport; + i < LLC_SAP_DYN_STOP; i += 2) { + sap = llc_ui_find_sap(i); + if (!sap) { + llc_ui_sap_last_autoport = i + 2; + goto out; + } + } + llc_ui_sap_last_autoport = LLC_SAP_DYN_START; + tries++; + } + i = 0; +out: return i; +} + +/** + * llc_ui_autobind - Bind a socket to a specific address. + * @sk: Socket to bind an address to. + * @addr: Address the user wants the socket bound to. + * + * Bind a socket to a specific address. For llc a user is able to bind to + * a specific sap only or mac + sap. If the user only specifies a sap and + * a null dmac (all zeros) the user is attempting to bind to an entire + * sap. This will stop anyone else on the local system from using that + * sap. If someone else has a mac + sap open the bind to null + sap will + * fail. + * If the user desires to bind to a specific mac + sap, it is possible to + * have multiple sap connections via multiple macs. + * Bind and autobind for that matter must enforce the correct sap usage + * otherwise all hell will break loose. + * Returns: 0 upon success, negative otherwise. + */ +static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) +{ + struct sock *sk = sock->sk; + struct llc_ui_opt *llc_ui = llc_ui_sk(sk); + struct llc_sap *sap; + struct net_device *dev = NULL; + int rc = -EINVAL; + + if (!sk->zapped) + goto out; + /* bind to a specific mac, optional. */ + if (!llc_ui_mac_null(addr->sllc_smac)) { + rtnl_lock(); + dev = dev_getbyhwaddr(addr->sllc_arphrd, addr->sllc_smac); + rtnl_unlock(); + rc = -ENETUNREACH; + if (!dev) + goto out; + llc_ui->dev = dev; + } + /* bind to a specific sap, optional. */ + if (!addr->sllc_ssap) { + rc = -EUSERS; + addr->sllc_ssap = llc_ui_autoport(); + if (!addr->sllc_ssap) + goto out; + } + sap = llc_ui_find_sap(addr->sllc_ssap); + if (!sap) { + sap = llc_sap_open(llc_ui_indicate, llc_ui_confirm, + addr->sllc_ssap); + rc = -EBUSY; /* some other network layer is using the sap */ + if (!sap) + goto out; + } else { + struct llc_addr laddr, daddr; + struct sock *ask; + + rc = -EUSERS; /* can't get exclusive use of sap */ + if (!dev && llc_ui_mac_null(addr->sllc_mmac)) + goto out; + memset(&laddr, 0, sizeof(laddr)); + memset(&daddr, 0, sizeof(daddr)); + if (!llc_ui_mac_null(addr->sllc_mmac)) { + if (sk->type != SOCK_DGRAM) { + rc = -EOPNOTSUPP; + goto out; + } + memcpy(laddr.mac, addr->sllc_mmac, IFHWADDRLEN); + } else + memcpy(laddr.mac, addr->sllc_smac, IFHWADDRLEN); + laddr.lsap = addr->sllc_ssap; + rc = -EADDRINUSE; /* mac + sap clash. */ + ask = llc_ui_bh_find_sk_by_addr(&laddr, &daddr, dev); + if (ask) { + sock_put(ask); + goto out; + } + } + memcpy(&llc_ui->addr, addr, sizeof(*addr)); + llc_ui->sap = sap; + rc = sk->zapped = 0; + llc_ui_insert_socket(sk); +out: return rc; +} + +/** + * llc_ui_bind - bind a socket to a specific address. + * @sock: Socket to bind an address to. + * @uaddr: Address the user wants the socket bound to. + * @addrlen: Length of the uaddr structure. + * + * Bind a socket to a specific address. For llc a user is able to bind to + * a specific sap only or mac + sap. If the user only specifies a sap and + * a null dmac (all zeros) the user is attempting to bind to an entire + * sap. This will stop anyone else on the local system from using that + * sap. If someone else has a mac + sap open the bind to null + sap will + * fail. + * If the user desires to bind to a specific mac + sap, it is possible to + * have multiple sap connections via multiple macs. + * Bind and autobind for that matter must enforce the correct sap usage + * otherwise all hell will break loose. + * Returns: 0 upon success, negative otherwise. + */ +static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) +{ + struct sockaddr_llc *addr = (struct sockaddr_llc *)uaddr; + struct sock *sk = sock->sk; + int rc = -EINVAL; + + if (!sk->zapped || addrlen != sizeof(*addr)) + goto out; + rc = -EAFNOSUPPORT; + if (addr->sllc_family != AF_LLC) + goto out; + /* use autobind, to avoid code replication. */ + rc = llc_ui_autobind(sock, addr); +out: return rc; +} + +/** + * llc_ui_shutdown - shutdown a connect llc2 socket. + * @sock: Socket to shutdown. + * @how: What part of the socket to shutdown. + * + * Shutdown a connected llc2 socket. Currently this function only supports + * shutting down both sends and receives (2), we could probably make this + * function such that a user can shutdown only half the connection but not + * right now. + * Returns: 0 upon success, negative otherwise. + */ +static int llc_ui_shutdown(struct socket *sock, int how) +{ + struct sock *sk = sock->sk; + int rc = -ENOTCONN; + + lock_sock(sk); + if (sk->state != TCP_ESTABLISHED) + goto out; + rc = -EINVAL; + if (how != 2) + goto out; + rc = llc_ui_send_disc(sk); + if (!rc) + llc_ui_wait_for_disc(sk, 255); + /* Wake up anyone sleeping in poll */ + sk->state_change(sk); +out: release_sock(sk); + return rc; +} + +/** + * llc_ui_connect - Connect to a remote llc2 mac + sap. + * @sock: Socket which will be connected to the remote destination. + * @uaddr: Remote and possibly the local address of the new connection. + * @addrlen: Size of uaddr structure. + * @flags: Operational flags specified by the user. + * + * Connect to a remote llc2 mac + sap. The caller must specify the + * destination mac and address to connect to. If the user previously + * called bind(2) with a smac the user does not need to specify the source + * address and mac. + * This function will autobind if user did not previously call bind. + * Returns: 0 upon success, negative otherwise. + */ +static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr, + int addrlen, int flags) +{ + struct sock *sk = sock->sk; + struct llc_ui_opt *llc_ui = llc_ui_sk(sk); + struct sockaddr_llc *addr = (struct sockaddr_llc *)uaddr; + struct net_device *dev; + int rc = -EINVAL; + + lock_sock(sk); + if (addrlen != sizeof(*addr)) + goto out; + rc = -EAFNOSUPPORT; + if (addr->sllc_family != AF_LLC) + goto out; + /* bind connection to sap if user hasn't done it. */ + if (sk->zapped) { + /* bind to sap with null dev, exclusive */ + rc = llc_ui_autobind(sock, addr); + if (rc) + goto out; + } + if (!llc_ui->dev) { + rtnl_lock(); + dev = dev_getbyhwaddr(addr->sllc_arphrd, addr->sllc_smac); + rtnl_unlock(); + if (!dev) + goto out; + } else + dev = llc_ui->dev; + if (sk->type != SOCK_STREAM) + goto out; + rc = -EALREADY; + if (sock->state == SS_CONNECTING) + goto out; + sock->state = SS_CONNECTING; + sk->state = TCP_SYN_SENT; + llc_ui->link = llc_ui_next_link_no(llc_ui->sap->laddr.lsap); + rc = llc_ui_send_conn(sk, llc_ui->sap, addr, dev, llc_ui->link); + if (rc) { + sock->state = SS_UNCONNECTED; + sk->state = TCP_CLOSE; + goto out; + } + rc = llc_ui_wait_for_conn(sk, 255); +out: release_sock(sk); + return rc; +} + +/** + * llc_ui_listen - allow a normal socket to accept incoming connections + * @sock: Socket to allow incoming connections on. + * @backlog: Number of connections to queue. + * + * Allow a normal socket to accept incoming connections. + * Returns 0 upon success, negative otherwise. + */ +static int llc_ui_listen(struct socket *sock, int backlog) +{ + struct sock *sk = sock->sk; + int rc = -EINVAL; + + lock_sock(sk); + if (sock->state != SS_UNCONNECTED) + goto out; + rc = -EOPNOTSUPP; + if (sk->type != SOCK_STREAM && sk->type != SOCK_SEQPACKET) + goto out; + rc = -EAGAIN; + if (sk->zapped) + goto out; + rc = 0; + if (!(unsigned)backlog) /* BSDism */ + backlog = 1; + if ((unsigned)backlog > SOMAXCONN) + backlog = SOMAXCONN; + sk->max_ack_backlog = backlog; + if (sk->state != TCP_LISTEN) { + sk->ack_backlog = 0; + sk->state = TCP_LISTEN; + } + sk->socket->flags |= __SO_ACCEPTCON; +out: release_sock(sk); + return rc; +} + +static int llc_ui_wait_for_disc(struct sock *sk, int seconds) +{ + DECLARE_WAITQUEUE(wait, current); + int rc, timeout = seconds * HZ; + + add_wait_queue_exclusive(sk->sleep, &wait); + for (;;) { + __set_current_state(TASK_INTERRUPTIBLE); + rc = 0; + if (sk->state != TCP_CLOSE) + timeout = schedule_timeout(timeout); + else + break; + rc = -ERESTARTSYS; + if (signal_pending(current)) + break; + rc = -EAGAIN; + if (!timeout) + break; + } + __set_current_state(TASK_RUNNING); + remove_wait_queue(sk->sleep, &wait); + return rc; +} + +static int llc_ui_wait_for_conn(struct sock *sk, int seconds) +{ + struct llc_ui_opt *llc_ui = llc_ui_sk(sk); + DECLARE_WAITQUEUE(wait, current); + int rc, timeout = seconds * HZ; + + add_wait_queue_exclusive(sk->sleep, &wait); + for (;;) { + __set_current_state(TASK_INTERRUPTIBLE); + rc = 0; + if (sk->state != TCP_ESTABLISHED) + timeout = schedule_timeout(timeout); + if (sk->state == TCP_ESTABLISHED) { + if (!llc_ui->core_sk) + rc = -EAGAIN; + break; + } + rc = -EAGAIN; + if (sk->state == TCP_CLOSE) + break; + rc = -ERESTARTSYS; + if (signal_pending(current)) + break; + rc = -EAGAIN; + if (!timeout) + break; + } + __set_current_state(TASK_RUNNING); + remove_wait_queue(sk->sleep, &wait); + return rc; +} + +/** + * llc_ui_accept - accept a new incoming connection. + * @sock: Socket which connections arrive on. + * @newsock: Socket to move incoming connection to. + * @flags: User specified operational flags. + * + * Accept a new incoming connection. + * Returns 0 upon success, negative otherwise. + */ +static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags) +{ + struct sock *sk = sock->sk, *newsk; + struct llc_ui_opt *llc_ui, *newllc_ui; + struct llc_opt *newllc_core; + struct sk_buff *skb; + int rc = -EOPNOTSUPP; + + lock_sock(sk); + if (sk->type != SOCK_SEQPACKET && sk->type != SOCK_STREAM) + goto out; + rc = -EINVAL; + if (sock->state != SS_UNCONNECTED || sk->state != TCP_LISTEN) + goto out; + /* wait for a connection to arrive. */ + do { + skb = skb_dequeue(&sk->receive_queue); + if (!skb) { + rc = -EWOULDBLOCK; + if (flags & O_NONBLOCK) + goto out; + interruptible_sleep_on(sk->sleep); + rc = -ERESTARTSYS; + if (signal_pending(current)) + goto out; + } + } while (!skb); + + rc = -EINVAL; + if(!skb->sk) + goto frees; + /* attach connection to a new socket. */ + rc = llc_ui_create(newsock, sk->protocol); + if (rc) + goto frees; + rc = 0; + newsk = newsock->sk; + newsk->pair = NULL; + newsk->socket = newsock; + newsk->sleep = &newsock->wait; + newsk->zapped = 0; + newsk->state = TCP_ESTABLISHED; + newsock->state = SS_CONNECTED; + llc_ui = llc_ui_sk(sk); + newllc_ui = llc_ui_sk(newsk); + newllc_ui->sap = llc_ui->sap; + newllc_ui->dev = llc_ui->dev; + newllc_ui->core_sk = skb->sk; + newllc_core = llc_sk(newllc_ui->core_sk); + newllc_ui->link = newllc_core->link; + newllc_core->handler = newsk; + memcpy(&newllc_ui->addr, &llc_ui->addr, sizeof(newllc_ui->addr)); + memcpy(newllc_ui->addr.sllc_dmac, newllc_core->daddr.mac, IFHWADDRLEN); + newllc_ui->addr.sllc_dsap = newllc_core->daddr.lsap; + + /* put original socket back into a clean listen state. */ + sk->state = TCP_LISTEN; + sk->ack_backlog--; + llc_ui_insert_socket(newsk); + skb->sk = NULL; +frees: kfree_skb(skb); +out: release_sock(sk); + return rc; +} + +/** + * llc_ui_recvmsg - copy received data to the socket user. + * @sock: Socket to copy data from. + * @msg: Various user space related information. + * @size: Size of user buffer. + * @flags: User specified flags. + * @scm: Unknown. + * + * Copy received data to the socket user. + * Returns non-negative upon success, negative otherwise. + */ +static int llc_ui_recvmsg(struct socket *sock, struct msghdr *msg, int size, + int flags, struct scm_cookie *scm) +{ + struct sock *sk = sock->sk; + struct sockaddr_llc *uaddr = (struct sockaddr_llc *)msg->msg_name; + struct sk_buff *skb; + int rc = -ENOMEM, copied = 0; + int noblock = flags & MSG_DONTWAIT; + + lock_sock(sk); + skb = skb_recv_datagram(sk, flags, noblock, &rc); + if (!skb) + goto out; + copied = skb->len; + if (copied > size) { + copied = size; + msg->msg_flags |= MSG_TRUNC; + } + rc = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); + if (rc) + goto dgram_free; + if (uaddr) + memcpy(uaddr, llc_ui_skb_cb(skb), sizeof(*uaddr)); + msg->msg_namelen = sizeof(*uaddr); +dgram_free: + skb_free_datagram(sk, skb); /* Free the datagram. */ +out: release_sock(sk); + return rc ? : copied; +} + +/** + * llc_ui_sendmsg - Transmit data provided by the socket user. + * @sock: Socket to transmit data from. + * @msg: Various user related information. + * @len: Length of data to transmit. + * @scm: Unknown. + * + * Transmit data provided by the socket user. + * Returns non-negative upon success, negative otherwise. + */ +static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, int len, + struct scm_cookie *scm) +{ + struct sock *sk = sock->sk; + struct llc_ui_opt *llc_ui = llc_ui_sk(sk); + struct sockaddr_llc *addr = (struct sockaddr_llc *)msg->msg_name; + int flags = msg->msg_flags; + struct net_device *dev; + struct sk_buff *skb; + int rc = -EOPNOTSUPP, size = 0; + + lock_sock(sk); + if (flags & ~MSG_DONTWAIT) + goto release; + rc = -EINVAL; + if (addr) { + if (msg->msg_namelen < sizeof(*addr)) + goto release; + } else { + if (llc_ui_addr_null(&llc_ui->addr)) + goto release; + addr = &llc_ui->addr; + } + /* must bind connection to sap if user hasn't done it. */ + if (sk->zapped) { + /* bind to sap with null dev, exclusive. */ + rc = llc_ui_autobind(sock, addr); + if (rc) + goto release; + } + if (!llc_ui->dev) { + rtnl_lock(); + dev = dev_getbyhwaddr(addr->sllc_arphrd, addr->sllc_smac); + rtnl_unlock(); + rc = -ENETUNREACH; + if (!dev) + goto release; + } else + dev = llc_ui->dev; + size = dev->hard_header_len + len + llc_ui_header_len(sk, addr); + rc = -EMSGSIZE; + if (size > dev->mtu) + goto release; + skb = sock_alloc_send_skb(sk, size, flags & MSG_DONTWAIT, &rc); + if (!skb) + goto release; + skb->sk = sk; + skb->dev = dev; + skb_reserve(skb, dev->hard_header_len + llc_ui_header_len(sk, addr)); + rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); + if (rc) + goto release; + if (addr->sllc_test) { + rc = llc_ui_send_llc1(llc_ui->sap, skb, addr, LLC_TEST_PRIM); + goto out; + } + if (addr->sllc_xid) { + rc = llc_ui_send_llc1(llc_ui->sap, skb, addr, LLC_XID_PRIM); + goto out; + } + if (sk->type == SOCK_DGRAM || addr->sllc_ua) { + rc = llc_ui_send_llc1(llc_ui->sap, skb, addr, LLC_DATAUNIT_PRIM); + goto out; + } + rc = -ENOPROTOOPT; + if (!(sk->type == SOCK_STREAM && !addr->sllc_ua)) + goto out; + rc = -ENOTCONN; + if (!llc_ui->core_sk) + goto out; + rc = llc_ui_send_data(llc_ui->sap, sk, skb, addr); +out: if (rc) + skb_free_datagram(sk, skb); +release: + release_sock(sk); + return rc ? : len; +} + +/** + * llc_ui_getname - return the address info of a socket + * @sock: Socket to get address of. + * @uaddr: Address structure to return information. + * @uaddrlen: Length of address structure. + * @peer: Does user want local or remote address information. + * + * Return the address information of a socket. + */ +static int llc_ui_getname(struct socket *sock, struct sockaddr *uaddr, + int *uaddrlen, int peer) +{ + struct sockaddr_llc sllc; + struct sock *sk = sock->sk; + struct llc_ui_opt *llc_ui = llc_ui_sk(sk); + int rc = 0; + + lock_sock(sk); + if (sk->zapped) + goto out; + *uaddrlen = sizeof(sllc); + memset(uaddr, 0, *uaddrlen); + if (peer) { + rc = -ENOTCONN; + if (sk->state != TCP_ESTABLISHED) + goto out; + if(llc_ui->dev) + sllc.sllc_arphrd = llc_ui->dev->type; + sllc.sllc_dsap = llc_sk(llc_ui->core_sk)->daddr.lsap; + memcpy(&sllc.sllc_dmac, &llc_sk(llc_ui->core_sk)->daddr.mac, + IFHWADDRLEN); + } else { + rc = -EINVAL; + if (!llc_ui->sap) + goto out; + sllc.sllc_ssap = llc_ui->sap->laddr.lsap; + + if (llc_ui->dev) { + sllc.sllc_arphrd = llc_ui->dev->type; + memcpy(&sllc.sllc_smac, &llc_ui->dev->dev_addr, + IFHWADDRLEN); + } + } + rc = 0; + sllc.sllc_family = AF_LLC; + memcpy(uaddr, &sllc, sizeof(sllc)); +out: release_sock(sk); + return rc; +} + +/** + * llc_ui_ioctl - io controls for PF_LLC + * @sock: Socket to get/set info + * @cmd: command + * @arg: optional argument for cmd + * + * get/set info on llc sockets + */ +static int llc_ui_ioctl(struct socket *sock, unsigned int cmd, + unsigned long arg) +{ + return dev_ioctl(cmd, (void *)arg); +} + +/** + * llc_ui_setsockopt - set various connection specific parameters. + * @sock: Socket to set options on. + * @level: Socket level user is requesting operations on. + * @optname: Operation name. + * @optval User provided operation data. + * @optlen: Length of optval. + * + * Set various connection specific parameters. + */ +static int llc_ui_setsockopt(struct socket *sock, int level, int optname, + char *optval, int optlen) +{ + struct sock *sk = sock->sk; + struct llc_ui_opt *llc_ui = llc_ui_sk(sk); + struct llc_opt *llc_core; + int rc = -EINVAL, opt; + + lock_sock(sk); + if (level != SOL_LLC || optlen != sizeof(int)) + goto out; + rc = -ENOTCONN; + if (!llc_ui->core_sk) + goto out; + rc = get_user(opt, (int *)optval); + if (rc) + goto out; + rc = -EINVAL; + llc_core = llc_sk(llc_ui->core_sk); + switch (optname) { + case LLC_OPT_RETRY: + if (opt > LLC_OPT_MAX_RETRY) + goto out; + llc_core->n2 = opt; + break; + case LLC_OPT_SIZE: + if (opt > LLC_OPT_MAX_SIZE) + goto out; + llc_core->n1 = opt; + break; + case LLC_OPT_ACK_TMR_EXP: + if (opt > LLC_OPT_MAX_ACK_TMR_EXP) + goto out; + llc_core->ack_timer.expire = opt; + break; + case LLC_OPT_P_TMR_EXP: + if (opt > LLC_OPT_MAX_P_TMR_EXP) + goto out; + llc_core->pf_cycle_timer.expire = opt; + break; + case LLC_OPT_REJ_TMR_EXP: + if (opt > LLC_OPT_MAX_REJ_TMR_EXP) + goto out; + llc_core->rej_sent_timer.expire = opt; + break; + case LLC_OPT_BUSY_TMR_EXP: + if (opt > LLC_OPT_MAX_BUSY_TMR_EXP) + goto out; + llc_core->busy_state_timer.expire = opt; + break; + case LLC_OPT_TX_WIN: + if (opt > LLC_OPT_MAX_WIN) + goto out; + llc_core->k = opt; + break; + case LLC_OPT_RX_WIN: + if (opt > LLC_OPT_MAX_WIN) + goto out; + llc_core->rw = opt; + break; + default: + rc = -ENOPROTOOPT; + goto out; + } + rc = 0; +out: release_sock(sk); + return rc; +} + +/** + * llc_ui_getsockopt - get connection specific socket info + * @sock: Socket to get information from. + * @level: Socket level user is requesting operations on. + * @optname: Operation name. + * @optval: Variable to return operation data in. + * @optlen: Length of optval. + * + * Get connection specific socket information. + */ +static int llc_ui_getsockopt(struct socket *sock, int level, int optname, + char *optval, int *optlen) +{ + struct sock *sk = sock->sk; + struct llc_ui_opt *llc_ui = llc_ui_sk(sk); + struct llc_opt *llc_core; + int val = 0, len = 0, rc = -EINVAL; + + lock_sock(sk); + if (level != SOL_LLC) + goto out; + rc = -ENOTCONN; + if (!llc_ui->core_sk) + goto out; + rc = get_user(len, optlen); + if (rc) + goto out; + rc = -EINVAL; + if (len != sizeof(int)) + goto out; + llc_core = llc_sk(llc_ui->core_sk); + switch (optname) { + case LLC_OPT_RETRY: + val = llc_core->n2; break; + case LLC_OPT_SIZE: + val = llc_core->n1; break; + case LLC_OPT_ACK_TMR_EXP: + val = llc_core->ack_timer.expire; break; + case LLC_OPT_P_TMR_EXP: + val = llc_core->pf_cycle_timer.expire; break; + case LLC_OPT_REJ_TMR_EXP: + val = llc_core->rej_sent_timer.expire; break; + case LLC_OPT_BUSY_TMR_EXP: + val = llc_core->busy_state_timer.expire; break; + case LLC_OPT_TX_WIN: + val = llc_core->k; break; + case LLC_OPT_RX_WIN: + val = llc_core->rw; break; + default: + rc = -ENOPROTOOPT; + goto out; + } + rc = 0; + if (put_user(len, optlen) || copy_to_user(optval, &val, len)) + rc = -EFAULT; +out: release_sock(sk); + return rc; +} + +/** + * llc_ui_ind_test - handle TEST indication + * @prim: Primitive block provided by the llc layer. + * + * handle TEST indication. + */ +static void llc_ui_ind_test(struct llc_prim_if_block *prim) +{ + struct llc_prim_test *prim_data = &prim->data->test; + struct sk_buff *skb = prim_data->skb; + struct sockaddr_llc *llc_ui = llc_ui_skb_cb(skb); + struct sock *sk = llc_ui_find_sk_by_addr(&prim_data->daddr, + &prim_data->saddr, skb->dev); + if (!sk) + goto out; + if (sk->state == TCP_LISTEN) + goto out_put; + /* save primitive for use by the user. */ + llc_ui->sllc_family = AF_LLC; + llc_ui->sllc_arphrd = skb->dev->type; + llc_ui->sllc_test = 1; + llc_ui->sllc_xid = 0; + llc_ui->sllc_ua = 0; + llc_ui->sllc_dsap = prim_data->daddr.lsap; + memcpy(llc_ui->sllc_dmac, prim_data->daddr.mac, IFHWADDRLEN); + llc_ui->sllc_ssap = prim_data->saddr.lsap; + memcpy(llc_ui->sllc_smac, prim_data->saddr.mac, IFHWADDRLEN); + /* queue skb to the user. */ + if (sock_queue_rcv_skb(sk, skb)) + kfree_skb(skb); +out_put: + sock_put(sk); +out:; +} + +/** + * llc_ui_ind_xid - handle XID indication + * @prim: Primitive block provided by the llc layer. + * + * handle XID indication. + */ +static void llc_ui_ind_xid(struct llc_prim_if_block *prim) +{ + struct llc_prim_xid *prim_data = &prim->data->xid; + struct sk_buff *skb = prim_data->skb; + struct sockaddr_llc *llc_ui = llc_ui_skb_cb(skb); + struct sock *sk = llc_ui_find_sk_by_addr(&prim_data->daddr, + &prim_data->saddr, skb->dev); + if (!sk) + goto out; + if (sk->state == TCP_LISTEN) + goto out_put; + /* save primitive for use by the user. */ + llc_ui->sllc_family = AF_LLC; + llc_ui->sllc_arphrd = 0; + llc_ui->sllc_test = 0; + llc_ui->sllc_xid = 1; + llc_ui->sllc_ua = 0; + llc_ui->sllc_dsap = prim_data->daddr.lsap; + memcpy(llc_ui->sllc_dmac, prim_data->daddr.mac, IFHWADDRLEN); + llc_ui->sllc_ssap = prim_data->saddr.lsap; + memcpy(llc_ui->sllc_smac, prim_data->saddr.mac, IFHWADDRLEN); + /* queue skb to the user. */ + if (sock_queue_rcv_skb(sk, skb)) + kfree_skb(skb); +out_put: + sock_put(sk); +out:; +} + +/** + * llc_ui_ind_dataunit - handle DATAUNIT indication + * @prim: Primitive block provided by the llc layer. + * + * handle DATAUNIT indication. + */ +static void llc_ui_ind_dataunit(struct llc_prim_if_block *prim) +{ + struct llc_prim_unit_data *prim_data = &prim->data->udata; + struct sk_buff *skb = prim_data->skb; + struct sockaddr_llc *llc_ui = llc_ui_skb_cb(skb); + struct sock *sk = llc_ui_find_sk_by_addr(&prim_data->daddr, + &prim_data->saddr, skb->dev); + if (!sk) + goto out; + if (sk->state == TCP_LISTEN) + goto out_put; + /* save primitive for use by the user. */ + llc_ui->sllc_family = AF_LLC; + llc_ui->sllc_arphrd = skb->dev->type; + llc_ui->sllc_test = 0; + llc_ui->sllc_xid = 0; + llc_ui->sllc_ua = 1; + llc_ui->sllc_dsap = prim_data->daddr.lsap; + memcpy(llc_ui->sllc_dmac, prim_data->daddr.mac, IFHWADDRLEN); + llc_ui->sllc_ssap = prim_data->saddr.lsap; + memcpy(llc_ui->sllc_smac, prim_data->saddr.mac, IFHWADDRLEN); + /* queue skb to the user. */ + if (sock_queue_rcv_skb(sk, skb)) + kfree_skb(skb); +out_put: + sock_put(sk); +out:; +} + +/** + * llc_ui_ind_conn - handle CONNECT indication + * @prim: Primitive block provided by the llc layer. + * + * handle CONNECT indication. + */ +static void llc_ui_ind_conn(struct llc_prim_if_block *prim) +{ + struct llc_prim_conn *prim_data = &prim->data->conn; + struct sock* sk; + struct sk_buff *skb2; + + llc_sk(prim_data->sk)->laddr.lsap = prim->sap->laddr.lsap; + sk = llc_ui_find_sk_by_addr(&llc_sk(prim_data->sk)->laddr, + &prim_data->saddr, prim_data->dev); + if (!sk) { + dprintk("llc_ui_find_sk_by_addr failed\n"); + goto out; + } + if (sk->type != SOCK_STREAM || sk->state != TCP_LISTEN) + goto out_put; + if (prim->data->conn.status) + goto out_put; /* bad status. */ + /* give this connection a link number. */ + llc_sk(prim_data->sk)->link = + llc_ui_next_link_no(llc_sk(prim_data->sk)->laddr.lsap); + skb2 = alloc_skb(0, GFP_ATOMIC); + if (!skb2) + goto out_put; + skb2->sk = prim_data->sk; + skb_queue_tail(&sk->receive_queue, skb2); + sk->state_change(sk); +out_put: + sock_put(sk); +out:; +} + +/** + * llc_ui_ind_data - handle DATA indication + * @prim: Primitive block provided by the llc layer. + * + * handle CONNECT indication. + */ +static void llc_ui_ind_data(struct llc_prim_if_block *prim) +{ + struct llc_prim_data *prim_data = &prim->data->data; + struct sk_buff *skb = prim_data->skb; + struct sockaddr_llc *llc_ui = llc_ui_skb_cb(skb); + struct sock* sk = llc_sk(prim_data->sk)->handler; + + if (!sk) + goto out; + sock_hold(sk); + if (sk->type != SOCK_STREAM || sk->state != TCP_ESTABLISHED) + goto out_put; + /* save primitive for use by the user. */ + llc_ui->sllc_family = AF_LLC; + llc_ui->sllc_arphrd = skb->dev->type; + llc_ui->sllc_test = 0; + llc_ui->sllc_xid = 0; + llc_ui->sllc_ua = 0; + llc_ui->sllc_dsap = llc_ui_sk(sk)->sap->laddr.lsap; + memcpy(llc_ui->sllc_dmac, llc_sk(prim_data->sk)->laddr.mac, + IFHWADDRLEN); + llc_ui->sllc_ssap = llc_sk(prim_data->sk)->daddr.lsap; + memcpy(llc_ui->sllc_smac, llc_sk(prim_data->sk)->daddr.mac, + IFHWADDRLEN); + /* queue skb to the user. */ + if (sock_queue_rcv_skb(sk, skb)) { + dprintk("sock_queue_rcv_skb failed!\n"); + kfree_skb(skb); + } +out_put: + sock_put(sk); +out:; +} + +/** + * llc_ui_ind_disc - handle DISC indication + * @prim: Primitive block provided by the llc layer. + * + * handle DISC indication. + */ +static void llc_ui_ind_disc(struct llc_prim_if_block *prim) +{ + struct llc_prim_disc *prim_data = &prim->data->disc; + struct sock* sk = llc_sk(prim_data->sk)->handler; + + if (!sk) + goto out; + sock_hold(sk); + if (sk->type != SOCK_STREAM || sk->state != TCP_ESTABLISHED) + goto out_put; + llc_ui_sk(sk)->core_sk = NULL; + sk->shutdown = SHUTDOWN_MASK; + sk->socket->state = SS_UNCONNECTED; + sk->state = TCP_CLOSE; + if (!sk->dead) { + sk->state_change(sk); + sk->dead = 1; + } +out_put: + sock_put(sk); +out:; +} + +/** + * llc_ui_indicate - LLC user interface hook into the LLC layer. + * @prim: Primitive block provided by the llc layer. + * + * LLC user interface hook into the LLC layer, every llc_ui sap references + * this function as its indicate handler. + * Always returns 0 to indicate reception of primitive. + */ +static int llc_ui_indicate(struct llc_prim_if_block *prim) +{ + switch (prim->prim) { + case LLC_TEST_PRIM: + llc_ui_ind_test(prim); break; + case LLC_XID_PRIM: + llc_ui_ind_xid(prim); break; + case LLC_DATAUNIT_PRIM: + llc_ui_ind_dataunit(prim); break; + case LLC_CONN_PRIM: + llc_ui_ind_conn(prim); break; + case LLC_DATA_PRIM: + llc_ui_ind_data(prim); break; + case LLC_DISC_PRIM: + llc_ui_ind_disc(prim); break; + case LLC_RESET_PRIM: + case LLC_FLOWCONTROL_PRIM: + default: break; + } + return 0; +} + +/** + * llc_ui_conf_conn - handle CONN confirm. + * @prim: Primitive block provided by the llc layer. + * + * handle CONN confirm. + */ +static void llc_ui_conf_conn(struct llc_prim_if_block *prim) +{ + struct llc_prim_conn *prim_data = &prim->data->conn; + struct llc_opt *llc_core = llc_sk(prim_data->sk); + struct llc_ui_opt *llc_ui = llc_ui_sk(prim_data->sk); + struct sock* sk = llc_core->handler; + + if (!sk) { + dprintk("llc_core->handler == NULL!\n"); + goto out; + } + sock_hold(sk); + if (sk->type != SOCK_STREAM || sk->state != TCP_SYN_SENT) + goto out_put; + if (!prim->data->conn.status) { + sk->socket->state = SS_CONNECTED; + sk->state = TCP_ESTABLISHED; + llc_ui->core_sk = prim_data->sk; + } else { + dprintk("prim->data->conn.status = %d\n", + prim->data->conn.status); + sk->socket->state = SS_UNCONNECTED; + sk->state = TCP_CLOSE; + llc_ui->core_sk = NULL; + } + sk->state_change(sk); +out_put: + sock_put(sk); +out:; +} + +/** + * llc_ui_conf_data - handle DATA confirm. + * @prim: Primitive block provided by the llc layer. + * + * handle DATA confirm. + */ +static void llc_ui_conf_data(struct llc_prim_if_block *prim) +{ + struct llc_prim_data *prim_data = &prim->data->data; + struct sock* sk = llc_sk(prim_data->sk)->handler; + + if (sk) + wake_up(sk->sleep); +} + +/** + * llc_ui_conf_disc - handle DISC confirm. + * @prim: Primitive block provided by the llc layer. + * + * handle DISC confirm. + */ +static void llc_ui_conf_disc(struct llc_prim_if_block *prim) +{ + struct llc_prim_disc *prim_data = &prim->data->disc; + struct sock* sk = llc_sk(prim_data->sk)->handler; + + if (!sk) + goto out; + sock_hold(sk); + if (sk->type != SOCK_STREAM || sk->state != TCP_CLOSING) + goto out_put; + llc_ui_sk(sk)->core_sk = NULL; + sk->socket->state = SS_UNCONNECTED; + sk->state = TCP_CLOSE; + sk->state_change(sk); +out_put: + sock_put(sk); +out:; +} + +/** + * llc_ui_confirm - LLC user interface hook into the LLC layer + * @prim: Primitive block provided by the llc layer. + * + * LLC user interface hook into the LLC layer, every llc_ui sap references + * this function as its confirm handler. + * Always returns 0 to indicate reception of primitive. + */ +static int llc_ui_confirm(struct llc_prim_if_block *prim) +{ + switch (prim->prim) { + case LLC_CONN_PRIM: + llc_ui_conf_conn(prim); break; + case LLC_DATA_PRIM: + llc_ui_conf_data(prim); break; + case LLC_DISC_PRIM: + llc_ui_conf_disc(prim); break; + case LLC_RESET_PRIM: break; + default: + printk(KERN_ERR __FUNCTION__ ": unknown prim %d\n", + prim->prim); + break; + } + return 0; +} + +#ifdef CONFIG_PROC_FS +/** + * llc_ui_get_info - return info to procfs + * @buffer: where to put the formatted output + * @start: starting from + * @offset: offset into buffer. + * @length: size of the buffer + * + * Get the output of the local llc ui socket list to the caller. + * Returns the length of data wrote to buffer. + */ +static int llc_ui_get_info(char *buffer, char **start, off_t offset, int length) +{ + off_t pos = 0; + off_t begin = 0; + struct sock *s; + int len = sprintf(buffer, "SocketID SKt Mc local_mac_sap\t " + "remote_mac_sap\t tx_queue rx_queue st uid " + "link_no\n"); + /* Output the LLC socket data for the /proc filesystem */ + read_lock_bh(&llc_ui_sockets_lock); + for (s = llc_ui_sockets; s; s = s->next) { + struct llc_ui_opt *llc_ui = llc_ui_sk(s); + len += sprintf(buffer + len, "%p %02X %02X ", s, s->type, + !llc_ui_mac_null(llc_ui->addr.sllc_mmac)); + if (llc_ui->sap) { + if (llc_ui->dev && + llc_ui_mac_null(llc_ui->addr.sllc_mmac)) + len += sprintf(buffer + len, + "%02X:%02X:%02X:%02X:%02X:%02X", + llc_ui->dev->dev_addr[0], + llc_ui->dev->dev_addr[1], + llc_ui->dev->dev_addr[2], + llc_ui->dev->dev_addr[3], + llc_ui->dev->dev_addr[4], + llc_ui->dev->dev_addr[5]); + else { + if (!llc_ui_mac_null(llc_ui->addr.sllc_mmac)) + len += sprintf(buffer + len, + "%02X:%02X:%02X:%02X:%02X:%02X", + llc_ui->addr.sllc_mmac[0], + llc_ui->addr.sllc_mmac[1], + llc_ui->addr.sllc_mmac[2], + llc_ui->addr.sllc_mmac[3], + llc_ui->addr.sllc_mmac[4], + llc_ui->addr.sllc_mmac[5]); + else + len += sprintf(buffer + len, + "00:00:00:00:00:00"); + } + len += sprintf(buffer + len, "@%02X ", + llc_ui->sap->laddr.lsap); + } else + len += sprintf(buffer + len, "00:00:00:00:00:00@00 "); + len += sprintf(buffer + len, + "%02X:%02X:%02X:%02X:%02X:%02X@%02X " + "%08X:%08X %02X %-3d ", + llc_ui->addr.sllc_dmac[0], llc_ui->addr.sllc_dmac[1], + llc_ui->addr.sllc_dmac[2], llc_ui->addr.sllc_dmac[3], + llc_ui->addr.sllc_dmac[4], llc_ui->addr.sllc_dmac[5], + llc_ui->addr.sllc_dsap, + atomic_read(&s->wmem_alloc), + atomic_read(&s->rmem_alloc), s->state, + SOCK_INODE(s->socket)->i_uid); + if (llc_ui->core_sk) + len += sprintf(buffer + len, "%-7d\n", + llc_sk(llc_ui->core_sk)->link); + else + len += sprintf(buffer + len, "no_link\n"); + /* Are we still dumping unwanted data then discard the record */ + pos = begin + len; + + if (pos < offset) { + len = 0; /* Keep dumping into the buffer start */ + begin = pos; + } + if (pos > offset + length) /* We have dumped enough */ + break; + } + read_unlock_bh(&llc_ui_sockets_lock); + + /* The data in question runs from begin to begin + len */ + *start = buffer + offset - begin; /* Start of wanted data */ + len -= offset - begin; /* Remove unwanted header data from length */ + if (len > length) + len = length; /* Remove unwanted tail data from length */ + return len; +} +#endif /* CONFIG_PROC_FS */ + +static struct net_proto_family llc_ui_family_ops = { + family: PF_LLC, + create: llc_ui_create, +}; + +static struct proto_ops SOCKOPS_WRAPPED(llc_ui_ops) = { + family: PF_LLC, + release: llc_ui_release, + bind: llc_ui_bind, + connect: llc_ui_connect, + socketpair: sock_no_socketpair, + accept: llc_ui_accept, + getname: llc_ui_getname, + poll: datagram_poll, + ioctl: llc_ui_ioctl, + listen: llc_ui_listen, + shutdown: llc_ui_shutdown, + setsockopt: llc_ui_setsockopt, + getsockopt: llc_ui_getsockopt, + sendmsg: llc_ui_sendmsg, + recvmsg: llc_ui_recvmsg, + mmap: sock_no_mmap, + sendpage: sock_no_sendpage, +}; + +#include +SOCKOPS_WRAP(llc_ui, PF_LLC); + +static char llc_ui_banner[] __initdata = + KERN_INFO "NET4.0 IEEE 802.2 User Interface SAPs, Jay Schulist, 2001\n"; + +int __init llc_ui_init(void) +{ + llc_ui_sap_last_autoport = LLC_SAP_DYN_START; + sock_register(&llc_ui_family_ops); + proc_net_create("llc", 0, llc_ui_get_info); + printk(llc_ui_banner); + return 0; +} + +void __exit llc_ui_exit(void) +{ + proc_net_remove("llc"); + sock_unregister(PF_LLC); +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_stat.c linux.19pre5-ac1/net/llc/llc_stat.c --- linux.19p5/net/llc/llc_stat.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/net/llc/llc_stat.c Tue Mar 19 19:15:34 2002 @@ -0,0 +1,199 @@ +/* + * llc_stat.c - Implementation of LLC station component state machine + * transitions + * Copyright (c) 1997 by Procom Technology, Inc. + * 2001 by Arnaldo Carvalho de Melo + * + * This program can be redistributed or modified under the terms of the + * GNU General Public License as published by the Free Software Foundation. + * This program is distributed without any warranty or implied warranty + * of merchantability or fitness for a particular purpose. + * + * See the GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include + +/* ------------------- COMMON STATION STATE transitions ------------------ */ + +/* dummy last-transition indicator; common to all state transition groups */ +/* last entry for this state */ +/* all members are zeros, .bss zeroes it */ +static struct llc_station_state_trans llc_stat_state_trans_n; + +/* ------------------------ DOWN STATE transitions ----------------------- */ + +/* state transition for LLC_STATION_EV_ENABLE_WITH_DUP_ADDR_CHECK event */ +static llc_station_action_t llc_stat_down_state_actions_1[] = { + llc_station_ac_start_ack_timer, + llc_station_ac_set_retry_cnt_0, + llc_station_ac_set_xid_r_cnt_0, + llc_station_ac_send_null_dsap_xid_c, + NULL +}; + +static struct llc_station_state_trans llc_stat_down_state_trans_1 = { + llc_stat_ev_enable_with_dup_addr_check, + LLC_STATION_STATE_DUP_ADDR_CHK, + llc_stat_down_state_actions_1 +}; + +/* state transition for LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK event */ +static llc_station_action_t llc_stat_down_state_actions_2[] = { + llc_station_ac_report_status, /* STATION UP */ + NULL +}; + +static struct llc_station_state_trans llc_stat_down_state_trans_2 = { + llc_stat_ev_enable_without_dup_addr_check, + LLC_STATION_STATE_UP, + llc_stat_down_state_actions_2 +}; + +/* array of pointers; one to each transition */ +static struct llc_station_state_trans *llc_stat_dwn_state_trans[] = { + &llc_stat_down_state_trans_1, + &llc_stat_down_state_trans_2, + &llc_stat_state_trans_n +}; + +/* ------------------------- UP STATE transitions ------------------------ */ +/* state transition for LLC_STATION_EV_DISABLE_REQ event */ +static llc_station_action_t llc_stat_up_state_actions_1[] = { + llc_station_ac_report_status, /* STATION DOWN */ + NULL +}; + +static struct llc_station_state_trans llc_stat_up_state_trans_1 = { + llc_stat_ev_disable_req, LLC_STATION_STATE_DOWN, + llc_stat_up_state_actions_1 +}; + +/* state transition for LLC_STATION_EV_RX_NULL_DSAP_XID_C event */ +static llc_station_action_t llc_stat_up_state_actions_2[] = { + llc_station_ac_send_xid_r, + NULL +}; + +static struct llc_station_state_trans llc_stat_up_state_trans_2 = { + llc_stat_ev_rx_null_dsap_xid_c, LLC_STATION_STATE_UP, + llc_stat_up_state_actions_2 +}; + +/* state transition for LLC_STATION_EV_RX_NULL_DSAP_TEST_C event */ +static llc_station_action_t llc_stat_up_state_actions_3[] = { + llc_station_ac_send_test_r, + NULL +}; + +static struct llc_station_state_trans llc_stat_up_state_trans_3 = { + llc_stat_ev_rx_null_dsap_test_c, LLC_STATION_STATE_UP, + llc_stat_up_state_actions_3 +}; + +/* array of pointers; one to each transition */ +static struct llc_station_state_trans *llc_stat_up_state_trans [] = { + &llc_stat_up_state_trans_1, + &llc_stat_up_state_trans_2, + &llc_stat_up_state_trans_3, + &llc_stat_state_trans_n +}; + +/* ---------------------- DUP ADDR CHK STATE transitions ----------------- */ +/* state transition for LLC_STATION_EV_RX_NULL_DSAP_0_XID_R_XID_R_CNT_EQ + * event */ +static llc_station_action_t llc_stat_dupaddr_state_actions_1[] = { + llc_station_ac_inc_xid_r_cnt_by_1, + NULL +}; + +static struct llc_station_state_trans llc_stat_dupaddr_state_trans_1 = { + llc_stat_ev_rx_null_dsap_0_xid_r_xid_r_cnt_eq, + LLC_STATION_STATE_DUP_ADDR_CHK, + llc_stat_dupaddr_state_actions_1 +}; + +/* state transition for LLC_STATION_EV_RX_NULL_DSAP_1_XID_R_XID_R_CNT_EQ + * event */ +static llc_station_action_t llc_stat_dupaddr_state_actions_2[] = { + llc_station_ac_report_status, /* DUPLICATE ADDRESS FOUND */ + NULL +}; + +static struct llc_station_state_trans llc_stat_dupaddr_state_trans_2 = { + llc_stat_ev_rx_null_dsap_1_xid_r_xid_r_cnt_eq, + LLC_STATION_STATE_DOWN, + llc_stat_dupaddr_state_actions_2 +}; + +/* state transition for LLC_STATION_EV_RX_NULL_DSAP_XID_C event */ +static llc_station_action_t llc_stat_dupaddr_state_actions_3[] = { + llc_station_ac_send_xid_r, + NULL +}; + +static struct llc_station_state_trans llc_stat_dupaddr_state_trans_3 = { + llc_stat_ev_rx_null_dsap_xid_c, LLC_STATION_STATE_DUP_ADDR_CHK, + llc_stat_dupaddr_state_actions_3 +}; + +/* state transition for LLC_STATION_EV_ACK_TMR_EXP_LT_RETRY_CNT_MAX_RETRY + * event */ +static llc_station_action_t llc_stat_dupaddr_state_actions_4[] = { + llc_station_ac_start_ack_timer, + llc_station_ac_inc_retry_cnt_by_1, + llc_station_ac_set_xid_r_cnt_0, + llc_station_ac_send_null_dsap_xid_c, + NULL +}; + +static struct llc_station_state_trans llc_stat_dupaddr_state_trans_4 = { + llc_stat_ev_ack_tmr_exp_lt_retry_cnt_max_retry, + LLC_STATION_STATE_DUP_ADDR_CHK, + llc_stat_dupaddr_state_actions_4 +}; + +/* state transition for LLC_STATION_EV_ACK_TMR_EXP_EQ_RETRY_CNT_MAX_RETRY + * event */ +static llc_station_action_t llc_stat_dupaddr_state_actions_5[] = { + llc_station_ac_report_status, /* STATION UP */ + NULL +}; + +static struct llc_station_state_trans llc_stat_dupaddr_state_trans_5 = { + llc_stat_ev_ack_tmr_exp_eq_retry_cnt_max_retry, + LLC_STATION_STATE_UP, + llc_stat_dupaddr_state_actions_5 +}; + +/* state transition for LLC_STATION_EV_DISABLE_REQ event */ +static llc_station_action_t llc_stat_dupaddr_state_actions_6[] = { + llc_station_ac_report_status, /* STATION DOWN */ + NULL +}; + +static struct llc_station_state_trans llc_stat_dupaddr_state_trans_6 = { + llc_stat_ev_disable_req, LLC_STATION_STATE_DOWN, + llc_stat_dupaddr_state_actions_6 +}; + +/* array of pointers; one to each transition */ +static struct llc_station_state_trans *llc_stat_dupaddr_state_trans[] = { + &llc_stat_dupaddr_state_trans_6, /* Request */ + &llc_stat_dupaddr_state_trans_4, /* Timer */ + &llc_stat_dupaddr_state_trans_5, + &llc_stat_dupaddr_state_trans_1, /* Receive frame */ + &llc_stat_dupaddr_state_trans_2, + &llc_stat_dupaddr_state_trans_3, + &llc_stat_state_trans_n +}; + +struct llc_station_state llc_station_state_table[LLC_NBR_STATION_STATES] = { + { LLC_STATION_STATE_DOWN, llc_stat_dwn_state_trans }, + { LLC_STATION_STATE_DUP_ADDR_CHK, llc_stat_dupaddr_state_trans }, + { LLC_STATION_STATE_UP, llc_stat_up_state_trans } +}; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/netsyms.c linux.19pre5-ac1/net/netsyms.c --- linux.19p5/net/netsyms.c Thu Apr 4 13:21:18 2002 +++ linux.19pre5-ac1/net/netsyms.c Thu Apr 4 14:08:28 2002 @@ -457,6 +457,7 @@ #endif /* CONFIG_INET */ #ifdef CONFIG_TR +EXPORT_SYMBOL(tr_source_route); EXPORT_SYMBOL(tr_type_trans); #endif @@ -475,6 +476,7 @@ EXPORT_SYMBOL(__dev_get_by_index); EXPORT_SYMBOL(dev_get_by_name); EXPORT_SYMBOL(__dev_get_by_name); +EXPORT_SYMBOL(dev_getbyhwaddr); EXPORT_SYMBOL(netdev_finish_unregister); EXPORT_SYMBOL(netdev_set_master); EXPORT_SYMBOL(eth_type_trans); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/sched/sch_generic.c linux.19pre5-ac1/net/sched/sch_generic.c --- linux.19p5/net/sched/sch_generic.c Thu Apr 4 13:18:47 2002 +++ linux.19pre5-ac1/net/sched/sch_generic.c Wed Feb 27 18:32:03 2002 @@ -475,10 +475,8 @@ dev_watchdog_down(dev); - while (test_bit(__LINK_STATE_SCHED, &dev->state)) { - current->policy |= SCHED_YIELD; - schedule(); - } + while (test_bit(__LINK_STATE_SCHED, &dev->state)) + yield(); spin_unlock_wait(&dev->xmit_lock); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/socket.c linux.19pre5-ac1/net/socket.c --- linux.19p5/net/socket.c Thu Apr 4 13:21:18 2002 +++ linux.19pre5-ac1/net/socket.c Wed Feb 27 18:35:59 2002 @@ -147,8 +147,7 @@ while (atomic_read(&net_family_lockct) != 0) { spin_unlock(&net_family_lock); - current->policy |= SCHED_YIELD; - schedule(); + yield(); spin_lock(&net_family_lock); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/sunrpc/clnt.c linux.19pre5-ac1/net/sunrpc/clnt.c --- linux.19p5/net/sunrpc/clnt.c Thu Apr 4 13:18:46 2002 +++ linux.19pre5-ac1/net/sunrpc/clnt.c Thu Mar 21 00:48:42 2002 @@ -78,10 +78,6 @@ dprintk("RPC: creating %s client for %s (xprt %p)\n", program->name, servname, xprt); -#ifdef RPC_DEBUG - rpc_register_sysctl(); -#endif - if (!xprt) goto out; if (vers >= program->nrvers || !(version = program->version[vers])) @@ -103,7 +99,7 @@ clnt->cl_vers = version->number; clnt->cl_prot = xprt->prot; clnt->cl_stats = program->stats; - clnt->cl_bindwait = RPC_INIT_WAITQ("bindwait"); + INIT_RPC_WAITQ(&clnt->cl_bindwait, "bindwait"); if (!clnt->cl_port) clnt->cl_autobind = 1; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/sunrpc/sched.c linux.19pre5-ac1/net/sunrpc/sched.c --- linux.19p5/net/sunrpc/sched.c Thu Apr 4 13:18:46 2002 +++ linux.19pre5-ac1/net/sunrpc/sched.c Thu Mar 21 00:48:42 2002 @@ -41,23 +41,23 @@ * handler, or while executing another RPC task, it is put on * schedq, and rpciod is woken up. */ -static struct rpc_wait_queue schedq = RPC_INIT_WAITQ("schedq"); +static RPC_WAITQ(schedq, "schedq"); /* * RPC tasks that create another task (e.g. for contacting the portmapper) * will wait on this queue for their child's completion */ -static struct rpc_wait_queue childq = RPC_INIT_WAITQ("childq"); +static RPC_WAITQ(childq, "childq"); /* * RPC tasks sit here while waiting for conditions to improve. */ -static struct rpc_wait_queue delay_queue = RPC_INIT_WAITQ("delayq"); +static RPC_WAITQ(delay_queue, "delayq"); /* * All RPC tasks are linked into this list */ -static struct rpc_task * all_tasks; +static LIST_HEAD(all_tasks); /* * rpciod-related stuff @@ -194,9 +194,9 @@ return -EWOULDBLOCK; } if (RPC_IS_SWAPPER(task)) - rpc_insert_list(&queue->task, task); + list_add(&task->tk_list, &queue->tasks); else - rpc_append_list(&queue->task, task); + list_add_tail(&task->tk_list, &queue->tasks); task->tk_rpcwait = queue; dprintk("RPC: %4d added to queue %p \"%s\"\n", @@ -228,7 +228,7 @@ if (!queue) return; - rpc_remove_list(&queue->task, task); + list_del(&task->tk_list); task->tk_rpcwait = NULL; dprintk("RPC: %4d removed from queue %p \"%s\"\n", @@ -450,11 +450,11 @@ struct rpc_task * rpc_wake_up_next(struct rpc_wait_queue *queue) { - struct rpc_task *task; + struct rpc_task *task = NULL; dprintk("RPC: wake_up_next(%p \"%s\")\n", queue, rpc_qname(queue)); spin_lock_bh(&rpc_queue_lock); - if ((task = queue->task) != 0) + task_for_first(task, &queue->tasks) __rpc_wake_up_task(task); spin_unlock_bh(&rpc_queue_lock); @@ -470,9 +470,12 @@ void rpc_wake_up(struct rpc_wait_queue *queue) { + struct rpc_task *task; + spin_lock_bh(&rpc_queue_lock); - while (queue->task) - __rpc_wake_up_task(queue->task); + while (!list_empty(&queue->tasks)) + task_for_first(task, &queue->tasks) + __rpc_wake_up_task(task); spin_unlock_bh(&rpc_queue_lock); } @@ -486,12 +489,14 @@ void rpc_wake_up_status(struct rpc_wait_queue *queue, int status) { - struct rpc_task *task; + struct rpc_task *task; spin_lock_bh(&rpc_queue_lock); - while ((task = queue->task) != NULL) { - task->tk_status = status; - __rpc_wake_up_task(task); + while (!list_empty(&queue->tasks)) { + task_for_first(task, &queue->tasks) { + task->tk_status = status; + __rpc_wake_up_task(task); + } } spin_unlock_bh(&rpc_queue_lock); } @@ -703,23 +708,25 @@ rpciod_tcp_dispatcher(); spin_lock_bh(&rpc_queue_lock); - if (!(task = schedq.task)) { - spin_unlock_bh(&rpc_queue_lock); - break; - } - if (task->tk_lock) { - spin_unlock_bh(&rpc_queue_lock); - printk(KERN_ERR "RPC: Locked task was scheduled !!!!\n"); + + task_for_first(task, &schedq.tasks) { + if (task->tk_lock) { + spin_unlock_bh(&rpc_queue_lock); + printk(KERN_ERR "RPC: Locked task was scheduled !!!!\n"); #ifdef RPC_DEBUG - rpc_debug = ~0; - rpc_show_tasks(); + rpc_debug = ~0; + rpc_show_tasks(); #endif + break; + } + __rpc_remove_wait_queue(task); + spin_unlock_bh(&rpc_queue_lock); + + __rpc_execute(task); + } else { + spin_unlock_bh(&rpc_queue_lock); break; } - __rpc_remove_wait_queue(task); - spin_unlock_bh(&rpc_queue_lock); - - __rpc_execute(task); if (++count >= 200 || current->need_resched) { count = 0; @@ -773,8 +780,7 @@ } if (flags & RPC_TASK_ASYNC) return NULL; - current->policy |= SCHED_YIELD; - schedule(); + yield(); } while (!signalled()); return NULL; @@ -815,11 +821,7 @@ /* Add to global list of all tasks */ spin_lock(&rpc_sched_lock); - task->tk_next_task = all_tasks; - task->tk_prev_task = NULL; - if (all_tasks) - all_tasks->tk_prev_task = task; - all_tasks = task; + list_add(&task->tk_task, &all_tasks); spin_unlock(&rpc_sched_lock); if (clnt) @@ -878,8 +880,6 @@ void rpc_release_task(struct rpc_task *task) { - struct rpc_task *next, *prev; - dprintk("RPC: %4d release task\n", task->tk_pid); #ifdef RPC_DEBUG @@ -893,15 +893,7 @@ /* Remove from global task list */ spin_lock(&rpc_sched_lock); - prev = task->tk_prev_task; - next = task->tk_next_task; - if (next) - next->tk_prev_task = prev; - if (prev) - prev->tk_next_task = next; - else - all_tasks = next; - task->tk_next_task = task->tk_prev_task = NULL; + list_del(&task->tk_task); spin_unlock(&rpc_sched_lock); /* Protect the execution below. */ @@ -955,14 +947,13 @@ rpc_find_parent(struct rpc_task *child) { struct rpc_task *task, *parent; + struct list_head *le; parent = (struct rpc_task *) child->tk_calldata; - if ((task = childq.task) != NULL) { - do { - if (task == parent) - return parent; - } while ((task = task->tk_next) != childq.task); - } + task_for_each(task, le, &childq.tasks) + if (task == parent) + return parent; + return NULL; } @@ -1016,7 +1007,8 @@ void rpc_killall_tasks(struct rpc_clnt *clnt) { - struct rpc_task **q, *rovr; + struct rpc_task *rovr; + struct list_head *le; dprintk("RPC: killing all tasks for client %p\n", clnt); @@ -1024,13 +1016,12 @@ * Spin lock all_tasks to prevent changes... */ spin_lock(&rpc_sched_lock); - for (q = &all_tasks; (rovr = *q); q = &rovr->tk_next_task) { + alltask_for_each(rovr, le, &all_tasks) if (!clnt || rovr->tk_client == clnt) { rovr->tk_flags |= RPC_TASK_KILLED; rpc_exit(rovr, -EIO); rpc_wake_up_task(rovr); } - } spin_unlock(&rpc_sched_lock); } @@ -1039,7 +1030,7 @@ static inline int rpciod_task_pending(void) { - return schedq.task != NULL || xprt_tcp_pending(); + return !list_empty(&schedq.tasks) || xprt_tcp_pending(); } @@ -1091,7 +1082,7 @@ } dprintk("RPC: rpciod shutdown commences\n"); - if (all_tasks) { + if (!list_empty(&all_tasks)) { printk(KERN_ERR "rpciod: active tasks at shutdown?!\n"); rpciod_killall(); } @@ -1109,14 +1100,13 @@ { unsigned long flags; - while (all_tasks) { + while (!list_empty(&all_tasks)) { current->sigpending = 0; rpc_killall_tasks(NULL); __rpc_schedule(); - if (all_tasks) { + if (!list_empty(&all_tasks)) { dprintk("rpciod_killall: waiting for tasks to exit\n"); - current->policy |= SCHED_YIELD; - schedule(); + yield(); } } @@ -1186,8 +1176,7 @@ * wait briefly before checking the process id. */ current->sigpending = 0; - current->policy |= SCHED_YIELD; - schedule(); + yield(); /* * Display a message if we're going to wait longer. */ @@ -1210,25 +1199,23 @@ #ifdef RPC_DEBUG void rpc_show_tasks(void) { - struct rpc_task *t = all_tasks, *next; + struct list_head *le; + struct rpc_task *t; spin_lock(&rpc_sched_lock); - t = all_tasks; - if (!t) { + if (list_empty(&all_tasks)) { spin_unlock(&rpc_sched_lock); return; } printk("-pid- proc flgs status -client- -prog- --rqstp- -timeout " "-rpcwait -action- --exit--\n"); - for (; t; t = next) { - next = t->tk_next_task; + alltask_for_each(t, le, &all_tasks) printk("%05d %04d %04x %06d %8p %6d %8p %08ld %8s %8p %8p\n", t->tk_pid, t->tk_msg.rpc_proc, t->tk_flags, t->tk_status, t->tk_client, t->tk_client->cl_prog, t->tk_rqstp, t->tk_timeout, t->tk_rpcwait ? rpc_qname(t->tk_rpcwait) : " ", t->tk_action, t->tk_exit); - } spin_unlock(&rpc_sched_lock); } #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/sunrpc/stats.c linux.19pre5-ac1/net/sunrpc/stats.c --- linux.19p5/net/sunrpc/stats.c Thu Apr 4 13:21:18 2002 +++ linux.19pre5-ac1/net/sunrpc/stats.c Mon Mar 25 18:18:33 2002 @@ -15,6 +15,7 @@ #define __NO_VERSION__ #include +#include #include #include #include @@ -182,10 +183,9 @@ } } -#ifdef MODULE -int -init_module(void) +static int __init +init_sunrpc(void) { #ifdef RPC_DEBUG rpc_register_sysctl(); @@ -194,13 +194,14 @@ return 0; } -void -cleanup_module(void) +static void __exit +cleanup_sunrpc(void) { #ifdef RPC_DEBUG rpc_unregister_sysctl(); #endif rpc_proc_exit(); } -#endif MODULE_LICENSE("GPL"); +module_init(init_sunrpc); +module_exit(cleanup_sunrpc); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/sunrpc/sunrpc_syms.c linux.19pre5-ac1/net/sunrpc/sunrpc_syms.c --- linux.19p5/net/sunrpc/sunrpc_syms.c Thu Apr 4 13:18:46 2002 +++ linux.19pre5-ac1/net/sunrpc/sunrpc_syms.c Thu Mar 21 00:48:42 2002 @@ -77,6 +77,7 @@ EXPORT_SYMBOL(svc_recv); EXPORT_SYMBOL(svc_wake_up); EXPORT_SYMBOL(svc_makesock); +EXPORT_SYMBOL(svc_reserve); /* RPC statistics */ #ifdef CONFIG_PROC_FS diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/sunrpc/svc.c linux.19pre5-ac1/net/sunrpc/svc.c --- linux.19p5/net/sunrpc/svc.c Thu Apr 4 13:18:46 2002 +++ linux.19pre5-ac1/net/sunrpc/svc.c Thu Mar 21 00:48:42 2002 @@ -31,10 +31,6 @@ { struct svc_serv *serv; -#ifdef RPC_DEBUG - rpc_register_sysctl(); -#endif - if (!(serv = (struct svc_serv *) kmalloc(sizeof(*serv), GFP_KERNEL))) return NULL; @@ -44,6 +40,10 @@ serv->sv_stats = prog->pg_stats; serv->sv_bufsz = bufsize? bufsize : 4096; serv->sv_xdrsize = xdrsize; + INIT_LIST_HEAD(&serv->sv_threads); + INIT_LIST_HEAD(&serv->sv_sockets); + INIT_LIST_HEAD(&serv->sv_tempsocks); + INIT_LIST_HEAD(&serv->sv_permsocks); spin_lock_init(&serv->sv_lock); serv->sv_name = prog->pg_name; @@ -67,13 +67,25 @@ serv->sv_nrthreads); if (serv->sv_nrthreads) { - if (--(serv->sv_nrthreads) != 0) + if (--(serv->sv_nrthreads) != 0) { + svc_sock_update_bufs(serv); return; + } } else printk("svc_destroy: no threads for serv=%p!\n", serv); - while ((svsk = serv->sv_allsocks) != NULL) + while (!list_empty(&serv->sv_tempsocks)) { + svsk = list_entry(serv->sv_tempsocks.next, + struct svc_sock, + sk_list); + svc_delete_socket(svsk); + } + while (!list_empty(&serv->sv_permsocks)) { + svsk = list_entry(serv->sv_permsocks.next, + struct svc_sock, + sk_list); svc_delete_socket(svsk); + } /* Unregister service with the portmapper */ svc_register(serv, 0, 0); @@ -138,6 +150,7 @@ error = kernel_thread((int (*)(void *)) func, rqstp, 0); if (error < 0) goto out_thread; + svc_sock_update_bufs(serv); error = 0; out: return error; @@ -296,6 +309,12 @@ memset(rqstp->rq_argp, 0, procp->pc_argsize); memset(rqstp->rq_resp, 0, procp->pc_ressize); + /* un-reserve some of the out-queue now that we have a + * better idea of reply size + */ + if (procp->pc_xdrressize) + svc_reserve(rqstp, procp->pc_xdrressize<<2); + /* Call the function that processes the request. */ if (!versp->vs_dispatch) { /* Decode arguments */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/sunrpc/svcsock.c linux.19pre5-ac1/net/sunrpc/svcsock.c --- linux.19p5/net/sunrpc/svcsock.c Thu Apr 4 13:18:46 2002 +++ linux.19pre5-ac1/net/sunrpc/svcsock.c Thu Mar 21 00:48:42 2002 @@ -44,10 +44,19 @@ /* SMP locking strategy: * - * svc_sock->sk_lock and svc_serv->sv_lock protect their - * respective structures. + * svc_serv->sv_lock protects most stuff for that service. + * + * Some flags can be set to certain values at any time + * providing that certain rules are followed: + * + * SK_BUSY can be set to 0 at any time. + * svc_sock_enqueue must be called afterwards + * SK_CONN, SK_DATA, can be set or cleared at any time. + * after a set, svc_sock_enqueue must be called. + * after a clear, the socket must be read/accepted + * if this succeeds, it must be set again. + * SK_CLOSE can set at any time. It is never cleared. * - * Antideadlock ordering is sk_lock --> sv_lock. */ #define RPCDBG_FACILITY RPCDBG_SVCSOCK @@ -62,11 +71,14 @@ /* * Queue up an idle server thread. Must have serv->sv_lock held. + * Note: this is really a stack rather than a queue, so that we only + * use as many different threads as we need, and the rest don't polute + * the cache. */ static inline void svc_serv_enqueue(struct svc_serv *serv, struct svc_rqst *rqstp) { - rpc_append_list(&serv->sv_threads, rqstp); + list_add(&rqstp->rq_list, &serv->sv_threads); } /* @@ -75,7 +87,7 @@ static inline void svc_serv_dequeue(struct svc_serv *serv, struct svc_rqst *rqstp) { - rpc_remove_list(&serv->sv_threads, rqstp); + list_del(&rqstp->rq_list); } /* @@ -98,7 +110,6 @@ * Queue up a socket with data pending. If there are idle nfsd * processes, wake 'em up. * - * This must be called with svsk->sk_lock held. */ static void svc_sock_enqueue(struct svc_sock *svsk) @@ -106,26 +117,44 @@ struct svc_serv *serv = svsk->sk_server; struct svc_rqst *rqstp; - /* NOTE: Local BH is already disabled by our caller. */ - spin_lock(&serv->sv_lock); + if (!(svsk->sk_flags & + ( (1<sv_lock); - if (serv->sv_threads && serv->sv_sockets) + if (!list_empty(&serv->sv_threads) && + !list_empty(&serv->sv_sockets)) printk(KERN_ERR "svc_sock_enqueue: threads and sockets both waiting??\n"); - if (svsk->sk_busy) { + if (test_bit(SK_BUSY, &svsk->sk_flags)) { /* Don't enqueue socket while daemon is receiving */ dprintk("svc: socket %p busy, not enqueued\n", svsk->sk_sk); goto out_unlock; } + if (((svsk->sk_reserved + serv->sv_bufsz)*2 + > sock_wspace(svsk->sk_sk)) + && !test_bit(SK_CLOSE, &svsk->sk_flags) + && !test_bit(SK_CONN, &svsk->sk_flags)) { + /* Don't enqueue while not enough space for reply */ + dprintk("svc: socket %p no space, %d > %ld, not enqueued\n", + svsk->sk_sk, svsk->sk_reserved+serv->sv_bufsz, + sock_wspace(svsk->sk_sk)); + goto out_unlock; + } + /* Mark socket as busy. It will remain in this state until the * server has processed all pending data and put the socket back * on the idle list. */ - svsk->sk_busy = 1; + set_bit(SK_BUSY, &svsk->sk_flags); - if ((rqstp = serv->sv_threads) != NULL) { + if (!list_empty(&serv->sv_threads)) { + rqstp = list_entry(serv->sv_threads.next, + struct svc_rqst, + rq_list); dprintk("svc: socket %p served by daemon %p\n", svsk->sk_sk, rqstp); svc_serv_dequeue(serv, rqstp); @@ -135,15 +164,17 @@ rqstp, rqstp->rq_sock); rqstp->rq_sock = svsk; svsk->sk_inuse++; + rqstp->rq_reserved = serv->sv_bufsz; + svsk->sk_reserved += rqstp->rq_reserved; wake_up(&rqstp->rq_wait); } else { dprintk("svc: socket %p put into queue\n", svsk->sk_sk); - rpc_append_list(&serv->sv_sockets, svsk); - svsk->sk_qued = 1; + list_add_tail(&svsk->sk_ready, &serv->sv_sockets); + set_bit(SK_QUED, &svsk->sk_flags); } out_unlock: - spin_unlock(&serv->sv_lock); + spin_unlock_bh(&serv->sv_lock); } /* @@ -154,71 +185,69 @@ { struct svc_sock *svsk; - if ((svsk = serv->sv_sockets) != NULL) - rpc_remove_list(&serv->sv_sockets, svsk); + if (list_empty(&serv->sv_sockets)) + return NULL; - if (svsk) { - dprintk("svc: socket %p dequeued, inuse=%d\n", - svsk->sk_sk, svsk->sk_inuse); - svsk->sk_qued = 0; - } + svsk = list_entry(serv->sv_sockets.next, + struct svc_sock, sk_ready); + list_del(&svsk->sk_ready); + + dprintk("svc: socket %p dequeued, inuse=%d\n", + svsk->sk_sk, svsk->sk_inuse); + clear_bit(SK_QUED, &svsk->sk_flags); return svsk; } /* - * Having read count bytes from a socket, check whether it + * Having read something from a socket, check whether it * needs to be re-enqueued. + * Note: SK_DATA only gets cleared when a read-attempt finds + * no (or insufficient) data. */ static inline void -svc_sock_received(struct svc_sock *svsk, int count) +svc_sock_received(struct svc_sock *svsk) { - spin_lock_bh(&svsk->sk_lock); - if ((svsk->sk_data -= count) < 0) { - printk(KERN_NOTICE "svc: sk_data negative!\n"); - svsk->sk_data = 0; - } - svsk->sk_rqstp = NULL; /* XXX */ - svsk->sk_busy = 0; - if (svsk->sk_conn || svsk->sk_data || svsk->sk_close) { - dprintk("svc: socket %p re-enqueued after receive\n", - svsk->sk_sk); - svc_sock_enqueue(svsk); - } - spin_unlock_bh(&svsk->sk_lock); + clear_bit(SK_BUSY, &svsk->sk_flags); + svc_sock_enqueue(svsk); } -/* - * Dequeue a new connection. + +/** + * svc_reserve - change the space reserved for the reply to a request. + * @rqstp: The request in question + * @space: new max space to reserve + * + * Each request reserves some space on the output queue of the socket + * to make sure the reply fits. This function reduces that reserved + * space to be the amount of space used already, plus @space. + * */ -static inline void -svc_sock_accepted(struct svc_sock *svsk) +void svc_reserve(struct svc_rqst *rqstp, int space) { - spin_lock_bh(&svsk->sk_lock); - svsk->sk_busy = 0; - svsk->sk_conn--; - if (svsk->sk_conn || svsk->sk_data || svsk->sk_close) { - dprintk("svc: socket %p re-enqueued after accept\n", - svsk->sk_sk); - svc_sock_enqueue(svsk); - } - spin_unlock_bh(&svsk->sk_lock); + space += rqstp->rq_resbuf.len<<2; + + if (space < rqstp->rq_reserved) { + struct svc_sock *svsk = rqstp->rq_sock; + spin_lock_bh(&svsk->sk_server->sv_lock); + svsk->sk_reserved -= (rqstp->rq_reserved - space); + rqstp->rq_reserved = space; + spin_unlock_bh(&svsk->sk_server->sv_lock); + + svc_sock_enqueue(svsk); + } } /* * Release a socket after use. */ static inline void -svc_sock_release(struct svc_rqst *rqstp) +svc_sock_put(struct svc_sock *svsk) { - struct svc_sock *svsk = rqstp->rq_sock; - struct svc_serv *serv = svsk->sk_server; - - svc_release_skb(rqstp); - rqstp->rq_sock = NULL; + struct svc_serv *serv = svsk->sk_server; spin_lock_bh(&serv->sv_lock); - if (!--(svsk->sk_inuse) && svsk->sk_dead) { + if (!--(svsk->sk_inuse) && test_bit(SK_DEAD, &svsk->sk_flags)) { spin_unlock_bh(&serv->sv_lock); dprintk("svc: releasing dead socket\n"); sock_release(svsk->sk_sock); @@ -228,6 +257,31 @@ spin_unlock_bh(&serv->sv_lock); } +static void +svc_sock_release(struct svc_rqst *rqstp) +{ + struct svc_sock *svsk = rqstp->rq_sock; + + svc_release_skb(rqstp); + + /* Reset response buffer and release + * the reservation. + * But first, check that enough space was reserved + * for the reply, otherwise we have a bug! + */ + if ((rqstp->rq_resbuf.len<<2) > rqstp->rq_reserved) + printk(KERN_ERR "RPC request reserved %d but used %d\n", + rqstp->rq_reserved, + rqstp->rq_resbuf.len<<2); + + rqstp->rq_resbuf.buf = rqstp->rq_resbuf.base; + rqstp->rq_resbuf.len = 0; + svc_reserve(rqstp, 0); + rqstp->rq_sock = NULL; + + svc_sock_put(svsk); +} + /* * External function to wake up a server waiting for data */ @@ -237,7 +291,10 @@ struct svc_rqst *rqstp; spin_lock_bh(&serv->sv_lock); - if ((rqstp = serv->sv_threads) != NULL) { + if (!list_empty(&serv->sv_threads)) { + rqstp = list_entry(serv->sv_threads.next, + struct svc_rqst, + rq_list); dprintk("svc: daemon %p woken up.\n", rqstp); /* svc_serv_dequeue(serv, rqstp); @@ -270,7 +327,13 @@ msg.msg_control = NULL; msg.msg_controllen = 0; - msg.msg_flags = MSG_DONTWAIT; + /* This was MSG_DONTWAIT, but I now want it to wait. + * The only thing that it would wait for is memory and + * if we are fairly low on memory, then we aren't likely + * to make much progress anyway. + * sk->sndtimeo is set to 30seconds just in case. + */ + msg.msg_flags = 0; oldfs = get_fs(); set_fs(KERNEL_DS); len = sock_sendmsg(sock, &msg, buflen); @@ -340,6 +403,32 @@ } /* + * Set socket snd and rcv buffer lengths + */ +static inline void +svc_sock_setbufsize(struct socket *sock, unsigned int snd, unsigned int rcv) +{ +#if 0 + mm_segment_t oldfs; + oldfs = get_fs(); set_fs(KERNEL_DS); + sock_setsockopt(sock, SOL_SOCKET, SO_SNDBUF, + (char*)&snd, sizeof(snd)); + sock_setsockopt(sock, SOL_SOCKET, SO_RCVBUF, + (char*)&rcv, sizeof(rcv)); +#else + /* sock_setsockopt limits use to sysctl_?mem_max, + * which isn't acceptable. Until that is made conditional + * on not having CAP_SYS_RESOURCE or similar, we go direct... + * DaveM said I could! + */ + lock_sock(sock->sk); + sock->sk->sndbuf = snd * 2; + sock->sk->rcvbuf = rcv * 2; + sock->sk->userlocks |= SOCK_SNDBUF_LOCK|SOCK_RCVBUF_LOCK; + release_sock(sock->sk); +#endif +} +/* * INET callback when data has been received on the socket. */ static void @@ -350,17 +439,36 @@ if (!svsk) goto out; dprintk("svc: socket %p(inet %p), count=%d, busy=%d\n", - svsk, sk, count, svsk->sk_busy); - spin_lock_bh(&svsk->sk_lock); - svsk->sk_data = 1; + svsk, sk, count, test_bit(SK_BUSY, &svsk->sk_flags)); + set_bit(SK_DATA, &svsk->sk_flags); svc_sock_enqueue(svsk); - spin_unlock_bh(&svsk->sk_lock); out: if (sk->sleep && waitqueue_active(sk->sleep)) wake_up_interruptible(sk->sleep); } /* + * INET callback when space is newly available on the socket. + */ +static void +svc_write_space(struct sock *sk) +{ + struct svc_sock *svsk = (struct svc_sock *)(sk->user_data); + + if (svsk) { + dprintk("svc: socket %p(inet %p), write_space busy=%d\n", + svsk, sk, test_bit(SK_BUSY, &svsk->sk_flags)); + svc_sock_enqueue(svsk); + } + + if (sk->sleep && waitqueue_active(sk->sleep)) { + printk(KERN_WARNING "RPC svc_write_space: some sleeping on %p\n", + svsk); + wake_up_interruptible(sk->sleep); + } +} + +/* * Receive a datagram from a UDP socket. */ static int @@ -372,20 +480,21 @@ u32 *data; int err, len; - svsk->sk_data = 0; + clear_bit(SK_DATA, &svsk->sk_flags); while ((skb = skb_recv_datagram(svsk->sk_sk, 0, 1, &err)) == NULL) { - svc_sock_received(svsk, 0); + svc_sock_received(svsk); if (err == -EAGAIN) return err; /* possibly an icmp error */ dprintk("svc: recvfrom returned error %d\n", -err); } + set_bit(SK_DATA, &svsk->sk_flags); /* there may be more data... */ /* Sorry. */ if (skb_is_nonlinear(skb)) { if (skb_linearize(skb, GFP_KERNEL) != 0) { kfree_skb(skb); - svc_sock_received(svsk, 0); + svc_sock_received(svsk); return 0; } } @@ -393,13 +502,11 @@ if (skb->ip_summed != CHECKSUM_UNNECESSARY) { if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) { skb_free_datagram(svsk->sk_sk, skb); - svc_sock_received(svsk, 0); + svc_sock_received(svsk); return 0; } } - /* There may be more data */ - svsk->sk_data = 1; len = skb->len - sizeof(struct udphdr); data = (u32 *) (skb->data + sizeof(struct udphdr)); @@ -421,7 +528,7 @@ /* One down, maybe more to go... */ svsk->sk_sk->stamp = skb->stamp; - svc_sock_received(svsk, 0); + svc_sock_received(svsk); return len; } @@ -444,9 +551,6 @@ if (error == -ECONNREFUSED) /* ICMP error on earlier request. */ error = svc_sendto(rqstp, bufp->iov, bufp->nriov); - else if (error == -EAGAIN) - /* Ignore and wait for re-xmit */ - error = 0; return error; } @@ -455,6 +559,7 @@ svc_udp_init(struct svc_sock *svsk) { svsk->sk_sk->data_ready = svc_udp_data_ready; + svsk->sk_sk->write_space = svc_write_space; svsk->sk_recvfrom = svc_udp_recvfrom; svsk->sk_sendto = svc_udp_sendto; @@ -481,10 +586,8 @@ printk("svc: socket %p: no user data\n", sk); goto out; } - spin_lock_bh(&svsk->sk_lock); - svsk->sk_conn++; + set_bit(SK_CONN, &svsk->sk_flags); svc_sock_enqueue(svsk); - spin_unlock_bh(&svsk->sk_lock); out: if (sk->sleep && waitqueue_active(sk->sleep)) wake_up_interruptible_all(sk->sleep); @@ -505,10 +608,8 @@ printk("svc: socket %p: no user data\n", sk); goto out; } - spin_lock_bh(&svsk->sk_lock); - svsk->sk_close = 1; + set_bit(SK_CLOSE, &svsk->sk_flags); svc_sock_enqueue(svsk); - spin_unlock_bh(&svsk->sk_lock); out: if (sk->sleep && waitqueue_active(sk->sleep)) wake_up_interruptible_all(sk->sleep); @@ -523,10 +624,8 @@ sk, sk->user_data); if (!(svsk = (struct svc_sock *)(sk->user_data))) goto out; - spin_lock_bh(&svsk->sk_lock); - svsk->sk_data++; + set_bit(SK_DATA, &svsk->sk_flags); svc_sock_enqueue(svsk); - spin_unlock_bh(&svsk->sk_lock); out: if (sk->sleep && waitqueue_active(sk->sleep)) wake_up_interruptible(sk->sleep); @@ -559,13 +658,14 @@ newsock->type = sock->type; newsock->ops = ops = sock->ops; + clear_bit(SK_CONN, &svsk->sk_flags); if ((err = ops->accept(sock, newsock, O_NONBLOCK)) < 0) { - if (net_ratelimit()) + if (err != -EAGAIN && net_ratelimit()) printk(KERN_WARNING "%s: accept failed (err %d)!\n", serv->sv_name, -err); goto failed; /* aborted connection or whatever */ } - + set_bit(SK_CONN, &svsk->sk_flags); slen = sizeof(sin); err = ops->getname(newsock, (struct sockaddr *) &sin, &slen, 1); if (err < 0) { @@ -593,14 +693,45 @@ if (!(newsvsk = svc_setup_socket(serv, newsock, &err, 0))) goto failed; + /* make sure that a write doesn't block forever when + * low on memory + */ + newsock->sk->sndtimeo = HZ*30; + /* Precharge. Data may have arrived on the socket before we * installed the data_ready callback. */ - spin_lock_bh(&newsvsk->sk_lock); - newsvsk->sk_data = 1; - newsvsk->sk_temp = 1; + set_bit(SK_DATA, &newsvsk->sk_flags); svc_sock_enqueue(newsvsk); - spin_unlock_bh(&newsvsk->sk_lock); + + /* make sure that we don't have too many active connections. + * If we have, something must be dropped. + * We randomly choose between newest and oldest (in terms + * of recent activity) and drop it. + */ + if (serv->sv_tmpcnt > serv->sv_nrthreads*5) { + struct svc_sock *svsk = NULL; + spin_lock_bh(&serv->sv_lock); + if (!list_empty(&serv->sv_tempsocks)) { + if (net_random()&1) + svsk = list_entry(serv->sv_tempsocks.prev, + struct svc_sock, + sk_list); + else + svsk = list_entry(serv->sv_tempsocks.next, + struct svc_sock, + sk_list); + set_bit(SK_CLOSE, &svsk->sk_flags); + svsk->sk_inuse ++; + } + spin_unlock_bh(&serv->sv_lock); + + if (svsk) { + svc_sock_enqueue(svsk); + svc_sock_put(svsk); + } + + } if (serv->sv_stats) serv->sv_stats->nettcpconn++; @@ -621,23 +752,25 @@ struct svc_sock *svsk = rqstp->rq_sock; struct svc_serv *serv = svsk->sk_server; struct svc_buf *bufp = &rqstp->rq_argbuf; - int len, ready, used; + int len; dprintk("svc: tcp_recv %p data %d conn %d close %d\n", - svsk, svsk->sk_data, svsk->sk_conn, svsk->sk_close); + svsk, test_bit(SK_DATA, &svsk->sk_flags), + test_bit(SK_CONN, &svsk->sk_flags), + test_bit(SK_CLOSE, &svsk->sk_flags)); - if (svsk->sk_close) { + if (test_bit(SK_CLOSE, &svsk->sk_flags)) { svc_delete_socket(svsk); return 0; } - if (svsk->sk_conn) { + if (test_bit(SK_CONN, &svsk->sk_flags)) { svc_tcp_accept(svsk); - svc_sock_accepted(svsk); + svc_sock_received(svsk); return 0; } - ready = svsk->sk_data; + clear_bit(SK_DATA, &svsk->sk_flags); /* Receive data. If we haven't got the record length yet, get * the next four bytes. Otherwise try to gobble up as much as @@ -660,13 +793,17 @@ * bit set in the fragment length header. * But apparently no known nfs clients send fragmented * records. */ - /* FIXME: shutdown socket */ - printk(KERN_NOTICE "RPC: bad TCP reclen %08lx", + printk(KERN_NOTICE "RPC: bad TCP reclen 0x%08lx (non-terminal)\n", (unsigned long) svsk->sk_reclen); - return -EIO; + goto err_delete; } svsk->sk_reclen &= 0x7fffffff; dprintk("svc: TCP record, %d bytes\n", svsk->sk_reclen); + if (svsk->sk_reclen > (bufp->buflen<<2)) { + printk(KERN_NOTICE "RPC: bad TCP reclen 0x%08lx (large)\n", + (unsigned long) svsk->sk_reclen); + goto err_delete; + } } /* Check whether enough data is available */ @@ -675,21 +812,12 @@ goto error; if (len < svsk->sk_reclen) { - /* FIXME: if sk_reclen > window-size, then we will - * never be able to receive the record, so should - * shutdown the connection - */ dprintk("svc: incomplete TCP record (%d of %d)\n", len, svsk->sk_reclen); - svc_sock_received(svsk, ready); + svc_sock_received(svsk); return -EAGAIN; /* record not complete */ } - /* if we think there is only one more record to read, but - * it is bigger than we expect, then two records must have arrived - * together, so pretend we aren't using the record.. */ - if (len > svsk->sk_reclen && ready == 1) - used = 0; - else used = 1; + set_bit(SK_DATA, &svsk->sk_flags); /* Frob argbuf */ bufp->iov[0].iov_base += 4; @@ -716,20 +844,24 @@ svsk->sk_reclen = 0; svsk->sk_tcplen = 0; - svc_sock_received(svsk, used); + svc_sock_received(svsk); if (serv->sv_stats) serv->sv_stats->nettcpcnt++; return len; -error: + err_delete: + svc_delete_socket(svsk); + return -EAGAIN; + + error: if (len == -EAGAIN) { dprintk("RPC: TCP recvfrom got EAGAIN\n"); - svc_sock_received(svsk, ready); /* Clear data ready */ + svc_sock_received(svsk); } else { printk(KERN_NOTICE "%s: recvfrom returned errno %d\n", svsk->sk_server->sv_name, -len); - svc_sock_received(svsk, 0); + svc_sock_received(svsk); } return len; @@ -737,8 +869,6 @@ /* * Send out data on TCP socket. - * FIXME: Make the sendto call non-blocking in order not to hang - * a daemon on a dead client. Requires write queue maintenance. */ static int svc_tcp_sendto(struct svc_rqst *rqstp) @@ -759,10 +889,8 @@ printk(KERN_NOTICE "rpc-srv/tcp: %s: sent only %d bytes of %d - should shutdown socket\n", rqstp->rq_sock->sk_server->sv_name, sent, bufp->len << 2); - /* FIXME: should shutdown the socket, or allocate more memort - * or wait and try again or something. Otherwise - * client will get confused - */ + svc_delete_socket(rqstp->rq_sock); + sent = -EAGAIN; } return sent; } @@ -782,21 +910,77 @@ dprintk("setting up TCP socket for reading\n"); sk->state_change = svc_tcp_state_change; sk->data_ready = svc_tcp_data_ready; + sk->write_space = svc_write_space; svsk->sk_reclen = 0; svsk->sk_tcplen = 0; + + /* sndbuf needs to have room for one request + * per thread, otherwise we can stall even when the + * network isn't a bottleneck. + * rcvbuf just needs to be able to hold a few requests. + * Normally they will be removed from the queue + * as soon a a complete request arrives. + */ + svc_sock_setbufsize(svsk->sk_sock, + svsk->sk_server->sv_nrthreads * + svsk->sk_server->sv_bufsz, + 3 * svsk->sk_server->sv_bufsz); } return 0; } +void +svc_sock_update_bufs(struct svc_serv *serv) +{ + /* + * The number of server threads has changed. Update + * rcvbuf and sndbuf accordingly on all sockets + */ + struct list_head *le; + + spin_lock_bh(&serv->sv_lock); + list_for_each(le, &serv->sv_permsocks) { + struct svc_sock *svsk = + list_entry(le, struct svc_sock, sk_list); + struct socket *sock = svsk->sk_sock; + if (sock->type == SOCK_DGRAM) { + /* udp sockets need large rcvbuf as all pending + * requests are still in that buffer. + * As outgoing requests do not wait for an + * ACK, only a moderate sndbuf is needed + */ + svc_sock_setbufsize(sock, + 5 * serv->sv_bufsz, + (serv->sv_nrthreads+2)* serv->sv_bufsz); + } else if (svsk->sk_sk->state != TCP_LISTEN) { + printk(KERN_ERR "RPC update_bufs: permanent sock neither UDP or TCP_LISTEN\n"); + } + } + list_for_each(le, &serv->sv_tempsocks) { + struct svc_sock *svsk = + list_entry(le, struct svc_sock, sk_list); + struct socket *sock = svsk->sk_sock; + if (sock->type == SOCK_STREAM) { + /* See svc_tcp_init above for rationale on buffer sizes */ + svc_sock_setbufsize(sock, + serv->sv_nrthreads * + serv->sv_bufsz, + 3 * serv->sv_bufsz); + } else + printk(KERN_ERR "RPC update_bufs: temp sock not TCP\n"); + } + spin_unlock_bh(&serv->sv_lock); +} + /* * Receive the next request on any socket. */ int svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout) { - struct svc_sock *svsk; + struct svc_sock *svsk =NULL; int len; DECLARE_WAITQUEUE(wait, current); @@ -820,9 +1004,28 @@ return -EINTR; spin_lock_bh(&serv->sv_lock); - if ((svsk = svc_sock_dequeue(serv)) != NULL) { + if (!list_empty(&serv->sv_tempsocks)) { + svsk = list_entry(serv->sv_tempsocks.next, + struct svc_sock, sk_list); + /* apparently the "standard" is that clients close + * idle connections after 5 minutes, servers after + * 6 minutes + * http://www.connectathon.org/talks96/nfstcp.pdf + */ + if (CURRENT_TIME - svsk->sk_lastrecv < 6*60 + || test_bit(SK_BUSY, &svsk->sk_flags)) + svsk = NULL; + } + if (svsk) { + set_bit(SK_BUSY, &svsk->sk_flags); + set_bit(SK_CLOSE, &svsk->sk_flags); + rqstp->rq_sock = svsk; + svsk->sk_inuse++; + } else if ((svsk = svc_sock_dequeue(serv)) != NULL) { rqstp->rq_sock = svsk; svsk->sk_inuse++; + rqstp->rq_reserved = serv->sv_bufsz; + svsk->sk_reserved += rqstp->rq_reserved; } else { /* No data pending. Go to sleep */ svc_serv_enqueue(serv, rqstp); @@ -859,6 +1062,14 @@ svc_sock_release(rqstp); return -EAGAIN; } + svsk->sk_lastrecv = CURRENT_TIME; + if (test_bit(SK_TEMP, &svsk->sk_flags)) { + /* push active sockets to end of list */ + spin_lock_bh(&serv->sv_lock); + list_del(&svsk->sk_list); + list_add_tail(&svsk->sk_list, &serv->sv_tempsocks); + spin_unlock_bh(&serv->sv_lock); + } rqstp->rq_secure = ntohs(rqstp->rq_addr.sin_port) < 1024; rqstp->rq_userset = 0; @@ -935,8 +1146,9 @@ svsk->sk_sk = inet; svsk->sk_ostate = inet->state_change; svsk->sk_odata = inet->data_ready; + svsk->sk_owspace = inet->write_space; svsk->sk_server = serv; - spin_lock_init(&svsk->sk_lock); + svsk->sk_lastrecv = CURRENT_TIME; /* Initialize the socket */ if (sock->type == SOCK_DGRAM) @@ -956,9 +1168,16 @@ return NULL; } + spin_lock_bh(&serv->sv_lock); - svsk->sk_list = serv->sv_allsocks; - serv->sv_allsocks = svsk; + if (!pmap_register) { + set_bit(SK_TEMP, &svsk->sk_flags); + list_add(&svsk->sk_list, &serv->sv_tempsocks); + serv->sv_tmpcnt++; + } else { + clear_bit(SK_TEMP, &svsk->sk_flags); + list_add(&svsk->sk_list, &serv->sv_permsocks); + } spin_unlock_bh(&serv->sv_lock); dprintk("svc: svc_setup_socket created %p (inet %p)\n", @@ -1019,7 +1238,6 @@ void svc_delete_socket(struct svc_sock *svsk) { - struct svc_sock **rsk; struct svc_serv *serv; struct sock *sk; @@ -1030,23 +1248,18 @@ sk->state_change = svsk->sk_ostate; sk->data_ready = svsk->sk_odata; + sk->write_space = svsk->sk_owspace; spin_lock_bh(&serv->sv_lock); - for (rsk = &serv->sv_allsocks; *rsk; rsk = &(*rsk)->sk_list) { - if (*rsk == svsk) - break; - } - if (!*rsk) { - spin_unlock_bh(&serv->sv_lock); - return; - } - *rsk = svsk->sk_list; - if (svsk->sk_qued) - rpc_remove_list(&serv->sv_sockets, svsk); + list_del(&svsk->sk_list); + if (test_bit(SK_TEMP, &svsk->sk_flags)) + serv->sv_tmpcnt--; + if (test_bit(SK_QUED, &svsk->sk_flags)) + list_del(&svsk->sk_ready); - svsk->sk_dead = 1; + set_bit(SK_DEAD, &svsk->sk_flags); if (!svsk->sk_inuse) { spin_unlock_bh(&serv->sv_lock); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/sunrpc/xprt.c linux.19pre5-ac1/net/sunrpc/xprt.c --- linux.19p5/net/sunrpc/xprt.c Thu Apr 4 13:21:18 2002 +++ linux.19pre5-ac1/net/sunrpc/xprt.c Mon Mar 25 18:18:33 2002 @@ -538,25 +538,15 @@ static inline struct rpc_rqst * xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid) { - struct rpc_task *head, *task; struct rpc_rqst *req; - int safe = 0; + struct list_head *le; + struct rpc_task *task; spin_lock_bh(&rpc_queue_lock); - if ((head = xprt->pending.task) != NULL) { - task = head; - do { - if ((req = task->tk_rqstp) && req->rq_xid == xid) - goto out; - task = task->tk_next; - if (++safe > 100) { - printk("xprt_lookup_rqst: loop in Q!\n"); - goto out_bad; - } - } while (task != head); - } + task_for_each(task, le, &xprt->pending.tasks) + if ((req = task->tk_rqstp) && req->rq_xid == xid) + goto out; dprintk("RPC: unknown XID %08x in reply.\n", xid); - out_bad: req = NULL; out: if (req && !__rpc_lock_task(req->rq_task)) @@ -1482,9 +1472,9 @@ } else xprt_default_timeout(&xprt->timeout, xprt->prot); - xprt->pending = RPC_INIT_WAITQ("xprt_pending"); - xprt->sending = RPC_INIT_WAITQ("xprt_sending"); - xprt->backlog = RPC_INIT_WAITQ("xprt_backlog"); + INIT_RPC_WAITQ(&xprt->pending, "xprt_pending"); + INIT_RPC_WAITQ(&xprt->sending, "xprt_sending"); + INIT_RPC_WAITQ(&xprt->backlog, "xprt_backlog"); /* initialize free list */ for (i = 0, req = xprt->slot; i < RPC_MAXREQS-1; i++, req++) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/unix/af_unix.c linux.19pre5-ac1/net/unix/af_unix.c --- linux.19p5/net/unix/af_unix.c Thu Apr 4 13:21:18 2002 +++ linux.19pre5-ac1/net/unix/af_unix.c Mon Mar 25 18:18:33 2002 @@ -565,10 +565,8 @@ addr->hash)) { write_unlock(&unix_table_lock); /* Sanity yield. It is unusual case, but yet... */ - if (!(ordernum&0xFF)) { - current->policy |= SCHED_YIELD; - schedule(); - } + if (!(ordernum&0xFF)) + yield(); goto retry; } addr->hash ^= sk->type; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/scripts/extract-ikconfig linux.19pre5-ac1/scripts/extract-ikconfig --- linux.19p5/scripts/extract-ikconfig Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/scripts/extract-ikconfig Fri Mar 15 22:34:00 2002 @@ -0,0 +1,17 @@ +#! /bin/bash -x +# extracts .config info from a [b]zImage file +# uses: binoffset (new), dd, zcat, strings, grep +# $arg1 is [b]zImage filename + +HDR=`binoffset $1 0x1f 0x8b 0x08 0x0` +PID=$$ +TMPFILE="$1.vmlin.$PID" + +# dd if=$1 bs=1 skip=$HDR | zcat - | strings /dev/stdin \ +# | grep "[A-Za-z_0-9]=[ynm]$" | sed "s/^/CONFIG_/" > $1.oldconfig.$PID +# exit + +dd if=$1 bs=1 skip=$HDR | zcat - > $TMPFILE +strings $TMPFILE | grep "^[\#[:blank:]]*CONFIG_[A-Za-z_0-9]*" > $1.oldconfig.$PID +wc $1.oldconfig.$PID +rm $TMPFILE diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/scripts/mkconfigs.c linux.19pre5-ac1/scripts/mkconfigs.c --- linux.19p5/scripts/mkconfigs.c Thu Jan 1 01:00:00 1970 +++ linux.19pre5-ac1/scripts/mkconfigs.c Wed Mar 20 15:47:46 2002 @@ -0,0 +1,181 @@ +/*************************************************************************** + * mkconfigs.c + * (C) 2002 Randy Dunlap + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the 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. + +# Rules for scripts/mkconfigs.c input.config output.c +# to generate configs.c from linux/.config: +# - drop lines that begin with '#' +# - drop blank lines +# - lines that use double-quotes must \\-escape-quote them + +################## skeleton configs.c file: #################### + +#include +#include + +static char *configs[] __initdata = + + , + +; + +################### end configs.c file ###################### + + * Changelog for ver. 0.2, 2002-02-15, rddunlap@osdl.org: + - strip leading "CONFIG_" from config option strings; + - use "static" and "__attribute__((unused))"; + - don't use EXPORT_SYMBOL(); + - separate each config line with \newline instead of space; + + * Changelog for ver. 0.3, 2002-02-18, rddunlap@osdl.org: + - keep all "not set" comment lines from .config so that 'make *config' + will be happy, but don't keep other comments; + - keep leading "CONFIG_" on each line; + +****************************************************************/ + +#include +#include +#include +#include + +#define VERSION "0.2" +#define LINE_SIZE 1000 + +int include_all_lines = 1; // whether to include "=n" lines in the output + +void usage (const char *progname) +{ + fprintf (stderr, "%s ver. %s\n", progname, VERSION); + fprintf (stderr, "usage: %s input.config.name path/configs.c\n", + progname); + exit (1); +} + +void make_intro (FILE *sourcefile) +{ + fprintf (sourcefile, "#include \n"); +///// fprintf (sourcefile, "#include \n"); + fprintf (sourcefile, "\n"); +///// fprintf (sourcefile, "char *configs[] __initdata = {\n"); + fprintf (sourcefile, "static char __attribute__ ((unused)) *configs[] __initdata = {\n"); + fprintf (sourcefile, " \"CONFIG_BEGIN=n\\n\" ,\n"); +} + +void make_ending (FILE *sourcefile) +{ + fprintf (sourcefile, " \"CONFIG_END=n\\n\"\n"); + fprintf (sourcefile, "};\n"); +///// fprintf (sourcefile, "EXPORT_SYMBOL (configs);\n"); +} + +void make_lines (FILE *configfile, FILE *sourcefile) +{ + char cfgline[LINE_SIZE]; + char *ch; + + while (fgets (cfgline, LINE_SIZE, configfile)) { + /* kill the trailing newline in cfgline */ + cfgline[strlen (cfgline) - 1] = '\0'; + + /* don't keep #-only line or an empty/blank line */ + if ((cfgline[0] == '#' && cfgline[1] == '\0') || + cfgline[0] == '\0') + continue; + + if (!include_all_lines && + cfgline[0] == '#') // strip out all comment lines + continue; + + /* really only want to keep lines that begin with + * "CONFIG_" or "# CONFIG_" */ + if (strncmp (cfgline, "CONFIG_", 7) && + strncmp (cfgline, "# CONFIG_", 9)) + continue; + + /* + * use strchr() to check for "-quote in cfgline; + * if not found, output the line, quoted; + * if found, output a char at a time, with \\-quote + * preceding double-quote chars + */ + if (!strchr (cfgline, '"')) { + fprintf (sourcefile, " \"%s\\n\" ,\n", cfgline); + continue; + } + + /* go to char-at-a-time mode for this config and + * precede any double-quote with a backslash */ + fprintf (sourcefile, " \""); /* lead-in */ + for (ch = cfgline; *ch; ch++) { + if (*ch == '"') + fputc ('\\', sourcefile); + fputc (*ch, sourcefile); + } + fprintf (sourcefile, "\\n\" ,\n"); + } +} + +int make_configs (FILE *configfile, FILE *sourcefile) +{ + make_intro (sourcefile); + make_lines (configfile, sourcefile); + make_ending (sourcefile); +} + +int main (int argc, char *argv[]) +{ + char *progname = argv[0]; + char *configname, *sourcename; + FILE *configfile, *sourcefile; + + if (argc != 3) + usage (progname); + + configname = argv[1]; + sourcename = argv[2]; + + configfile = fopen (configname, "r"); + if (!configfile) { + fprintf (stderr, "%s: cannot open '%s'\n", + progname, configname); + exit (2); + } + sourcefile = fopen (sourcename, "w"); + if (!sourcefile) { + fprintf (stderr, "%s: cannot open '%s'\n", + progname, sourcename); + exit (2); + } + + make_configs (configfile, sourcefile); + + if (fclose (sourcefile)) { + fprintf (stderr, "%s: error %d closing '%s'\n", + progname, errno, sourcename); + exit (3); + } + if (fclose (configfile)) { + fprintf (stderr, "%s: error %d closing '%s'\n", + progname, errno, configname); + exit (3); + } + + exit (0); +} + +/* end mkconfigs.c */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/scripts/mkspec linux.19pre5-ac1/scripts/mkspec --- linux.19p5/scripts/mkspec Thu Apr 4 13:21:18 2002 +++ linux.19pre5-ac1/scripts/mkspec Tue Mar 26 18:49:42 2002 @@ -42,6 +42,7 @@ echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make modules_install' echo 'cp arch/i386/boot/bzImage $RPM_BUILD_ROOT'"/boot/vmlinuz-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION" echo 'cp System.map $RPM_BUILD_ROOT'"/boot/System.map-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION" +echo 'cp .config $RPM_BUILD_ROOT'"/boot/config-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION" echo "" echo "%clean" echo '#echo -rf $RPM_BUILD_ROOT'